@visuno/angular 0.0.0-stage → 0.1.0

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 (175) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +56 -2
  3. package/account-table/account-table.component.d.ts +72 -0
  4. package/action-log/action-log.component.d.ts +41 -0
  5. package/activity-heatmap/activity-heatmap.component.d.ts +67 -0
  6. package/agent-inbox/agent-inbox.component.d.ts +75 -0
  7. package/agent-lanes/agent-lanes.component.d.ts +152 -0
  8. package/agent-phases/agent-phases.component.d.ts +62 -0
  9. package/agent-run-timeline/agent-run-timeline.component.d.ts +113 -0
  10. package/agent-tree/agent-tree.component.d.ts +80 -0
  11. package/answer-action-bar/answer-action-bar.component.d.ts +110 -0
  12. package/artifact-card/artifact-card.component.d.ts +145 -0
  13. package/attachment-tray/attachment-tray.component.d.ts +84 -0
  14. package/badge/badge.component.d.ts +25 -0
  15. package/bar-chart/bar-chart.component.d.ts +87 -0
  16. package/browser-session/browser-session.component.d.ts +70 -0
  17. package/buttons/buttons.component.d.ts +63 -0
  18. package/card/card.component.d.ts +21 -0
  19. package/change-review/change-review.component.d.ts +97 -0
  20. package/citation-hover-card/citation-hover-card.component.d.ts +95 -0
  21. package/code-viewer/code-viewer.component.d.ts +86 -0
  22. package/composer/composer.component.d.ts +114 -0
  23. package/context-meter/context-meter.component.d.ts +60 -0
  24. package/core/icon.component.d.ts +10 -0
  25. package/core/reduced-motion.service.d.ts +15 -0
  26. package/decision-prompt/decision-prompt.component.d.ts +56 -0
  27. package/design-review/design-review.component.d.ts +108 -0
  28. package/design-tuner/design-tuner.component.d.ts +75 -0
  29. package/details-panel/details-panel.component.d.ts +150 -0
  30. package/donut-chart/donut-chart.component.d.ts +63 -0
  31. package/draft-review/draft-review.component.d.ts +128 -0
  32. package/error-recovery/error-recovery.component.d.ts +59 -0
  33. package/esm2022/account-table/account-table.component.mjs +399 -0
  34. package/esm2022/action-log/action-log.component.mjs +177 -0
  35. package/esm2022/activity-heatmap/activity-heatmap.component.mjs +285 -0
  36. package/esm2022/agent-inbox/agent-inbox.component.mjs +284 -0
  37. package/esm2022/agent-lanes/agent-lanes.component.mjs +600 -0
  38. package/esm2022/agent-phases/agent-phases.component.mjs +300 -0
  39. package/esm2022/agent-run-timeline/agent-run-timeline.component.mjs +412 -0
  40. package/esm2022/agent-tree/agent-tree.component.mjs +393 -0
  41. package/esm2022/answer-action-bar/answer-action-bar.component.mjs +636 -0
  42. package/esm2022/artifact-card/artifact-card.component.mjs +916 -0
  43. package/esm2022/attachment-tray/attachment-tray.component.mjs +402 -0
  44. package/esm2022/badge/badge.component.mjs +97 -0
  45. package/esm2022/bar-chart/bar-chart.component.mjs +300 -0
  46. package/esm2022/browser-session/browser-session.component.mjs +352 -0
  47. package/esm2022/buttons/buttons.component.mjs +215 -0
  48. package/esm2022/card/card.component.mjs +107 -0
  49. package/esm2022/change-review/change-review.component.mjs +398 -0
  50. package/esm2022/citation-hover-card/citation-hover-card.component.mjs +360 -0
  51. package/esm2022/code-viewer/code-viewer.component.mjs +291 -0
  52. package/esm2022/composer/composer.component.mjs +743 -0
  53. package/esm2022/context-meter/context-meter.component.mjs +275 -0
  54. package/esm2022/core/icon.component.mjs +111 -0
  55. package/esm2022/core/reduced-motion.service.mjs +34 -0
  56. package/esm2022/decision-prompt/decision-prompt.component.mjs +259 -0
  57. package/esm2022/design-review/design-review.component.mjs +428 -0
  58. package/esm2022/design-tuner/design-tuner.component.mjs +341 -0
  59. package/esm2022/details-panel/details-panel.component.mjs +537 -0
  60. package/esm2022/donut-chart/donut-chart.component.mjs +240 -0
  61. package/esm2022/draft-review/draft-review.component.mjs +549 -0
  62. package/esm2022/error-recovery/error-recovery.component.mjs +231 -0
  63. package/esm2022/eval-results/eval-results.component.mjs +368 -0
  64. package/esm2022/feedback-sheet/feedback-sheet.component.mjs +411 -0
  65. package/esm2022/field-extraction/field-extraction.component.mjs +368 -0
  66. package/esm2022/funnel-chart/funnel-chart.component.mjs +258 -0
  67. package/esm2022/grid/grid.component.mjs +66 -0
  68. package/esm2022/health-score/health-score.component.mjs +420 -0
  69. package/esm2022/human-handoff/human-handoff.component.mjs +676 -0
  70. package/esm2022/image-generation/image-generation.component.mjs +1028 -0
  71. package/esm2022/inline-text-diff/inline-text-diff.component.mjs +390 -0
  72. package/esm2022/launch-checklist/launch-checklist.component.mjs +229 -0
  73. package/esm2022/line-chart/line-chart.component.mjs +417 -0
  74. package/esm2022/live-answer/live-answer.component.mjs +411 -0
  75. package/esm2022/metric-insight/metric-insight.component.mjs +511 -0
  76. package/esm2022/modal/modal.component.mjs +202 -0
  77. package/esm2022/model-picker/model-picker.component.mjs +491 -0
  78. package/esm2022/permission-gate/permission-gate.component.mjs +498 -0
  79. package/esm2022/plan-review/plan-review.component.mjs +432 -0
  80. package/esm2022/progress/progress.component.mjs +503 -0
  81. package/esm2022/prompt-library/prompt-library.component.mjs +453 -0
  82. package/esm2022/prompt-starters/prompt-starters.component.mjs +272 -0
  83. package/esm2022/proposal-card/proposal-card.component.mjs +402 -0
  84. package/esm2022/public-api.mjs +88 -0
  85. package/esm2022/radar-chart/radar-chart.component.mjs +500 -0
  86. package/esm2022/radial-goals/radial-goals.component.mjs +418 -0
  87. package/esm2022/reasoning-trail/reasoning-trail.component.mjs +284 -0
  88. package/esm2022/response-versions/response-versions.component.mjs +288 -0
  89. package/esm2022/rewrite-toolbar/rewrite-toolbar.component.mjs +397 -0
  90. package/esm2022/rich-text-editor/rich-text-editor.component.mjs +1755 -0
  91. package/esm2022/run-cost/run-cost.component.mjs +215 -0
  92. package/esm2022/run-queue/run-queue.component.mjs +481 -0
  93. package/esm2022/run-summary/run-summary.component.mjs +331 -0
  94. package/esm2022/scatter-chart/scatter-chart.component.mjs +705 -0
  95. package/esm2022/score-breakdown/score-breakdown.component.mjs +460 -0
  96. package/esm2022/segmented-control/segmented-control.component.mjs +180 -0
  97. package/esm2022/source-stack/source-stack.component.mjs +245 -0
  98. package/esm2022/stat-cards/stat-cards.component.mjs +258 -0
  99. package/esm2022/status-pill/status-pill.component.mjs +305 -0
  100. package/esm2022/steering/steering.component.mjs +343 -0
  101. package/esm2022/step-loader/step-loader.component.mjs +209 -0
  102. package/esm2022/task-table/task-table.component.mjs +534 -0
  103. package/esm2022/terminal-stream/terminal-stream.component.mjs +583 -0
  104. package/esm2022/thinking/thinking.component.mjs +276 -0
  105. package/esm2022/thinking-states/thinking-states.component.mjs +333 -0
  106. package/esm2022/thread-panel/thread-panel.component.mjs +271 -0
  107. package/esm2022/toast/toast.component.mjs +195 -0
  108. package/esm2022/toast-stack/toast-stack.component.mjs +301 -0
  109. package/esm2022/tool-call/tool-call.component.mjs +273 -0
  110. package/esm2022/tooltip/tooltip.component.mjs +417 -0
  111. package/esm2022/top-pages/top-pages.component.mjs +240 -0
  112. package/esm2022/trace-view/trace-view.component.mjs +440 -0
  113. package/esm2022/visuno-angular.mjs +5 -0
  114. package/esm2022/voice-capture/voice-capture.component.mjs +650 -0
  115. package/esm2022/voice-orb/voice-orb.component.mjs +538 -0
  116. package/esm2022/web-search/web-search.component.mjs +374 -0
  117. package/eval-results/eval-results.component.d.ts +67 -0
  118. package/feedback-sheet/feedback-sheet.component.d.ts +74 -0
  119. package/fesm2022/visuno-angular.mjs +31992 -0
  120. package/fesm2022/visuno-angular.mjs.map +1 -0
  121. package/field-extraction/field-extraction.component.d.ts +82 -0
  122. package/funnel-chart/funnel-chart.component.d.ts +70 -0
  123. package/grid/grid.component.d.ts +22 -0
  124. package/health-score/health-score.component.d.ts +87 -0
  125. package/human-handoff/human-handoff.component.d.ts +125 -0
  126. package/image-generation/image-generation.component.d.ts +253 -0
  127. package/index.d.ts +5 -0
  128. package/inline-text-diff/inline-text-diff.component.d.ts +76 -0
  129. package/launch-checklist/launch-checklist.component.d.ts +46 -0
  130. package/line-chart/line-chart.component.d.ts +89 -0
  131. package/live-answer/live-answer.component.d.ts +110 -0
  132. package/metric-insight/metric-insight.component.d.ts +110 -0
  133. package/modal/modal.component.d.ts +37 -0
  134. package/model-picker/model-picker.component.d.ts +97 -0
  135. package/package.json +51 -4
  136. package/permission-gate/permission-gate.component.d.ts +100 -0
  137. package/plan-review/plan-review.component.d.ts +86 -0
  138. package/progress/progress.component.d.ts +91 -0
  139. package/prompt-library/prompt-library.component.d.ts +121 -0
  140. package/prompt-starters/prompt-starters.component.d.ts +65 -0
  141. package/proposal-card/proposal-card.component.d.ts +101 -0
  142. package/public-api.d.ts +82 -0
  143. package/radar-chart/radar-chart.component.d.ts +110 -0
  144. package/radial-goals/radial-goals.component.d.ts +90 -0
  145. package/reasoning-trail/reasoning-trail.component.d.ts +73 -0
  146. package/response-versions/response-versions.component.d.ts +54 -0
  147. package/rewrite-toolbar/rewrite-toolbar.component.d.ts +92 -0
  148. package/rich-text-editor/rich-text-editor.component.d.ts +180 -0
  149. package/run-cost/run-cost.component.d.ts +43 -0
  150. package/run-queue/run-queue.component.d.ts +93 -0
  151. package/run-summary/run-summary.component.d.ts +81 -0
  152. package/scatter-chart/scatter-chart.component.d.ts +139 -0
  153. package/score-breakdown/score-breakdown.component.d.ts +107 -0
  154. package/segmented-control/segmented-control.component.d.ts +44 -0
  155. package/source-stack/source-stack.component.d.ts +60 -0
  156. package/stat-cards/stat-cards.component.d.ts +86 -0
  157. package/status-pill/status-pill.component.d.ts +64 -0
  158. package/steering/steering.component.d.ts +75 -0
  159. package/step-loader/step-loader.component.d.ts +40 -0
  160. package/styles.css +424 -0
  161. package/task-table/task-table.component.d.ts +114 -0
  162. package/terminal-stream/terminal-stream.component.d.ts +110 -0
  163. package/thinking/thinking.component.d.ts +63 -0
  164. package/thinking-states/thinking-states.component.d.ts +51 -0
  165. package/thread-panel/thread-panel.component.d.ts +75 -0
  166. package/toast/toast.component.d.ts +56 -0
  167. package/toast-stack/toast-stack.component.d.ts +72 -0
  168. package/tokens.css +424 -0
  169. package/tool-call/tool-call.component.d.ts +61 -0
  170. package/tooltip/tooltip.component.d.ts +89 -0
  171. package/top-pages/top-pages.component.d.ts +75 -0
  172. package/trace-view/trace-view.component.d.ts +95 -0
  173. package/voice-capture/voice-capture.component.d.ts +103 -0
  174. package/voice-orb/voice-orb.component.d.ts +78 -0
  175. package/web-search/web-search.component.d.ts +77 -0
@@ -0,0 +1,650 @@
1
+ // framework/angular/voice-capture/voice-capture.component.ts
2
+ //
3
+ // Native Angular port of framework/react/voice-capture/VoiceCapture.tsx.
4
+ // Speech to text that shows what it heard as it hears it, and lets the person fix
5
+ // the words it was unsure of. The status line, the scrolling wave, the words and
6
+ // the buttons sit in one column. Once recording stops the box keeps its height:
7
+ // the wave stays, still, as the whole recording, and the words stay where they
8
+ // were. Unsure words open a small "Did you mean" menu. Inputs mirror the React
9
+ // props; the buttons move the state along when it is left uncontrolled.
10
+ import { Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, inject, } from '@angular/core';
11
+ import { VoIconComponent } from '../core/icon.component';
12
+ import { ReducedMotionService } from '../core/reduced-motion.service';
13
+ import * as i0 from "@angular/core";
14
+ const STATUS = {
15
+ listening: 'Listening',
16
+ paused: 'Paused',
17
+ review: 'Check what I heard',
18
+ sent: 'Sent',
19
+ cancelled: 'Cancelled',
20
+ };
21
+ const clock = (s) => `${Math.floor(s / 60)}:${String(s % 60).padStart(2, '0')}`;
22
+ export class VoiceCaptureComponent {
23
+ get now() {
24
+ return this.state ?? this.inner;
25
+ }
26
+ get live() {
27
+ return this.now === 'listening' || this.now === 'paused';
28
+ }
29
+ get ended() {
30
+ return this.now === 'sent' || this.now === 'cancelled';
31
+ }
32
+ get clockText() {
33
+ return clock(this.seconds ?? this.count);
34
+ }
35
+ constructor() {
36
+ /** The words heard so far, in order. Add to the end as they arrive and each one fades in. */
37
+ this.words = [];
38
+ this.defaultState = 'listening';
39
+ /** The input level from 0 to 1, drawn into the wave about 20 times a second.
40
+ Pass a function to read the microphone on every sample without re-rendering. */
41
+ this.level = 0;
42
+ this.stateChange = new EventEmitter();
43
+ /** Emitted with the checked transcript when the person presses Done in review. */
44
+ this.send = new EventEmitter();
45
+ /** Emitted when the person picks one of a word's alternatives. */
46
+ this.fixWord = new EventEmitter();
47
+ /** Emitted by Record again, once the capture is sent or cancelled. */
48
+ this.recordAgain = new EventEmitter();
49
+ this.motion = inject(ReducedMotionService);
50
+ this.STATUS = STATUS;
51
+ // the state when uncontrolled; mirrors the controllable hook in React
52
+ this.inner = 'listening';
53
+ // the clock counts while listening, unless the parent passes seconds
54
+ this.count = 0;
55
+ // the fixes the person has picked, by word index
56
+ this.fixes = {};
57
+ this.rendered = [];
58
+ // the "Did you mean" menu
59
+ this.menuOpen = false;
60
+ this.menu = {
61
+ index: -1,
62
+ alts: [],
63
+ left: 0,
64
+ top: 0,
65
+ };
66
+ this.keyOpen = false;
67
+ this.inMenu = false;
68
+ // the wave
69
+ this.samples = [];
70
+ this.raf = 0;
71
+ this.lastSample = 0;
72
+ this.cols = null;
73
+ this.colsAt = -1e9;
74
+ this.drawn = '';
75
+ this.onDocClick = (e) => this.docClick(e);
76
+ this.inner = this.defaultState;
77
+ }
78
+ ngOnChanges(changes) {
79
+ if (changes['words'])
80
+ this.buildWords();
81
+ if (changes['state'] || changes['seconds'])
82
+ this.syncClock();
83
+ // a controlled state change can flip live/held and the wave mode
84
+ if (changes['state'] && !changes['state'].firstChange)
85
+ this.onStateFlip();
86
+ }
87
+ ngAfterViewInit() {
88
+ this.inner = this.defaultState;
89
+ this.buildWords();
90
+ this.syncClock();
91
+ this.measure();
92
+ this.startWave();
93
+ document.addEventListener('click', this.onDocClick);
94
+ }
95
+ ngOnDestroy() {
96
+ cancelAnimationFrame(this.raf);
97
+ this.ro?.disconnect();
98
+ if (this.tick)
99
+ clearInterval(this.tick);
100
+ document.removeEventListener('click', this.onDocClick);
101
+ }
102
+ buildWords() {
103
+ this.rendered = this.words.map((w, i) => {
104
+ const word = typeof w === 'string' ? { text: w } : w;
105
+ const alternatives = word.alternatives ?? [];
106
+ const fixed = this.fixes[i] !== undefined;
107
+ return {
108
+ index: i,
109
+ text: this.fixes[i] ?? word.text,
110
+ alternatives,
111
+ fixed,
112
+ };
113
+ });
114
+ }
115
+ syncClock() {
116
+ if (this.seconds !== undefined || this.now !== 'listening') {
117
+ if (this.tick) {
118
+ clearInterval(this.tick);
119
+ this.tick = undefined;
120
+ }
121
+ return;
122
+ }
123
+ if (!this.tick) {
124
+ this.tick = setInterval(() => {
125
+ this.count++;
126
+ }, 1000);
127
+ }
128
+ }
129
+ measure() {
130
+ if (this.live && this.root)
131
+ this.liveHeight = this.root.nativeElement.offsetHeight;
132
+ }
133
+ onStateFlip() {
134
+ if (!this.live) {
135
+ this.held = this.liveHeight;
136
+ this.startWave();
137
+ }
138
+ else {
139
+ this.held = undefined;
140
+ this.measure();
141
+ this.startWave();
142
+ }
143
+ this.syncClock();
144
+ this.buildWords();
145
+ }
146
+ togglePause() {
147
+ this.setState(this.now === 'paused' ? 'listening' : 'paused');
148
+ }
149
+ setState(s) {
150
+ const wasLive = this.live;
151
+ if (this.state === undefined)
152
+ this.inner = s;
153
+ this.stateChange.emit(s);
154
+ const nowLive = this.now === 'listening' || this.now === 'paused';
155
+ if (wasLive && !nowLive) {
156
+ this.held = this.liveHeight;
157
+ }
158
+ else if (!wasLive && nowLive) {
159
+ this.held = undefined;
160
+ }
161
+ this.syncClock();
162
+ // defer so the template reflects the new state before we re-measure / repaint
163
+ queueMicrotask(() => {
164
+ if (!wasLive && nowLive)
165
+ this.measure();
166
+ this.startWave();
167
+ });
168
+ }
169
+ transcript() {
170
+ return this.words
171
+ .map((w, i) => this.fixes[i] ?? (typeof w === 'string' ? w : w.text))
172
+ .join(' ');
173
+ }
174
+ done() {
175
+ if (this.live)
176
+ this.setState('review');
177
+ else if (this.now === 'review') {
178
+ this.setState('sent');
179
+ this.send.emit(this.transcript());
180
+ }
181
+ }
182
+ cancel() {
183
+ this.menuOpen = false;
184
+ this.setState('cancelled');
185
+ }
186
+ again() {
187
+ this.count = 0;
188
+ this.fixes = {};
189
+ this.menuOpen = false;
190
+ this.samples = [];
191
+ this.recordAgain.emit();
192
+ this.setState('listening');
193
+ this.buildWords();
194
+ }
195
+ // ----- the "Did you mean" menu -----
196
+ wordKey(index, e) {
197
+ if (e.key === 'Enter' || e.key === ' ') {
198
+ e.preventDefault();
199
+ this.keyOpen = true;
200
+ this.show(index, e, true);
201
+ }
202
+ }
203
+ show(index, e, key) {
204
+ const el = e.currentTarget;
205
+ const box = this.root?.nativeElement;
206
+ if (!box || !el)
207
+ return;
208
+ const hr = box.getBoundingClientRect();
209
+ const lr = el.getBoundingClientRect();
210
+ const word = this.words[index];
211
+ const alts = typeof word === 'string' ? [] : word.alternatives ?? [];
212
+ this.menu = {
213
+ index,
214
+ alts,
215
+ left: lr.left - hr.left,
216
+ top: lr.bottom - hr.top + 6,
217
+ };
218
+ this.menuOpen = true;
219
+ if (key)
220
+ this.keyOpen = true;
221
+ e.stopPropagation();
222
+ queueMicrotask(() => {
223
+ if (this.keyOpen) {
224
+ this.keyOpen = false;
225
+ this.popRef?.nativeElement
226
+ .querySelector('.vo-mi')
227
+ ?.focus({ preventScroll: true });
228
+ }
229
+ });
230
+ }
231
+ closeMenu() {
232
+ const back = this.menuOpen && this.menu.index;
233
+ const focusWord = this.inMenu;
234
+ this.menuOpen = false;
235
+ this.inMenu = false;
236
+ if (focusWord) {
237
+ queueMicrotask(() => this.wordEl(back)?.focus({ preventScroll: true }));
238
+ }
239
+ }
240
+ wordEl(i) {
241
+ return this.root?.nativeElement.querySelector(`.vo-low[data-i="${i}"]`);
242
+ }
243
+ menuKey(e) {
244
+ const all = Array.from(this.popRef?.nativeElement.querySelectorAll('.vo-mi') ?? []);
245
+ const i = all.indexOf(document.activeElement);
246
+ const go = {
247
+ ArrowDown: all[(i + 1) % all.length],
248
+ ArrowUp: all[(i - 1 + all.length) % all.length],
249
+ Home: all[0],
250
+ End: all[all.length - 1],
251
+ };
252
+ if (go[e.key]) {
253
+ e.preventDefault();
254
+ go[e.key].focus({ preventScroll: true });
255
+ }
256
+ else if (e.key === 'Escape') {
257
+ e.preventDefault();
258
+ e.stopPropagation();
259
+ this.inMenu = true;
260
+ this.closeMenu();
261
+ }
262
+ else if (e.key === 'Tab') {
263
+ this.inMenu = true;
264
+ this.closeMenu();
265
+ }
266
+ }
267
+ fix(index, text) {
268
+ this.fixes = { ...this.fixes, [index]: text };
269
+ this.fixWord.emit({ index, text });
270
+ this.menuOpen = false;
271
+ this.buildWords();
272
+ }
273
+ docClick(e) {
274
+ if (!this.menuOpen)
275
+ return;
276
+ const t = e.target;
277
+ const pop = this.popRef?.nativeElement;
278
+ const box = this.root?.nativeElement;
279
+ if (t.isConnected &&
280
+ !pop?.contains(t) &&
281
+ !(box?.contains(t) && t.closest('.vo-low'))) {
282
+ this.menuOpen = false;
283
+ }
284
+ }
285
+ // ----- the wave -----
286
+ colours(el) {
287
+ const t = performance.now();
288
+ if (!this.cols || t - this.colsAt > 400) {
289
+ const cs = getComputedStyle(el);
290
+ this.cols = ['--vo-fg2', '--vo-faint', '--vo-muted'].map((k) => cs.getPropertyValue(k).trim());
291
+ this.colsAt = t;
292
+ }
293
+ return this.cols;
294
+ }
295
+ bars(cv) {
296
+ return Math.floor(cv.clientWidth / 5);
297
+ }
298
+ paint(vals, still) {
299
+ const cv = this.waveRef?.nativeElement;
300
+ const el = this.root?.nativeElement;
301
+ if (!cv || !el)
302
+ return;
303
+ const dpr = devicePixelRatio || 1;
304
+ const w = cv.clientWidth;
305
+ const h = cv.clientHeight;
306
+ if (!w)
307
+ return;
308
+ if (cv.width !== w * dpr) {
309
+ cv.width = w * dpr;
310
+ cv.height = h * dpr;
311
+ }
312
+ const x = cv.getContext('2d');
313
+ if (!x)
314
+ return;
315
+ x.setTransform(dpr, 0, 0, dpr, 0, 0);
316
+ x.clearRect(0, 0, w, h);
317
+ const [on, off, rec] = this.colours(el);
318
+ const n = vals.length;
319
+ for (let i = 0; i < n; i++) {
320
+ const v = vals[i];
321
+ const px = i * 5 + 2;
322
+ const bh = v ? Math.max(4, v * (h - 6)) : 2;
323
+ x.globalAlpha = still
324
+ ? v
325
+ ? 0.6
326
+ : 1
327
+ : Math.min(1, i / 14, (n - i) / 3 + 0.2);
328
+ x.fillStyle = v ? (still ? rec : on) : off;
329
+ x.beginPath();
330
+ if (x.roundRect)
331
+ x.roundRect(px, h / 2 - bh / 2, 2.5, bh, 1.2);
332
+ else
333
+ x.rect(px, h / 2 - bh / 2, 2.5, bh);
334
+ x.fill();
335
+ }
336
+ }
337
+ still() {
338
+ const cv = this.waveRef?.nativeElement;
339
+ if (!cv)
340
+ return;
341
+ // the recording without the silence either side, fitted to the width
342
+ const s = this.samples;
343
+ const n = this.bars(cv);
344
+ const a = s.findIndex((v) => v);
345
+ let z = s.length - 1;
346
+ while (z > a && !s[z])
347
+ z--;
348
+ const rec = a < 0 ? [] : s.slice(Math.max(0, a - 2), z + 3);
349
+ this.paint(Array.from({ length: n }, (_, i) => {
350
+ const from = Math.floor((i * rec.length) / n);
351
+ const to = Math.max(from + 1, Math.floor(((i + 1) * rec.length) / n));
352
+ return Math.max(0, ...rec.slice(from, to).map((v) => v || 0));
353
+ }), true);
354
+ }
355
+ startWave() {
356
+ cancelAnimationFrame(this.raf);
357
+ this.ro?.disconnect();
358
+ this.ro = undefined;
359
+ const cv = this.waveRef?.nativeElement;
360
+ if (!cv)
361
+ return;
362
+ if (!this.live) {
363
+ // drawn again only when its width or the theme changes
364
+ const again = () => {
365
+ this.cols = null;
366
+ this.still();
367
+ };
368
+ this.still();
369
+ if (typeof ResizeObserver === 'function') {
370
+ this.ro = new ResizeObserver(again);
371
+ this.ro.observe(cv);
372
+ }
373
+ return;
374
+ }
375
+ const draw = (t) => {
376
+ this.raf = requestAnimationFrame(draw);
377
+ if (t - this.lastSample > 50) {
378
+ this.lastSample = t;
379
+ const l = this.level;
380
+ const v = this.now === 'listening'
381
+ ? typeof l === 'function'
382
+ ? l()
383
+ : l
384
+ : 0;
385
+ this.samples.push(Math.max(0, Math.min(1, v)));
386
+ if (this.samples.length > 300)
387
+ this.samples.shift();
388
+ }
389
+ const n = this.bars(cv);
390
+ this.paint(Array.from({ length: n }, (_, i) => this.samples[this.samples.length - n + i] || 0), false);
391
+ };
392
+ this.raf = requestAnimationFrame(draw);
393
+ }
394
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VoiceCaptureComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
395
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: VoiceCaptureComponent, isStandalone: true, selector: "vo-voice-capture", inputs: { words: "words", state: "state", defaultState: "defaultState", seconds: "seconds", level: "level", status: "status" }, outputs: { stateChange: "stateChange", send: "send", fixWord: "fixWord", recordAgain: "recordAgain" }, viewQueries: [{ propertyName: "root", first: true, predicate: ["root"], descendants: true }, { propertyName: "waveRef", first: true, predicate: ["wave"], descendants: true }, { propertyName: "popRef", first: true, predicate: ["pop"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
396
+ <div
397
+ #root
398
+ data-vo=""
399
+ class="vo-vcx vo-panel"
400
+ [class.vo-paused]="now === 'paused'"
401
+ [class.vo-done]="!live"
402
+ [class.vo-gone]="now === 'cancelled'"
403
+ [class.vo-held]="held !== undefined"
404
+ [style.minHeight.px]="held"
405
+ >
406
+ <div class="vo-vcx-top">
407
+ <span class="vo-vcx-dot"></span>
408
+ <span class="vo-vcx-st">{{ status ?? STATUS[now] }}</span>
409
+ <span class="vo-vcx-t vo-num vo-muted">{{ clockText }}</span>
410
+ </div>
411
+ <canvas #wave class="vo-vcx-wave" aria-hidden="true"></canvas>
412
+ <p class="vo-vcx-tx" aria-live="polite">
413
+ @for (w of rendered; track w.index) {
414
+ @if (w.alternatives.length && now !== 'cancelled') {
415
+ <span class="vo-w"
416
+ ><span
417
+ class="vo-low"
418
+ [class.vo-fixed]="w.fixed"
419
+ role="button"
420
+ tabindex="0"
421
+ aria-haspopup="menu"
422
+ [attr.aria-expanded]="menuOpen && menu.index === w.index"
423
+ [attr.data-tip]="
424
+ !live ? (w.fixed ? 'Fixed' : 'Not sure about this word') : null
425
+ "
426
+ [attr.data-i]="w.index"
427
+ (click)="show(w.index, $event, false)"
428
+ (keydown)="wordKey(w.index, $event)"
429
+ >{{ w.text }}</span
430
+ >
431
+ </span>
432
+ } @else {
433
+ <span class="vo-w">{{ w.text }} </span>
434
+ }
435
+ }
436
+ </p>
437
+ <div class="vo-vcx-acts">
438
+ @if (ended) {
439
+ <span class="vo-muted" style="font-size:12.5px">{{
440
+ now === 'sent' ? 'Sent to the agent' : 'Nothing was sent'
441
+ }}</span>
442
+ <span class="vo-sp"></span>
443
+ <button
444
+ type="button"
445
+ class="vo-pill vo-ghost vo-sm vo-vcx-again"
446
+ (click)="again()"
447
+ >
448
+ <vo-icon name="refresh" size="xs"></vo-icon>Record again
449
+ </button>
450
+ } @else {
451
+ @if (live) {
452
+ <button
453
+ type="button"
454
+ class="vo-ib vo-fill vo-vcx-pause"
455
+ [attr.aria-label]="now === 'paused' ? 'Resume' : 'Pause'"
456
+ [attr.data-tip]="now === 'paused' ? 'Resume' : 'Pause'"
457
+ (click)="togglePause()"
458
+ >
459
+ <vo-icon [name]="now === 'paused' ? 'spark' : 'pause'"></vo-icon>
460
+ </button>
461
+ }
462
+ <span class="vo-sp"></span>
463
+ <button
464
+ type="button"
465
+ class="vo-pill vo-ghost vo-sm vo-vcx-x"
466
+ (click)="cancel()"
467
+ >
468
+ Cancel
469
+ </button>
470
+ <button
471
+ type="button"
472
+ class="vo-pill vo-primary vo-sm vo-vcx-done"
473
+ (click)="done()"
474
+ >
475
+ Done
476
+ </button>
477
+ }
478
+ </div>
479
+ <div
480
+ #pop
481
+ class="vo-pop vo-vcx-fix"
482
+ [class.vo-open]="menuOpen"
483
+ role="menu"
484
+ aria-label="Did you mean"
485
+ [style.left.px]="menu.left"
486
+ [style.top.px]="menu.top"
487
+ [attr.inert]="menuOpen ? null : ''"
488
+ [attr.aria-hidden]="!menuOpen"
489
+ (keydown)="menuKey($event)"
490
+ >
491
+ <div class="vo-ph">Did you mean</div>
492
+ @for (a of menu.alts; track a) {
493
+ <button
494
+ type="button"
495
+ role="menuitem"
496
+ tabindex="-1"
497
+ class="vo-mi"
498
+ (click)="fix(menu.index, a)"
499
+ >
500
+ {{ a }}
501
+ </button>
502
+ }
503
+ </div>
504
+ </div>
505
+ `, isInline: true, styles: [".vo-vcx{padding:var(--vo-s-4);position:relative;display:flex;flex-direction:column;gap:var(--vo-s-3)}.vo-vcx.vo-held{justify-content:flex-start}.vo-vcx.vo-held .vo-vcx-tx{flex:1}.vo-vcx-top{display:flex;align-items:center;gap:var(--vo-s-2);font-size:13px}.vo-vcx-dot{width:8px;height:8px;border-radius:50%;background:var(--vo-bad);animation:vo-vpulse 1.4s var(--vo-ease-io) infinite}@keyframes vo-vpulse{0%,to{box-shadow:0 0 color-mix(in srgb,var(--vo-fg) 14%,transparent)}50%{box-shadow:0 0 0 5px transparent}}.vo-vcx.vo-paused .vo-vcx-dot,.vo-vcx.vo-done .vo-vcx-dot{animation:none;background:var(--vo-faint)}.vo-vcx-t{margin-left:auto;font-size:12.5px}.vo-vcx-wave{display:block;width:100%;height:48px}.vo-vcx-tx{margin:0;min-height:3.2em;font-size:14px;line-height:1.6;color:var(--vo-fg)}.vo-vcx-tx .vo-w{animation:vo-lvw .45s var(--vo-ease) both}@keyframes vo-lvw{0%{opacity:0;filter:blur(3px)}to{opacity:1;filter:none}}.vo-vcx-tx .vo-low{padding:1px 2px;margin:0 -2px;background:var(--vo-hl);-webkit-box-decoration-break:clone;box-decoration-break:clone;cursor:pointer;transition:background .25s}@media (hover:hover) and (pointer:fine){.vo-vcx-tx .vo-low:hover{background:color-mix(in srgb,var(--vo-hl) 70%,var(--vo-py))}}.vo-vcx-tx .vo-low.vo-fixed{background:var(--vo-hl-ok)}.vo-vcx.vo-gone .vo-vcx-tx{color:var(--vo-muted)}.vo-vcx-acts{display:flex;align-items:center;gap:var(--vo-s-2);min-height:32px}.vo-vcx-fix{width:220px}.vo-panel{background:var(--vo-surface);border-radius:var(--vo-r-card);box-shadow:var(--vo-shadow);position:relative}.vo-num{font-variant-numeric:tabular-nums}.vo-muted{color:var(--vo-muted)}.vo-sp{flex:1}.vo-pop{position:absolute;z-index:50;min-width:200px;background:var(--vo-raised);border-radius:calc(14px * var(--vo-rk,1));box-shadow:var(--vo-shadow-pop);padding:6px;opacity:0;visibility:hidden;pointer-events:none;transform:translateY(6px) scale(.98);transform-origin:var(--vo-origin,top left);filter:blur(3px);transition:opacity .2s var(--vo-ease),transform .35s var(--vo-ease),filter .2s var(--vo-ease),visibility 0s .2s}.vo-pop.vo-open{opacity:1;visibility:visible;pointer-events:auto;transform:none;filter:none;transition-property:opacity,transform,filter}.vo-pop .vo-ph{padding:6px var(--vo-s-2) var(--vo-s-1);font-size:11.5px;color:var(--vo-muted)}.vo-mi{display:flex;align-items:center;gap:10px;width:100%;padding:7px var(--vo-s-2);border-radius:calc(9px * var(--vo-rk,1));font-size:13px;text-align:left;color:var(--vo-fg);cursor:pointer;transition:background var(--vo-t-fast)}@media (hover:hover) and (pointer:fine){.vo-mi:hover{background:var(--vo-row)}}.vo-mi+.vo-mi{margin-top:2px}.vo-ib{width:30px;height:30px;border-radius:50%;display:inline-grid;place-items:center;color:var(--vo-fg2);cursor:pointer;transition:background var(--vo-t-fast),color var(--vo-t-fast),transform .15s}@media (hover:hover) and (pointer:fine){.vo-ib:hover{background:var(--vo-row);color:var(--vo-fg)}}.vo-ib:active{transform:scale(.94)}.vo-ib.vo-fill{background:var(--vo-chip)}.vo-pill{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:32px;padding:0 14px;border-radius:var(--vo-r-pill);font-size:13px;font-weight:500;white-space:nowrap;cursor:pointer;transition:background var(--vo-t-fast),color var(--vo-t-fast),opacity var(--vo-t-fast),transform .15s}.vo-pill:active{transform:scale(.97)}.vo-pill.vo-primary{background:var(--vo-accent);color:var(--vo-on-accent)}@media (hover:hover) and (pointer:fine){.vo-pill.vo-primary:hover{background:var(--vo-accent-2)}}.vo-pill.vo-ghost{color:var(--vo-fg2)}@media (hover:hover) and (pointer:fine){.vo-pill.vo-ghost:hover{background:var(--vo-row);color:var(--vo-fg)}}.vo-pill.vo-sm{height:28px;padding:0 11px;font-size:12.5px}\n"], dependencies: [{ kind: "component", type: VoIconComponent, selector: "vo-icon", inputs: ["name", "size"] }], encapsulation: i0.ViewEncapsulation.None }); }
506
+ }
507
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VoiceCaptureComponent, decorators: [{
508
+ type: Component,
509
+ args: [{ selector: 'vo-voice-capture', standalone: true, encapsulation: ViewEncapsulation.None, imports: [VoIconComponent], template: `
510
+ <div
511
+ #root
512
+ data-vo=""
513
+ class="vo-vcx vo-panel"
514
+ [class.vo-paused]="now === 'paused'"
515
+ [class.vo-done]="!live"
516
+ [class.vo-gone]="now === 'cancelled'"
517
+ [class.vo-held]="held !== undefined"
518
+ [style.minHeight.px]="held"
519
+ >
520
+ <div class="vo-vcx-top">
521
+ <span class="vo-vcx-dot"></span>
522
+ <span class="vo-vcx-st">{{ status ?? STATUS[now] }}</span>
523
+ <span class="vo-vcx-t vo-num vo-muted">{{ clockText }}</span>
524
+ </div>
525
+ <canvas #wave class="vo-vcx-wave" aria-hidden="true"></canvas>
526
+ <p class="vo-vcx-tx" aria-live="polite">
527
+ @for (w of rendered; track w.index) {
528
+ @if (w.alternatives.length && now !== 'cancelled') {
529
+ <span class="vo-w"
530
+ ><span
531
+ class="vo-low"
532
+ [class.vo-fixed]="w.fixed"
533
+ role="button"
534
+ tabindex="0"
535
+ aria-haspopup="menu"
536
+ [attr.aria-expanded]="menuOpen && menu.index === w.index"
537
+ [attr.data-tip]="
538
+ !live ? (w.fixed ? 'Fixed' : 'Not sure about this word') : null
539
+ "
540
+ [attr.data-i]="w.index"
541
+ (click)="show(w.index, $event, false)"
542
+ (keydown)="wordKey(w.index, $event)"
543
+ >{{ w.text }}</span
544
+ >
545
+ </span>
546
+ } @else {
547
+ <span class="vo-w">{{ w.text }} </span>
548
+ }
549
+ }
550
+ </p>
551
+ <div class="vo-vcx-acts">
552
+ @if (ended) {
553
+ <span class="vo-muted" style="font-size:12.5px">{{
554
+ now === 'sent' ? 'Sent to the agent' : 'Nothing was sent'
555
+ }}</span>
556
+ <span class="vo-sp"></span>
557
+ <button
558
+ type="button"
559
+ class="vo-pill vo-ghost vo-sm vo-vcx-again"
560
+ (click)="again()"
561
+ >
562
+ <vo-icon name="refresh" size="xs"></vo-icon>Record again
563
+ </button>
564
+ } @else {
565
+ @if (live) {
566
+ <button
567
+ type="button"
568
+ class="vo-ib vo-fill vo-vcx-pause"
569
+ [attr.aria-label]="now === 'paused' ? 'Resume' : 'Pause'"
570
+ [attr.data-tip]="now === 'paused' ? 'Resume' : 'Pause'"
571
+ (click)="togglePause()"
572
+ >
573
+ <vo-icon [name]="now === 'paused' ? 'spark' : 'pause'"></vo-icon>
574
+ </button>
575
+ }
576
+ <span class="vo-sp"></span>
577
+ <button
578
+ type="button"
579
+ class="vo-pill vo-ghost vo-sm vo-vcx-x"
580
+ (click)="cancel()"
581
+ >
582
+ Cancel
583
+ </button>
584
+ <button
585
+ type="button"
586
+ class="vo-pill vo-primary vo-sm vo-vcx-done"
587
+ (click)="done()"
588
+ >
589
+ Done
590
+ </button>
591
+ }
592
+ </div>
593
+ <div
594
+ #pop
595
+ class="vo-pop vo-vcx-fix"
596
+ [class.vo-open]="menuOpen"
597
+ role="menu"
598
+ aria-label="Did you mean"
599
+ [style.left.px]="menu.left"
600
+ [style.top.px]="menu.top"
601
+ [attr.inert]="menuOpen ? null : ''"
602
+ [attr.aria-hidden]="!menuOpen"
603
+ (keydown)="menuKey($event)"
604
+ >
605
+ <div class="vo-ph">Did you mean</div>
606
+ @for (a of menu.alts; track a) {
607
+ <button
608
+ type="button"
609
+ role="menuitem"
610
+ tabindex="-1"
611
+ class="vo-mi"
612
+ (click)="fix(menu.index, a)"
613
+ >
614
+ {{ a }}
615
+ </button>
616
+ }
617
+ </div>
618
+ </div>
619
+ `, styles: [".vo-vcx{padding:var(--vo-s-4);position:relative;display:flex;flex-direction:column;gap:var(--vo-s-3)}.vo-vcx.vo-held{justify-content:flex-start}.vo-vcx.vo-held .vo-vcx-tx{flex:1}.vo-vcx-top{display:flex;align-items:center;gap:var(--vo-s-2);font-size:13px}.vo-vcx-dot{width:8px;height:8px;border-radius:50%;background:var(--vo-bad);animation:vo-vpulse 1.4s var(--vo-ease-io) infinite}@keyframes vo-vpulse{0%,to{box-shadow:0 0 color-mix(in srgb,var(--vo-fg) 14%,transparent)}50%{box-shadow:0 0 0 5px transparent}}.vo-vcx.vo-paused .vo-vcx-dot,.vo-vcx.vo-done .vo-vcx-dot{animation:none;background:var(--vo-faint)}.vo-vcx-t{margin-left:auto;font-size:12.5px}.vo-vcx-wave{display:block;width:100%;height:48px}.vo-vcx-tx{margin:0;min-height:3.2em;font-size:14px;line-height:1.6;color:var(--vo-fg)}.vo-vcx-tx .vo-w{animation:vo-lvw .45s var(--vo-ease) both}@keyframes vo-lvw{0%{opacity:0;filter:blur(3px)}to{opacity:1;filter:none}}.vo-vcx-tx .vo-low{padding:1px 2px;margin:0 -2px;background:var(--vo-hl);-webkit-box-decoration-break:clone;box-decoration-break:clone;cursor:pointer;transition:background .25s}@media (hover:hover) and (pointer:fine){.vo-vcx-tx .vo-low:hover{background:color-mix(in srgb,var(--vo-hl) 70%,var(--vo-py))}}.vo-vcx-tx .vo-low.vo-fixed{background:var(--vo-hl-ok)}.vo-vcx.vo-gone .vo-vcx-tx{color:var(--vo-muted)}.vo-vcx-acts{display:flex;align-items:center;gap:var(--vo-s-2);min-height:32px}.vo-vcx-fix{width:220px}.vo-panel{background:var(--vo-surface);border-radius:var(--vo-r-card);box-shadow:var(--vo-shadow);position:relative}.vo-num{font-variant-numeric:tabular-nums}.vo-muted{color:var(--vo-muted)}.vo-sp{flex:1}.vo-pop{position:absolute;z-index:50;min-width:200px;background:var(--vo-raised);border-radius:calc(14px * var(--vo-rk,1));box-shadow:var(--vo-shadow-pop);padding:6px;opacity:0;visibility:hidden;pointer-events:none;transform:translateY(6px) scale(.98);transform-origin:var(--vo-origin,top left);filter:blur(3px);transition:opacity .2s var(--vo-ease),transform .35s var(--vo-ease),filter .2s var(--vo-ease),visibility 0s .2s}.vo-pop.vo-open{opacity:1;visibility:visible;pointer-events:auto;transform:none;filter:none;transition-property:opacity,transform,filter}.vo-pop .vo-ph{padding:6px var(--vo-s-2) var(--vo-s-1);font-size:11.5px;color:var(--vo-muted)}.vo-mi{display:flex;align-items:center;gap:10px;width:100%;padding:7px var(--vo-s-2);border-radius:calc(9px * var(--vo-rk,1));font-size:13px;text-align:left;color:var(--vo-fg);cursor:pointer;transition:background var(--vo-t-fast)}@media (hover:hover) and (pointer:fine){.vo-mi:hover{background:var(--vo-row)}}.vo-mi+.vo-mi{margin-top:2px}.vo-ib{width:30px;height:30px;border-radius:50%;display:inline-grid;place-items:center;color:var(--vo-fg2);cursor:pointer;transition:background var(--vo-t-fast),color var(--vo-t-fast),transform .15s}@media (hover:hover) and (pointer:fine){.vo-ib:hover{background:var(--vo-row);color:var(--vo-fg)}}.vo-ib:active{transform:scale(.94)}.vo-ib.vo-fill{background:var(--vo-chip)}.vo-pill{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:32px;padding:0 14px;border-radius:var(--vo-r-pill);font-size:13px;font-weight:500;white-space:nowrap;cursor:pointer;transition:background var(--vo-t-fast),color var(--vo-t-fast),opacity var(--vo-t-fast),transform .15s}.vo-pill:active{transform:scale(.97)}.vo-pill.vo-primary{background:var(--vo-accent);color:var(--vo-on-accent)}@media (hover:hover) and (pointer:fine){.vo-pill.vo-primary:hover{background:var(--vo-accent-2)}}.vo-pill.vo-ghost{color:var(--vo-fg2)}@media (hover:hover) and (pointer:fine){.vo-pill.vo-ghost:hover{background:var(--vo-row);color:var(--vo-fg)}}.vo-pill.vo-sm{height:28px;padding:0 11px;font-size:12.5px}\n"] }]
620
+ }], ctorParameters: () => [], propDecorators: { words: [{
621
+ type: Input
622
+ }], state: [{
623
+ type: Input
624
+ }], defaultState: [{
625
+ type: Input
626
+ }], seconds: [{
627
+ type: Input
628
+ }], level: [{
629
+ type: Input
630
+ }], status: [{
631
+ type: Input
632
+ }], stateChange: [{
633
+ type: Output
634
+ }], send: [{
635
+ type: Output
636
+ }], fixWord: [{
637
+ type: Output
638
+ }], recordAgain: [{
639
+ type: Output
640
+ }], root: [{
641
+ type: ViewChild,
642
+ args: ['root']
643
+ }], waveRef: [{
644
+ type: ViewChild,
645
+ args: ['wave']
646
+ }], popRef: [{
647
+ type: ViewChild,
648
+ args: ['pop']
649
+ }] } });
650
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtY2FwdHVyZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi92b2ljZS1jYXB0dXJlL3ZvaWNlLWNhcHR1cmUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDZEQUE2RDtBQUM3RCxFQUFFO0FBQ0YseUVBQXlFO0FBQ3pFLGtGQUFrRjtBQUNsRixpRkFBaUY7QUFDakYsZ0ZBQWdGO0FBQ2hGLCtFQUErRTtBQUMvRSwrRUFBK0U7QUFDL0Usd0VBQXdFO0FBRXhFLE9BQU8sRUFFTCxTQUFTLEVBRVQsWUFBWSxFQUNaLEtBQUssRUFHTCxNQUFNLEVBRU4sU0FBUyxFQUNULGlCQUFpQixFQUNqQixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGVBQWUsRUFBbUIsTUFBTSx3QkFBd0IsQ0FBQztBQUMxRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQzs7QUFpQnRFLE1BQU0sTUFBTSxHQUFzQztJQUNoRCxTQUFTLEVBQUUsV0FBVztJQUN0QixNQUFNLEVBQUUsUUFBUTtJQUNoQixNQUFNLEVBQUUsb0JBQW9CO0lBQzVCLElBQUksRUFBRSxNQUFNO0lBQ1osU0FBUyxFQUFFLFdBQVc7Q0FDdkIsQ0FBQztBQUVGLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBUyxFQUFVLEVBQUUsQ0FDbEMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQztBQWdJN0QsTUFBTSxPQUFPLHFCQUFxQjtJQXNDaEMsSUFBSSxHQUFHO1FBQ0wsT0FBTyxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDbEMsQ0FBQztJQUNELElBQUksSUFBSTtRQUNOLE9BQU8sSUFB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RUFBRSxFQUFFLENBQUM7WUFDM0IsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xCLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM1QyxDQUFDLENBQUMsV0FBVyxHQUFHLEtBQUs7Z0JBQ25CLENBQUMsQ0FBQyxDQUFDO29CQUNELENBQUMsQ0FBQyxHQUFHO29CQUNMLENBQUMsQ0FBQyxDQUFDO2dCQUNMLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztZQUMzQyxDQUFDLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUMzQyxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDZCxJQUFJLENBQUMsQ0FBQyxTQUFTO2dCQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDOztnQkFDMUQsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN6QyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDWCxDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUs7UUFDWCxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLGFBQWEsQ0FBQztRQUN2QyxJQUFJLENBQUMsRUFBRTtZQUFFLE9BQU87UUFDaEIscUVBQXFFO1FBQ3JFLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDdkIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4QixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUNyQixPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQUUsQ0FBQyxFQUFFLENBQUM7UUFDM0IsTUFBTSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDNUQsSUFBSSxDQUFDLEtBQUssQ0FDUixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ2pDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzlDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdEUsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEUsQ0FBQyxDQUFDLEVBQ0YsSUFBSSxDQUNMLENBQUM7SUFDSixDQUFDO0lBRU8sU0FBUztRQUNmLG9CQUFvQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsRUFBRSxFQUFFLFVBQVUsRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxFQUFFLEdBQUcsU0FBUyxDQUFDO1FBQ3BCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsYUFBYSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxFQUFFO1lBQUUsT0FBTztRQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2YsdURBQXVEO1lBQ3ZELE1BQU0sS0FBSyxHQUFHLEdBQUcsRUFBRTtnQkFDakIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7Z0JBQ2pCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNmLENBQUMsQ0FBQztZQUNGLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNiLElBQUksT0FBTyxjQUFjLEtBQUssVUFBVSxFQUFFLENBQUM7Z0JBQ3pDLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3RCLENBQUM7WUFDRCxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUU7WUFDekIsSUFBSSxDQUFDLEdBQUcsR0FBRyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN2QyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsRUFBRSxDQUFDO2dCQUM3QixJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztnQkFDcEIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztnQkFDckIsTUFBTSxDQUFDLEdBQ0wsSUFBSSxDQUFDLEdBQUcsS0FBSyxXQUFXO29CQUN0QixDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssVUFBVTt3QkFDdkIsQ0FBQyxDQUFDLENBQUMsRUFBRTt3QkFDTCxDQUFDLENBQUMsQ0FBQztvQkFDTCxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNSLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDL0MsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxHQUFHO29CQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDdEQsQ0FBQztZQUNELE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDeEIsSUFBSSxDQUFDLEtBQUssQ0FDUixLQUFLLENBQUMsSUFBSSxDQUNSLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUNiLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUN6RCxFQUNELEtBQUssQ0FDTixDQUFDO1FBQ0osQ0FBQyxDQUFDO1FBQ0YsSUFBSSxDQUFDLEdBQUcsR0FBRyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN6QyxDQUFDOytHQTFhVSxxQkFBcUI7bUdBQXJCLHFCQUFxQix3a0JBakh0Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4R1QsdXRIQS9HUyxlQUFlOzs0RkFrSGQscUJBQXFCO2tCQXRIakMsU0FBUzsrQkFDRSxrQkFBa0IsY0FDaEIsSUFBSSxpQkFDRCxpQkFBaUIsQ0FBQyxJQUFJLFdBQzVCLENBQUMsZUFBZSxDQUFDLFlBQ2hCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQThHVDt3REFPUSxLQUFLO3NCQUFiLEtBQUs7Z0JBR0csS0FBSztzQkFBYixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBR0csT0FBTztzQkFBZixLQUFLO2dCQUlHLEtBQUs7c0JBQWIsS0FBSztnQkFHRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUksV0FBVztzQkFBcEIsTUFBTTtnQkFFRyxJQUFJO3NCQUFiLE1BQU07Z0JBRUcsT0FBTztzQkFBaEIsTUFBTTtnQkFFRyxXQUFXO3NCQUFwQixNQUFNO2dCQUVZLElBQUk7c0JBQXRCLFNBQVM7dUJBQUMsTUFBTTtnQkFDRSxPQUFPO3NCQUF6QixTQUFTO3VCQUFDLE1BQU07Z0JBQ0MsTUFBTTtzQkFBdkIsU0FBUzt1QkFBQyxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiLy8gZnJhbWV3b3JrL2FuZ3VsYXIvdm9pY2UtY2FwdHVyZS92b2ljZS1jYXB0dXJlLmNvbXBvbmVudC50c1xuLy9cbi8vIE5hdGl2ZSBBbmd1bGFyIHBvcnQgb2YgZnJhbWV3b3JrL3JlYWN0L3ZvaWNlLWNhcHR1cmUvVm9pY2VDYXB0dXJlLnRzeC5cbi8vIFNwZWVjaCB0byB0ZXh0IHRoYXQgc2hvd3Mgd2hhdCBpdCBoZWFyZCBhcyBpdCBoZWFycyBpdCwgYW5kIGxldHMgdGhlIHBlcnNvbiBmaXhcbi8vIHRoZSB3b3JkcyBpdCB3YXMgdW5zdXJlIG9mLiBUaGUgc3RhdHVzIGxpbmUsIHRoZSBzY3JvbGxpbmcgd2F2ZSwgdGhlIHdvcmRzIGFuZFxuLy8gdGhlIGJ1dHRvbnMgc2l0IGluIG9uZSBjb2x1bW4uIE9uY2UgcmVjb3JkaW5nIHN0b3BzIHRoZSBib3gga2VlcHMgaXRzIGhlaWdodDpcbi8vIHRoZSB3YXZlIHN0YXlzLCBzdGlsbCwgYXMgdGhlIHdob2xlIHJlY29yZGluZywgYW5kIHRoZSB3b3JkcyBzdGF5IHdoZXJlIHRoZXlcbi8vIHdlcmUuIFVuc3VyZSB3b3JkcyBvcGVuIGEgc21hbGwgXCJEaWQgeW91IG1lYW5cIiBtZW51LiBJbnB1dHMgbWlycm9yIHRoZSBSZWFjdFxuLy8gcHJvcHM7IHRoZSBidXR0b25zIG1vdmUgdGhlIHN0YXRlIGFsb25nIHdoZW4gaXQgaXMgbGVmdCB1bmNvbnRyb2xsZWQuXG5cbmltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFZvSWNvbkNvbXBvbmVudCwgdHlwZSBWb0ljb25OYW1lIH0gZnJvbSAnLi4vY29yZS9pY29uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBSZWR1Y2VkTW90aW9uU2VydmljZSB9IGZyb20gJy4uL2NvcmUvcmVkdWNlZC1tb3Rpb24uc2VydmljZSc7XG5cbi8qKiBsaXN0ZW5pbmcgYW5kIHBhdXNlZCByZWNvcmQsIHJldmlldyBhc2tzIHRoZSBwZXJzb24gdG8gY2hlY2sgdGhlIHdvcmRzLCBzZW50IGFuZCBjYW5jZWxsZWQgYXJlIHRoZSBlbmQuICovXG5leHBvcnQgdHlwZSBWb2ljZUNhcHR1cmVTdGF0ZSA9XG4gIHwgJ2xpc3RlbmluZydcbiAgfCAncGF1c2VkJ1xuICB8ICdyZXZpZXcnXG4gIHwgJ3NlbnQnXG4gIHwgJ2NhbmNlbGxlZCc7XG5cbi8qKiBBIHdvcmQgdGhlIHNwZWVjaCBtb2RlbCB3YXMgbm90IHN1cmUgYWJvdXQuICovXG5leHBvcnQgaW50ZXJmYWNlIEhlYXJkV29yZCB7XG4gIHRleHQ6IHN0cmluZztcbiAgLyoqIFdoYXQgaXQgbWlnaHQgaGF2ZSBiZWVuIGluc3RlYWQuIEhpZ2hsaWdodHMgdGhlIHdvcmQgYW5kIGxldHMgdGhlIHBlcnNvbiBwaWNrIG9uZS4gKi9cbiAgYWx0ZXJuYXRpdmVzPzogc3RyaW5nW107XG59XG5cbmNvbnN0IFNUQVRVUzogUmVjb3JkPFZvaWNlQ2FwdHVyZVN0YXRlLCBzdHJpbmc+ID0ge1xuICBsaXN0ZW5pbmc6ICdMaXN0ZW5pbmcnLFxuICBwYXVzZWQ6ICdQYXVzZWQnLFxuICByZXZpZXc6ICdDaGVjayB3aGF0IEkgaGVhcmQnLFxuICBzZW50OiAnU2VudCcsXG4gIGNhbmNlbGxlZDogJ0NhbmNlbGxlZCcsXG59O1xuXG5jb25zdCBjbG9jayA9IChzOiBudW1iZXIpOiBzdHJpbmcgPT5cbiAgYCR7TWF0aC5mbG9vcihzIC8gNjApfToke1N0cmluZyhzICUgNjApLnBhZFN0YXJ0KDIsICcwJyl9YDtcblxuLyoqIE9uZSB3b3JkIGFzIGl0IGlzIHJlbmRlcmVkOiBpdHMgdGV4dCwgd2hldGhlciBpdCBpcyB1bnN1cmUsIGFuZCB3aGV0aGVyIGEgZml4IGhhcyBiZWVuIHBpY2tlZC4gKi9cbmludGVyZmFjZSBSZW5kZXJXb3JkIHtcbiAgaW5kZXg6IG51bWJlcjtcbiAgdGV4dDogc3RyaW5nO1xuICBhbHRlcm5hdGl2ZXM6IHN0cmluZ1tdO1xuICBmaXhlZDogYm9vbGVhbjtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndm8tdm9pY2UtY2FwdHVyZScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGltcG9ydHM6IFtWb0ljb25Db21wb25lbnRdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXZcbiAgICAgICNyb290XG4gICAgICBkYXRhLXZvPVwiXCJcbiAgICAgIGNsYXNzPVwidm8tdmN4IHZvLXBhbmVsXCJcbiAgICAgIFtjbGFzcy52by1wYXVzZWRdPVwibm93ID09PSAncGF1c2VkJ1wiXG4gICAgICBbY2xhc3Mudm8tZG9uZV09XCIhbGl2ZVwiXG4gICAgICBbY2xhc3Mudm8tZ29uZV09XCJub3cgPT09ICdjYW5jZWxsZWQnXCJcbiAgICAgIFtjbGFzcy52by1oZWxkXT1cImhlbGQgIT09IHVuZGVmaW5lZFwiXG4gICAgICBbc3R5bGUubWluSGVpZ2h0LnB4XT1cImhlbGRcIlxuICAgID5cbiAgICAgIDxkaXYgY2xhc3M9XCJ2by12Y3gtdG9wXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwidm8tdmN4LWRvdFwiPjwvc3Bhbj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by12Y3gtc3RcIj57eyBzdGF0dXMgPz8gU1RBVFVTW25vd10gfX08L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwidm8tdmN4LXQgdm8tbnVtIHZvLW11dGVkXCI+e3sgY2xvY2tUZXh0IH19PC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgICA8Y2FudmFzICN3YXZlIGNsYXNzPVwidm8tdmN4LXdhdmVcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2NhbnZhcz5cbiAgICAgIDxwIGNsYXNzPVwidm8tdmN4LXR4XCIgYXJpYS1saXZlPVwicG9saXRlXCI+XG4gICAgICAgIEBmb3IgKHcgb2YgcmVuZGVyZWQ7IHRyYWNrIHcuaW5kZXgpIHtcbiAgICAgICAgICBAaWYgKHcuYWx0ZXJuYXRpdmVzLmxlbmd0aCAmJiBub3cgIT09ICdjYW5jZWxsZWQnKSB7XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLXdcIlxuICAgICAgICAgICAgICA+PHNwYW5cbiAgICAgICAgICAgICAgICBjbGFzcz1cInZvLWxvd1wiXG4gICAgICAgICAgICAgICAgW2NsYXNzLnZvLWZpeGVkXT1cIncuZml4ZWRcIlxuICAgICAgICAgICAgICAgIHJvbGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgICAgICAgICAgYXJpYS1oYXNwb3B1cD1cIm1lbnVcIlxuICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwibWVudU9wZW4gJiYgbWVudS5pbmRleCA9PT0gdy5pbmRleFwiXG4gICAgICAgICAgICAgICAgW2F0dHIuZGF0YS10aXBdPVwiXG4gICAgICAgICAgICAgICAgICAhbGl2ZSA/ICh3LmZpeGVkID8gJ0ZpeGVkJyA6ICdOb3Qgc3VyZSBhYm91dCB0aGlzIHdvcmQnKSA6IG51bGxcbiAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgIFthdHRyLmRhdGEtaV09XCJ3LmluZGV4XCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwic2hvdyh3LmluZGV4LCAkZXZlbnQsIGZhbHNlKVwiXG4gICAgICAgICAgICAgICAgKGtleWRvd24pPVwid29yZEtleSh3LmluZGV4LCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICA+e3sgdy50ZXh0IH19PC9zcGFuXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8td1wiPnt7IHcudGV4dCB9fSA8L3NwYW4+XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICA8L3A+XG4gICAgICA8ZGl2IGNsYXNzPVwidm8tdmN4LWFjdHNcIj5cbiAgICAgICAgQGlmIChlbmRlZCkge1xuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tbXV0ZWRcIiBzdHlsZT1cImZvbnQtc2l6ZToxMi41cHhcIj57e1xuICAgICAgICAgICAgbm93ID09PSAnc2VudCcgPyAnU2VudCB0byB0aGUgYWdlbnQnIDogJ05vdGhpbmcgd2FzIHNlbnQnXG4gICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by1zcFwiPjwvc3Bhbj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwidm8tcGlsbCB2by1naG9zdCB2by1zbSB2by12Y3gtYWdhaW5cIlxuICAgICAgICAgICAgKGNsaWNrKT1cImFnYWluKClcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDx2by1pY29uIG5hbWU9XCJyZWZyZXNoXCIgc2l6ZT1cInhzXCI+PC92by1pY29uPlJlY29yZCBhZ2FpblxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICBAaWYgKGxpdmUpIHtcbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzPVwidm8taWIgdm8tZmlsbCB2by12Y3gtcGF1c2VcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIm5vdyA9PT0gJ3BhdXNlZCcgPyAnUmVzdW1lJyA6ICdQYXVzZSdcIlxuICAgICAgICAgICAgICBbYXR0ci5kYXRhLXRpcF09XCJub3cgPT09ICdwYXVzZWQnID8gJ1Jlc3VtZScgOiAnUGF1c2UnXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZVBhdXNlKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8dm8taWNvbiBbbmFtZV09XCJub3cgPT09ICdwYXVzZWQnID8gJ3NwYXJrJyA6ICdwYXVzZSdcIj48L3ZvLWljb24+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICB9XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by1zcFwiPjwvc3Bhbj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwidm8tcGlsbCB2by1naG9zdCB2by1zbSB2by12Y3gteFwiXG4gICAgICAgICAgICAoY2xpY2spPVwiY2FuY2VsKClcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIENhbmNlbFxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJ2by1waWxsIHZvLXByaW1hcnkgdm8tc20gdm8tdmN4LWRvbmVcIlxuICAgICAgICAgICAgKGNsaWNrKT1cImRvbmUoKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgRG9uZVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXZcbiAgICAgICAgI3BvcFxuICAgICAgICBjbGFzcz1cInZvLXBvcCB2by12Y3gtZml4XCJcbiAgICAgICAgW2NsYXNzLnZvLW9wZW5dPVwibWVudU9wZW5cIlxuICAgICAgICByb2xlPVwibWVudVwiXG4gICAgICAgIGFyaWEtbGFiZWw9XCJEaWQgeW91IG1lYW5cIlxuICAgICAgICBbc3R5bGUubGVmdC5weF09XCJtZW51LmxlZnRcIlxuICAgICAgICBbc3R5bGUudG9wLnB4XT1cIm1lbnUudG9wXCJcbiAgICAgICAgW2F0dHIuaW5lcnRdPVwibWVudU9wZW4gPyBudWxsIDogJydcIlxuICAgICAgICBbYXR0ci5hcmlhLWhpZGRlbl09XCIhbWVudU9wZW5cIlxuICAgICAgICAoa2V5ZG93bik9XCJtZW51S2V5KCRldmVudClcIlxuICAgICAgPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidm8tcGhcIj5EaWQgeW91IG1lYW48L2Rpdj5cbiAgICAgICAgQGZvciAoYSBvZiBtZW51LmFsdHM7IHRyYWNrIGEpIHtcbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIHJvbGU9XCJtZW51aXRlbVwiXG4gICAgICAgICAgICB0YWJpbmRleD1cIi0xXCJcbiAgICAgICAgICAgIGNsYXNzPVwidm8tbWlcIlxuICAgICAgICAgICAgKGNsaWNrKT1cImZpeChtZW51LmluZGV4LCBhKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAge3sgYSB9fVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVVcmw6ICcuL3ZvaWNlLWNhcHR1cmUuY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgVm9pY2VDYXB0dXJlQ29tcG9uZW50XG4gIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3lcbntcbiAgLyoqIFRoZSB3b3JkcyBoZWFyZCBzbyBmYXIsIGluIG9yZGVyLiBBZGQgdG8gdGhlIGVuZCBhcyB0aGV5IGFycml2ZSBhbmQgZWFjaCBvbmUgZmFkZXMgaW4uICovXG4gIEBJbnB1dCgpIHdvcmRzOiBBcnJheTxzdHJpbmcgfCBIZWFyZFdvcmQ+ID0gW107XG5cbiAgLyoqIFRoZSBzdGF0ZSwgb3IgbGVhdmUgaXQgb3V0IHRvIGxldCB0aGUgYnV0dG9ucyBtb3ZlIGl0IGFsb25nLiAqL1xuICBASW5wdXQoKSBzdGF0ZT86IFZvaWNlQ2FwdHVyZVN0YXRlO1xuICBASW5wdXQoKSBkZWZhdWx0U3RhdGU6IFZvaWNlQ2FwdHVyZVN0YXRlID0gJ2xpc3RlbmluZyc7XG5cbiAgLyoqIFNlY29uZHMgcmVjb3JkZWQuIExlYXZlIGl0IG91dCB0byBsZXQgaXQgY291bnQgd2hpbGUgbGlzdGVuaW5nLiAqL1xuICBASW5wdXQoKSBzZWNvbmRzPzogbnVtYmVyO1xuXG4gIC8qKiBUaGUgaW5wdXQgbGV2ZWwgZnJvbSAwIHRvIDEsIGRyYXduIGludG8gdGhlIHdhdmUgYWJvdXQgMjAgdGltZXMgYSBzZWNvbmQuXG4gICAgICBQYXNzIGEgZnVuY3Rpb24gdG8gcmVhZCB0aGUgbWljcm9waG9uZSBvbiBldmVyeSBzYW1wbGUgd2l0aG91dCByZS1yZW5kZXJpbmcuICovXG4gIEBJbnB1dCgpIGxldmVsOiBudW1iZXIgfCAoKCkgPT4gbnVtYmVyKSA9IDA7XG5cbiAgLyoqIFRoZSBzdGF0dXMgbGluZS4gRGVmYXVsdHMgdG8gTGlzdGVuaW5nLCBQYXVzZWQsIENoZWNrIHdoYXQgSSBoZWFyZCwgU2VudCBvciBDYW5jZWxsZWQuICovXG4gIEBJbnB1dCgpIHN0YXR1cz86IHN0cmluZztcblxuICBAT3V0cHV0KCkgc3RhdGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFZvaWNlQ2FwdHVyZVN0YXRlPigpO1xuICAvKiogRW1pdHRlZCB3aXRoIHRoZSBjaGVja2VkIHRyYW5zY3JpcHQgd2hlbiB0aGUgcGVyc29uIHByZXNzZXMgRG9uZSBpbiByZXZpZXcuICovXG4gIEBPdXRwdXQoKSBzZW5kID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIC8qKiBFbWl0dGVkIHdoZW4gdGhlIHBlcnNvbiBwaWNrcyBvbmUgb2YgYSB3b3JkJ3MgYWx0ZXJuYXRpdmVzLiAqL1xuICBAT3V0cHV0KCkgZml4V29yZCA9IG5ldyBFdmVudEVtaXR0ZXI8eyBpbmRleDogbnVtYmVyOyB0ZXh0OiBzdHJpbmcgfT4oKTtcbiAgLyoqIEVtaXR0ZWQgYnkgUmVjb3JkIGFnYWluLCBvbmNlIHRoZSBjYXB0dXJlIGlzIHNlbnQgb3IgY2FuY2VsbGVkLiAqL1xuICBAT3V0cHV0KCkgcmVjb3JkQWdhaW4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgQFZpZXdDaGlsZCgncm9vdCcpIHJvb3QhOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcbiAgQFZpZXdDaGlsZCgnd2F2ZScpIHdhdmVSZWYhOiBFbGVtZW50UmVmPEhUTUxDYW52YXNFbGVtZW50PjtcbiAgQFZpZXdDaGlsZCgncG9wJykgcG9wUmVmITogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBtb3Rpb24gPSBpbmplY3QoUmVkdWNlZE1vdGlvblNlcnZpY2UpO1xuXG4gIHJlYWRvbmx5IFNUQVRVUyA9IFNUQVRVUztcblxuICAvLyB0aGUgc3RhdGUgd2hlbiB1bmNvbnRyb2xsZWQ7IG1pcnJvcnMgdGhlIGNvbnRyb2xsYWJsZSBob29rIGluIFJlYWN0XG4gIHByaXZhdGUgaW5uZXI6IFZvaWNlQ2FwdHVyZVN0YXRlID0gJ2xpc3RlbmluZyc7XG4gIGdldCBub3coKTogVm9pY2VDYXB0dXJlU3RhdGUge1xuICAgIHJldHVybiB0aGlzLnN0YXRlID8/IHRoaXMuaW5uZXI7XG4gIH1cbiAgZ2V0IGxpdmUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubm93ID09PSAnbGlzdGVuaW5nJyB8fCB0aGlzLm5vdyA9PT0gJ3BhdXNlZCc7XG4gIH1cbiAgZ2V0IGVuZGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm5vdyA9PT0gJ3NlbnQnIHx8IHRoaXMubm93ID09PSAnY2FuY2VsbGVkJztcbiAgfVxuXG4gIC8vIG9uY2UgcmVjb3JkaW5nIHN0b3BzIHRoZSBib3gga2VlcHMgdGhlIGhlaWdodCBpdCBoYWQgd2hpbGUgcmVjb3JkaW5nXG4gIGhlbGQ/OiBudW1iZXI7XG4gIHByaXZhdGUgbGl2ZUhlaWdodD86IG51bWJlcjtcblxuICAvLyB0aGUgY2xvY2sgY291bnRzIHdoaWxlIGxpc3RlbmluZywgdW5sZXNzIHRoZSBwYXJlbnQgcGFzc2VzIHNlY29uZHNcbiAgcHJpdmF0ZSBjb3VudCA9IDA7XG4gIGdldCBjbG9ja1RleHQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gY2xvY2sodGhpcy5zZWNvbmRzID8/IHRoaXMuY291bnQpO1xuICB9XG4gIHByaXZhdGUgdGljaz86IFJldHVyblR5cGU8dHlwZW9mIHNldEludGVydmFsPjtcblxuICAvLyB0aGUgZml4ZXMgdGhlIHBlcnNvbiBoYXMgcGlja2VkLCBieSB3b3JkIGluZGV4XG4gIHByaXZhdGUgZml4ZXM6IFJlY29yZDxudW1iZXIsIHN0cmluZz4gPSB7fTtcbiAgcmVuZGVyZWQ6IFJlbmRlcldvcmRbXSA9IFtdO1xuXG4gIC8vIHRoZSBcIkRpZCB5b3UgbWVhblwiIG1lbnVcbiAgbWVudU9wZW4gPSBmYWxzZTtcbiAgbWVudTogeyBpbmRleDogbnVtYmVyOyBhbHRzOiBzdHJpbmdbXTsgbGVmdDogbnVtYmVyOyB0b3A6IG51bWJlciB9ID0ge1xuICAgIGluZGV4OiAtMSxcbiAgICBhbHRzOiBbXSxcbiAgICBsZWZ0OiAwLFxuICAgIHRvcDogMCxcbiAgfTtcbiAgcHJpdmF0ZSBrZXlPcGVuID0gZmFsc2U7XG4gIHByaXZhdGUgaW5NZW51ID0gZmFsc2U7XG5cbiAgLy8gdGhlIHdhdmVcbiAgcHJpdmF0ZSBzYW1wbGVzOiBudW1iZXJbXSA9IFtdO1xuICBwcml2YXRlIHJhZiA9IDA7XG4gIHByaXZhdGUgbGFzdFNhbXBsZSA9IDA7XG4gIHByaXZhdGUgY29sczogc3RyaW5nW10gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjb2xzQXQgPSAtMWU5O1xuICBwcml2YXRlIGRyYXduID0gJyc7XG4gIHByaXZhdGUgcm8/OiBSZXNpemVPYnNlcnZlcjtcbiAgcHJpdmF0ZSBvbkRvY0NsaWNrID0gKGU6IE1vdXNlRXZlbnQpID0+IHRoaXMuZG9jQ2xpY2soZSk7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5pbm5lciA9IHRoaXMuZGVmYXVsdFN0YXRlO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWyd3b3JkcyddKSB0aGlzLmJ1aWxkV29yZHMoKTtcbiAgICBpZiAoY2hhbmdlc1snc3RhdGUnXSB8fCBjaGFuZ2VzWydzZWNvbmRzJ10pIHRoaXMuc3luY0Nsb2NrKCk7XG4gICAgLy8gYSBjb250cm9sbGVkIHN0YXRlIGNoYW5nZSBjYW4gZmxpcCBsaXZlL2hlbGQgYW5kIHRoZSB3YXZlIG1vZGVcbiAgICBpZiAoY2hhbmdlc1snc3RhdGUnXSAmJiAhY2hhbmdlc1snc3RhdGUnXS5maXJzdENoYW5nZSkgdGhpcy5vblN0YXRlRmxpcCgpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuaW5uZXIgPSB0aGlzLmRlZmF1bHRTdGF0ZTtcbiAgICB0aGlzLmJ1aWxkV29yZHMoKTtcbiAgICB0aGlzLnN5bmNDbG9jaygpO1xuICAgIHRoaXMubWVhc3VyZSgpO1xuICAgIHRoaXMuc3RhcnRXYXZlKCk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLm9uRG9jQ2xpY2spO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5yYWYpO1xuICAgIHRoaXMucm8/LmRpc2Nvbm5lY3QoKTtcbiAgICBpZiAodGhpcy50aWNrKSBjbGVhckludGVydmFsKHRoaXMudGljayk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLm9uRG9jQ2xpY2spO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFdvcmRzKCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyZWQgPSB0aGlzLndvcmRzLm1hcCgodywgaSkgPT4ge1xuICAgICAgY29uc3Qgd29yZCA9IHR5cGVvZiB3ID09PSAnc3RyaW5nJyA/IHsgdGV4dDogdyB9IDogdztcbiAgICAgIGNvbnN0IGFsdGVybmF0aXZlcyA9IHdvcmQuYWx0ZXJuYXRpdmVzID8/IFtdO1xuICAgICAgY29uc3QgZml4ZWQgPSB0aGlzLmZpeGVzW2ldICE9PSB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBpbmRleDogaSxcbiAgICAgICAgdGV4dDogdGhpcy5maXhlc1tpXSA/PyB3b3JkLnRleHQsXG4gICAgICAgIGFsdGVybmF0aXZlcyxcbiAgICAgICAgZml4ZWQsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzeW5jQ2xvY2soKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2Vjb25kcyAhPT0gdW5kZWZpbmVkIHx8IHRoaXMubm93ICE9PSAnbGlzdGVuaW5nJykge1xuICAgICAgaWYgKHRoaXMudGljaykge1xuICAgICAgICBjbGVhckludGVydmFsKHRoaXMudGljayk7XG4gICAgICAgIHRoaXMudGljayA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnRpY2spIHtcbiAgICAgIHRoaXMudGljayA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgdGhpcy5jb3VudCsrO1xuICAgICAgfSwgMTAwMCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtZWFzdXJlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmxpdmUgJiYgdGhpcy5yb290KSB0aGlzLmxpdmVIZWlnaHQgPSB0aGlzLnJvb3QubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHQ7XG4gIH1cblxuICBwcml2YXRlIG9uU3RhdGVGbGlwKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5saXZlKSB7XG4gICAgICB0aGlzLmhlbGQgPSB0aGlzLmxpdmVIZWlnaHQ7XG4gICAgICB0aGlzLnN0YXJ0V2F2ZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmhlbGQgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLm1lYXN1cmUoKTtcbiAgICAgIHRoaXMuc3RhcnRXYXZlKCk7XG4gICAgfVxuICAgIHRoaXMuc3luY0Nsb2NrKCk7XG4gICAgdGhpcy5idWlsZFdvcmRzKCk7XG4gIH1cblxuICB0b2dnbGVQYXVzZSgpOiB2b2lkIHtcbiAgICB0aGlzLnNldFN0YXRlKHRoaXMubm93ID09PSAncGF1c2VkJyA/ICdsaXN0ZW5pbmcnIDogJ3BhdXNlZCcpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRTdGF0ZShzOiBWb2ljZUNhcHR1cmVTdGF0ZSk6IHZvaWQge1xuICAgIGNvbnN0IHdhc0xpdmUgPSB0aGlzLmxpdmU7XG4gICAgaWYgKHRoaXMuc3RhdGUgPT09IHVuZGVmaW5lZCkgdGhpcy5pbm5lciA9IHM7XG4gICAgdGhpcy5zdGF0ZUNoYW5nZS5lbWl0KHMpO1xuICAgIGNvbnN0IG5vd0xpdmUgPSB0aGlzLm5vdyA9PT0gJ2xpc3RlbmluZycgfHwgdGhpcy5ub3cgPT09ICdwYXVzZWQnO1xuICAgIGlmICh3YXNMaXZlICYmICFub3dMaXZlKSB7XG4gICAgICB0aGlzLmhlbGQgPSB0aGlzLmxpdmVIZWlnaHQ7XG4gICAgfSBlbHNlIGlmICghd2FzTGl2ZSAmJiBub3dMaXZlKSB7XG4gICAgICB0aGlzLmhlbGQgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMuc3luY0Nsb2NrKCk7XG4gICAgLy8gZGVmZXIgc28gdGhlIHRlbXBsYXRlIHJlZmxlY3RzIHRoZSBuZXcgc3RhdGUgYmVmb3JlIHdlIHJlLW1lYXN1cmUgLyByZXBhaW50XG4gICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgICAgaWYgKCF3YXNMaXZlICYmIG5vd0xpdmUpIHRoaXMubWVhc3VyZSgpO1xuICAgICAgdGhpcy5zdGFydFdhdmUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdHJhbnNjcmlwdCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLndvcmRzXG4gICAgICAubWFwKCh3LCBpKSA9PlxuICAgICAgICB0aGlzLmZpeGVzW2ldID8/ICh0eXBlb2YgdyA9PT0gJ3N0cmluZycgPyB3IDogdy50ZXh0KVxuICAgICAgKVxuICAgICAgLmpvaW4oJyAnKTtcbiAgfVxuXG4gIGRvbmUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubGl2ZSkgdGhpcy5zZXRTdGF0ZSgncmV2aWV3Jyk7XG4gICAgZWxzZSBpZiAodGhpcy5ub3cgPT09ICdyZXZpZXcnKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKCdzZW50Jyk7XG4gICAgICB0aGlzLnNlbmQuZW1pdCh0aGlzLnRyYW5zY3JpcHQoKSk7XG4gICAgfVxuICB9XG5cbiAgY2FuY2VsKCk6IHZvaWQge1xuICAgIHRoaXMubWVudU9wZW4gPSBmYWxzZTtcbiAgICB0aGlzLnNldFN0YXRlKCdjYW5jZWxsZWQnKTtcbiAgfVxuXG4gIGFnYWluKCk6IHZvaWQge1xuICAgIHRoaXMuY291bnQgPSAwO1xuICAgIHRoaXMuZml4ZXMgPSB7fTtcbiAgICB0aGlzLm1lbnVPcGVuID0gZmFsc2U7XG4gICAgdGhpcy5zYW1wbGVzID0gW107XG4gICAgdGhpcy5yZWNvcmRBZ2Fpbi5lbWl0KCk7XG4gICAgdGhpcy5zZXRTdGF0ZSgnbGlzdGVuaW5nJyk7XG4gICAgdGhpcy5idWlsZFdvcmRzKCk7XG4gIH1cblxuICAvLyAtLS0tLSB0aGUgXCJEaWQgeW91IG1lYW5cIiBtZW51IC0tLS0tXG4gIHdvcmRLZXkoaW5kZXg6IG51bWJlciwgZTogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmIChlLmtleSA9PT0gJ0VudGVyJyB8fCBlLmtleSA9PT0gJyAnKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB0aGlzLmtleU9wZW4gPSB0cnVlO1xuICAgICAgdGhpcy5zaG93KGluZGV4LCBlLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICBzaG93KGluZGV4OiBudW1iZXIsIGU6IEV2ZW50LCBrZXk6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zdCBlbCA9IGUuY3VycmVudFRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICBjb25zdCBib3ggPSB0aGlzLnJvb3Q/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFib3ggfHwgIWVsKSByZXR1cm47XG4gICAgY29uc3QgaHIgPSBib3guZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgbHIgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCB3b3JkID0gdGhpcy53b3Jkc1tpbmRleF07XG4gICAgY29uc3QgYWx0cyA9XG4gICAgICB0eXBlb2Ygd29yZCA9PT0gJ3N0cmluZycgPyBbXSA6IHdvcmQuYWx0ZXJuYXRpdmVzID8/IFtdO1xuICAgIHRoaXMubWVudSA9IHtcbiAgICAgIGluZGV4LFxuICAgICAgYWx0cyxcbiAgICAgIGxlZnQ6IGxyLmxlZnQgLSBoci5sZWZ0LFxuICAgICAgdG9wOiBsci5ib3R0b20gLSBoci50b3AgKyA2LFxuICAgIH07XG4gICAgdGhpcy5tZW51T3BlbiA9IHRydWU7XG4gICAgaWYgKGtleSkgdGhpcy5rZXlPcGVuID0gdHJ1ZTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgIGlmICh0aGlzLmtleU9wZW4pIHtcbiAgICAgICAgdGhpcy5rZXlPcGVuID0gZmFsc2U7XG4gICAgICAgIHRoaXMucG9wUmVmPy5uYXRpdmVFbGVtZW50XG4gICAgICAgICAgLnF1ZXJ5U2VsZWN0b3I8SFRNTEVsZW1lbnQ+KCcudm8tbWknKVxuICAgICAgICAgID8uZm9jdXMoeyBwcmV2ZW50U2Nyb2xsOiB0cnVlIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjbG9zZU1lbnUoKTogdm9pZCB7XG4gICAgY29uc3QgYmFjayA9IHRoaXMubWVudU9wZW4gJiYgdGhpcy5tZW51LmluZGV4O1xuICAgIGNvbnN0IGZvY3VzV29yZCA9IHRoaXMuaW5NZW51O1xuICAgIHRoaXMubWVudU9wZW4gPSBmYWxzZTtcbiAgICB0aGlzLmluTWVudSA9IGZhbHNlO1xuICAgIGlmIChmb2N1c1dvcmQpIHtcbiAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+XG4gICAgICAgIHRoaXMud29yZEVsKGJhY2sgYXMgbnVtYmVyKT8uZm9jdXMoeyBwcmV2ZW50U2Nyb2xsOiB0cnVlIH0pXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgd29yZEVsKGk6IG51bWJlcik6IEhUTUxFbGVtZW50IHwgbnVsbCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMucm9vdD8ubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yPEhUTUxFbGVtZW50PihcbiAgICAgIGAudm8tbG93W2RhdGEtaT1cIiR7aX1cIl1gXG4gICAgKTtcbiAgfVxuXG4gIG1lbnVLZXkoZTogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IGFsbCA9IEFycmF5LmZyb20oXG4gICAgICB0aGlzLnBvcFJlZj8ubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsPEhUTUxFbGVtZW50PignLnZvLW1pJykgPz8gW11cbiAgICApO1xuICAgIGNvbnN0IGkgPSBhbGwuaW5kZXhPZihkb2N1bWVudC5hY3RpdmVFbGVtZW50IGFzIEhUTUxFbGVtZW50KTtcbiAgICBjb25zdCBnbzogUmVjb3JkPHN0cmluZywgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQ+ID0ge1xuICAgICAgQXJyb3dEb3duOiBhbGxbKGkgKyAxKSAlIGFsbC5sZW5ndGhdLFxuICAgICAgQXJyb3dVcDogYWxsWyhpIC0gMSArIGFsbC5sZW5ndGgpICUgYWxsLmxlbmd0aF0sXG4gICAgICBIb21lOiBhbGxbMF0sXG4gICAgICBFbmQ6IGFsbFthbGwubGVuZ3RoIC0gMV0sXG4gICAgfTtcbiAgICBpZiAoZ29bZS5rZXldKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBnb1tlLmtleV0hLmZvY3VzKHsgcHJldmVudFNjcm9sbDogdHJ1ZSB9KTtcbiAgICB9IGVsc2UgaWYgKGUua2V5ID09PSAnRXNjYXBlJykge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIHRoaXMuaW5NZW51ID0gdHJ1ZTtcbiAgICAgIHRoaXMuY2xvc2VNZW51KCk7XG4gICAgfSBlbHNlIGlmIChlLmtleSA9PT0gJ1RhYicpIHtcbiAgICAgIHRoaXMuaW5NZW51ID0gdHJ1ZTtcbiAgICAgIHRoaXMuY2xvc2VNZW51KCk7XG4gICAgfVxuICB9XG5cbiAgZml4KGluZGV4OiBudW1iZXIsIHRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZml4ZXMgPSB7IC4uLnRoaXMuZml4ZXMsIFtpbmRleF06IHRleHQgfTtcbiAgICB0aGlzLmZpeFdvcmQuZW1pdCh7IGluZGV4LCB0ZXh0IH0pO1xuICAgIHRoaXMubWVudU9wZW4gPSBmYWxzZTtcbiAgICB0aGlzLmJ1aWxkV29yZHMoKTtcbiAgfVxuXG4gIHByaXZhdGUgZG9jQ2xpY2soZTogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5tZW51T3BlbikgcmV0dXJuO1xuICAgIGNvbnN0IHQgPSBlLnRhcmdldCBhcyBFbGVtZW50O1xuICAgIGNvbnN0IHBvcCA9IHRoaXMucG9wUmVmPy5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IGJveCA9IHRoaXMucm9vdD8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoXG4gICAgICB0LmlzQ29ubmVjdGVkICYmXG4gICAgICAhcG9wPy5jb250YWlucyh0KSAmJlxuICAgICAgIShib3g/LmNvbnRhaW5zKHQpICYmIHQuY2xvc2VzdCgnLnZvLWxvdycpKVxuICAgICkge1xuICAgICAgdGhpcy5tZW51T3BlbiA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0tIHRoZSB3YXZlIC0tLS0tXG4gIHByaXZhdGUgY29sb3VycyhlbDogSFRNTEVsZW1lbnQpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgdCA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgIGlmICghdGhpcy5jb2xzIHx8IHQgLSB0aGlzLmNvbHNBdCA+IDQwMCkge1xuICAgICAgY29uc3QgY3MgPSBnZXRDb21wdXRlZFN0eWxlKGVsKTtcbiAgICAgIHRoaXMuY29scyA9IFsnLS12by1mZzInLCAnLS12by1mYWludCcsICctLXZvLW11dGVkJ10ubWFwKChrKSA9PlxuICAgICAgICBjcy5nZXRQcm9wZXJ0eVZhbHVlKGspLnRyaW0oKVxuICAgICAgKTtcbiAgICAgIHRoaXMuY29sc0F0ID0gdDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29scztcbiAgfVxuXG4gIHByaXZhdGUgYmFycyhjdjogSFRNTENhbnZhc0VsZW1lbnQpOiBudW1iZXIge1xuICAgIHJldHVybiBNYXRoLmZsb29yKGN2LmNsaWVudFdpZHRoIC8gNSk7XG4gIH1cblxuICBwcml2YXRlIHBhaW50KHZhbHM6IG51bWJlcltdLCBzdGlsbDogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IGN2ID0gdGhpcy53YXZlUmVmPy5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IGVsID0gdGhpcy5yb290Py5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghY3YgfHwgIWVsKSByZXR1cm47XG4gICAgY29uc3QgZHByID0gZGV2aWNlUGl4ZWxSYXRpbyB8fCAxO1xuICAgIGNvbnN0IHcgPSBjdi5jbGllbnRXaWR0aDtcbiAgICBjb25zdCBoID0gY3YuY2xpZW50SGVpZ2h0O1xuICAgIGlmICghdykgcmV0dXJuO1xuICAgIGlmIChjdi53aWR0aCAhPT0gdyAqIGRwcikge1xuICAgICAgY3Yud2lkdGggPSB3ICogZHByO1xuICAgICAgY3YuaGVpZ2h0ID0gaCAqIGRwcjtcbiAgICB9XG4gICAgY29uc3QgeCA9IGN2LmdldENvbnRleHQoJzJkJyk7XG4gICAgaWYgKCF4KSByZXR1cm47XG4gICAgeC5zZXRUcmFuc2Zvcm0oZHByLCAwLCAwLCBkcHIsIDAsIDApO1xuICAgIHguY2xlYXJSZWN0KDAsIDAsIHcsIGgpO1xuICAgIGNvbnN0IFtvbiwgb2ZmLCByZWNdID0gdGhpcy5jb2xvdXJzKGVsKTtcbiAgICBjb25zdCBuID0gdmFscy5sZW5ndGg7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgIGNvbnN0IHYgPSB2YWxzW2ldO1xuICAgICAgY29uc3QgcHggPSBpICogNSArIDI7XG4gICAgICBjb25zdCBiaCA9IHYgPyBNYXRoLm1heCg0LCB2ICogKGggLSA2KSkgOiAyO1xuICAgICAgeC5nbG9iYWxBbHBoYSA9IHN0aWxsXG4gICAgICAgID8gdlxuICAgICAgICAgID8gMC42XG4gICAgICAgICAgOiAxXG4gICAgICAgIDogTWF0aC5taW4oMSwgaSAvIDE0LCAobiAtIGkpIC8gMyArIDAuMik7XG4gICAgICB4LmZpbGxTdHlsZSA9IHYgPyAoc3RpbGwgPyByZWMgOiBvbikgOiBvZmY7XG4gICAgICB4LmJlZ2luUGF0aCgpO1xuICAgICAgaWYgKHgucm91bmRSZWN0KSB4LnJvdW5kUmVjdChweCwgaCAvIDIgLSBiaCAvIDIsIDIuNSwgYmgsIDEuMik7XG4gICAgICBlbHNlIHgucmVjdChweCwgaCAvIDIgLSBiaCAvIDIsIDIuNSwgYmgpO1xuICAgICAgeC5maWxsKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGlsbCgpOiB2b2lkIHtcbiAgICBjb25zdCBjdiA9IHRoaXMud2F2ZVJlZj8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIWN2KSByZXR1cm47XG4gICAgLy8gdGhlIHJlY29yZGluZyB3aXRob3V0IHRoZSBzaWxlbmNlIGVpdGhlciBzaWRlLCBmaXR0ZWQgdG8gdGhlIHdpZHRoXG4gICAgY29uc3QgcyA9IHRoaXMuc2FtcGxlcztcbiAgICBjb25zdCBuID0gdGhpcy5iYXJzKGN2KTtcbiAgICBjb25zdCBhID0gcy5maW5kSW5kZXgoKHYpID0+IHYpO1xuICAgIGxldCB6ID0gcy5sZW5ndGggLSAxO1xuICAgIHdoaWxlICh6ID4gYSAmJiAhc1t6XSkgei0tO1xuICAgIGNvbnN0IHJlYyA9IGEgPCAwID8gW10gOiBzLnNsaWNlKE1hdGgubWF4KDAsIGEgLSAyKSwgeiArIDMpO1xuICAgIHRoaXMucGFpbnQoXG4gICAgICBBcnJheS5mcm9tKHsgbGVuZ3RoOiBuIH0sIChfLCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IGZyb20gPSBNYXRoLmZsb29yKChpICogcmVjLmxlbmd0aCkgLyBuKTtcbiAgICAgICAgY29uc3QgdG8gPSBNYXRoLm1heChmcm9tICsgMSwgTWF0aC5mbG9vcigoKGkgKyAxKSAqIHJlYy5sZW5ndGgpIC8gbikpO1xuICAgICAgICByZXR1cm4gTWF0aC5tYXgoMCwgLi4ucmVjLnNsaWNlKGZyb20sIHRvKS5tYXAoKHYpID0+IHYgfHwgMCkpO1xuICAgICAgfSksXG4gICAgICB0cnVlXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRXYXZlKCk6IHZvaWQge1xuICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMucmFmKTtcbiAgICB0aGlzLnJvPy5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy5ybyA9IHVuZGVmaW5lZDtcbiAgICBjb25zdCBjdiA9IHRoaXMud2F2ZVJlZj8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIWN2KSByZXR1cm47XG4gICAgaWYgKCF0aGlzLmxpdmUpIHtcbiAgICAgIC8vIGRyYXduIGFnYWluIG9ubHkgd2hlbiBpdHMgd2lkdGggb3IgdGhlIHRoZW1lIGNoYW5nZXNcbiAgICAgIGNvbnN0IGFnYWluID0gKCkgPT4ge1xuICAgICAgICB0aGlzLmNvbHMgPSBudWxsO1xuICAgICAgICB0aGlzLnN0aWxsKCk7XG4gICAgICB9O1xuICAgICAgdGhpcy5zdGlsbCgpO1xuICAgICAgaWYgKHR5cGVvZiBSZXNpemVPYnNlcnZlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJvID0gbmV3IFJlc2l6ZU9ic2VydmVyKGFnYWluKTtcbiAgICAgICAgdGhpcy5yby5vYnNlcnZlKGN2KTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZHJhdyA9ICh0OiBudW1iZXIpID0+IHtcbiAgICAgIHRoaXMucmFmID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGRyYXcpO1xuICAgICAgaWYgKHQgLSB0aGlzLmxhc3RTYW1wbGUgPiA1MCkge1xuICAgICAgICB0aGlzLmxhc3RTYW1wbGUgPSB0O1xuICAgICAgICBjb25zdCBsID0gdGhpcy5sZXZlbDtcbiAgICAgICAgY29uc3QgdiA9XG4gICAgICAgICAgdGhpcy5ub3cgPT09ICdsaXN0ZW5pbmcnXG4gICAgICAgICAgICA/IHR5cGVvZiBsID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgID8gbCgpXG4gICAgICAgICAgICAgIDogbFxuICAgICAgICAgICAgOiAwO1xuICAgICAgICB0aGlzLnNhbXBsZXMucHVzaChNYXRoLm1heCgwLCBNYXRoLm1pbigxLCB2KSkpO1xuICAgICAgICBpZiAodGhpcy5zYW1wbGVzLmxlbmd0aCA+IDMwMCkgdGhpcy5zYW1wbGVzLnNoaWZ0KCk7XG4gICAgICB9XG4gICAgICBjb25zdCBuID0gdGhpcy5iYXJzKGN2KTtcbiAgICAgIHRoaXMucGFpbnQoXG4gICAgICAgIEFycmF5LmZyb20oXG4gICAgICAgICAgeyBsZW5ndGg6IG4gfSxcbiAgICAgICAgICAoXywgaSkgPT4gdGhpcy5zYW1wbGVzW3RoaXMuc2FtcGxlcy5sZW5ndGggLSBuICsgaV0gfHwgMFxuICAgICAgICApLFxuICAgICAgICBmYWxzZVxuICAgICAgKTtcbiAgICB9O1xuICAgIHRoaXMucmFmID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGRyYXcpO1xuICB9XG59XG4iXX0=