@projectcor/maia-components 2.11.31-1 → 2.11.31-3

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 (65) hide show
  1. package/lib/components/atoms/FeedbackButton/FeedbackButton.styles.js +2 -2
  2. package/lib/components/atoms/icons/ChatConversation.js +40 -0
  3. package/lib/components/atoms/icons/MaiaChatLayoutMenuIcon.js +33 -0
  4. package/lib/components/atoms/icons/index.js +3 -1
  5. package/lib/components/molecules/ChatAIClientSelector/ChatAIClientSelector.js +41 -10
  6. package/lib/components/molecules/ChatAIContent/ChatAIContent.js +7 -4
  7. package/lib/components/molecules/ChatAIHistory/ChatAIHistory.js +16 -3
  8. package/lib/components/molecules/ChatAIHome/ChatAIHome.js +54 -44
  9. package/lib/components/molecules/ChatAIHome/styles.js +43 -35
  10. package/lib/components/molecules/ChatAIMessages/ChatAIMessages.js +204 -198
  11. package/lib/components/molecules/ChatAIMessages/ChatDaySeparator.js +43 -0
  12. package/lib/components/molecules/ChatAIMessages/ChatDaySeparator.styles.js +11 -0
  13. package/lib/components/molecules/ChatAIMessages/chatMessageUtils.js +5 -0
  14. package/lib/components/molecules/ChatAIModal/ChatAIModal.js +343 -100
  15. package/lib/components/molecules/ChatAIModal/ChatAIModal.styles.js +28 -15
  16. package/lib/components/molecules/ChatAIModal/components/ChatAiModalHeader/ChatAiModalHeader.js +91 -18
  17. package/lib/components/molecules/ChatAIModal/components/ChatAiModalHeader/ChatAiModalHeader.styles.js +17 -2
  18. package/lib/components/molecules/ChatAIModal/floatingPanelMotion/FloatingPanelMotion.js +13 -0
  19. package/lib/components/molecules/ChatAIModal/floatingPanelMotion/FloatingPanelMotion.styles.js +9 -0
  20. package/lib/components/molecules/ChatAIModal/floatingPanelMotion/constants.js +13 -0
  21. package/lib/components/molecules/ChatAIModal/floatingPanelMotion/index.js +3 -0
  22. package/lib/components/molecules/ChatAIModal/floatingPanelMotion/useFloatingPanelDragTilt.js +57 -0
  23. package/lib/components/molecules/ChatAIModal/layout.js +35 -0
  24. package/lib/components/molecules/ChatAIMyAgents/ChatAIMyAgents.js +10 -9
  25. package/lib/components/molecules/ChatAIProjectSelector/ChatAIProjectSelector.js +37 -6
  26. package/lib/components/molecules/Sidebar/Sidebar.js +269 -323
  27. package/lib/components/molecules/Sidebar/Sidebar.layout.styles.js +18 -23
  28. package/lib/components/molecules/Sidebar/Sidebar.styles.js +54 -37
  29. package/lib/components/molecules/Sidebar/SidebarChats.styles.js +73 -0
  30. package/lib/components/molecules/Sidebar/SidebarChatsSection.js +69 -0
  31. package/lib/components/molecules/Sidebar/SidebarChatsSectionModal.js +150 -0
  32. package/lib/components/molecules/Sidebar/SidebarHistoryChat.js +238 -0
  33. package/lib/components/molecules/Sidebar/sidebarChats.helpers.js +70 -0
  34. package/lib/components/molecules/Sidebar/sidebarChats.types.js +14 -0
  35. package/lib/dev/Providers.js +2 -2
  36. package/lib/dev/fixtures/devUser.js +173 -0
  37. package/lib/dev/fixtures/mockedUser.js +169 -0
  38. package/lib/hooks/useChatManager/useChatManager.js +35 -85
  39. package/lib/hooks/useChats/useChats.js +12 -4
  40. package/lib/hooks/useOrchestratorStream/useOrchestratorStream.js +76 -142
  41. package/lib/hooks/useProjectSearch.js +11 -4
  42. package/lib/lang/br/index.js +19 -2
  43. package/lib/lang/en/index.js +19 -2
  44. package/lib/lang/es/index.js +19 -2
  45. package/lib/lang/fr/index.js +19 -2
  46. package/lib/services/maia/Chats/getChatMessagesV2.js +114 -0
  47. package/lib/services/maia/Chats/getChatsByUserId.js +14 -8
  48. package/lib/services/maia/Chats/getSessionByAgent.js +66 -0
  49. package/lib/services/maia/Chats/getSessionsGroupedV2.js +70 -0
  50. package/lib/services/maia/Chats/index.js +7 -1
  51. package/lib/services/maia/Orchestrator/orchestrator.js +6 -4
  52. package/lib/services/maia/client.js +44 -9
  53. package/lib/services/query/projectSearchByValueQuery.js +2 -2
  54. package/lib/store/chatsStore.types.js +10 -2
  55. package/lib/store/useChatsStore.js +75 -37
  56. package/lib/types/Chat.js +3 -1
  57. package/lib/types/Project.js +1 -1
  58. package/package.json +1 -1
  59. package/lib/hooks/useSmoothStreamText/index.js +0 -2
  60. package/lib/hooks/useSmoothStreamText/useSmoothStreamText.js +0 -292
  61. package/lib/hooks/useStreamingMessage/index.js +0 -3
  62. package/lib/hooks/useStreamingMessage/streamingStore.js +0 -69
  63. package/lib/hooks/useStreamingMessage/useStreamingMessage.js +0 -22
  64. package/lib/mocks/mockChats.js +0 -395
  65. package/lib/mocks/mockedUser.js +0 -169
@@ -1,292 +0,0 @@
1
- import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
- /* eslint-disable no-console */
3
- import { useEffect, useRef, useState } from 'react';
4
- /**
5
- * Hook que desacopla la cadencia de llegada del texto (stream SSE) de la
6
- * cadencia de renderizado. Usa `requestAnimationFrame` para liberar chars
7
- * a ritmo constante hacia el DOM, eliminando los "frenos" que se producen
8
- * cuando el backend emite ráfagas de tokens.
9
- *
10
- * Cuando `enabled` pasa a false (fin de stream), el texto se completa al
11
- * instante. Durante el streaming, el buffer se vacía dinámicamente apuntando
12
- * al lag configurado.
13
- */
14
- export var useSmoothStreamText = function useSmoothStreamText(targetText, _ref) {
15
- var enabled = _ref.enabled,
16
- _ref$minCharsPerFrame = _ref.minCharsPerFrame,
17
- minCharsPerFrame = _ref$minCharsPerFrame === void 0 ? 1 : _ref$minCharsPerFrame,
18
- _ref$maxCharsPerFrame = _ref.maxCharsPerFrame,
19
- maxCharsPerFrame = _ref$maxCharsPerFrame === void 0 ? 24 : _ref$maxCharsPerFrame,
20
- _ref$targetLagMs = _ref.targetLagMs,
21
- targetLagMs = _ref$targetLagMs === void 0 ? 120 : _ref$targetLagMs,
22
- _ref$snapToWordBounda = _ref.snapToWordBoundary,
23
- snapToWordBoundary = _ref$snapToWordBounda === void 0 ? false : _ref$snapToWordBounda,
24
- _ref$adaptToBackendRa = _ref.adaptToBackendRate,
25
- adaptToBackendRate = _ref$adaptToBackendRa === void 0 ? false : _ref$adaptToBackendRa,
26
- _ref$backendRateFacto = _ref.backendRateFactor,
27
- backendRateFactor = _ref$backendRateFacto === void 0 ? 0.95 : _ref$backendRateFacto,
28
- targetBufferMs = _ref.targetBufferMs,
29
- _ref$bufferCorrection = _ref.bufferCorrectionMs,
30
- bufferCorrectionMs = _ref$bufferCorrection === void 0 ? 500 : _ref$bufferCorrection,
31
- _ref$minBufferChars = _ref.minBufferChars,
32
- minBufferChars = _ref$minBufferChars === void 0 ? 40 : _ref$minBufferChars,
33
- _ref$warmupMs = _ref.warmupMs,
34
- warmupMs = _ref$warmupMs === void 0 ? 0 : _ref$warmupMs,
35
- _ref$debug = _ref.debug,
36
- debug = _ref$debug === void 0 ? false : _ref$debug,
37
- _ref$debugLabel = _ref.debugLabel,
38
- debugLabel = _ref$debugLabel === void 0 ? 'smoothStream' : _ref$debugLabel;
39
- var _useState = useState(function () {
40
- return enabled ? '' : targetText;
41
- }),
42
- _useState2 = _slicedToArray(_useState, 2),
43
- displayed = _useState2[0],
44
- setDisplayed = _useState2[1];
45
- var targetRef = useRef(targetText);
46
- var displayedLenRef = useRef(displayed.length);
47
- var rafRef = useRef(null);
48
- var lastTickRef = useRef(0);
49
-
50
- // Medición de la cadencia del backend: se actualiza cuando cambia targetText.
51
- var lastTargetLenRef = useRef(0);
52
- var lastTargetUpdateRef = useRef(0);
53
- // Estimación EMA de chars/ms producidos por el backend.
54
- var backendCharsPerMsRef = useRef(0);
55
- // Timestamp del primer chunk recibido (para warmup).
56
- var firstChunkAtRef = useRef(0);
57
- // Si el warmup ya terminó (una vez true, no vuelve a activarse en este stream).
58
- var warmupDoneRef = useRef(false);
59
-
60
- // Métricas para debug
61
- var metricsRef = useRef({
62
- framesWithBuffer: 0,
63
- framesIdle: 0,
64
- totalCharsEmitted: 0,
65
- maxBuffer: 0,
66
- idleTimeMs: 0,
67
- chunksSeen: 0,
68
- interChunkSum: 0,
69
- interChunkMax: 0,
70
- lastLogAt: 0,
71
- streamStartAt: 0
72
- });
73
- useEffect(function () {
74
- var now = typeof performance !== 'undefined' ? performance.now() : Date.now();
75
- var prevTargetLen = lastTargetLenRef.current;
76
- var deltaChars = targetText.length - prevTargetLen;
77
- var prevTargetAt = lastTargetUpdateRef.current;
78
- if (enabled && deltaChars > 0) {
79
- if (firstChunkAtRef.current === 0) firstChunkAtRef.current = now;
80
- }
81
- if (enabled && deltaChars > 0 && prevTargetAt > 0) {
82
- var dt = Math.max(1, now - prevTargetAt);
83
- var rate = deltaChars / dt;
84
- var prevRate = backendCharsPerMsRef.current;
85
- // EMA suave (alpha = 0.2) para absorber jitter y seguir la tendencia.
86
- backendCharsPerMsRef.current = prevRate === 0 ? rate : prevRate * 0.8 + rate * 0.2;
87
- if (debug) {
88
- var m = metricsRef.current;
89
- m.chunksSeen += 1;
90
- m.interChunkSum += dt;
91
- if (dt > m.interChunkMax) m.interChunkMax = dt;
92
- }
93
- }
94
- if (enabled && targetText.length !== prevTargetLen) {
95
- lastTargetLenRef.current = targetText.length;
96
- lastTargetUpdateRef.current = now;
97
- }
98
- targetRef.current = targetText;
99
- if (!enabled) {
100
- if (rafRef.current != null) {
101
- cancelAnimationFrame(rafRef.current);
102
- rafRef.current = null;
103
- }
104
- lastTickRef.current = 0;
105
- if (debug && metricsRef.current.streamStartAt > 0) {
106
- var _m = metricsRef.current;
107
- var totalMs = now - _m.streamStartAt;
108
- console.log("[".concat(debugLabel, "] FINAL"), {
109
- totalMs: Math.round(totalMs),
110
- finalChars: targetText.length,
111
- backendAvgCharsPerSec: _m.chunksSeen > 0 ? Math.round(targetText.length / totalMs * 1000) : 0,
112
- chunksSeen: _m.chunksSeen,
113
- avgInterChunkMs: _m.chunksSeen > 0 ? Math.round(_m.interChunkSum / _m.chunksSeen) : 0,
114
- maxInterChunkMs: Math.round(_m.interChunkMax),
115
- idleTimeMs: Math.round(_m.idleTimeMs),
116
- idleRatio: totalMs > 0 ? (_m.idleTimeMs / totalMs).toFixed(2) : '0',
117
- maxBuffer: _m.maxBuffer
118
- });
119
- metricsRef.current = {
120
- framesWithBuffer: 0,
121
- framesIdle: 0,
122
- totalCharsEmitted: 0,
123
- maxBuffer: 0,
124
- idleTimeMs: 0,
125
- chunksSeen: 0,
126
- interChunkSum: 0,
127
- interChunkMax: 0,
128
- lastLogAt: 0,
129
- streamStartAt: 0
130
- };
131
- }
132
- if (displayedLenRef.current !== targetText.length) {
133
- displayedLenRef.current = targetText.length;
134
- setDisplayed(targetText);
135
- }
136
- // Reset de cadencia cuando se apaga para no contaminar el próximo stream.
137
- lastTargetLenRef.current = 0;
138
- lastTargetUpdateRef.current = 0;
139
- backendCharsPerMsRef.current = 0;
140
- firstChunkAtRef.current = 0;
141
- warmupDoneRef.current = false;
142
- return undefined;
143
- }
144
- if (debug && metricsRef.current.streamStartAt === 0) {
145
- metricsRef.current.streamStartAt = now;
146
- metricsRef.current.lastLogAt = now;
147
- console.log("[".concat(debugLabel, "] START"), {
148
- targetLagMs: targetLagMs,
149
- maxCharsPerFrame: maxCharsPerFrame,
150
- adaptToBackendRate: adaptToBackendRate,
151
- backendRateFactor: backendRateFactor,
152
- targetBufferMs: targetBufferMs,
153
- bufferCorrectionMs: bufferCorrectionMs,
154
- minBufferChars: minBufferChars,
155
- warmupMs: warmupMs
156
- });
157
- }
158
- if (displayedLenRef.current > targetText.length) {
159
- displayedLenRef.current = 0;
160
- setDisplayed('');
161
- }
162
- if (rafRef.current != null) return undefined;
163
- var logMetrics = function logMetrics(tickNow) {
164
- var m = metricsRef.current;
165
- var el = targetRef.current;
166
- var buffer = el.length - displayedLenRef.current;
167
- var windowMs = Math.max(1, tickNow - m.lastLogAt);
168
- var totalFrames = m.framesWithBuffer + m.framesIdle;
169
- var fps = Math.round(totalFrames / windowMs * 1000);
170
- var backendRate = backendCharsPerMsRef.current;
171
- console.log("[".concat(debugLabel, "] tick"), {
172
- elapsedMs: Math.round(tickNow - m.streamStartAt),
173
- buffer: buffer,
174
- displayed: displayedLenRef.current,
175
- target: el.length,
176
- framesWithBuffer: m.framesWithBuffer,
177
- framesIdle: m.framesIdle,
178
- idleRatio: totalFrames > 0 ? (m.framesIdle / totalFrames).toFixed(2) : '0',
179
- fps: fps,
180
- backendCharsPerSec: Math.round(backendRate * 1000),
181
- avgInterChunkMs: m.chunksSeen > 0 ? Math.round(m.interChunkSum / m.chunksSeen) : 0,
182
- maxInterChunkMs: Math.round(m.interChunkMax)
183
- });
184
- m.framesWithBuffer = 0;
185
- m.framesIdle = 0;
186
- m.lastLogAt = tickNow;
187
- };
188
- var _tick = function tick(tickNow) {
189
- var prev = lastTickRef.current;
190
- var dt = prev ? Math.min(tickNow - prev, 64) : 16;
191
- lastTickRef.current = tickNow;
192
- var target = targetRef.current;
193
- var currentLen = displayedLenRef.current;
194
- var remaining = target.length - currentLen;
195
- if (remaining <= 0) {
196
- if (debug) {
197
- metricsRef.current.framesIdle += 1;
198
- metricsRef.current.idleTimeMs += dt;
199
- }
200
- rafRef.current = requestAnimationFrame(_tick);
201
- // Log periódico aún estando idle (para ver si estamos esperando chunks)
202
- if (debug && tickNow - metricsRef.current.lastLogAt > 500) {
203
- logMetrics(tickNow);
204
- }
205
- return;
206
- }
207
-
208
- // Warmup: al comienzo del stream esperamos `warmupMs` desde el primer
209
- // chunk antes de empezar a pintar. Esto construye un colchón inicial y
210
- // evita arrancar rápido para congelarnos acto seguido si el backend
211
- // tarda mucho en emitir el segundo chunk.
212
- if (!warmupDoneRef.current) {
213
- var firstAt = firstChunkAtRef.current;
214
- var waitedMs = firstAt > 0 ? tickNow - firstAt : 0;
215
- var warmupComplete = warmupMs <= 0 || waitedMs >= warmupMs || target.length >= minBufferChars * 2;
216
- if (!warmupComplete) {
217
- if (debug) {
218
- metricsRef.current.framesIdle += 1;
219
- metricsRef.current.idleTimeMs += dt;
220
- }
221
- rafRef.current = requestAnimationFrame(_tick);
222
- if (debug && tickNow - metricsRef.current.lastLogAt > 500) {
223
- logMetrics(tickNow);
224
- }
225
- return;
226
- }
227
- warmupDoneRef.current = true;
228
- }
229
- if (debug) {
230
- metricsRef.current.framesWithBuffer += 1;
231
- if (remaining > metricsRef.current.maxBuffer) metricsRef.current.maxBuffer = remaining;
232
- }
233
-
234
- // Velocidad base: vaciar el buffer en ~targetLagMs.
235
- var charsPerMs = remaining / targetLagMs;
236
- var effectiveCharsPerMs = charsPerMs;
237
- var backendRate = backendCharsPerMsRef.current;
238
- if (adaptToBackendRate && backendRate > 0) {
239
- if (typeof targetBufferMs === 'number') {
240
- // Control proporcional: mantener el buffer en torno al colchón
241
- // objetivo. Si bufferMs < target → frenamos por debajo del backend
242
- // para acumular; si bufferMs > target → aceleramos para descargar.
243
- // En equilibrio, pintamos al ritmo promedio del backend.
244
- // Piso absoluto: el colchón nunca baja de `minBufferChars` aunque
245
- // el backend esté mandando lento al inicio del stream.
246
- var targetBufferChars = Math.max(minBufferChars, targetBufferMs * backendRate);
247
- var bufferDelta = remaining - targetBufferChars;
248
- // Corrección tiene unidades de chars/ms. bufferCorrectionMs controla
249
- // qué tan rápido el buffer real converge al objetivo.
250
- var correction = bufferDelta / Math.max(1, bufferCorrectionMs);
251
- effectiveCharsPerMs = Math.max(0, backendRate + correction);
252
- // Acotar por la velocidad de "vaciar en targetLagMs" para que si
253
- // de pronto hay un pico gigante de buffer no salgamos disparados.
254
- effectiveCharsPerMs = Math.min(effectiveCharsPerMs, charsPerMs);
255
- } else {
256
- // Modo simple: cap a la tasa del backend * factor.
257
- var cap = backendRate * backendRateFactor;
258
- effectiveCharsPerMs = Math.min(effectiveCharsPerMs, cap);
259
- }
260
- }
261
- var rawStep = Math.ceil(effectiveCharsPerMs * dt);
262
- var step = Math.max(minCharsPerFrame, Math.min(maxCharsPerFrame, rawStep));
263
- var nextLen = Math.min(target.length, currentLen + step);
264
- if (snapToWordBoundary && nextLen < target.length) {
265
- var slice = target.slice(currentLen, nextLen);
266
- var lastBoundary = Math.max(slice.lastIndexOf(' '), slice.lastIndexOf('\n'), slice.lastIndexOf('\t'));
267
- if (lastBoundary >= 0) {
268
- nextLen = currentLen + lastBoundary + 1;
269
- }
270
- }
271
- if (nextLen !== currentLen) {
272
- if (debug) metricsRef.current.totalCharsEmitted += nextLen - currentLen;
273
- displayedLenRef.current = nextLen;
274
- setDisplayed(target.slice(0, nextLen));
275
- }
276
- if (debug && tickNow - metricsRef.current.lastLogAt > 500) {
277
- logMetrics(tickNow);
278
- }
279
- rafRef.current = requestAnimationFrame(_tick);
280
- };
281
- rafRef.current = requestAnimationFrame(_tick);
282
- return function () {
283
- if (rafRef.current != null) {
284
- cancelAnimationFrame(rafRef.current);
285
- rafRef.current = null;
286
- }
287
- lastTickRef.current = 0;
288
- };
289
- }, [targetText, enabled, minCharsPerFrame, maxCharsPerFrame, targetLagMs, snapToWordBoundary, adaptToBackendRate, backendRateFactor, targetBufferMs, bufferCorrectionMs, minBufferChars, warmupMs, debug, debugLabel]);
290
- return displayed;
291
- };
292
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ1c2VFZmZlY3QiLCJ1c2VSZWYiLCJ1c2VTdGF0ZSIsInVzZVNtb290aFN0cmVhbVRleHQiLCJ0YXJnZXRUZXh0IiwiX3JlZiIsImVuYWJsZWQiLCJfcmVmJG1pbkNoYXJzUGVyRnJhbWUiLCJtaW5DaGFyc1BlckZyYW1lIiwiX3JlZiRtYXhDaGFyc1BlckZyYW1lIiwibWF4Q2hhcnNQZXJGcmFtZSIsIl9yZWYkdGFyZ2V0TGFnTXMiLCJ0YXJnZXRMYWdNcyIsIl9yZWYkc25hcFRvV29yZEJvdW5kYSIsInNuYXBUb1dvcmRCb3VuZGFyeSIsIl9yZWYkYWRhcHRUb0JhY2tlbmRSYSIsImFkYXB0VG9CYWNrZW5kUmF0ZSIsIl9yZWYkYmFja2VuZFJhdGVGYWN0byIsImJhY2tlbmRSYXRlRmFjdG9yIiwidGFyZ2V0QnVmZmVyTXMiLCJfcmVmJGJ1ZmZlckNvcnJlY3Rpb24iLCJidWZmZXJDb3JyZWN0aW9uTXMiLCJfcmVmJG1pbkJ1ZmZlckNoYXJzIiwibWluQnVmZmVyQ2hhcnMiLCJfcmVmJHdhcm11cE1zIiwid2FybXVwTXMiLCJfcmVmJGRlYnVnIiwiZGVidWciLCJfcmVmJGRlYnVnTGFiZWwiLCJkZWJ1Z0xhYmVsIiwiX3VzZVN0YXRlIiwiX3VzZVN0YXRlMiIsIl9zbGljZWRUb0FycmF5IiwiZGlzcGxheWVkIiwic2V0RGlzcGxheWVkIiwidGFyZ2V0UmVmIiwiZGlzcGxheWVkTGVuUmVmIiwibGVuZ3RoIiwicmFmUmVmIiwibGFzdFRpY2tSZWYiLCJsYXN0VGFyZ2V0TGVuUmVmIiwibGFzdFRhcmdldFVwZGF0ZVJlZiIsImJhY2tlbmRDaGFyc1Blck1zUmVmIiwiZmlyc3RDaHVua0F0UmVmIiwid2FybXVwRG9uZVJlZiIsIm1ldHJpY3NSZWYiLCJmcmFtZXNXaXRoQnVmZmVyIiwiZnJhbWVzSWRsZSIsInRvdGFsQ2hhcnNFbWl0dGVkIiwibWF4QnVmZmVyIiwiaWRsZVRpbWVNcyIsImNodW5rc1NlZW4iLCJpbnRlckNodW5rU3VtIiwiaW50ZXJDaHVua01heCIsImxhc3RMb2dBdCIsInN0cmVhbVN0YXJ0QXQiLCJub3ciLCJwZXJmb3JtYW5jZSIsIkRhdGUiLCJwcmV2VGFyZ2V0TGVuIiwiY3VycmVudCIsImRlbHRhQ2hhcnMiLCJwcmV2VGFyZ2V0QXQiLCJkdCIsIk1hdGgiLCJtYXgiLCJyYXRlIiwicHJldlJhdGUiLCJtIiwiY2FuY2VsQW5pbWF0aW9uRnJhbWUiLCJ0b3RhbE1zIiwiY29uc29sZSIsImxvZyIsImNvbmNhdCIsInJvdW5kIiwiZmluYWxDaGFycyIsImJhY2tlbmRBdmdDaGFyc1BlclNlYyIsImF2Z0ludGVyQ2h1bmtNcyIsIm1heEludGVyQ2h1bmtNcyIsImlkbGVSYXRpbyIsInRvRml4ZWQiLCJ1bmRlZmluZWQiLCJsb2dNZXRyaWNzIiwidGlja05vdyIsImVsIiwiYnVmZmVyIiwid2luZG93TXMiLCJ0b3RhbEZyYW1lcyIsImZwcyIsImJhY2tlbmRSYXRlIiwiZWxhcHNlZE1zIiwidGFyZ2V0IiwiYmFja2VuZENoYXJzUGVyU2VjIiwidGljayIsInByZXYiLCJtaW4iLCJjdXJyZW50TGVuIiwicmVtYWluaW5nIiwicmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwiZmlyc3RBdCIsIndhaXRlZE1zIiwid2FybXVwQ29tcGxldGUiLCJjaGFyc1Blck1zIiwiZWZmZWN0aXZlQ2hhcnNQZXJNcyIsInRhcmdldEJ1ZmZlckNoYXJzIiwiYnVmZmVyRGVsdGEiLCJjb3JyZWN0aW9uIiwiY2FwIiwicmF3U3RlcCIsImNlaWwiLCJzdGVwIiwibmV4dExlbiIsInNsaWNlIiwibGFzdEJvdW5kYXJ5IiwibGFzdEluZGV4T2YiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaG9va3MvdXNlU21vb3RoU3RyZWFtVGV4dC91c2VTbW9vdGhTdHJlYW1UZXh0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbmltcG9ydCB7IHVzZUVmZmVjdCwgdXNlUmVmLCB1c2VTdGF0ZSB9IGZyb20gJ3JlYWN0J1xuXG50eXBlIFVzZVNtb290aFN0cmVhbVRleHRPcHRpb25zID0ge1xuICAvKiogU2kgZXN0w6EgZGVzaGFiaWxpdGFkbywgZGV2dWVsdmUgZWwgdGFyZ2V0IHRhbCBjdWFsIChzaW4gYW5pbWFjacOzbikuICovXG4gIGVuYWJsZWQ6IGJvb2xlYW5cbiAgLyoqIENhbnRpZGFkIG3DrW5pbWEgZGUgY2hhcnMgYSBsaWJlcmFyIHBvciBmcmFtZSBjdWFuZG8gaGF5IGJ1ZmZlci4gKi9cbiAgbWluQ2hhcnNQZXJGcmFtZT86IG51bWJlclxuICAvKiogQ290YSBzdXBlcmlvciBkZSBjaGFycyBwb3IgZnJhbWUgcGFyYSBldml0YXIgc2FsdG9zIGdyYW5kZXMuICovXG4gIG1heENoYXJzUGVyRnJhbWU/OiBudW1iZXJcbiAgLyoqXG4gICAqIExhZyBvYmpldGl2byAobXMpIGVudHJlIGVsIHRleHRvIHJlY2liaWRvIHkgZWwgbW9zdHJhZG8uIEVsIGhvb2sgY2FsY3VsYVxuICAgKiBkaW7DoW1pY2FtZW50ZSBlbCBzdGVwIHBvciBmcmFtZSBwYXJhIHZhY2lhciBlbCBidWZmZXIgZW4gfnRhcmdldExhZ01zLlxuICAgKiBWYWxvcmVzIG3DoXMgYmFqb3MgPSBzZSBwb25lIGFsIGTDrWEgbcOhcyByw6FwaWRvIChtZW5vcyBcInN1YXZlXCIpLlxuICAgKi9cbiAgdGFyZ2V0TGFnTXM/OiBudW1iZXJcbiAgLyoqXG4gICAqIFNpIGVzdMOhIGFjdGl2bywgYWwgYXZhbnphciBzZSBkZXRpZW5lIGVuIGVsIMO6bHRpbW8gc2VwYXJhZG9yIGRlIHBhbGFicmFcbiAgICogKGVzcGFjaW8sIHNhbHRvIGRlIGzDrW5lYSwgc2lnbm9zIGRlIHB1bnR1YWNpw7NuKSBwYXJhIGV2aXRhciByZW5kZXJpemFyXG4gICAqIG1hcmtkb3duIFwiY29ydGFkbyBhIGxhIG1pdGFkXCIgeSBkYXIgdW5hIHNlbnNhY2nDs24gbcOhcyBuYXR1cmFsLlxuICAgKi9cbiAgc25hcFRvV29yZEJvdW5kYXJ5PzogYm9vbGVhblxuICAvKipcbiAgICogU2kgZXN0w6EgYWN0aXZvLCBtaWRlIGxhIHRhc2EgcHJvbWVkaW8gYSBsYSBxdWUgY3JlY2UgZWwgdGFyZ2V0IChjYWRlbmNpYVxuICAgKiBkZWwgYmFja2VuZCBlbiBjaGFycy9tcykgeSBsaW1pdGEgbGEgdmVsb2NpZGFkIGRlIHBpbnRhZG8gYSBlc2EgdGFzYVxuICAgKiAobXVsdGlwbGljYWRhIHBvciBgYmFja2VuZFJhdGVGYWN0b3JgKS4gRXN0byBldml0YSBlbCBjYXNvIHTDrXBpY28gZGVcbiAgICogXCJwaW50byByw6FwaWRvIGhhc3RhIHZhY2lhciBlbCBidWZmZXIgeSBkZXNwdcOpcyBzZSBjb25nZWxhIGVzcGVyYW5kb1xuICAgKiBhbCBwcsOzeGltbyBjaHVuayBkZWwgYmFja2VuZFwiLlxuICAgKi9cbiAgYWRhcHRUb0JhY2tlbmRSYXRlPzogYm9vbGVhblxuICAvKipcbiAgICogRmFjdG9yIGFwbGljYWRvIGEgbGEgdGFzYSBkZWwgYmFja2VuZCBjdWFuZG8gYGFkYXB0VG9CYWNrZW5kUmF0ZWAgZXN0w6FcbiAgICogYWN0aXZvLiBWYWxvcmVzIDwgMSBkZWphbiB1biBjb2xjaMOzbiBjcmVjaWVudGUgKG3DoXMgdG9sZXJhbnRlIGEgcGF1c2FzKTtcbiAgICogdmFsb3JlcyA+IDEgaW50ZW50YW4gYWxjYW56YXIuIERlZmF1bHQ6IDAuOTUuXG4gICAqL1xuICBiYWNrZW5kUmF0ZUZhY3Rvcj86IG51bWJlclxuICAvKipcbiAgICogQ29sY2jDs24gb2JqZXRpdm8gZGUgYnVmZmVyIGV4cHJlc2FkbyBlbiBtcyAoY3XDoW50byB0aWVtcG8gZGUgdGV4dG8gcXVlcmVtb3NcbiAgICogdGVuZXIgc2llbXByZSBhZGVsYW50YWRvIGFsIHBpbnRhZG8pLiBTaSBlc3TDoSBkZWZpbmlkbyBqdW50byBjb25cbiAgICogYGFkYXB0VG9CYWNrZW5kUmF0ZWAsIHNlIHVzYSB1biBjb250cm9sIHByb3BvcmNpb25hbDogY3VhbmRvIGVsIGJ1ZmZlclxuICAgKiBiYWphIGRlbCBvYmpldGl2bywgbGEgdmVsb2NpZGFkIGNhZSBwb3IgZGViYWpvIGRlIGxhIGRlbCBiYWNrZW5kIHBhcmFcbiAgICogcmVsbGVuYXJsbzsgY3VhbmRvIGxvIHN1cGVyYSwgc2UgYWNlbGVyYSBwYXJhIGRlc2NhcmdhcmxvLiBBc8OtIGxhXG4gICAqIGFuaW1hY2nDs24gYWJzb3JiZSBwYXVzYXMgZGVsIGJhY2tlbmQgc2luIHF1ZWRhcnNlIGlkbGUuXG4gICAqXG4gICAqIFZhbG9yIHJlY29tZW5kYWRvOiAzMDDigJM1MDBtcyBzZWfDum4gbGEgZXN0YWJpbGlkYWQgZGVsIGJhY2tlbmQuXG4gICAqL1xuICB0YXJnZXRCdWZmZXJNcz86IG51bWJlclxuICAvKipcbiAgICogQ29uc3RhbnRlIGRlIHRpZW1wbyAobXMpIGRlbCBjb250cm9sYWRvciBkZWwgYnVmZmVyLiBDdWFudG8gbcOhcyBiYWpvLFxuICAgKiBtw6FzIGFncmVzaXZhbWVudGUgY29ycmlnZSBkZXN2w61vcy4gRGVmYXVsdDogNTAwLlxuICAgKi9cbiAgYnVmZmVyQ29ycmVjdGlvbk1zPzogbnVtYmVyXG4gIC8qKlxuICAgKiBQaXNvIGFic29sdXRvIGRlbCBjb2xjaMOzbiBlbiBjaGFyczogZWwgYHRhcmdldEJ1ZmZlckNoYXJzYCBjYWxjdWxhZG8gYVxuICAgKiBwYXJ0aXIgZGUgYHRhcmdldEJ1ZmZlck1zIMOXIGJhY2tlbmRSYXRlYCBudW5jYSBiYWphIGRlIGVzdGUgdmFsb3IuIMOadGlsXG4gICAqIGFsIGNvbWllbnpvIGRlbCBzdHJlYW0gY3VhbmRvIGxhIHRhc2EgZXN0aW1hZGEgZGVsIGJhY2tlbmQgZXMgYmFqYS5cbiAgICogRGVmYXVsdDogNDAuXG4gICAqL1xuICBtaW5CdWZmZXJDaGFycz86IG51bWJlclxuICAvKipcbiAgICogV2FybXVwOiBtcyBxdWUgZWwgaG9vayBlc3BlcmEgXCJhY3VtdWxhbmRvXCIgYW50ZXMgZGUgZW1wZXphciBhIHBpbnRhcixcbiAgICogaW5jbHVzbyBzaSB5YSBoYXkgY2hhcnMgZW4gZWwgYnVmZmVyLiBFdml0YSBlbCB0w61waWNvIFwiYXJyYW5xdWUgcsOhcGlkbyxcbiAgICogY29uZ2VsYW1pZW50b1wiIGN1YW5kbyBlbCBwcmltZXIgY2h1bmsgbGxlZ2EgYW50ZXMgcXVlIGVsIHNlZ3VuZG8gc2VcbiAgICogdGFyZGEgbXVjaG8uIFNpIHNlIGRlZmluZSBjb21vIDAsIG5vIGhheSB3YXJtdXAuIERlZmF1bHQ6IDAuXG4gICAqL1xuICB3YXJtdXBNcz86IG51bWJlclxuICAvKipcbiAgICogTW9kbyBkZWJ1ZzogaW1wcmltZSBtw6l0cmljYXMgY2FkYSB+NTAwbXMgbWllbnRyYXMgYGVuYWJsZWQgPT09IHRydWVgLlxuICAgKiDDmnRpbCBwYXJhIGFqdXN0YXIgYHRhcmdldExhZ01zYCwgYG1heENoYXJzUGVyRnJhbWVgIHkgZXZhbHVhciBzaSBjb252aWVuZVxuICAgKiBhY3RpdmFyIGBhZGFwdFRvQmFja2VuZFJhdGVgLlxuICAgKi9cbiAgZGVidWc/OiBib29sZWFuXG4gIC8qKiBFdGlxdWV0YSBvcGNpb25hbCBwYXJhIGRpc3Rpbmd1aXIgbcO6bHRpcGxlcyBpbnN0YW5jaWFzIGVuIGxvcyBsb2dzLiAqL1xuICBkZWJ1Z0xhYmVsPzogc3RyaW5nXG59XG5cbi8qKlxuICogSG9vayBxdWUgZGVzYWNvcGxhIGxhIGNhZGVuY2lhIGRlIGxsZWdhZGEgZGVsIHRleHRvIChzdHJlYW0gU1NFKSBkZSBsYVxuICogY2FkZW5jaWEgZGUgcmVuZGVyaXphZG8uIFVzYSBgcmVxdWVzdEFuaW1hdGlvbkZyYW1lYCBwYXJhIGxpYmVyYXIgY2hhcnNcbiAqIGEgcml0bW8gY29uc3RhbnRlIGhhY2lhIGVsIERPTSwgZWxpbWluYW5kbyBsb3MgXCJmcmVub3NcIiBxdWUgc2UgcHJvZHVjZW5cbiAqIGN1YW5kbyBlbCBiYWNrZW5kIGVtaXRlIHLDoWZhZ2FzIGRlIHRva2Vucy5cbiAqXG4gKiBDdWFuZG8gYGVuYWJsZWRgIHBhc2EgYSBmYWxzZSAoZmluIGRlIHN0cmVhbSksIGVsIHRleHRvIHNlIGNvbXBsZXRhIGFsXG4gKiBpbnN0YW50ZS4gRHVyYW50ZSBlbCBzdHJlYW1pbmcsIGVsIGJ1ZmZlciBzZSB2YWPDrWEgZGluw6FtaWNhbWVudGUgYXB1bnRhbmRvXG4gKiBhbCBsYWcgY29uZmlndXJhZG8uXG4gKi9cbmV4cG9ydCBjb25zdCB1c2VTbW9vdGhTdHJlYW1UZXh0ID0gKFxuICB0YXJnZXRUZXh0OiBzdHJpbmcsXG4gIHtcbiAgICBlbmFibGVkLFxuICAgIG1pbkNoYXJzUGVyRnJhbWUgPSAxLFxuICAgIG1heENoYXJzUGVyRnJhbWUgPSAyNCxcbiAgICB0YXJnZXRMYWdNcyA9IDEyMCxcbiAgICBzbmFwVG9Xb3JkQm91bmRhcnkgPSBmYWxzZSxcbiAgICBhZGFwdFRvQmFja2VuZFJhdGUgPSBmYWxzZSxcbiAgICBiYWNrZW5kUmF0ZUZhY3RvciA9IDAuOTUsXG4gICAgdGFyZ2V0QnVmZmVyTXMsXG4gICAgYnVmZmVyQ29ycmVjdGlvbk1zID0gNTAwLFxuICAgIG1pbkJ1ZmZlckNoYXJzID0gNDAsXG4gICAgd2FybXVwTXMgPSAwLFxuICAgIGRlYnVnID0gZmFsc2UsXG4gICAgZGVidWdMYWJlbCA9ICdzbW9vdGhTdHJlYW0nLFxuICB9OiBVc2VTbW9vdGhTdHJlYW1UZXh0T3B0aW9uc1xuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgW2Rpc3BsYXllZCwgc2V0RGlzcGxheWVkXSA9IHVzZVN0YXRlPHN0cmluZz4oKCkgPT4gKGVuYWJsZWQgPyAnJyA6IHRhcmdldFRleHQpKVxuXG4gIGNvbnN0IHRhcmdldFJlZiA9IHVzZVJlZih0YXJnZXRUZXh0KVxuICBjb25zdCBkaXNwbGF5ZWRMZW5SZWYgPSB1c2VSZWYoZGlzcGxheWVkLmxlbmd0aClcbiAgY29uc3QgcmFmUmVmID0gdXNlUmVmPG51bWJlciB8IG51bGw+KG51bGwpXG4gIGNvbnN0IGxhc3RUaWNrUmVmID0gdXNlUmVmPG51bWJlcj4oMClcblxuICAvLyBNZWRpY2nDs24gZGUgbGEgY2FkZW5jaWEgZGVsIGJhY2tlbmQ6IHNlIGFjdHVhbGl6YSBjdWFuZG8gY2FtYmlhIHRhcmdldFRleHQuXG4gIGNvbnN0IGxhc3RUYXJnZXRMZW5SZWYgPSB1c2VSZWY8bnVtYmVyPigwKVxuICBjb25zdCBsYXN0VGFyZ2V0VXBkYXRlUmVmID0gdXNlUmVmPG51bWJlcj4oMClcbiAgLy8gRXN0aW1hY2nDs24gRU1BIGRlIGNoYXJzL21zIHByb2R1Y2lkb3MgcG9yIGVsIGJhY2tlbmQuXG4gIGNvbnN0IGJhY2tlbmRDaGFyc1Blck1zUmVmID0gdXNlUmVmPG51bWJlcj4oMClcbiAgLy8gVGltZXN0YW1wIGRlbCBwcmltZXIgY2h1bmsgcmVjaWJpZG8gKHBhcmEgd2FybXVwKS5cbiAgY29uc3QgZmlyc3RDaHVua0F0UmVmID0gdXNlUmVmPG51bWJlcj4oMClcbiAgLy8gU2kgZWwgd2FybXVwIHlhIHRlcm1pbsOzICh1bmEgdmV6IHRydWUsIG5vIHZ1ZWx2ZSBhIGFjdGl2YXJzZSBlbiBlc3RlIHN0cmVhbSkuXG4gIGNvbnN0IHdhcm11cERvbmVSZWYgPSB1c2VSZWY8Ym9vbGVhbj4oZmFsc2UpXG5cbiAgLy8gTcOpdHJpY2FzIHBhcmEgZGVidWdcbiAgY29uc3QgbWV0cmljc1JlZiA9IHVzZVJlZih7XG4gICAgZnJhbWVzV2l0aEJ1ZmZlcjogMCxcbiAgICBmcmFtZXNJZGxlOiAwLFxuICAgIHRvdGFsQ2hhcnNFbWl0dGVkOiAwLFxuICAgIG1heEJ1ZmZlcjogMCxcbiAgICBpZGxlVGltZU1zOiAwLFxuICAgIGNodW5rc1NlZW46IDAsXG4gICAgaW50ZXJDaHVua1N1bTogMCxcbiAgICBpbnRlckNodW5rTWF4OiAwLFxuICAgIGxhc3RMb2dBdDogMCxcbiAgICBzdHJlYW1TdGFydEF0OiAwLFxuICB9KVxuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3Qgbm93ID0gdHlwZW9mIHBlcmZvcm1hbmNlICE9PSAndW5kZWZpbmVkJyA/IHBlcmZvcm1hbmNlLm5vdygpIDogRGF0ZS5ub3coKVxuICAgIGNvbnN0IHByZXZUYXJnZXRMZW4gPSBsYXN0VGFyZ2V0TGVuUmVmLmN1cnJlbnRcbiAgICBjb25zdCBkZWx0YUNoYXJzID0gdGFyZ2V0VGV4dC5sZW5ndGggLSBwcmV2VGFyZ2V0TGVuXG4gICAgY29uc3QgcHJldlRhcmdldEF0ID0gbGFzdFRhcmdldFVwZGF0ZVJlZi5jdXJyZW50XG5cbiAgICBpZiAoZW5hYmxlZCAmJiBkZWx0YUNoYXJzID4gMCkge1xuICAgICAgaWYgKGZpcnN0Q2h1bmtBdFJlZi5jdXJyZW50ID09PSAwKSBmaXJzdENodW5rQXRSZWYuY3VycmVudCA9IG5vd1xuICAgIH1cblxuICAgIGlmIChlbmFibGVkICYmIGRlbHRhQ2hhcnMgPiAwICYmIHByZXZUYXJnZXRBdCA+IDApIHtcbiAgICAgIGNvbnN0IGR0ID0gTWF0aC5tYXgoMSwgbm93IC0gcHJldlRhcmdldEF0KVxuICAgICAgY29uc3QgcmF0ZSA9IGRlbHRhQ2hhcnMgLyBkdFxuICAgICAgY29uc3QgcHJldlJhdGUgPSBiYWNrZW5kQ2hhcnNQZXJNc1JlZi5jdXJyZW50XG4gICAgICAvLyBFTUEgc3VhdmUgKGFscGhhID0gMC4yKSBwYXJhIGFic29yYmVyIGppdHRlciB5IHNlZ3VpciBsYSB0ZW5kZW5jaWEuXG4gICAgICBiYWNrZW5kQ2hhcnNQZXJNc1JlZi5jdXJyZW50ID0gcHJldlJhdGUgPT09IDAgPyByYXRlIDogcHJldlJhdGUgKiAwLjggKyByYXRlICogMC4yXG5cbiAgICAgIGlmIChkZWJ1Zykge1xuICAgICAgICBjb25zdCBtID0gbWV0cmljc1JlZi5jdXJyZW50XG4gICAgICAgIG0uY2h1bmtzU2VlbiArPSAxXG4gICAgICAgIG0uaW50ZXJDaHVua1N1bSArPSBkdFxuICAgICAgICBpZiAoZHQgPiBtLmludGVyQ2h1bmtNYXgpIG0uaW50ZXJDaHVua01heCA9IGR0XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbmFibGVkICYmIHRhcmdldFRleHQubGVuZ3RoICE9PSBwcmV2VGFyZ2V0TGVuKSB7XG4gICAgICBsYXN0VGFyZ2V0TGVuUmVmLmN1cnJlbnQgPSB0YXJnZXRUZXh0Lmxlbmd0aFxuICAgICAgbGFzdFRhcmdldFVwZGF0ZVJlZi5jdXJyZW50ID0gbm93XG4gICAgfVxuXG4gICAgdGFyZ2V0UmVmLmN1cnJlbnQgPSB0YXJnZXRUZXh0XG5cbiAgICBpZiAoIWVuYWJsZWQpIHtcbiAgICAgIGlmIChyYWZSZWYuY3VycmVudCAhPSBudWxsKSB7XG4gICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHJhZlJlZi5jdXJyZW50KVxuICAgICAgICByYWZSZWYuY3VycmVudCA9IG51bGxcbiAgICAgIH1cbiAgICAgIGxhc3RUaWNrUmVmLmN1cnJlbnQgPSAwXG4gICAgICBpZiAoZGVidWcgJiYgbWV0cmljc1JlZi5jdXJyZW50LnN0cmVhbVN0YXJ0QXQgPiAwKSB7XG4gICAgICAgIGNvbnN0IG0gPSBtZXRyaWNzUmVmLmN1cnJlbnRcbiAgICAgICAgY29uc3QgdG90YWxNcyA9IG5vdyAtIG0uc3RyZWFtU3RhcnRBdFxuICAgICAgICBjb25zb2xlLmxvZyhgWyR7ZGVidWdMYWJlbH1dIEZJTkFMYCwge1xuICAgICAgICAgIHRvdGFsTXM6IE1hdGgucm91bmQodG90YWxNcyksXG4gICAgICAgICAgZmluYWxDaGFyczogdGFyZ2V0VGV4dC5sZW5ndGgsXG4gICAgICAgICAgYmFja2VuZEF2Z0NoYXJzUGVyU2VjOiBtLmNodW5rc1NlZW4gPiAwID8gTWF0aC5yb3VuZCgodGFyZ2V0VGV4dC5sZW5ndGggLyB0b3RhbE1zKSAqIDEwMDApIDogMCxcbiAgICAgICAgICBjaHVua3NTZWVuOiBtLmNodW5rc1NlZW4sXG4gICAgICAgICAgYXZnSW50ZXJDaHVua01zOiBtLmNodW5rc1NlZW4gPiAwID8gTWF0aC5yb3VuZChtLmludGVyQ2h1bmtTdW0gLyBtLmNodW5rc1NlZW4pIDogMCxcbiAgICAgICAgICBtYXhJbnRlckNodW5rTXM6IE1hdGgucm91bmQobS5pbnRlckNodW5rTWF4KSxcbiAgICAgICAgICBpZGxlVGltZU1zOiBNYXRoLnJvdW5kKG0uaWRsZVRpbWVNcyksXG4gICAgICAgICAgaWRsZVJhdGlvOiB0b3RhbE1zID4gMCA/IChtLmlkbGVUaW1lTXMgLyB0b3RhbE1zKS50b0ZpeGVkKDIpIDogJzAnLFxuICAgICAgICAgIG1heEJ1ZmZlcjogbS5tYXhCdWZmZXIsXG4gICAgICAgIH0pXG4gICAgICAgIG1ldHJpY3NSZWYuY3VycmVudCA9IHtcbiAgICAgICAgICBmcmFtZXNXaXRoQnVmZmVyOiAwLFxuICAgICAgICAgIGZyYW1lc0lkbGU6IDAsXG4gICAgICAgICAgdG90YWxDaGFyc0VtaXR0ZWQ6IDAsXG4gICAgICAgICAgbWF4QnVmZmVyOiAwLFxuICAgICAgICAgIGlkbGVUaW1lTXM6IDAsXG4gICAgICAgICAgY2h1bmtzU2VlbjogMCxcbiAgICAgICAgICBpbnRlckNodW5rU3VtOiAwLFxuICAgICAgICAgIGludGVyQ2h1bmtNYXg6IDAsXG4gICAgICAgICAgbGFzdExvZ0F0OiAwLFxuICAgICAgICAgIHN0cmVhbVN0YXJ0QXQ6IDAsXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChkaXNwbGF5ZWRMZW5SZWYuY3VycmVudCAhPT0gdGFyZ2V0VGV4dC5sZW5ndGgpIHtcbiAgICAgICAgZGlzcGxheWVkTGVuUmVmLmN1cnJlbnQgPSB0YXJnZXRUZXh0Lmxlbmd0aFxuICAgICAgICBzZXREaXNwbGF5ZWQodGFyZ2V0VGV4dClcbiAgICAgIH1cbiAgICAgIC8vIFJlc2V0IGRlIGNhZGVuY2lhIGN1YW5kbyBzZSBhcGFnYSBwYXJhIG5vIGNvbnRhbWluYXIgZWwgcHLDs3hpbW8gc3RyZWFtLlxuICAgICAgbGFzdFRhcmdldExlblJlZi5jdXJyZW50ID0gMFxuICAgICAgbGFzdFRhcmdldFVwZGF0ZVJlZi5jdXJyZW50ID0gMFxuICAgICAgYmFja2VuZENoYXJzUGVyTXNSZWYuY3VycmVudCA9IDBcbiAgICAgIGZpcnN0Q2h1bmtBdFJlZi5jdXJyZW50ID0gMFxuICAgICAgd2FybXVwRG9uZVJlZi5jdXJyZW50ID0gZmFsc2VcbiAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICB9XG5cbiAgICBpZiAoZGVidWcgJiYgbWV0cmljc1JlZi5jdXJyZW50LnN0cmVhbVN0YXJ0QXQgPT09IDApIHtcbiAgICAgIG1ldHJpY3NSZWYuY3VycmVudC5zdHJlYW1TdGFydEF0ID0gbm93XG4gICAgICBtZXRyaWNzUmVmLmN1cnJlbnQubGFzdExvZ0F0ID0gbm93XG4gICAgICBjb25zb2xlLmxvZyhgWyR7ZGVidWdMYWJlbH1dIFNUQVJUYCwge1xuICAgICAgICB0YXJnZXRMYWdNcyxcbiAgICAgICAgbWF4Q2hhcnNQZXJGcmFtZSxcbiAgICAgICAgYWRhcHRUb0JhY2tlbmRSYXRlLFxuICAgICAgICBiYWNrZW5kUmF0ZUZhY3RvcixcbiAgICAgICAgdGFyZ2V0QnVmZmVyTXMsXG4gICAgICAgIGJ1ZmZlckNvcnJlY3Rpb25NcyxcbiAgICAgICAgbWluQnVmZmVyQ2hhcnMsXG4gICAgICAgIHdhcm11cE1zLFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAoZGlzcGxheWVkTGVuUmVmLmN1cnJlbnQgPiB0YXJnZXRUZXh0Lmxlbmd0aCkge1xuICAgICAgZGlzcGxheWVkTGVuUmVmLmN1cnJlbnQgPSAwXG4gICAgICBzZXREaXNwbGF5ZWQoJycpXG4gICAgfVxuXG4gICAgaWYgKHJhZlJlZi5jdXJyZW50ICE9IG51bGwpIHJldHVybiB1bmRlZmluZWRcblxuICAgIGNvbnN0IGxvZ01ldHJpY3MgPSAodGlja05vdzogbnVtYmVyKSA9PiB7XG4gICAgICBjb25zdCBtID0gbWV0cmljc1JlZi5jdXJyZW50XG4gICAgICBjb25zdCBlbCA9IHRhcmdldFJlZi5jdXJyZW50XG4gICAgICBjb25zdCBidWZmZXIgPSBlbC5sZW5ndGggLSBkaXNwbGF5ZWRMZW5SZWYuY3VycmVudFxuICAgICAgY29uc3Qgd2luZG93TXMgPSBNYXRoLm1heCgxLCB0aWNrTm93IC0gbS5sYXN0TG9nQXQpXG4gICAgICBjb25zdCB0b3RhbEZyYW1lcyA9IG0uZnJhbWVzV2l0aEJ1ZmZlciArIG0uZnJhbWVzSWRsZVxuICAgICAgY29uc3QgZnBzID0gTWF0aC5yb3VuZCgodG90YWxGcmFtZXMgLyB3aW5kb3dNcykgKiAxMDAwKVxuICAgICAgY29uc3QgYmFja2VuZFJhdGUgPSBiYWNrZW5kQ2hhcnNQZXJNc1JlZi5jdXJyZW50XG4gICAgICBjb25zb2xlLmxvZyhgWyR7ZGVidWdMYWJlbH1dIHRpY2tgLCB7XG4gICAgICAgIGVsYXBzZWRNczogTWF0aC5yb3VuZCh0aWNrTm93IC0gbS5zdHJlYW1TdGFydEF0KSxcbiAgICAgICAgYnVmZmVyLFxuICAgICAgICBkaXNwbGF5ZWQ6IGRpc3BsYXllZExlblJlZi5jdXJyZW50LFxuICAgICAgICB0YXJnZXQ6IGVsLmxlbmd0aCxcbiAgICAgICAgZnJhbWVzV2l0aEJ1ZmZlcjogbS5mcmFtZXNXaXRoQnVmZmVyLFxuICAgICAgICBmcmFtZXNJZGxlOiBtLmZyYW1lc0lkbGUsXG4gICAgICAgIGlkbGVSYXRpbzogdG90YWxGcmFtZXMgPiAwID8gKG0uZnJhbWVzSWRsZSAvIHRvdGFsRnJhbWVzKS50b0ZpeGVkKDIpIDogJzAnLFxuICAgICAgICBmcHMsXG4gICAgICAgIGJhY2tlbmRDaGFyc1BlclNlYzogTWF0aC5yb3VuZChiYWNrZW5kUmF0ZSAqIDEwMDApLFxuICAgICAgICBhdmdJbnRlckNodW5rTXM6IG0uY2h1bmtzU2VlbiA+IDAgPyBNYXRoLnJvdW5kKG0uaW50ZXJDaHVua1N1bSAvIG0uY2h1bmtzU2VlbikgOiAwLFxuICAgICAgICBtYXhJbnRlckNodW5rTXM6IE1hdGgucm91bmQobS5pbnRlckNodW5rTWF4KSxcbiAgICAgIH0pXG4gICAgICBtLmZyYW1lc1dpdGhCdWZmZXIgPSAwXG4gICAgICBtLmZyYW1lc0lkbGUgPSAwXG4gICAgICBtLmxhc3RMb2dBdCA9IHRpY2tOb3dcbiAgICB9XG5cbiAgICBjb25zdCB0aWNrID0gKHRpY2tOb3c6IG51bWJlcikgPT4ge1xuICAgICAgY29uc3QgcHJldiA9IGxhc3RUaWNrUmVmLmN1cnJlbnRcbiAgICAgIGNvbnN0IGR0ID0gcHJldiA/IE1hdGgubWluKHRpY2tOb3cgLSBwcmV2LCA2NCkgOiAxNlxuICAgICAgbGFzdFRpY2tSZWYuY3VycmVudCA9IHRpY2tOb3dcblxuICAgICAgY29uc3QgdGFyZ2V0ID0gdGFyZ2V0UmVmLmN1cnJlbnRcbiAgICAgIGNvbnN0IGN1cnJlbnRMZW4gPSBkaXNwbGF5ZWRMZW5SZWYuY3VycmVudFxuICAgICAgY29uc3QgcmVtYWluaW5nID0gdGFyZ2V0Lmxlbmd0aCAtIGN1cnJlbnRMZW5cblxuICAgICAgaWYgKHJlbWFpbmluZyA8PSAwKSB7XG4gICAgICAgIGlmIChkZWJ1Zykge1xuICAgICAgICAgIG1ldHJpY3NSZWYuY3VycmVudC5mcmFtZXNJZGxlICs9IDFcbiAgICAgICAgICBtZXRyaWNzUmVmLmN1cnJlbnQuaWRsZVRpbWVNcyArPSBkdFxuICAgICAgICB9XG4gICAgICAgIHJhZlJlZi5jdXJyZW50ID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRpY2spXG4gICAgICAgIC8vIExvZyBwZXJpw7NkaWNvIGHDum4gZXN0YW5kbyBpZGxlIChwYXJhIHZlciBzaSBlc3RhbW9zIGVzcGVyYW5kbyBjaHVua3MpXG4gICAgICAgIGlmIChkZWJ1ZyAmJiB0aWNrTm93IC0gbWV0cmljc1JlZi5jdXJyZW50Lmxhc3RMb2dBdCA+IDUwMCkge1xuICAgICAgICAgIGxvZ01ldHJpY3ModGlja05vdylcbiAgICAgICAgfVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgLy8gV2FybXVwOiBhbCBjb21pZW56byBkZWwgc3RyZWFtIGVzcGVyYW1vcyBgd2FybXVwTXNgIGRlc2RlIGVsIHByaW1lclxuICAgICAgLy8gY2h1bmsgYW50ZXMgZGUgZW1wZXphciBhIHBpbnRhci4gRXN0byBjb25zdHJ1eWUgdW4gY29sY2jDs24gaW5pY2lhbCB5XG4gICAgICAvLyBldml0YSBhcnJhbmNhciByw6FwaWRvIHBhcmEgY29uZ2VsYXJub3MgYWN0byBzZWd1aWRvIHNpIGVsIGJhY2tlbmRcbiAgICAgIC8vIHRhcmRhIG11Y2hvIGVuIGVtaXRpciBlbCBzZWd1bmRvIGNodW5rLlxuICAgICAgaWYgKCF3YXJtdXBEb25lUmVmLmN1cnJlbnQpIHtcbiAgICAgICAgY29uc3QgZmlyc3RBdCA9IGZpcnN0Q2h1bmtBdFJlZi5jdXJyZW50XG4gICAgICAgIGNvbnN0IHdhaXRlZE1zID0gZmlyc3RBdCA+IDAgPyB0aWNrTm93IC0gZmlyc3RBdCA6IDBcbiAgICAgICAgY29uc3Qgd2FybXVwQ29tcGxldGUgPSB3YXJtdXBNcyA8PSAwIHx8IHdhaXRlZE1zID49IHdhcm11cE1zIHx8IHRhcmdldC5sZW5ndGggPj0gbWluQnVmZmVyQ2hhcnMgKiAyXG4gICAgICAgIGlmICghd2FybXVwQ29tcGxldGUpIHtcbiAgICAgICAgICBpZiAoZGVidWcpIHtcbiAgICAgICAgICAgIG1ldHJpY3NSZWYuY3VycmVudC5mcmFtZXNJZGxlICs9IDFcbiAgICAgICAgICAgIG1ldHJpY3NSZWYuY3VycmVudC5pZGxlVGltZU1zICs9IGR0XG4gICAgICAgICAgfVxuICAgICAgICAgIHJhZlJlZi5jdXJyZW50ID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRpY2spXG4gICAgICAgICAgaWYgKGRlYnVnICYmIHRpY2tOb3cgLSBtZXRyaWNzUmVmLmN1cnJlbnQubGFzdExvZ0F0ID4gNTAwKSB7XG4gICAgICAgICAgICBsb2dNZXRyaWNzKHRpY2tOb3cpXG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIHdhcm11cERvbmVSZWYuY3VycmVudCA9IHRydWVcbiAgICAgIH1cblxuICAgICAgaWYgKGRlYnVnKSB7XG4gICAgICAgIG1ldHJpY3NSZWYuY3VycmVudC5mcmFtZXNXaXRoQnVmZmVyICs9IDFcbiAgICAgICAgaWYgKHJlbWFpbmluZyA+IG1ldHJpY3NSZWYuY3VycmVudC5tYXhCdWZmZXIpIG1ldHJpY3NSZWYuY3VycmVudC5tYXhCdWZmZXIgPSByZW1haW5pbmdcbiAgICAgIH1cblxuICAgICAgLy8gVmVsb2NpZGFkIGJhc2U6IHZhY2lhciBlbCBidWZmZXIgZW4gfnRhcmdldExhZ01zLlxuICAgICAgY29uc3QgY2hhcnNQZXJNcyA9IHJlbWFpbmluZyAvIHRhcmdldExhZ01zXG4gICAgICBsZXQgZWZmZWN0aXZlQ2hhcnNQZXJNcyA9IGNoYXJzUGVyTXNcblxuICAgICAgY29uc3QgYmFja2VuZFJhdGUgPSBiYWNrZW5kQ2hhcnNQZXJNc1JlZi5jdXJyZW50XG5cbiAgICAgIGlmIChhZGFwdFRvQmFja2VuZFJhdGUgJiYgYmFja2VuZFJhdGUgPiAwKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGFyZ2V0QnVmZmVyTXMgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgLy8gQ29udHJvbCBwcm9wb3JjaW9uYWw6IG1hbnRlbmVyIGVsIGJ1ZmZlciBlbiB0b3JubyBhbCBjb2xjaMOzblxuICAgICAgICAgIC8vIG9iamV0aXZvLiBTaSBidWZmZXJNcyA8IHRhcmdldCDihpIgZnJlbmFtb3MgcG9yIGRlYmFqbyBkZWwgYmFja2VuZFxuICAgICAgICAgIC8vIHBhcmEgYWN1bXVsYXI7IHNpIGJ1ZmZlck1zID4gdGFyZ2V0IOKGkiBhY2VsZXJhbW9zIHBhcmEgZGVzY2FyZ2FyLlxuICAgICAgICAgIC8vIEVuIGVxdWlsaWJyaW8sIHBpbnRhbW9zIGFsIHJpdG1vIHByb21lZGlvIGRlbCBiYWNrZW5kLlxuICAgICAgICAgIC8vIFBpc28gYWJzb2x1dG86IGVsIGNvbGNow7NuIG51bmNhIGJhamEgZGUgYG1pbkJ1ZmZlckNoYXJzYCBhdW5xdWVcbiAgICAgICAgICAvLyBlbCBiYWNrZW5kIGVzdMOpIG1hbmRhbmRvIGxlbnRvIGFsIGluaWNpbyBkZWwgc3RyZWFtLlxuICAgICAgICAgIGNvbnN0IHRhcmdldEJ1ZmZlckNoYXJzID0gTWF0aC5tYXgobWluQnVmZmVyQ2hhcnMsIHRhcmdldEJ1ZmZlck1zICogYmFja2VuZFJhdGUpXG4gICAgICAgICAgY29uc3QgYnVmZmVyRGVsdGEgPSByZW1haW5pbmcgLSB0YXJnZXRCdWZmZXJDaGFyc1xuICAgICAgICAgIC8vIENvcnJlY2Npw7NuIHRpZW5lIHVuaWRhZGVzIGRlIGNoYXJzL21zLiBidWZmZXJDb3JyZWN0aW9uTXMgY29udHJvbGFcbiAgICAgICAgICAvLyBxdcOpIHRhbiByw6FwaWRvIGVsIGJ1ZmZlciByZWFsIGNvbnZlcmdlIGFsIG9iamV0aXZvLlxuICAgICAgICAgIGNvbnN0IGNvcnJlY3Rpb24gPSBidWZmZXJEZWx0YSAvIE1hdGgubWF4KDEsIGJ1ZmZlckNvcnJlY3Rpb25NcylcbiAgICAgICAgICBlZmZlY3RpdmVDaGFyc1Blck1zID0gTWF0aC5tYXgoMCwgYmFja2VuZFJhdGUgKyBjb3JyZWN0aW9uKVxuICAgICAgICAgIC8vIEFjb3RhciBwb3IgbGEgdmVsb2NpZGFkIGRlIFwidmFjaWFyIGVuIHRhcmdldExhZ01zXCIgcGFyYSBxdWUgc2lcbiAgICAgICAgICAvLyBkZSBwcm9udG8gaGF5IHVuIHBpY28gZ2lnYW50ZSBkZSBidWZmZXIgbm8gc2FsZ2Ftb3MgZGlzcGFyYWRvcy5cbiAgICAgICAgICBlZmZlY3RpdmVDaGFyc1Blck1zID0gTWF0aC5taW4oZWZmZWN0aXZlQ2hhcnNQZXJNcywgY2hhcnNQZXJNcylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBNb2RvIHNpbXBsZTogY2FwIGEgbGEgdGFzYSBkZWwgYmFja2VuZCAqIGZhY3Rvci5cbiAgICAgICAgICBjb25zdCBjYXAgPSBiYWNrZW5kUmF0ZSAqIGJhY2tlbmRSYXRlRmFjdG9yXG4gICAgICAgICAgZWZmZWN0aXZlQ2hhcnNQZXJNcyA9IE1hdGgubWluKGVmZmVjdGl2ZUNoYXJzUGVyTXMsIGNhcClcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCByYXdTdGVwID0gTWF0aC5jZWlsKGVmZmVjdGl2ZUNoYXJzUGVyTXMgKiBkdClcbiAgICAgIGNvbnN0IHN0ZXAgPSBNYXRoLm1heChtaW5DaGFyc1BlckZyYW1lLCBNYXRoLm1pbihtYXhDaGFyc1BlckZyYW1lLCByYXdTdGVwKSlcblxuICAgICAgbGV0IG5leHRMZW4gPSBNYXRoLm1pbih0YXJnZXQubGVuZ3RoLCBjdXJyZW50TGVuICsgc3RlcClcblxuICAgICAgaWYgKHNuYXBUb1dvcmRCb3VuZGFyeSAmJiBuZXh0TGVuIDwgdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgICBjb25zdCBzbGljZSA9IHRhcmdldC5zbGljZShjdXJyZW50TGVuLCBuZXh0TGVuKVxuICAgICAgICBjb25zdCBsYXN0Qm91bmRhcnkgPSBNYXRoLm1heChzbGljZS5sYXN0SW5kZXhPZignICcpLCBzbGljZS5sYXN0SW5kZXhPZignXFxuJyksIHNsaWNlLmxhc3RJbmRleE9mKCdcXHQnKSlcbiAgICAgICAgaWYgKGxhc3RCb3VuZGFyeSA+PSAwKSB7XG4gICAgICAgICAgbmV4dExlbiA9IGN1cnJlbnRMZW4gKyBsYXN0Qm91bmRhcnkgKyAxXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKG5leHRMZW4gIT09IGN1cnJlbnRMZW4pIHtcbiAgICAgICAgaWYgKGRlYnVnKSBtZXRyaWNzUmVmLmN1cnJlbnQudG90YWxDaGFyc0VtaXR0ZWQgKz0gbmV4dExlbiAtIGN1cnJlbnRMZW5cbiAgICAgICAgZGlzcGxheWVkTGVuUmVmLmN1cnJlbnQgPSBuZXh0TGVuXG4gICAgICAgIHNldERpc3BsYXllZCh0YXJnZXQuc2xpY2UoMCwgbmV4dExlbikpXG4gICAgICB9XG5cbiAgICAgIGlmIChkZWJ1ZyAmJiB0aWNrTm93IC0gbWV0cmljc1JlZi5jdXJyZW50Lmxhc3RMb2dBdCA+IDUwMCkge1xuICAgICAgICBsb2dNZXRyaWNzKHRpY2tOb3cpXG4gICAgICB9XG5cbiAgICAgIHJhZlJlZi5jdXJyZW50ID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRpY2spXG4gICAgfVxuXG4gICAgcmFmUmVmLmN1cnJlbnQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGljaylcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBpZiAocmFmUmVmLmN1cnJlbnQgIT0gbnVsbCkge1xuICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZShyYWZSZWYuY3VycmVudClcbiAgICAgICAgcmFmUmVmLmN1cnJlbnQgPSBudWxsXG4gICAgICB9XG4gICAgICBsYXN0VGlja1JlZi5jdXJyZW50ID0gMFxuICAgIH1cbiAgfSwgW1xuICAgIHRhcmdldFRleHQsXG4gICAgZW5hYmxlZCxcbiAgICBtaW5DaGFyc1BlckZyYW1lLFxuICAgIG1heENoYXJzUGVyRnJhbWUsXG4gICAgdGFyZ2V0TGFnTXMsXG4gICAgc25hcFRvV29yZEJvdW5kYXJ5LFxuICAgIGFkYXB0VG9CYWNrZW5kUmF0ZSxcbiAgICBiYWNrZW5kUmF0ZUZhY3RvcixcbiAgICB0YXJnZXRCdWZmZXJNcyxcbiAgICBidWZmZXJDb3JyZWN0aW9uTXMsXG4gICAgbWluQnVmZmVyQ2hhcnMsXG4gICAgd2FybXVwTXMsXG4gICAgZGVidWcsXG4gICAgZGVidWdMYWJlbCxcbiAgXSlcblxuICByZXR1cm4gZGlzcGxheWVkXG59XG4iXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBLFNBQVNBLFNBQVMsRUFBRUMsTUFBTSxFQUFFQyxRQUFRLFFBQVEsT0FBTztBQTJFbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLElBQU1DLG1CQUFtQixHQUFHLFNBQXRCQSxtQkFBbUJBLENBQzlCQyxVQUFrQixFQUFBQyxJQUFBLEVBZ0JQO0VBQUEsSUFkVEMsT0FBTyxHQUFBRCxJQUFBLENBQVBDLE9BQU87SUFBQUMscUJBQUEsR0FBQUYsSUFBQSxDQUNQRyxnQkFBZ0I7SUFBaEJBLGdCQUFnQixHQUFBRCxxQkFBQSxjQUFHLENBQUMsR0FBQUEscUJBQUE7SUFBQUUscUJBQUEsR0FBQUosSUFBQSxDQUNwQkssZ0JBQWdCO0lBQWhCQSxnQkFBZ0IsR0FBQUQscUJBQUEsY0FBRyxFQUFFLEdBQUFBLHFCQUFBO0lBQUFFLGdCQUFBLEdBQUFOLElBQUEsQ0FDckJPLFdBQVc7SUFBWEEsV0FBVyxHQUFBRCxnQkFBQSxjQUFHLEdBQUcsR0FBQUEsZ0JBQUE7SUFBQUUscUJBQUEsR0FBQVIsSUFBQSxDQUNqQlMsa0JBQWtCO0lBQWxCQSxrQkFBa0IsR0FBQUQscUJBQUEsY0FBRyxLQUFLLEdBQUFBLHFCQUFBO0lBQUFFLHFCQUFBLEdBQUFWLElBQUEsQ0FDMUJXLGtCQUFrQjtJQUFsQkEsa0JBQWtCLEdBQUFELHFCQUFBLGNBQUcsS0FBSyxHQUFBQSxxQkFBQTtJQUFBRSxxQkFBQSxHQUFBWixJQUFBLENBQzFCYSxpQkFBaUI7SUFBakJBLGlCQUFpQixHQUFBRCxxQkFBQSxjQUFHLElBQUksR0FBQUEscUJBQUE7SUFDeEJFLGNBQWMsR0FBQWQsSUFBQSxDQUFkYyxjQUFjO0lBQUFDLHFCQUFBLEdBQUFmLElBQUEsQ0FDZGdCLGtCQUFrQjtJQUFsQkEsa0JBQWtCLEdBQUFELHFCQUFBLGNBQUcsR0FBRyxHQUFBQSxxQkFBQTtJQUFBRSxtQkFBQSxHQUFBakIsSUFBQSxDQUN4QmtCLGNBQWM7SUFBZEEsY0FBYyxHQUFBRCxtQkFBQSxjQUFHLEVBQUUsR0FBQUEsbUJBQUE7SUFBQUUsYUFBQSxHQUFBbkIsSUFBQSxDQUNuQm9CLFFBQVE7SUFBUkEsUUFBUSxHQUFBRCxhQUFBLGNBQUcsQ0FBQyxHQUFBQSxhQUFBO0lBQUFFLFVBQUEsR0FBQXJCLElBQUEsQ0FDWnNCLEtBQUs7SUFBTEEsS0FBSyxHQUFBRCxVQUFBLGNBQUcsS0FBSyxHQUFBQSxVQUFBO0lBQUFFLGVBQUEsR0FBQXZCLElBQUEsQ0FDYndCLFVBQVU7SUFBVkEsVUFBVSxHQUFBRCxlQUFBLGNBQUcsY0FBYyxHQUFBQSxlQUFBO0VBRzdCLElBQUFFLFNBQUEsR0FBa0M1QixRQUFRLENBQVM7TUFBQSxPQUFPSSxPQUFPLEdBQUcsRUFBRSxHQUFHRixVQUFVO0lBQUEsQ0FBQyxDQUFDO0lBQUEyQixVQUFBLEdBQUFDLGNBQUEsQ0FBQUYsU0FBQTtJQUE5RUcsU0FBUyxHQUFBRixVQUFBO0lBQUVHLFlBQVksR0FBQUgsVUFBQTtFQUU5QixJQUFNSSxTQUFTLEdBQUdsQyxNQUFNLENBQUNHLFVBQVUsQ0FBQztFQUNwQyxJQUFNZ0MsZUFBZSxHQUFHbkMsTUFBTSxDQUFDZ0MsU0FBUyxDQUFDSSxNQUFNLENBQUM7RUFDaEQsSUFBTUMsTUFBTSxHQUFHckMsTUFBTSxDQUFnQixJQUFJLENBQUM7RUFDMUMsSUFBTXNDLFdBQVcsR0FBR3RDLE1BQU0sQ0FBUyxDQUFDLENBQUM7O0VBRXJDO0VBQ0EsSUFBTXVDLGdCQUFnQixHQUFHdkMsTUFBTSxDQUFTLENBQUMsQ0FBQztFQUMxQyxJQUFNd0MsbUJBQW1CLEdBQUd4QyxNQUFNLENBQVMsQ0FBQyxDQUFDO0VBQzdDO0VBQ0EsSUFBTXlDLG9CQUFvQixHQUFHekMsTUFBTSxDQUFTLENBQUMsQ0FBQztFQUM5QztFQUNBLElBQU0wQyxlQUFlLEdBQUcxQyxNQUFNLENBQVMsQ0FBQyxDQUFDO0VBQ3pDO0VBQ0EsSUFBTTJDLGFBQWEsR0FBRzNDLE1BQU0sQ0FBVSxLQUFLLENBQUM7O0VBRTVDO0VBQ0EsSUFBTTRDLFVBQVUsR0FBRzVDLE1BQU0sQ0FBQztJQUN4QjZDLGdCQUFnQixFQUFFLENBQUM7SUFDbkJDLFVBQVUsRUFBRSxDQUFDO0lBQ2JDLGlCQUFpQixFQUFFLENBQUM7SUFDcEJDLFNBQVMsRUFBRSxDQUFDO0lBQ1pDLFVBQVUsRUFBRSxDQUFDO0lBQ2JDLFVBQVUsRUFBRSxDQUFDO0lBQ2JDLGFBQWEsRUFBRSxDQUFDO0lBQ2hCQyxhQUFhLEVBQUUsQ0FBQztJQUNoQkMsU0FBUyxFQUFFLENBQUM7SUFDWkMsYUFBYSxFQUFFO0VBQ2pCLENBQUMsQ0FBQztFQUVGdkQsU0FBUyxDQUFDLFlBQU07SUFDZCxJQUFNd0QsR0FBRyxHQUFHLE9BQU9DLFdBQVcsS0FBSyxXQUFXLEdBQUdBLFdBQVcsQ0FBQ0QsR0FBRyxDQUFDLENBQUMsR0FBR0UsSUFBSSxDQUFDRixHQUFHLENBQUMsQ0FBQztJQUMvRSxJQUFNRyxhQUFhLEdBQUduQixnQkFBZ0IsQ0FBQ29CLE9BQU87SUFDOUMsSUFBTUMsVUFBVSxHQUFHekQsVUFBVSxDQUFDaUMsTUFBTSxHQUFHc0IsYUFBYTtJQUNwRCxJQUFNRyxZQUFZLEdBQUdyQixtQkFBbUIsQ0FBQ21CLE9BQU87SUFFaEQsSUFBSXRELE9BQU8sSUFBSXVELFVBQVUsR0FBRyxDQUFDLEVBQUU7TUFDN0IsSUFBSWxCLGVBQWUsQ0FBQ2lCLE9BQU8sS0FBSyxDQUFDLEVBQUVqQixlQUFlLENBQUNpQixPQUFPLEdBQUdKLEdBQUc7SUFDbEU7SUFFQSxJQUFJbEQsT0FBTyxJQUFJdUQsVUFBVSxHQUFHLENBQUMsSUFBSUMsWUFBWSxHQUFHLENBQUMsRUFBRTtNQUNqRCxJQUFNQyxFQUFFLEdBQUdDLElBQUksQ0FBQ0MsR0FBRyxDQUFDLENBQUMsRUFBRVQsR0FBRyxHQUFHTSxZQUFZLENBQUM7TUFDMUMsSUFBTUksSUFBSSxHQUFHTCxVQUFVLEdBQUdFLEVBQUU7TUFDNUIsSUFBTUksUUFBUSxHQUFHekIsb0JBQW9CLENBQUNrQixPQUFPO01BQzdDO01BQ0FsQixvQkFBb0IsQ0FBQ2tCLE9BQU8sR0FBR08sUUFBUSxLQUFLLENBQUMsR0FBR0QsSUFBSSxHQUFHQyxRQUFRLEdBQUcsR0FBRyxHQUFHRCxJQUFJLEdBQUcsR0FBRztNQUVsRixJQUFJdkMsS0FBSyxFQUFFO1FBQ1QsSUFBTXlDLENBQUMsR0FBR3ZCLFVBQVUsQ0FBQ2UsT0FBTztRQUM1QlEsQ0FBQyxDQUFDakIsVUFBVSxJQUFJLENBQUM7UUFDakJpQixDQUFDLENBQUNoQixhQUFhLElBQUlXLEVBQUU7UUFDckIsSUFBSUEsRUFBRSxHQUFHSyxDQUFDLENBQUNmLGFBQWEsRUFBRWUsQ0FBQyxDQUFDZixhQUFhLEdBQUdVLEVBQUU7TUFDaEQ7SUFDRjtJQUNBLElBQUl6RCxPQUFPLElBQUlGLFVBQVUsQ0FBQ2lDLE1BQU0sS0FBS3NCLGFBQWEsRUFBRTtNQUNsRG5CLGdCQUFnQixDQUFDb0IsT0FBTyxHQUFHeEQsVUFBVSxDQUFDaUMsTUFBTTtNQUM1Q0ksbUJBQW1CLENBQUNtQixPQUFPLEdBQUdKLEdBQUc7SUFDbkM7SUFFQXJCLFNBQVMsQ0FBQ3lCLE9BQU8sR0FBR3hELFVBQVU7SUFFOUIsSUFBSSxDQUFDRSxPQUFPLEVBQUU7TUFDWixJQUFJZ0MsTUFBTSxDQUFDc0IsT0FBTyxJQUFJLElBQUksRUFBRTtRQUMxQlMsb0JBQW9CLENBQUMvQixNQUFNLENBQUNzQixPQUFPLENBQUM7UUFDcEN0QixNQUFNLENBQUNzQixPQUFPLEdBQUcsSUFBSTtNQUN2QjtNQUNBckIsV0FBVyxDQUFDcUIsT0FBTyxHQUFHLENBQUM7TUFDdkIsSUFBSWpDLEtBQUssSUFBSWtCLFVBQVUsQ0FBQ2UsT0FBTyxDQUFDTCxhQUFhLEdBQUcsQ0FBQyxFQUFFO1FBQ2pELElBQU1hLEVBQUMsR0FBR3ZCLFVBQVUsQ0FBQ2UsT0FBTztRQUM1QixJQUFNVSxPQUFPLEdBQUdkLEdBQUcsR0FBR1ksRUFBQyxDQUFDYixhQUFhO1FBQ3JDZ0IsT0FBTyxDQUFDQyxHQUFHLEtBQUFDLE1BQUEsQ0FBSzVDLFVBQVUsY0FBVztVQUNuQ3lDLE9BQU8sRUFBRU4sSUFBSSxDQUFDVSxLQUFLLENBQUNKLE9BQU8sQ0FBQztVQUM1QkssVUFBVSxFQUFFdkUsVUFBVSxDQUFDaUMsTUFBTTtVQUM3QnVDLHFCQUFxQixFQUFFUixFQUFDLENBQUNqQixVQUFVLEdBQUcsQ0FBQyxHQUFHYSxJQUFJLENBQUNVLEtBQUssQ0FBRXRFLFVBQVUsQ0FBQ2lDLE1BQU0sR0FBR2lDLE9BQU8sR0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDO1VBQzlGbkIsVUFBVSxFQUFFaUIsRUFBQyxDQUFDakIsVUFBVTtVQUN4QjBCLGVBQWUsRUFBRVQsRUFBQyxDQUFDakIsVUFBVSxHQUFHLENBQUMsR0FBR2EsSUFBSSxDQUFDVSxLQUFLLENBQUNOLEVBQUMsQ0FBQ2hCLGFBQWEsR0FBR2dCLEVBQUMsQ0FBQ2pCLFVBQVUsQ0FBQyxHQUFHLENBQUM7VUFDbEYyQixlQUFlLEVBQUVkLElBQUksQ0FBQ1UsS0FBSyxDQUFDTixFQUFDLENBQUNmLGFBQWEsQ0FBQztVQUM1Q0gsVUFBVSxFQUFFYyxJQUFJLENBQUNVLEtBQUssQ0FBQ04sRUFBQyxDQUFDbEIsVUFBVSxDQUFDO1VBQ3BDNkIsU0FBUyxFQUFFVCxPQUFPLEdBQUcsQ0FBQyxHQUFHLENBQUNGLEVBQUMsQ0FBQ2xCLFVBQVUsR0FBR29CLE9BQU8sRUFBRVUsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUc7VUFDbEUvQixTQUFTLEVBQUVtQixFQUFDLENBQUNuQjtRQUNmLENBQUMsQ0FBQztRQUNGSixVQUFVLENBQUNlLE9BQU8sR0FBRztVQUNuQmQsZ0JBQWdCLEVBQUUsQ0FBQztVQUNuQkMsVUFBVSxFQUFFLENBQUM7VUFDYkMsaUJBQWlCLEVBQUUsQ0FBQztVQUNwQkMsU0FBUyxFQUFFLENBQUM7VUFDWkMsVUFBVSxFQUFFLENBQUM7VUFDYkMsVUFBVSxFQUFFLENBQUM7VUFDYkMsYUFBYSxFQUFFLENBQUM7VUFDaEJDLGFBQWEsRUFBRSxDQUFDO1VBQ2hCQyxTQUFTLEVBQUUsQ0FBQztVQUNaQyxhQUFhLEVBQUU7UUFDakIsQ0FBQztNQUNIO01BQ0EsSUFBSW5CLGVBQWUsQ0FBQ3dCLE9BQU8sS0FBS3hELFVBQVUsQ0FBQ2lDLE1BQU0sRUFBRTtRQUNqREQsZUFBZSxDQUFDd0IsT0FBTyxHQUFHeEQsVUFBVSxDQUFDaUMsTUFBTTtRQUMzQ0gsWUFBWSxDQUFDOUIsVUFBVSxDQUFDO01BQzFCO01BQ0E7TUFDQW9DLGdCQUFnQixDQUFDb0IsT0FBTyxHQUFHLENBQUM7TUFDNUJuQixtQkFBbUIsQ0FBQ21CLE9BQU8sR0FBRyxDQUFDO01BQy9CbEIsb0JBQW9CLENBQUNrQixPQUFPLEdBQUcsQ0FBQztNQUNoQ2pCLGVBQWUsQ0FBQ2lCLE9BQU8sR0FBRyxDQUFDO01BQzNCaEIsYUFBYSxDQUFDZ0IsT0FBTyxHQUFHLEtBQUs7TUFDN0IsT0FBT3FCLFNBQVM7SUFDbEI7SUFFQSxJQUFJdEQsS0FBSyxJQUFJa0IsVUFBVSxDQUFDZSxPQUFPLENBQUNMLGFBQWEsS0FBSyxDQUFDLEVBQUU7TUFDbkRWLFVBQVUsQ0FBQ2UsT0FBTyxDQUFDTCxhQUFhLEdBQUdDLEdBQUc7TUFDdENYLFVBQVUsQ0FBQ2UsT0FBTyxDQUFDTixTQUFTLEdBQUdFLEdBQUc7TUFDbENlLE9BQU8sQ0FBQ0MsR0FBRyxLQUFBQyxNQUFBLENBQUs1QyxVQUFVLGNBQVc7UUFDbkNqQixXQUFXLEVBQVhBLFdBQVc7UUFDWEYsZ0JBQWdCLEVBQWhCQSxnQkFBZ0I7UUFDaEJNLGtCQUFrQixFQUFsQkEsa0JBQWtCO1FBQ2xCRSxpQkFBaUIsRUFBakJBLGlCQUFpQjtRQUNqQkMsY0FBYyxFQUFkQSxjQUFjO1FBQ2RFLGtCQUFrQixFQUFsQkEsa0JBQWtCO1FBQ2xCRSxjQUFjLEVBQWRBLGNBQWM7UUFDZEUsUUFBUSxFQUFSQTtNQUNGLENBQUMsQ0FBQztJQUNKO0lBRUEsSUFBSVcsZUFBZSxDQUFDd0IsT0FBTyxHQUFHeEQsVUFBVSxDQUFDaUMsTUFBTSxFQUFFO01BQy9DRCxlQUFlLENBQUN3QixPQUFPLEdBQUcsQ0FBQztNQUMzQjFCLFlBQVksQ0FBQyxFQUFFLENBQUM7SUFDbEI7SUFFQSxJQUFJSSxNQUFNLENBQUNzQixPQUFPLElBQUksSUFBSSxFQUFFLE9BQU9xQixTQUFTO0lBRTVDLElBQU1DLFVBQVUsR0FBRyxTQUFiQSxVQUFVQSxDQUFJQyxPQUFlLEVBQUs7TUFDdEMsSUFBTWYsQ0FBQyxHQUFHdkIsVUFBVSxDQUFDZSxPQUFPO01BQzVCLElBQU13QixFQUFFLEdBQUdqRCxTQUFTLENBQUN5QixPQUFPO01BQzVCLElBQU15QixNQUFNLEdBQUdELEVBQUUsQ0FBQy9DLE1BQU0sR0FBR0QsZUFBZSxDQUFDd0IsT0FBTztNQUNsRCxJQUFNMEIsUUFBUSxHQUFHdEIsSUFBSSxDQUFDQyxHQUFHLENBQUMsQ0FBQyxFQUFFa0IsT0FBTyxHQUFHZixDQUFDLENBQUNkLFNBQVMsQ0FBQztNQUNuRCxJQUFNaUMsV0FBVyxHQUFHbkIsQ0FBQyxDQUFDdEIsZ0JBQWdCLEdBQUdzQixDQUFDLENBQUNyQixVQUFVO01BQ3JELElBQU15QyxHQUFHLEdBQUd4QixJQUFJLENBQUNVLEtBQUssQ0FBRWEsV0FBVyxHQUFHRCxRQUFRLEdBQUksSUFBSSxDQUFDO01BQ3ZELElBQU1HLFdBQVcsR0FBRy9DLG9CQUFvQixDQUFDa0IsT0FBTztNQUNoRFcsT0FBTyxDQUFDQyxHQUFHLEtBQUFDLE1BQUEsQ0FBSzVDLFVBQVUsYUFBVTtRQUNsQzZELFNBQVMsRUFBRTFCLElBQUksQ0FBQ1UsS0FBSyxDQUFDUyxPQUFPLEdBQUdmLENBQUMsQ0FBQ2IsYUFBYSxDQUFDO1FBQ2hEOEIsTUFBTSxFQUFOQSxNQUFNO1FBQ05wRCxTQUFTLEVBQUVHLGVBQWUsQ0FBQ3dCLE9BQU87UUFDbEMrQixNQUFNLEVBQUVQLEVBQUUsQ0FBQy9DLE1BQU07UUFDakJTLGdCQUFnQixFQUFFc0IsQ0FBQyxDQUFDdEIsZ0JBQWdCO1FBQ3BDQyxVQUFVLEVBQUVxQixDQUFDLENBQUNyQixVQUFVO1FBQ3hCZ0MsU0FBUyxFQUFFUSxXQUFXLEdBQUcsQ0FBQyxHQUFHLENBQUNuQixDQUFDLENBQUNyQixVQUFVLEdBQUd3QyxXQUFXLEVBQUVQLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHO1FBQzFFUSxHQUFHLEVBQUhBLEdBQUc7UUFDSEksa0JBQWtCLEVBQUU1QixJQUFJLENBQUNVLEtBQUssQ0FBQ2UsV0FBVyxHQUFHLElBQUksQ0FBQztRQUNsRFosZUFBZSxFQUFFVCxDQUFDLENBQUNqQixVQUFVLEdBQUcsQ0FBQyxHQUFHYSxJQUFJLENBQUNVLEtBQUssQ0FBQ04sQ0FBQyxDQUFDaEIsYUFBYSxHQUFHZ0IsQ0FBQyxDQUFDakIsVUFBVSxDQUFDLEdBQUcsQ0FBQztRQUNsRjJCLGVBQWUsRUFBRWQsSUFBSSxDQUFDVSxLQUFLLENBQUNOLENBQUMsQ0FBQ2YsYUFBYTtNQUM3QyxDQUFDLENBQUM7TUFDRmUsQ0FBQyxDQUFDdEIsZ0JBQWdCLEdBQUcsQ0FBQztNQUN0QnNCLENBQUMsQ0FBQ3JCLFVBQVUsR0FBRyxDQUFDO01BQ2hCcUIsQ0FBQyxDQUFDZCxTQUFTLEdBQUc2QixPQUFPO0lBQ3ZCLENBQUM7SUFFRCxJQUFNVSxLQUFJLEdBQUcsU0FBUEEsSUFBSUEsQ0FBSVYsT0FBZSxFQUFLO01BQ2hDLElBQU1XLElBQUksR0FBR3ZELFdBQVcsQ0FBQ3FCLE9BQU87TUFDaEMsSUFBTUcsRUFBRSxHQUFHK0IsSUFBSSxHQUFHOUIsSUFBSSxDQUFDK0IsR0FBRyxDQUFDWixPQUFPLEdBQUdXLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFO01BQ25EdkQsV0FBVyxDQUFDcUIsT0FBTyxHQUFHdUIsT0FBTztNQUU3QixJQUFNUSxNQUFNLEdBQUd4RCxTQUFTLENBQUN5QixPQUFPO01BQ2hDLElBQU1vQyxVQUFVLEdBQUc1RCxlQUFlLENBQUN3QixPQUFPO01BQzFDLElBQU1xQyxTQUFTLEdBQUdOLE1BQU0sQ0FBQ3RELE1BQU0sR0FBRzJELFVBQVU7TUFFNUMsSUFBSUMsU0FBUyxJQUFJLENBQUMsRUFBRTtRQUNsQixJQUFJdEUsS0FBSyxFQUFFO1VBQ1RrQixVQUFVLENBQUNlLE9BQU8sQ0FBQ2IsVUFBVSxJQUFJLENBQUM7VUFDbENGLFVBQVUsQ0FBQ2UsT0FBTyxDQUFDVixVQUFVLElBQUlhLEVBQUU7UUFDckM7UUFDQXpCLE1BQU0sQ0FBQ3NCLE9BQU8sR0FBR3NDLHFCQUFxQixDQUFDTCxLQUFJLENBQUM7UUFDNUM7UUFDQSxJQUFJbEUsS0FBSyxJQUFJd0QsT0FBTyxHQUFHdEMsVUFBVSxDQUFDZSxPQUFPLENBQUNOLFNBQVMsR0FBRyxHQUFHLEVBQUU7VUFDekQ0QixVQUFVLENBQUNDLE9BQU8sQ0FBQztRQUNyQjtRQUNBO01BQ0Y7O01BRUE7TUFDQTtNQUNBO01BQ0E7TUFDQSxJQUFJLENBQUN2QyxhQUFhLENBQUNnQixPQUFPLEVBQUU7UUFDMUIsSUFBTXVDLE9BQU8sR0FBR3hELGVBQWUsQ0FBQ2lCLE9BQU87UUFDdkMsSUFBTXdDLFFBQVEsR0FBR0QsT0FBTyxHQUFHLENBQUMsR0FBR2hCLE9BQU8sR0FBR2dCLE9BQU8sR0FBRyxDQUFDO1FBQ3BELElBQU1FLGNBQWMsR0FBRzVFLFFBQVEsSUFBSSxDQUFDLElBQUkyRSxRQUFRLElBQUkzRSxRQUFRLElBQUlrRSxNQUFNLENBQUN0RCxNQUFNLElBQUlkLGNBQWMsR0FBRyxDQUFDO1FBQ25HLElBQUksQ0FBQzhFLGNBQWMsRUFBRTtVQUNuQixJQUFJMUUsS0FBSyxFQUFFO1lBQ1RrQixVQUFVLENBQUNlLE9BQU8sQ0FBQ2IsVUFBVSxJQUFJLENBQUM7WUFDbENGLFVBQVUsQ0FBQ2UsT0FBTyxDQUFDVixVQUFVLElBQUlhLEVBQUU7VUFDckM7VUFDQXpCLE1BQU0sQ0FBQ3NCLE9BQU8sR0FBR3NDLHFCQUFxQixDQUFDTCxLQUFJLENBQUM7VUFDNUMsSUFBSWxFLEtBQUssSUFBSXdELE9BQU8sR0FBR3RDLFVBQVUsQ0FBQ2UsT0FBTyxDQUFDTixTQUFTLEdBQUcsR0FBRyxFQUFFO1lBQ3pENEIsVUFBVSxDQUFDQyxPQUFPLENBQUM7VUFDckI7VUFDQTtRQUNGO1FBQ0F2QyxhQUFhLENBQUNnQixPQUFPLEdBQUcsSUFBSTtNQUM5QjtNQUVBLElBQUlqQyxLQUFLLEVBQUU7UUFDVGtCLFVBQVUsQ0FBQ2UsT0FBTyxDQUFDZCxnQkFBZ0IsSUFBSSxDQUFDO1FBQ3hDLElBQUltRCxTQUFTLEdBQUdwRCxVQUFVLENBQUNlLE9BQU8sQ0FBQ1gsU0FBUyxFQUFFSixVQUFVLENBQUNlLE9BQU8sQ0FBQ1gsU0FBUyxHQUFHZ0QsU0FBUztNQUN4Rjs7TUFFQTtNQUNBLElBQU1LLFVBQVUsR0FBR0wsU0FBUyxHQUFHckYsV0FBVztNQUMxQyxJQUFJMkYsbUJBQW1CLEdBQUdELFVBQVU7TUFFcEMsSUFBTWIsV0FBVyxHQUFHL0Msb0JBQW9CLENBQUNrQixPQUFPO01BRWhELElBQUk1QyxrQkFBa0IsSUFBSXlFLFdBQVcsR0FBRyxDQUFDLEVBQUU7UUFDekMsSUFBSSxPQUFPdEUsY0FBYyxLQUFLLFFBQVEsRUFBRTtVQUN0QztVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQSxJQUFNcUYsaUJBQWlCLEdBQUd4QyxJQUFJLENBQUNDLEdBQUcsQ0FBQzFDLGNBQWMsRUFBRUosY0FBYyxHQUFHc0UsV0FBVyxDQUFDO1VBQ2hGLElBQU1nQixXQUFXLEdBQUdSLFNBQVMsR0FBR08saUJBQWlCO1VBQ2pEO1VBQ0E7VUFDQSxJQUFNRSxVQUFVLEdBQUdELFdBQVcsR0FBR3pDLElBQUksQ0FBQ0MsR0FBRyxDQUFDLENBQUMsRUFBRTVDLGtCQUFrQixDQUFDO1VBQ2hFa0YsbUJBQW1CLEdBQUd2QyxJQUFJLENBQUNDLEdBQUcsQ0FBQyxDQUFDLEVBQUV3QixXQUFXLEdBQUdpQixVQUFVLENBQUM7VUFDM0Q7VUFDQTtVQUNBSCxtQkFBbUIsR0FBR3ZDLElBQUksQ0FBQytCLEdBQUcsQ0FBQ1EsbUJBQW1CLEVBQUVELFVBQVUsQ0FBQztRQUNqRSxDQUFDLE1BQU07VUFDTDtVQUNBLElBQU1LLEdBQUcsR0FBR2xCLFdBQVcsR0FBR3ZFLGlCQUFpQjtVQUMzQ3FGLG1CQUFtQixHQUFHdkMsSUFBSSxDQUFDK0IsR0FBRyxDQUFDUSxtQkFBbUIsRUFBRUksR0FBRyxDQUFDO1FBQzFEO01BQ0Y7TUFFQSxJQUFNQyxPQUFPLEdBQUc1QyxJQUFJLENBQUM2QyxJQUFJLENBQUNOLG1CQUFtQixHQUFHeEMsRUFBRSxDQUFDO01BQ25ELElBQU0rQyxJQUFJLEdBQUc5QyxJQUFJLENBQUNDLEdBQUcsQ0FBQ3pELGdCQUFnQixFQUFFd0QsSUFBSSxDQUFDK0IsR0FBRyxDQUFDckYsZ0JBQWdCLEVBQUVrRyxPQUFPLENBQUMsQ0FBQztNQUU1RSxJQUFJRyxPQUFPLEdBQUcvQyxJQUFJLENBQUMrQixHQUFHLENBQUNKLE1BQU0sQ0FBQ3RELE1BQU0sRUFBRTJELFVBQVUsR0FBR2MsSUFBSSxDQUFDO01BRXhELElBQUloRyxrQkFBa0IsSUFBSWlHLE9BQU8sR0FBR3BCLE1BQU0sQ0FBQ3RELE1BQU0sRUFBRTtRQUNqRCxJQUFNMkUsS0FBSyxHQUFHckIsTUFBTSxDQUFDcUIsS0FBSyxDQUFDaEIsVUFBVSxFQUFFZSxPQUFPLENBQUM7UUFDL0MsSUFBTUUsWUFBWSxHQUFHakQsSUFBSSxDQUFDQyxHQUFHLENBQUMrQyxLQUFLLENBQUNFLFdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRUYsS0FBSyxDQUFDRSxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUVGLEtBQUssQ0FBQ0UsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZHLElBQUlELFlBQVksSUFBSSxDQUFDLEVBQUU7VUFDckJGLE9BQU8sR0FBR2YsVUFBVSxHQUFHaUIsWUFBWSxHQUFHLENBQUM7UUFDekM7TUFDRjtNQUVBLElBQUlGLE9BQU8sS0FBS2YsVUFBVSxFQUFFO1FBQzFCLElBQUlyRSxLQUFLLEVBQUVrQixVQUFVLENBQUNlLE9BQU8sQ0FBQ1osaUJBQWlCLElBQUkrRCxPQUFPLEdBQUdmLFVBQVU7UUFDdkU1RCxlQUFlLENBQUN3QixPQUFPLEdBQUdtRCxPQUFPO1FBQ2pDN0UsWUFBWSxDQUFDeUQsTUFBTSxDQUFDcUIsS0FBSyxDQUFDLENBQUMsRUFBRUQsT0FBTyxDQUFDLENBQUM7TUFDeEM7TUFFQSxJQUFJcEYsS0FBSyxJQUFJd0QsT0FBTyxHQUFHdEMsVUFBVSxDQUFDZSxPQUFPLENBQUNOLFNBQVMsR0FBRyxHQUFHLEVBQUU7UUFDekQ0QixVQUFVLENBQUNDLE9BQU8sQ0FBQztNQUNyQjtNQUVBN0MsTUFBTSxDQUFDc0IsT0FBTyxHQUFHc0MscUJBQXFCLENBQUNMLEtBQUksQ0FBQztJQUM5QyxDQUFDO0lBRUR2RCxNQUFNLENBQUNzQixPQUFPLEdBQUdzQyxxQkFBcUIsQ0FBQ0wsS0FBSSxDQUFDO0lBRTVDLE9BQU8sWUFBTTtNQUNYLElBQUl2RCxNQUFNLENBQUNzQixPQUFPLElBQUksSUFBSSxFQUFFO1FBQzFCUyxvQkFBb0IsQ0FBQy9CLE1BQU0sQ0FBQ3NCLE9BQU8sQ0FBQztRQUNwQ3RCLE1BQU0sQ0FBQ3NCLE9BQU8sR0FBRyxJQUFJO01BQ3ZCO01BQ0FyQixXQUFXLENBQUNxQixPQUFPLEdBQUcsQ0FBQztJQUN6QixDQUFDO0VBQ0gsQ0FBQyxFQUFFLENBQ0R4RCxVQUFVLEVBQ1ZFLE9BQU8sRUFDUEUsZ0JBQWdCLEVBQ2hCRSxnQkFBZ0IsRUFDaEJFLFdBQVcsRUFDWEUsa0JBQWtCLEVBQ2xCRSxrQkFBa0IsRUFDbEJFLGlCQUFpQixFQUNqQkMsY0FBYyxFQUNkRSxrQkFBa0IsRUFDbEJFLGNBQWMsRUFDZEUsUUFBUSxFQUNSRSxLQUFLLEVBQ0xFLFVBQVUsQ0FDWCxDQUFDO0VBRUYsT0FBT0ksU0FBUztBQUNsQixDQUFDIiwiaWdub3JlTGlzdCI6W119
@@ -1,3 +0,0 @@
1
- export { useStreamingMessage, useStreamingMessageId } from './useStreamingMessage';
2
- export { streamingStore } from './streamingStore';
3
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ1c2VTdHJlYW1pbmdNZXNzYWdlIiwidXNlU3RyZWFtaW5nTWVzc2FnZUlkIiwic3RyZWFtaW5nU3RvcmUiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaG9va3MvdXNlU3RyZWFtaW5nTWVzc2FnZS9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyB1c2VTdHJlYW1pbmdNZXNzYWdlLCB1c2VTdHJlYW1pbmdNZXNzYWdlSWQgfSBmcm9tICcuL3VzZVN0cmVhbWluZ01lc3NhZ2UnXG5leHBvcnQgeyBzdHJlYW1pbmdTdG9yZSB9IGZyb20gJy4vc3RyZWFtaW5nU3RvcmUnXG4iXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLG1CQUFtQixFQUFFQyxxQkFBcUIsUUFBUSx1QkFBdUI7QUFDbEYsU0FBU0MsY0FBYyxRQUFRLGtCQUFrQiIsImlnbm9yZUxpc3QiOltdfQ==
@@ -1,69 +0,0 @@
1
- /**
2
- * Store externo (module-level) para el mensaje actualmente en streaming.
3
- *
4
- * Desacopla el texto del stream del array de `messages` de React: durante
5
- * el streaming, el texto se mantiene acá y solo los componentes suscritos
6
- * (vía `useStreamingMessage` / `useSyncExternalStore`) re-renderizan cuando
7
- * cambia. El array `messages` no se muta en cada token, evitando ráfagas
8
- * de re-renders del padre y ejecuciones innecesarias de useEffects.
9
- */
10
-
11
- var snapshot = {
12
- id: null,
13
- text: ''
14
- };
15
- var listeners = new Set();
16
- var emitChange = function emitChange() {
17
- listeners.forEach(function (listener) {
18
- listener();
19
- });
20
- };
21
- export var streamingStore = {
22
- /** Inicia una nueva sesión de streaming para el mensaje con este id. */start: function start(id) {
23
- snapshot = {
24
- id: id,
25
- text: ''
26
- };
27
- emitChange();
28
- },
29
- /** Setea el texto del mensaje en streaming. Solo aplica si el id coincide. */setText: function setText(id, text) {
30
- if (snapshot.id !== id) {
31
- snapshot = {
32
- id: id,
33
- text: text
34
- };
35
- } else if (snapshot.text !== text) {
36
- snapshot = {
37
- id: id,
38
- text: text
39
- };
40
- } else {
41
- return;
42
- }
43
- emitChange();
44
- },
45
- /** Limpia el estado de streaming (fin de stream, error o aprobación). */clear: function clear() {
46
- if (snapshot.id == null && snapshot.text === '') return;
47
- snapshot = {
48
- id: null,
49
- text: ''
50
- };
51
- emitChange();
52
- },
53
- /** API para useSyncExternalStore. */subscribe: function subscribe(listener) {
54
- listeners.add(listener);
55
- return function () {
56
- listeners["delete"](listener);
57
- };
58
- },
59
- /** Snapshot referencialmente estable mientras no haya cambios. */getSnapshot: function getSnapshot() {
60
- return snapshot;
61
- },
62
- /** Server snapshot (SSR): siempre vacío. */getServerSnapshot: function getServerSnapshot() {
63
- return {
64
- id: null,
65
- text: ''
66
- };
67
- }
68
- };
69
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJzbmFwc2hvdCIsImlkIiwidGV4dCIsImxpc3RlbmVycyIsIlNldCIsImVtaXRDaGFuZ2UiLCJmb3JFYWNoIiwibGlzdGVuZXIiLCJzdHJlYW1pbmdTdG9yZSIsInN0YXJ0Iiwic2V0VGV4dCIsImNsZWFyIiwic3Vic2NyaWJlIiwiYWRkIiwiZ2V0U25hcHNob3QiLCJnZXRTZXJ2ZXJTbmFwc2hvdCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ob29rcy91c2VTdHJlYW1pbmdNZXNzYWdlL3N0cmVhbWluZ1N0b3JlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU3RvcmUgZXh0ZXJubyAobW9kdWxlLWxldmVsKSBwYXJhIGVsIG1lbnNhamUgYWN0dWFsbWVudGUgZW4gc3RyZWFtaW5nLlxuICpcbiAqIERlc2Fjb3BsYSBlbCB0ZXh0byBkZWwgc3RyZWFtIGRlbCBhcnJheSBkZSBgbWVzc2FnZXNgIGRlIFJlYWN0OiBkdXJhbnRlXG4gKiBlbCBzdHJlYW1pbmcsIGVsIHRleHRvIHNlIG1hbnRpZW5lIGFjw6EgeSBzb2xvIGxvcyBjb21wb25lbnRlcyBzdXNjcml0b3NcbiAqICh2w61hIGB1c2VTdHJlYW1pbmdNZXNzYWdlYCAvIGB1c2VTeW5jRXh0ZXJuYWxTdG9yZWApIHJlLXJlbmRlcml6YW4gY3VhbmRvXG4gKiBjYW1iaWEuIEVsIGFycmF5IGBtZXNzYWdlc2Agbm8gc2UgbXV0YSBlbiBjYWRhIHRva2VuLCBldml0YW5kbyByw6FmYWdhc1xuICogZGUgcmUtcmVuZGVycyBkZWwgcGFkcmUgeSBlamVjdWNpb25lcyBpbm5lY2VzYXJpYXMgZGUgdXNlRWZmZWN0cy5cbiAqL1xuXG50eXBlIFN0cmVhbWluZ1NuYXBzaG90ID0ge1xuICBpZDogc3RyaW5nIHwgbnVsbFxuICB0ZXh0OiBzdHJpbmdcbn1cblxubGV0IHNuYXBzaG90OiBTdHJlYW1pbmdTbmFwc2hvdCA9IHsgaWQ6IG51bGwsIHRleHQ6ICcnIH1cbmNvbnN0IGxpc3RlbmVycyA9IG5ldyBTZXQ8KCkgPT4gdm9pZD4oKVxuXG5jb25zdCBlbWl0Q2hhbmdlID0gKCkgPT4ge1xuICBsaXN0ZW5lcnMuZm9yRWFjaChsaXN0ZW5lciA9PiB7XG4gICAgbGlzdGVuZXIoKVxuICB9KVxufVxuXG5leHBvcnQgY29uc3Qgc3RyZWFtaW5nU3RvcmUgPSB7XG4gIC8qKiBJbmljaWEgdW5hIG51ZXZhIHNlc2nDs24gZGUgc3RyZWFtaW5nIHBhcmEgZWwgbWVuc2FqZSBjb24gZXN0ZSBpZC4gKi9cbiAgc3RhcnQoaWQ6IHN0cmluZykge1xuICAgIHNuYXBzaG90ID0geyBpZCwgdGV4dDogJycgfVxuICAgIGVtaXRDaGFuZ2UoKVxuICB9LFxuICAvKiogU2V0ZWEgZWwgdGV4dG8gZGVsIG1lbnNhamUgZW4gc3RyZWFtaW5nLiBTb2xvIGFwbGljYSBzaSBlbCBpZCBjb2luY2lkZS4gKi9cbiAgc2V0VGV4dChpZDogc3RyaW5nLCB0ZXh0OiBzdHJpbmcpIHtcbiAgICBpZiAoc25hcHNob3QuaWQgIT09IGlkKSB7XG4gICAgICBzbmFwc2hvdCA9IHsgaWQsIHRleHQgfVxuICAgIH0gZWxzZSBpZiAoc25hcHNob3QudGV4dCAhPT0gdGV4dCkge1xuICAgICAgc25hcHNob3QgPSB7IGlkLCB0ZXh0IH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGVtaXRDaGFuZ2UoKVxuICB9LFxuICAvKiogTGltcGlhIGVsIGVzdGFkbyBkZSBzdHJlYW1pbmcgKGZpbiBkZSBzdHJlYW0sIGVycm9yIG8gYXByb2JhY2nDs24pLiAqL1xuICBjbGVhcigpIHtcbiAgICBpZiAoc25hcHNob3QuaWQgPT0gbnVsbCAmJiBzbmFwc2hvdC50ZXh0ID09PSAnJykgcmV0dXJuXG4gICAgc25hcHNob3QgPSB7IGlkOiBudWxsLCB0ZXh0OiAnJyB9XG4gICAgZW1pdENoYW5nZSgpXG4gIH0sXG4gIC8qKiBBUEkgcGFyYSB1c2VTeW5jRXh0ZXJuYWxTdG9yZS4gKi9cbiAgc3Vic2NyaWJlKGxpc3RlbmVyOiAoKSA9PiB2b2lkKSB7XG4gICAgbGlzdGVuZXJzLmFkZChsaXN0ZW5lcilcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgbGlzdGVuZXJzLmRlbGV0ZShsaXN0ZW5lcilcbiAgICB9XG4gIH0sXG4gIC8qKiBTbmFwc2hvdCByZWZlcmVuY2lhbG1lbnRlIGVzdGFibGUgbWllbnRyYXMgbm8gaGF5YSBjYW1iaW9zLiAqL1xuICBnZXRTbmFwc2hvdCgpOiBTdHJlYW1pbmdTbmFwc2hvdCB7XG4gICAgcmV0dXJuIHNuYXBzaG90XG4gIH0sXG4gIC8qKiBTZXJ2ZXIgc25hcHNob3QgKFNTUik6IHNpZW1wcmUgdmFjw61vLiAqL1xuICBnZXRTZXJ2ZXJTbmFwc2hvdCgpOiBTdHJlYW1pbmdTbmFwc2hvdCB7XG4gICAgcmV0dXJuIHsgaWQ6IG51bGwsIHRleHQ6ICcnIH1cbiAgfSxcbn1cblxuZXhwb3J0IHR5cGUgeyBTdHJlYW1pbmdTbmFwc2hvdCB9XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFPQSxJQUFJQSxRQUEyQixHQUFHO0VBQUVDLEVBQUUsRUFBRSxJQUFJO0VBQUVDLElBQUksRUFBRTtBQUFHLENBQUM7QUFDeEQsSUFBTUMsU0FBUyxHQUFHLElBQUlDLEdBQUcsQ0FBYSxDQUFDO0FBRXZDLElBQU1DLFVBQVUsR0FBRyxTQUFiQSxVQUFVQSxDQUFBLEVBQVM7RUFDdkJGLFNBQVMsQ0FBQ0csT0FBTyxDQUFDLFVBQUFDLFFBQVEsRUFBSTtJQUM1QkEsUUFBUSxDQUFDLENBQUM7RUFDWixDQUFDLENBQUM7QUFDSixDQUFDO0FBRUQsT0FBTyxJQUFNQyxjQUFjLEdBQUc7RUFDNUIsd0VBQ0FDLEtBQUssV0FBTEEsS0FBS0EsQ0FBQ1IsRUFBVSxFQUFFO0lBQ2hCRCxRQUFRLEdBQUc7TUFBRUMsRUFBRSxFQUFGQSxFQUFFO01BQUVDLElBQUksRUFBRTtJQUFHLENBQUM7SUFDM0JHLFVBQVUsQ0FBQyxDQUFDO0VBQ2QsQ0FBQztFQUNELDhFQUNBSyxPQUFPLFdBQVBBLE9BQU9BLENBQUNULEVBQVUsRUFBRUMsSUFBWSxFQUFFO0lBQ2hDLElBQUlGLFFBQVEsQ0FBQ0MsRUFBRSxLQUFLQSxFQUFFLEVBQUU7TUFDdEJELFFBQVEsR0FBRztRQUFFQyxFQUFFLEVBQUZBLEVBQUU7UUFBRUMsSUFBSSxFQUFKQTtNQUFLLENBQUM7SUFDekIsQ0FBQyxNQUFNLElBQUlGLFFBQVEsQ0FBQ0UsSUFBSSxLQUFLQSxJQUFJLEVBQUU7TUFDakNGLFFBQVEsR0FBRztRQUFFQyxFQUFFLEVBQUZBLEVBQUU7UUFBRUMsSUFBSSxFQUFKQTtNQUFLLENBQUM7SUFDekIsQ0FBQyxNQUFNO01BQ0w7SUFDRjtJQUNBRyxVQUFVLENBQUMsQ0FBQztFQUNkLENBQUM7RUFDRCx5RUFDQU0sS0FBSyxXQUFMQSxLQUFLQSxDQUFBLEVBQUc7SUFDTixJQUFJWCxRQUFRLENBQUNDLEVBQUUsSUFBSSxJQUFJLElBQUlELFFBQVEsQ0FBQ0UsSUFBSSxLQUFLLEVBQUUsRUFBRTtJQUNqREYsUUFBUSxHQUFHO01BQUVDLEVBQUUsRUFBRSxJQUFJO01BQUVDLElBQUksRUFBRTtJQUFHLENBQUM7SUFDakNHLFVBQVUsQ0FBQyxDQUFDO0VBQ2QsQ0FBQztFQUNELHFDQUNBTyxTQUFTLFdBQVRBLFNBQVNBLENBQUNMLFFBQW9CLEVBQUU7SUFDOUJKLFNBQVMsQ0FBQ1UsR0FBRyxDQUFDTixRQUFRLENBQUM7SUFDdkIsT0FBTyxZQUFNO01BQ1hKLFNBQVMsVUFBTyxDQUFDSSxRQUFRLENBQUM7SUFDNUIsQ0FBQztFQUNILENBQUM7RUFDRCxrRUFDQU8sV0FBVyxXQUFYQSxXQUFXQSxDQUFBLEVBQXNCO0lBQy9CLE9BQU9kLFFBQVE7RUFDakIsQ0FBQztFQUNELDRDQUNBZSxpQkFBaUIsV0FBakJBLGlCQUFpQkEsQ0FBQSxFQUFzQjtJQUNyQyxPQUFPO01BQUVkLEVBQUUsRUFBRSxJQUFJO01BQUVDLElBQUksRUFBRTtJQUFHLENBQUM7RUFDL0I7QUFDRixDQUFDIiwiaWdub3JlTGlzdCI6W119
@@ -1,22 +0,0 @@
1
- import { useSyncExternalStore } from 'react';
2
- import { streamingStore } from './streamingStore';
3
-
4
- /**
5
- * Devuelve el texto actual del mensaje en streaming si el `id` coincide con
6
- * el mensaje activo. Si no hay streaming activo o el id no coincide, devuelve
7
- * una cadena vacía. Esto permite que solo el componente del mensaje en
8
- * streaming se re-renderice, sin afectar al resto del árbol.
9
- */
10
- export var useStreamingMessage = function useStreamingMessage(messageId) {
11
- var snapshot = useSyncExternalStore(streamingStore.subscribe, streamingStore.getSnapshot, streamingStore.getServerSnapshot);
12
- if (!messageId) return '';
13
- if (snapshot.id !== messageId) return '';
14
- return snapshot.text;
15
- };
16
-
17
- /** Devuelve el id del mensaje que está actualmente en streaming (o null). */
18
- export var useStreamingMessageId = function useStreamingMessageId() {
19
- var snapshot = useSyncExternalStore(streamingStore.subscribe, streamingStore.getSnapshot, streamingStore.getServerSnapshot);
20
- return snapshot.id;
21
- };
22
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ1c2VTeW5jRXh0ZXJuYWxTdG9yZSIsInN0cmVhbWluZ1N0b3JlIiwidXNlU3RyZWFtaW5nTWVzc2FnZSIsIm1lc3NhZ2VJZCIsInNuYXBzaG90Iiwic3Vic2NyaWJlIiwiZ2V0U25hcHNob3QiLCJnZXRTZXJ2ZXJTbmFwc2hvdCIsImlkIiwidGV4dCIsInVzZVN0cmVhbWluZ01lc3NhZ2VJZCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ob29rcy91c2VTdHJlYW1pbmdNZXNzYWdlL3VzZVN0cmVhbWluZ01lc3NhZ2UudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdXNlU3luY0V4dGVybmFsU3RvcmUgfSBmcm9tICdyZWFjdCdcbmltcG9ydCB7IHN0cmVhbWluZ1N0b3JlIH0gZnJvbSAnLi9zdHJlYW1pbmdTdG9yZSdcblxuLyoqXG4gKiBEZXZ1ZWx2ZSBlbCB0ZXh0byBhY3R1YWwgZGVsIG1lbnNhamUgZW4gc3RyZWFtaW5nIHNpIGVsIGBpZGAgY29pbmNpZGUgY29uXG4gKiBlbCBtZW5zYWplIGFjdGl2by4gU2kgbm8gaGF5IHN0cmVhbWluZyBhY3Rpdm8gbyBlbCBpZCBubyBjb2luY2lkZSwgZGV2dWVsdmVcbiAqIHVuYSBjYWRlbmEgdmFjw61hLiBFc3RvIHBlcm1pdGUgcXVlIHNvbG8gZWwgY29tcG9uZW50ZSBkZWwgbWVuc2FqZSBlblxuICogc3RyZWFtaW5nIHNlIHJlLXJlbmRlcmljZSwgc2luIGFmZWN0YXIgYWwgcmVzdG8gZGVsIMOhcmJvbC5cbiAqL1xuZXhwb3J0IGNvbnN0IHVzZVN0cmVhbWluZ01lc3NhZ2UgPSAobWVzc2FnZUlkOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogc3RyaW5nID0+IHtcbiAgY29uc3Qgc25hcHNob3QgPSB1c2VTeW5jRXh0ZXJuYWxTdG9yZShcbiAgICBzdHJlYW1pbmdTdG9yZS5zdWJzY3JpYmUsXG4gICAgc3RyZWFtaW5nU3RvcmUuZ2V0U25hcHNob3QsXG4gICAgc3RyZWFtaW5nU3RvcmUuZ2V0U2VydmVyU25hcHNob3RcbiAgKVxuICBpZiAoIW1lc3NhZ2VJZCkgcmV0dXJuICcnXG4gIGlmIChzbmFwc2hvdC5pZCAhPT0gbWVzc2FnZUlkKSByZXR1cm4gJydcbiAgcmV0dXJuIHNuYXBzaG90LnRleHRcbn1cblxuLyoqIERldnVlbHZlIGVsIGlkIGRlbCBtZW5zYWplIHF1ZSBlc3TDoSBhY3R1YWxtZW50ZSBlbiBzdHJlYW1pbmcgKG8gbnVsbCkuICovXG5leHBvcnQgY29uc3QgdXNlU3RyZWFtaW5nTWVzc2FnZUlkID0gKCk6IHN0cmluZyB8IG51bGwgPT4ge1xuICBjb25zdCBzbmFwc2hvdCA9IHVzZVN5bmNFeHRlcm5hbFN0b3JlKFxuICAgIHN0cmVhbWluZ1N0b3JlLnN1YnNjcmliZSxcbiAgICBzdHJlYW1pbmdTdG9yZS5nZXRTbmFwc2hvdCxcbiAgICBzdHJlYW1pbmdTdG9yZS5nZXRTZXJ2ZXJTbmFwc2hvdFxuICApXG4gIHJldHVybiBzbmFwc2hvdC5pZFxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxvQkFBb0IsUUFBUSxPQUFPO0FBQzVDLFNBQVNDLGNBQWMsUUFBUSxrQkFBa0I7O0FBRWpEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sSUFBTUMsbUJBQW1CLEdBQUcsU0FBdEJBLG1CQUFtQkEsQ0FBSUMsU0FBb0MsRUFBYTtFQUNuRixJQUFNQyxRQUFRLEdBQUdKLG9CQUFvQixDQUNuQ0MsY0FBYyxDQUFDSSxTQUFTLEVBQ3hCSixjQUFjLENBQUNLLFdBQVcsRUFDMUJMLGNBQWMsQ0FBQ00saUJBQ2pCLENBQUM7RUFDRCxJQUFJLENBQUNKLFNBQVMsRUFBRSxPQUFPLEVBQUU7RUFDekIsSUFBSUMsUUFBUSxDQUFDSSxFQUFFLEtBQUtMLFNBQVMsRUFBRSxPQUFPLEVBQUU7RUFDeEMsT0FBT0MsUUFBUSxDQUFDSyxJQUFJO0FBQ3RCLENBQUM7O0FBRUQ7QUFDQSxPQUFPLElBQU1DLHFCQUFxQixHQUFHLFNBQXhCQSxxQkFBcUJBLENBQUEsRUFBd0I7RUFDeEQsSUFBTU4sUUFBUSxHQUFHSixvQkFBb0IsQ0FDbkNDLGNBQWMsQ0FBQ0ksU0FBUyxFQUN4QkosY0FBYyxDQUFDSyxXQUFXLEVBQzFCTCxjQUFjLENBQUNNLGlCQUNqQixDQUFDO0VBQ0QsT0FBT0gsUUFBUSxDQUFDSSxFQUFFO0FBQ3BCLENBQUMiLCJpZ25vcmVMaXN0IjpbXX0=