@tolle_/tolle-ui 18.2.29 → 18.3.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 (294) hide show
  1. package/esm2022/lib/accordion-item.component.mjs +5 -11
  2. package/esm2022/lib/accordion.component.mjs +4 -9
  3. package/esm2022/lib/alert-dialog-dynamic.component.mjs +12 -12
  4. package/esm2022/lib/alert-dialog.component.mjs +82 -64
  5. package/esm2022/lib/alert-dialog.service.mjs +38 -6
  6. package/esm2022/lib/alert.component.mjs +5 -11
  7. package/esm2022/lib/aspect-ratio.component.mjs +119 -0
  8. package/esm2022/lib/attachment.component.mjs +334 -0
  9. package/esm2022/lib/avatar-fallback.component.mjs +3 -3
  10. package/esm2022/lib/avatar.component.mjs +4 -9
  11. package/esm2022/lib/badge.component.mjs +4 -9
  12. package/esm2022/lib/breadcrumb-item.component.mjs +3 -3
  13. package/esm2022/lib/breadcrumb-link.component.mjs +3 -3
  14. package/esm2022/lib/breadcrumb-separator.component.mjs +3 -3
  15. package/esm2022/lib/breadcrumb.component.mjs +3 -3
  16. package/esm2022/lib/bubble.component.mjs +301 -0
  17. package/esm2022/lib/button.component.mjs +5 -11
  18. package/esm2022/lib/calendar.component.mjs +5 -11
  19. package/esm2022/lib/card.component.mjs +14 -43
  20. package/esm2022/lib/carousel/carousel.component.mjs +5 -12
  21. package/esm2022/lib/chain-of-thought.component.mjs +380 -0
  22. package/esm2022/lib/chart-pie.component.mjs +386 -0
  23. package/esm2022/lib/chart.component.mjs +1146 -0
  24. package/esm2022/lib/chart.service.mjs +555 -0
  25. package/esm2022/lib/checkbox.component.mjs +5 -11
  26. package/esm2022/lib/checkpoint.component.mjs +134 -0
  27. package/esm2022/lib/collapsible.component.mjs +4 -11
  28. package/esm2022/lib/combobox.component.mjs +372 -0
  29. package/esm2022/lib/command-dialog.component.mjs +164 -0
  30. package/esm2022/lib/command.component.mjs +514 -0
  31. package/esm2022/lib/command.service.mjs +130 -0
  32. package/esm2022/lib/confirmation.component.mjs +219 -0
  33. package/esm2022/lib/context-menu-trigger.directive.mjs +36 -0
  34. package/esm2022/lib/context-menu.component.mjs +460 -0
  35. package/esm2022/lib/context-menu.service.mjs +125 -0
  36. package/esm2022/lib/context.component.mjs +377 -0
  37. package/esm2022/lib/conversation.component.mjs +442 -0
  38. package/esm2022/lib/country-selector.component.mjs +5 -11
  39. package/esm2022/lib/data-table.component.mjs +59 -12
  40. package/esm2022/lib/date-picker.component.mjs +251 -198
  41. package/esm2022/lib/date-range-picker.component.mjs +224 -116
  42. package/esm2022/lib/date-time-picker.component.mjs +506 -0
  43. package/esm2022/lib/direction.component.mjs +79 -0
  44. package/esm2022/lib/dropdown-item.component.mjs +3 -3
  45. package/esm2022/lib/dropdown-label.component.mjs +3 -3
  46. package/esm2022/lib/dropdown-menu.component.mjs +3 -3
  47. package/esm2022/lib/dropdown-separator.component.mjs +3 -3
  48. package/esm2022/lib/dropdown-trigger.directive.mjs +6 -4
  49. package/esm2022/lib/empty-state.component.mjs +4 -9
  50. package/esm2022/lib/field.component.mjs +394 -0
  51. package/esm2022/lib/hover-card.component.mjs +6 -16
  52. package/esm2022/lib/inline-citation.component.mjs +263 -0
  53. package/esm2022/lib/input-group.component.mjs +418 -0
  54. package/esm2022/lib/input.component.mjs +5 -11
  55. package/esm2022/lib/item.component.mjs +243 -0
  56. package/esm2022/lib/kbd.component.mjs +82 -0
  57. package/esm2022/lib/label.component.mjs +4 -9
  58. package/esm2022/lib/marker.component.mjs +135 -0
  59. package/esm2022/lib/masked-input.component.mjs +5 -11
  60. package/esm2022/lib/menubar.component.mjs +683 -0
  61. package/esm2022/lib/message-scroller.component.mjs +353 -0
  62. package/esm2022/lib/message-scroller.service.mjs +157 -0
  63. package/esm2022/lib/message.component.mjs +228 -0
  64. package/esm2022/lib/modal-ref.mjs +36 -7
  65. package/esm2022/lib/modal.component.mjs +42 -28
  66. package/esm2022/lib/modal.mjs +2 -29
  67. package/esm2022/lib/modal.service.mjs +26 -4
  68. package/esm2022/lib/model-selector.component.mjs +310 -0
  69. package/esm2022/lib/multi-select.component.mjs +155 -72
  70. package/esm2022/lib/native-select.component.mjs +201 -0
  71. package/esm2022/lib/navigation-menu.component.mjs +642 -0
  72. package/esm2022/lib/otp-group.component.mjs +3 -3
  73. package/esm2022/lib/otp-slot.component.mjs +4 -9
  74. package/esm2022/lib/otp.component.mjs +5 -11
  75. package/esm2022/lib/pagination.component.mjs +7 -10
  76. package/esm2022/lib/plan.component.mjs +335 -0
  77. package/esm2022/lib/popover-content.component.mjs +4 -9
  78. package/esm2022/lib/popover.component.mjs +15 -13
  79. package/esm2022/lib/progress.component.mjs +4 -9
  80. package/esm2022/lib/prompt-input.component.mjs +526 -0
  81. package/esm2022/lib/queue.component.mjs +280 -0
  82. package/esm2022/lib/radio-group.component.mjs +6 -13
  83. package/esm2022/lib/radio-item.component.mjs +4 -9
  84. package/esm2022/lib/range-calendar.component.mjs +5 -11
  85. package/esm2022/lib/reasoning.component.mjs +335 -0
  86. package/esm2022/lib/resizable-panel.component.mjs +5 -5
  87. package/esm2022/lib/resizable.component.mjs +219 -0
  88. package/esm2022/lib/segment.component.mjs +19 -9
  89. package/esm2022/lib/select-group.component.mjs +4 -8
  90. package/esm2022/lib/select-item.component.mjs +4 -9
  91. package/esm2022/lib/select-separator.component.mjs +4 -8
  92. package/esm2022/lib/select.component.mjs +133 -49
  93. package/esm2022/lib/separator.component.mjs +4 -9
  94. package/esm2022/lib/sheet.component.mjs +38 -56
  95. package/esm2022/lib/shimmer.component.mjs +84 -0
  96. package/esm2022/lib/sidebar.component.mjs +11 -1
  97. package/esm2022/lib/skeleton.component.mjs +4 -9
  98. package/esm2022/lib/sources.component.mjs +452 -0
  99. package/esm2022/lib/spinner.component.mjs +68 -0
  100. package/esm2022/lib/suggestion.component.mjs +207 -0
  101. package/esm2022/lib/switch.component.mjs +5 -11
  102. package/esm2022/lib/table.component.mjs +213 -0
  103. package/esm2022/lib/tabs.component.mjs +4 -11
  104. package/esm2022/lib/tag-input.component.mjs +5 -11
  105. package/esm2022/lib/task.component.mjs +359 -0
  106. package/esm2022/lib/textarea.component.mjs +5 -11
  107. package/esm2022/lib/theme.service.mjs +17 -6
  108. package/esm2022/lib/time-picker.component.mjs +923 -0
  109. package/esm2022/lib/toast.service.mjs +3 -2
  110. package/esm2022/lib/toaster.component.mjs +76 -39
  111. package/esm2022/lib/toggle-group.component.mjs +4 -9
  112. package/esm2022/lib/toggle.component.mjs +5 -11
  113. package/esm2022/lib/tool.component.mjs +462 -0
  114. package/esm2022/lib/typography.component.mjs +83 -0
  115. package/esm2022/lib/utils/color.mjs +140 -19
  116. package/esm2022/public-api.mjs +61 -1
  117. package/fesm2022/tolle-ui.mjs +16642 -1105
  118. package/fesm2022/tolle-ui.mjs.map +1 -1
  119. package/lib/alert-dialog-dynamic.component.d.ts +5 -0
  120. package/lib/alert-dialog.component.d.ts +23 -2
  121. package/lib/aspect-ratio.component.d.ts +20 -0
  122. package/lib/attachment.component.d.ts +101 -0
  123. package/lib/bubble.component.d.ts +112 -0
  124. package/lib/chain-of-thought.component.d.ts +166 -0
  125. package/lib/chart-pie.component.d.ts +108 -0
  126. package/lib/chart.component.d.ts +369 -0
  127. package/lib/chart.service.d.ts +222 -0
  128. package/lib/checkpoint.component.d.ts +51 -0
  129. package/lib/combobox.component.d.ts +90 -0
  130. package/lib/command-dialog.component.d.ts +53 -0
  131. package/lib/command.component.d.ts +189 -0
  132. package/lib/command.service.d.ts +67 -0
  133. package/lib/confirmation.component.d.ts +70 -0
  134. package/lib/context-menu-trigger.directive.d.ts +12 -0
  135. package/lib/context-menu.component.d.ts +41 -0
  136. package/lib/context-menu.service.d.ts +38 -0
  137. package/lib/context.component.d.ts +134 -0
  138. package/lib/conversation.component.d.ts +165 -0
  139. package/lib/data-table.component.d.ts +26 -1
  140. package/lib/date-picker.component.d.ts +72 -11
  141. package/lib/date-range-picker.component.d.ts +63 -6
  142. package/lib/date-time-picker.component.d.ts +119 -0
  143. package/lib/direction.component.d.ts +45 -0
  144. package/lib/field.component.d.ts +201 -0
  145. package/lib/inline-citation.component.d.ts +103 -0
  146. package/lib/input-group.component.d.ts +150 -0
  147. package/lib/item.component.d.ts +154 -0
  148. package/lib/kbd.component.d.ts +50 -0
  149. package/lib/marker.component.d.ts +58 -0
  150. package/lib/menubar.component.d.ts +247 -0
  151. package/lib/message-scroller.component.d.ts +159 -0
  152. package/lib/message-scroller.service.d.ts +73 -0
  153. package/lib/message.component.d.ts +128 -0
  154. package/lib/modal-ref.d.ts +6 -1
  155. package/lib/modal.component.d.ts +7 -4
  156. package/lib/modal.d.ts +9 -3
  157. package/lib/model-selector.component.d.ts +103 -0
  158. package/lib/multi-select.component.d.ts +66 -14
  159. package/lib/native-select.component.d.ts +57 -0
  160. package/lib/navigation-menu.component.d.ts +230 -0
  161. package/lib/plan.component.d.ts +120 -0
  162. package/lib/popover.component.d.ts +1 -0
  163. package/lib/prompt-input.component.d.ts +194 -0
  164. package/lib/queue.component.d.ts +106 -0
  165. package/lib/reasoning.component.d.ts +127 -0
  166. package/lib/resizable.component.d.ts +43 -0
  167. package/lib/segment.component.d.ts +13 -3
  168. package/lib/select.component.d.ts +37 -5
  169. package/lib/sheet.component.d.ts +3 -0
  170. package/lib/shimmer.component.d.ts +38 -0
  171. package/lib/sidebar.component.d.ts +2 -0
  172. package/lib/sources.component.d.ts +156 -0
  173. package/lib/spinner.component.d.ts +29 -0
  174. package/lib/suggestion.component.d.ts +96 -0
  175. package/lib/table.component.d.ts +106 -0
  176. package/lib/task.component.d.ts +151 -0
  177. package/lib/theme.service.d.ts +9 -0
  178. package/lib/time-picker.component.d.ts +243 -0
  179. package/lib/toast.service.d.ts +3 -1
  180. package/lib/toaster.component.d.ts +26 -9
  181. package/lib/tool.component.d.ts +158 -0
  182. package/lib/typography.component.d.ts +32 -0
  183. package/lib/utils/color.d.ts +19 -5
  184. package/package.json +3 -2
  185. package/preset.js +7 -1
  186. package/public-api.d.ts +50 -0
  187. package/registry/docs-content.json +8480 -1542
  188. package/registry/llms-full.txt +2679 -319
  189. package/registry/llms.txt +43 -4
  190. package/registry/manifest.json +9090 -1742
  191. package/registry/r/accordion-item.json +1 -1
  192. package/registry/r/accordion.json +1 -1
  193. package/registry/r/alert-dialog-dynamic.json +1 -1
  194. package/registry/r/alert-dialog.json +1 -1
  195. package/registry/r/alert.json +1 -1
  196. package/registry/r/attachment.json +23 -0
  197. package/registry/r/avatar-fallback.json +1 -1
  198. package/registry/r/avatar.json +1 -1
  199. package/registry/r/badge.json +1 -1
  200. package/registry/r/breadcrumb-item.json +1 -1
  201. package/registry/r/breadcrumb-link.json +1 -1
  202. package/registry/r/breadcrumb-separator.json +1 -1
  203. package/registry/r/breadcrumb.json +1 -1
  204. package/registry/r/bubble.json +23 -0
  205. package/registry/r/button.json +1 -1
  206. package/registry/r/calendar.json +1 -1
  207. package/registry/r/card.json +1 -1
  208. package/registry/r/carousel.json +1 -1
  209. package/registry/r/chain-of-thought.json +23 -0
  210. package/registry/r/chart-pie.json +30 -0
  211. package/registry/r/chart.json +28 -0
  212. package/registry/r/checkbox.json +1 -1
  213. package/registry/r/checkpoint.json +23 -0
  214. package/registry/r/collapsible.json +1 -1
  215. package/registry/r/combobox.json +31 -0
  216. package/registry/r/command-dialog.json +21 -0
  217. package/registry/r/command.json +26 -0
  218. package/registry/r/confirmation.json +23 -0
  219. package/registry/r/context-menu-trigger.json +1 -1
  220. package/registry/r/context-menu.json +1 -1
  221. package/registry/r/context.json +26 -0
  222. package/registry/r/conversation.json +23 -0
  223. package/registry/r/country-selector.json +1 -1
  224. package/registry/r/data-table.json +1 -1
  225. package/registry/r/date-picker.json +4 -4
  226. package/registry/r/date-range-picker.json +3 -3
  227. package/registry/r/date-time-picker.json +28 -0
  228. package/registry/r/direction.json +16 -0
  229. package/registry/r/dropdown-item.json +1 -1
  230. package/registry/r/dropdown-label.json +1 -1
  231. package/registry/r/dropdown-menu.json +1 -1
  232. package/registry/r/dropdown-separator.json +1 -1
  233. package/registry/r/dropdown-trigger.json +1 -1
  234. package/registry/r/empty-state.json +1 -1
  235. package/registry/r/field.json +23 -0
  236. package/registry/r/hover-card.json +1 -1
  237. package/registry/r/inline-citation.json +26 -0
  238. package/registry/r/input-group.json +23 -0
  239. package/registry/r/input.json +1 -1
  240. package/registry/r/item.json +23 -0
  241. package/registry/r/kbd.json +23 -0
  242. package/registry/r/label.json +1 -1
  243. package/registry/r/marker.json +23 -0
  244. package/registry/r/masked-input.json +1 -1
  245. package/registry/r/menubar.json +24 -0
  246. package/registry/r/message-scroller.json +26 -0
  247. package/registry/r/message.json +23 -0
  248. package/registry/r/modal.json +3 -3
  249. package/registry/r/model-selector.json +32 -0
  250. package/registry/r/multi-select.json +2 -2
  251. package/registry/r/native-select.json +23 -0
  252. package/registry/r/navigation-menu.json +24 -0
  253. package/registry/r/otp-group.json +1 -1
  254. package/registry/r/otp-slot.json +1 -1
  255. package/registry/r/otp.json +1 -1
  256. package/registry/r/pagination.json +3 -2
  257. package/registry/r/plan.json +23 -0
  258. package/registry/r/popover-content.json +1 -1
  259. package/registry/r/popover.json +1 -1
  260. package/registry/r/progress.json +1 -1
  261. package/registry/r/prompt-input.json +23 -0
  262. package/registry/r/queue.json +23 -0
  263. package/registry/r/radio-group.json +1 -1
  264. package/registry/r/radio-item.json +1 -1
  265. package/registry/r/range-calendar.json +1 -1
  266. package/registry/r/reasoning.json +23 -0
  267. package/registry/r/resizable-panel.json +1 -1
  268. package/registry/r/segment.json +1 -1
  269. package/registry/r/select-group.json +1 -1
  270. package/registry/r/select-item.json +1 -1
  271. package/registry/r/select-separator.json +1 -1
  272. package/registry/r/select.json +4 -3
  273. package/registry/r/separator.json +1 -1
  274. package/registry/r/sheet.json +1 -1
  275. package/registry/r/shimmer.json +23 -0
  276. package/registry/r/sidebar.json +1 -1
  277. package/registry/r/skeleton.json +1 -1
  278. package/registry/r/sources.json +23 -0
  279. package/registry/r/spinner.json +23 -0
  280. package/registry/r/suggestion.json +23 -0
  281. package/registry/r/switch.json +1 -1
  282. package/registry/r/table.json +21 -0
  283. package/registry/r/tabs.json +1 -1
  284. package/registry/r/tag-input.json +1 -1
  285. package/registry/r/task.json +23 -0
  286. package/registry/r/textarea.json +1 -1
  287. package/registry/r/time-picker.json +24 -0
  288. package/registry/r/toaster.json +2 -2
  289. package/registry/r/toggle-group.json +1 -1
  290. package/registry/r/toggle.json +1 -1
  291. package/registry/r/tool.json +23 -0
  292. package/registry/r/typography.json +23 -0
  293. package/registry/registry.json +915 -22
  294. package/theme.css +121 -8
@@ -0,0 +1,923 @@
1
+ import { Component, Input, Output, EventEmitter, forwardRef, ViewChild, ViewChildren, ChangeDetectionStrategy } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
4
+ import { computePosition, flip, shift, offset, autoUpdate } from '@floating-ui/dom';
5
+ import { cva } from 'class-variance-authority';
6
+ import { cn } from './utils/cn';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "@angular/common";
9
+ const pad2 = (n) => (n < 10 ? '0' + n : String(n));
10
+ /** Seconds elapsed since midnight for a wall-clock time. */
11
+ export function timePartsToSeconds(parts) {
12
+ return parts.hour * 3600 + parts.minute * 60 + parts.second;
13
+ }
14
+ /**
15
+ * Parses `HH:mm` or `HH:mm:ss` (24-hour). Returns `null` for anything that
16
+ * is not a well-formed, in-range time — callers treat that as "no value".
17
+ */
18
+ export function parseTimeString(value) {
19
+ if (typeof value !== 'string')
20
+ return null;
21
+ const match = /^(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?$/.exec(value.trim());
22
+ if (!match)
23
+ return null;
24
+ const hour = Number(match[1]);
25
+ const minute = Number(match[2]);
26
+ const second = match[3] === undefined ? 0 : Number(match[3]);
27
+ if (hour > 23 || minute > 59 || second > 59)
28
+ return null;
29
+ return { hour, minute, second };
30
+ }
31
+ /** Renders a wall-clock time as `HH:mm`, or `HH:mm:ss` when `withSeconds`. */
32
+ export function formatTimeString(parts, withSeconds = false) {
33
+ const base = pad2(parts.hour) + ':' + pad2(parts.minute);
34
+ return withSeconds ? base + ':' + pad2(parts.second) : base;
35
+ }
36
+ /**
37
+ * 24-hour hour to its 12-hour clock face. Midnight is `12 AM` and noon is
38
+ * `12 PM` — the two values that a naive `hour % 12` gets wrong.
39
+ */
40
+ export function to12Hour(hour24) {
41
+ const meridiem = hour24 < 12 ? 'AM' : 'PM';
42
+ const hour12 = hour24 % 12 === 0 ? 12 : hour24 % 12;
43
+ return { hour12, meridiem };
44
+ }
45
+ /** 12-hour clock face back to a 24-hour hour. `12 AM` is 0, `12 PM` is 12. */
46
+ export function from12Hour(hour12, meridiem) {
47
+ const base = hour12 % 12; // 12 -> 0, leaves 1..11 alone
48
+ return meridiem === 'PM' ? base + 12 : base;
49
+ }
50
+ const SECONDS_PER_DAY = 24 * 3600;
51
+ const timeOptionVariants = cva('flex w-full shrink-0 cursor-pointer select-none items-center justify-center rounded-md tabular-nums ' +
52
+ 'transition-colors focus:outline-none disabled:pointer-events-none disabled:opacity-40', {
53
+ variants: {
54
+ size: {
55
+ xs: 'h-6 px-2 text-[11px]',
56
+ sm: 'h-7 px-2 text-xs',
57
+ default: 'h-8 px-2.5 text-sm',
58
+ lg: 'h-9 px-3 text-base',
59
+ },
60
+ selected: {
61
+ true: 'bg-primary text-primary-foreground hover:bg-primary',
62
+ false: 'text-foreground hover:bg-accent hover:text-accent-foreground',
63
+ },
64
+ },
65
+ defaultVariants: { size: 'default', selected: false },
66
+ });
67
+ /**
68
+ * The bare scrollable hour / minute / second / AM-PM columns, with no trigger
69
+ * and no popover of its own.
70
+ *
71
+ * `tolle-time-picker` wraps this in a floating panel, and
72
+ * `tolle-date-time-picker` sits it beside a calendar — so the option
73
+ * generation, the min/max disabling and the roving keyboard model live here
74
+ * once instead of in both.
75
+ */
76
+ export class TimeColumnsComponent {
77
+ cdr;
78
+ /** Selected hour in 24-hour form, or `null` when nothing is chosen yet. @default null */
79
+ hour = null;
80
+ /** Selected minute, or `null` when nothing is chosen yet. @default null */
81
+ minute = null;
82
+ /** Selected second, or `null` when nothing is chosen yet. @default null */
83
+ second = null;
84
+ /** Renders a 12-hour clock face with an AM/PM column. @default false */
85
+ use12Hours = false;
86
+ /** Adds the seconds column. @default false */
87
+ showSeconds = false;
88
+ /** Interval between minute entries, in minutes. @default 1 */
89
+ minuteStep = 1;
90
+ /** Interval between second entries, in seconds. @default 1 */
91
+ secondStep = 1;
92
+ /** Earliest selectable time, as seconds since midnight. @default 0 */
93
+ minSeconds = 0;
94
+ /** Latest selectable time, as seconds since midnight. @default 86399 */
95
+ maxSeconds = SECONDS_PER_DAY - 1;
96
+ /** Row height and text size of the entries. @default 'default' */
97
+ size = 'default';
98
+ /** Extra Tailwind classes merged onto the column strip via `cn()` (last-wins). */
99
+ class = '';
100
+ /** Emitted with the full wall-clock time whenever an entry is chosen. */
101
+ timeChange = new EventEmitter();
102
+ listboxes;
103
+ columnsId = 'time-col-' + Math.random().toString(36).slice(2, 11);
104
+ /**
105
+ * Built once per input change rather than read from a getter: a getter would
106
+ * hand `*ngFor` a fresh array on every change-detection pass, so every row —
107
+ * each carrying a click handler — would be torn down and rebuilt on every
108
+ * pass.
109
+ */
110
+ columns = [];
111
+ /** Roving active entry per column, for `aria-activedescendant`. */
112
+ activeIndex = [];
113
+ cn = cn;
114
+ constructor(cdr) {
115
+ this.cdr = cdr;
116
+ }
117
+ ngOnInit() {
118
+ if (!this.columns.length)
119
+ this.rebuild();
120
+ }
121
+ ngOnChanges() {
122
+ this.rebuild();
123
+ // A bound `class` input is written through Angular's styling path,
124
+ // which does not mark an OnPush view dirty on its own.
125
+ this.cdr.markForCheck();
126
+ }
127
+ get heightClass() {
128
+ switch (this.size) {
129
+ case 'xs':
130
+ return 'max-h-[144px]';
131
+ case 'sm':
132
+ return 'max-h-[168px]';
133
+ case 'lg':
134
+ return 'max-h-[216px]';
135
+ default:
136
+ return 'max-h-[192px]';
137
+ }
138
+ }
139
+ /* ---------------- option generation ---------------- */
140
+ rebuild() {
141
+ const step = (value, fallback) => Number.isFinite(value) && value >= 1 ? Math.floor(value) : fallback;
142
+ const minuteStep = step(this.minuteStep, 1);
143
+ const secondStep = step(this.secondStep, 1);
144
+ const effectiveHour = this.hour ?? 0;
145
+ const effectiveMinute = this.minute ?? 0;
146
+ const meridiem = to12Hour(effectiveHour).meridiem;
147
+ // How far a partially-specified time can stretch. With no seconds column
148
+ // the seconds are pinned to :00, so an hour only reaches :59:00.
149
+ const hourSpan = this.showSeconds ? 3599 : 3540;
150
+ const minuteSpan = this.showSeconds ? 59 : 0;
151
+ const columns = [];
152
+ // Hours
153
+ const hourOptions = [];
154
+ if (this.use12Hours) {
155
+ // Clock-face order: 12, 1, 2 … 11.
156
+ const faces = [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
157
+ for (const face of faces) {
158
+ const raw = from12Hour(face, meridiem);
159
+ hourOptions.push({
160
+ id: this.columnsId + '-hour-' + face,
161
+ label: pad2(face),
162
+ raw,
163
+ face,
164
+ disabled: this.rangeDisabled(raw * 3600, hourSpan),
165
+ });
166
+ }
167
+ }
168
+ else {
169
+ for (let h = 0; h < 24; h++) {
170
+ hourOptions.push({
171
+ id: this.columnsId + '-hour-' + h,
172
+ label: pad2(h),
173
+ raw: h,
174
+ face: h,
175
+ disabled: this.rangeDisabled(h * 3600, hourSpan),
176
+ });
177
+ }
178
+ }
179
+ columns.push({ kind: 'hour', label: 'Hour', options: hourOptions });
180
+ // Minutes
181
+ const minuteOptions = [];
182
+ for (let m = 0; m < 60; m += minuteStep) {
183
+ const start = effectiveHour * 3600 + m * 60;
184
+ minuteOptions.push({
185
+ id: this.columnsId + '-minute-' + m,
186
+ label: pad2(m),
187
+ raw: m,
188
+ face: m,
189
+ disabled: this.rangeDisabled(start, minuteSpan),
190
+ });
191
+ }
192
+ columns.push({ kind: 'minute', label: 'Min', options: minuteOptions });
193
+ // Seconds
194
+ if (this.showSeconds) {
195
+ const secondOptions = [];
196
+ for (let s = 0; s < 60; s += secondStep) {
197
+ const at = effectiveHour * 3600 + effectiveMinute * 60 + s;
198
+ secondOptions.push({
199
+ id: this.columnsId + '-second-' + s,
200
+ label: pad2(s),
201
+ raw: s,
202
+ face: s,
203
+ disabled: this.rangeDisabled(at, 0),
204
+ });
205
+ }
206
+ columns.push({ kind: 'second', label: 'Sec', options: secondOptions });
207
+ }
208
+ // Meridiem
209
+ if (this.use12Hours) {
210
+ const face12 = to12Hour(effectiveHour).hour12;
211
+ const meridiemOptions = ['AM', 'PM'].map((m, i) => {
212
+ const raw = from12Hour(face12, m);
213
+ const halfStart = m === 'AM' ? 0 : 12 * 3600;
214
+ return {
215
+ id: this.columnsId + '-meridiem-' + m,
216
+ label: m,
217
+ raw,
218
+ face: i, // 0 = AM, 1 = PM
219
+ disabled: this.rangeDisabled(halfStart, 12 * 3600 - 1),
220
+ };
221
+ });
222
+ columns.push({ kind: 'meridiem', label: 'AM/PM', options: meridiemOptions });
223
+ }
224
+ this.columns = columns;
225
+ this.syncActiveToSelection();
226
+ }
227
+ /**
228
+ * True when nothing in `[start, start + span]` falls inside the allowed
229
+ * window — i.e. picking this entry could not produce a legal time.
230
+ */
231
+ rangeDisabled(start, span) {
232
+ return start + span < this.minSeconds || start > this.maxSeconds;
233
+ }
234
+ syncActiveToSelection() {
235
+ this.activeIndex = this.columns.map((column) => {
236
+ const idx = column.options.findIndex((o) => this.isSelected(column, o));
237
+ if (idx >= 0)
238
+ return idx;
239
+ const firstEnabled = column.options.findIndex((o) => !o.disabled);
240
+ return firstEnabled >= 0 ? firstEnabled : 0;
241
+ });
242
+ }
243
+ /* ---------------- selection ---------------- */
244
+ isSelected(column, option) {
245
+ switch (column.kind) {
246
+ case 'hour':
247
+ if (this.hour === null)
248
+ return false;
249
+ return this.use12Hours ? to12Hour(this.hour).hour12 === option.face : this.hour === option.face;
250
+ case 'minute':
251
+ return this.minute !== null && this.minute === option.face;
252
+ case 'second':
253
+ return this.second !== null && this.second === option.face;
254
+ case 'meridiem':
255
+ if (this.hour === null)
256
+ return false;
257
+ return (to12Hour(this.hour).meridiem === 'AM' ? 0 : 1) === option.face;
258
+ }
259
+ }
260
+ isActive(columnIndex, option) {
261
+ const column = this.columns[columnIndex];
262
+ if (!column)
263
+ return false;
264
+ return column.options[this.activeIndex[columnIndex]] === option;
265
+ }
266
+ activeDescendantFor(columnIndex) {
267
+ const column = this.columns[columnIndex];
268
+ return column?.options[this.activeIndex[columnIndex]]?.id ?? null;
269
+ }
270
+ optionClass(column, option, columnIndex) {
271
+ const selected = this.isSelected(column, option);
272
+ return cn(timeOptionVariants({ size: this.size, selected }),
273
+ // The roving highlight has to read as distinct from the committed value,
274
+ // otherwise arrowing around looks like it is already selecting.
275
+ !selected && this.isActive(columnIndex, option) && 'bg-accent text-accent-foreground');
276
+ }
277
+ /** Commits `option` in its column and emits the resulting whole time. */
278
+ choose(column, option, columnIndex) {
279
+ if (option.disabled)
280
+ return;
281
+ const next = {
282
+ hour: this.hour ?? 0,
283
+ minute: this.minute ?? 0,
284
+ second: this.second ?? 0,
285
+ };
286
+ switch (column.kind) {
287
+ case 'hour':
288
+ case 'meridiem':
289
+ next.hour = option.raw;
290
+ break;
291
+ case 'minute':
292
+ next.minute = option.raw;
293
+ break;
294
+ case 'second':
295
+ next.second = option.raw;
296
+ break;
297
+ }
298
+ this.activeIndex[columnIndex] = column.options.indexOf(option);
299
+ this.timeChange.emit(next);
300
+ this.cdr.markForCheck();
301
+ }
302
+ /* ---------------- keyboard ---------------- */
303
+ onColumnKeydown(event, columnIndex) {
304
+ const column = this.columns[columnIndex];
305
+ if (!column)
306
+ return;
307
+ switch (event.key) {
308
+ case 'ArrowDown':
309
+ event.preventDefault();
310
+ this.moveActive(columnIndex, 1);
311
+ break;
312
+ case 'ArrowUp':
313
+ event.preventDefault();
314
+ this.moveActive(columnIndex, -1);
315
+ break;
316
+ case 'Home':
317
+ event.preventDefault();
318
+ this.setActive(columnIndex, 0, 1);
319
+ break;
320
+ case 'End':
321
+ event.preventDefault();
322
+ this.setActive(columnIndex, column.options.length - 1, -1);
323
+ break;
324
+ case 'ArrowLeft':
325
+ event.preventDefault();
326
+ this.focusColumn(columnIndex - 1);
327
+ break;
328
+ case 'ArrowRight':
329
+ event.preventDefault();
330
+ this.focusColumn(columnIndex + 1);
331
+ break;
332
+ case 'Enter':
333
+ case ' ':
334
+ event.preventDefault();
335
+ {
336
+ const option = column.options[this.activeIndex[columnIndex]];
337
+ if (option)
338
+ this.choose(column, option, columnIndex);
339
+ }
340
+ break;
341
+ default:
342
+ return;
343
+ }
344
+ }
345
+ moveActive(columnIndex, delta) {
346
+ const current = this.activeIndex[columnIndex] ?? 0;
347
+ this.setActive(columnIndex, current + delta, delta);
348
+ }
349
+ /** Lands on the first enabled entry at or past `index`, walking `direction`. */
350
+ setActive(columnIndex, index, direction) {
351
+ const column = this.columns[columnIndex];
352
+ if (!column)
353
+ return;
354
+ let i = Math.max(0, Math.min(index, column.options.length - 1));
355
+ while (column.options[i]?.disabled) {
356
+ i += direction;
357
+ if (i < 0 || i >= column.options.length)
358
+ return; // no enabled entry that way
359
+ }
360
+ this.activeIndex[columnIndex] = i;
361
+ this.scrollOptionIntoView(columnIndex, i);
362
+ this.cdr.markForCheck();
363
+ }
364
+ focusColumn(columnIndex) {
365
+ if (columnIndex < 0 || columnIndex >= this.columns.length)
366
+ return;
367
+ this.listboxes?.get(columnIndex)?.nativeElement.focus();
368
+ }
369
+ /** Focuses the first column — used when the panel opens. */
370
+ focusFirstColumn() {
371
+ this.focusColumn(0);
372
+ }
373
+ /**
374
+ * Centres each column on its selected entry. Scrolls the listbox directly
375
+ * rather than calling `scrollIntoView`, which would also scroll the page
376
+ * behind a fixed-position panel.
377
+ */
378
+ scrollSelectedIntoView() {
379
+ this.listboxes?.forEach((ref) => {
380
+ const list = ref.nativeElement;
381
+ const selected = list.querySelector('[data-selected="true"]');
382
+ if (!selected)
383
+ return;
384
+ list.scrollTop = selected.offsetTop - list.clientHeight / 2 + selected.clientHeight / 2;
385
+ });
386
+ }
387
+ scrollOptionIntoView(columnIndex, optionIndex) {
388
+ const list = this.listboxes?.get(columnIndex)?.nativeElement;
389
+ if (!list)
390
+ return;
391
+ const el = list.children[optionIndex];
392
+ if (!el)
393
+ return;
394
+ if (el.offsetTop < list.scrollTop) {
395
+ list.scrollTop = el.offsetTop;
396
+ }
397
+ else if (el.offsetTop + el.clientHeight > list.scrollTop + list.clientHeight) {
398
+ list.scrollTop = el.offsetTop + el.clientHeight - list.clientHeight;
399
+ }
400
+ }
401
+ trackColumn = (_, column) => column.kind;
402
+ trackOption = (_, option) => option.id;
403
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimeColumnsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
404
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TimeColumnsComponent, isStandalone: true, selector: "tolle-time-columns", inputs: { hour: "hour", minute: "minute", second: "second", use12Hours: "use12Hours", showSeconds: "showSeconds", minuteStep: "minuteStep", secondStep: "secondStep", minSeconds: "minSeconds", maxSeconds: "maxSeconds", size: "size", class: "class" }, outputs: { timeChange: "timeChange" }, viewQueries: [{ propertyName: "listboxes", predicate: ["listbox"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
405
+ <div [class]="cn('flex items-stretch gap-1', class)">
406
+ <div
407
+ *ngFor="let column of columns; let ci = index; trackBy: trackColumn"
408
+ class="flex flex-col"
409
+ >
410
+ <div class="px-1 pb-1 text-center text-[10px] font-medium uppercase tracking-wide text-muted-foreground">
411
+ {{ column.label }}
412
+ </div>
413
+ <div
414
+ #listbox
415
+ role="listbox"
416
+ tabindex="0"
417
+ [attr.aria-label]="column.label"
418
+ [attr.aria-activedescendant]="activeDescendantFor(ci)"
419
+ (keydown)="onColumnKeydown($event, ci)"
420
+ [class]="cn(
421
+ 'flex flex-col gap-0.5 overflow-y-auto scroll-smooth rounded-md p-1',
422
+ 'focus:outline-none focus-visible:ring-2 focus-visible:ring-ring',
423
+ column.kind === 'meridiem' ? 'w-14' : 'w-14',
424
+ heightClass
425
+ )"
426
+ >
427
+ <button
428
+ *ngFor="let option of column.options; trackBy: trackOption"
429
+ type="button"
430
+ role="option"
431
+ tabindex="-1"
432
+ [id]="option.id"
433
+ [attr.aria-selected]="isSelected(column, option)"
434
+ [attr.aria-disabled]="option.disabled"
435
+ [attr.data-selected]="isSelected(column, option)"
436
+ [attr.data-active]="isActive(ci, option)"
437
+ [disabled]="option.disabled"
438
+ [class]="optionClass(column, option, ci)"
439
+ (click)="choose(column, option, ci)"
440
+ >
441
+ {{ option.label }}
442
+ </button>
443
+ </div>
444
+ </div>
445
+ </div>
446
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
447
+ }
448
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimeColumnsComponent, decorators: [{
449
+ type: Component,
450
+ args: [{ selector: 'tolle-time-columns', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
451
+ <div [class]="cn('flex items-stretch gap-1', class)">
452
+ <div
453
+ *ngFor="let column of columns; let ci = index; trackBy: trackColumn"
454
+ class="flex flex-col"
455
+ >
456
+ <div class="px-1 pb-1 text-center text-[10px] font-medium uppercase tracking-wide text-muted-foreground">
457
+ {{ column.label }}
458
+ </div>
459
+ <div
460
+ #listbox
461
+ role="listbox"
462
+ tabindex="0"
463
+ [attr.aria-label]="column.label"
464
+ [attr.aria-activedescendant]="activeDescendantFor(ci)"
465
+ (keydown)="onColumnKeydown($event, ci)"
466
+ [class]="cn(
467
+ 'flex flex-col gap-0.5 overflow-y-auto scroll-smooth rounded-md p-1',
468
+ 'focus:outline-none focus-visible:ring-2 focus-visible:ring-ring',
469
+ column.kind === 'meridiem' ? 'w-14' : 'w-14',
470
+ heightClass
471
+ )"
472
+ >
473
+ <button
474
+ *ngFor="let option of column.options; trackBy: trackOption"
475
+ type="button"
476
+ role="option"
477
+ tabindex="-1"
478
+ [id]="option.id"
479
+ [attr.aria-selected]="isSelected(column, option)"
480
+ [attr.aria-disabled]="option.disabled"
481
+ [attr.data-selected]="isSelected(column, option)"
482
+ [attr.data-active]="isActive(ci, option)"
483
+ [disabled]="option.disabled"
484
+ [class]="optionClass(column, option, ci)"
485
+ (click)="choose(column, option, ci)"
486
+ >
487
+ {{ option.label }}
488
+ </button>
489
+ </div>
490
+ </div>
491
+ </div>
492
+ `, styles: [":host{display:block}\n"] }]
493
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { hour: [{
494
+ type: Input
495
+ }], minute: [{
496
+ type: Input
497
+ }], second: [{
498
+ type: Input
499
+ }], use12Hours: [{
500
+ type: Input
501
+ }], showSeconds: [{
502
+ type: Input
503
+ }], minuteStep: [{
504
+ type: Input
505
+ }], secondStep: [{
506
+ type: Input
507
+ }], minSeconds: [{
508
+ type: Input
509
+ }], maxSeconds: [{
510
+ type: Input
511
+ }], size: [{
512
+ type: Input
513
+ }], class: [{
514
+ type: Input
515
+ }], timeChange: [{
516
+ type: Output
517
+ }], listboxes: [{
518
+ type: ViewChildren,
519
+ args: ['listbox']
520
+ }] } });
521
+ /* ------------------------------------------------------------------ *
522
+ * The picker
523
+ * ------------------------------------------------------------------ */
524
+ const timePickerTriggerVariants = cva('flex w-full items-center justify-between gap-2 rounded-md border border-input bg-background text-foreground shadow-sm transition-colors ' +
525
+ 'focus:outline-none focus-visible:border-primary/80 focus-visible:ring-4 focus-visible:ring-ring/30 ' +
526
+ 'disabled:cursor-not-allowed disabled:opacity-50', {
527
+ variants: {
528
+ size: {
529
+ xs: 'h-8 px-2 text-xs',
530
+ sm: 'h-9 px-3 text-sm',
531
+ default: 'h-10 px-3 text-sm',
532
+ lg: 'h-11 px-4 text-base',
533
+ },
534
+ invalid: {
535
+ true: 'border-destructive focus-visible:border-destructive/80 focus-visible:ring-destructive/30',
536
+ false: '',
537
+ },
538
+ },
539
+ defaultVariants: { size: 'default', invalid: false },
540
+ });
541
+ /**
542
+ * A trigger that opens scrollable hour / minute / second columns in a floating
543
+ * panel.
544
+ *
545
+ * The value is a **24-hour `HH:mm` string** (or `HH:mm:ss` when `showSeconds`),
546
+ * regardless of whether the face is rendered as 12-hour — a wall-clock time has
547
+ * no date and no timezone, and a `Date` would invent both. Set
548
+ * `valueType="date"` to exchange `Date` objects instead, in which case the time
549
+ * is written onto today's date (or onto the date already held by the control).
550
+ *
551
+ * Implements `ControlValueAccessor`, so it works with `ngModel` and reactive
552
+ * forms. Use `tolle-date-time-picker` when a date is needed alongside.
553
+ * @new
554
+ */
555
+ export class TimePickerComponent {
556
+ cdr;
557
+ /**
558
+ * Angular writes a bound `class` input through its styling path, which does
559
+ * not mark an OnPush component dirty — without this hook the component keeps
560
+ * rendering the class it was born with.
561
+ */
562
+ ngOnChanges() {
563
+ this.cdr.markForCheck();
564
+ }
565
+ /** Text shown on the trigger when no time is selected. @default 'Select a time' */
566
+ placeholder = 'Select a time';
567
+ /** Disables the control. @default false */
568
+ disabled = false;
569
+ /** Renders a 12-hour face with an AM/PM column. The emitted value stays 24-hour. @default false */
570
+ use12Hours = false;
571
+ /** Adds a seconds column and emits `HH:mm:ss`. @default false */
572
+ showSeconds = false;
573
+ /** Interval between minute entries, in minutes. @default 1 */
574
+ minuteStep = 1;
575
+ /** Interval between second entries, in seconds. @default 1 */
576
+ secondStep = 1;
577
+ /** Earliest selectable time as a 24-hour `HH:mm` string; earlier entries are disabled. */
578
+ min;
579
+ /** Latest selectable time as a 24-hour `HH:mm` string; later entries are disabled. */
580
+ max;
581
+ /** Height and text size of the trigger and entries. @default 'default' */
582
+ size = 'default';
583
+ /** Applies the destructive border and focus ring. @default false */
584
+ invalid = false;
585
+ /** Accessible name when there is no associated visible label. @default '' */
586
+ ariaLabel = '';
587
+ /** Exchange `Date` objects instead of `HH:mm` strings through the form control. @default 'string' */
588
+ valueType = 'string';
589
+ /** Extra Tailwind classes merged onto the trigger via `cn()` (last-wins). */
590
+ class = '';
591
+ /** Emitted with the chosen time whenever it changes. */
592
+ valueChange = new EventEmitter();
593
+ /** Emitted when the panel opens. */
594
+ opened = new EventEmitter();
595
+ /** Emitted when the panel closes. */
596
+ closed = new EventEmitter();
597
+ triggerEl;
598
+ panelEl;
599
+ columnsCmp;
600
+ panelId = 'time-picker-panel-' + Math.random().toString(36).slice(2, 11);
601
+ hour = null;
602
+ minute = null;
603
+ second = null;
604
+ isOpen = false;
605
+ cn = cn;
606
+ cleanup;
607
+ /** The date half of a `Date` value, kept so round-tripping does not move the day. */
608
+ dateAnchor = null;
609
+ onChange = () => { };
610
+ onTouched = () => { };
611
+ constructor(cdr) {
612
+ this.cdr = cdr;
613
+ }
614
+ outsideClickHandler = (event) => {
615
+ const target = event.target;
616
+ if (!this.triggerEl?.nativeElement.contains(target) &&
617
+ !this.panelEl?.nativeElement.contains(target)) {
618
+ this.close();
619
+ }
620
+ };
621
+ escapeHandler = (event) => {
622
+ if (event.key === 'Escape' && this.isOpen) {
623
+ event.preventDefault();
624
+ this.close();
625
+ this.triggerEl?.nativeElement.focus();
626
+ }
627
+ };
628
+ /* ---------------- derived ---------------- */
629
+ /** The current selection as wall-clock parts, or `null` when incomplete. */
630
+ get parts() {
631
+ if (this.hour === null || this.minute === null)
632
+ return null;
633
+ return { hour: this.hour, minute: this.minute, second: this.second ?? 0 };
634
+ }
635
+ get displayValue() {
636
+ const parts = this.parts;
637
+ if (!parts)
638
+ return '';
639
+ if (this.use12Hours) {
640
+ const { hour12, meridiem } = to12Hour(parts.hour);
641
+ const body = String(hour12) +
642
+ ':' +
643
+ pad2(parts.minute) +
644
+ (this.showSeconds ? ':' + pad2(parts.second) : '');
645
+ return body + ' ' + meridiem;
646
+ }
647
+ return formatTimeString(parts, this.showSeconds);
648
+ }
649
+ get minSeconds() {
650
+ const parsed = parseTimeString(this.min);
651
+ return parsed ? timePartsToSeconds(parsed) : 0;
652
+ }
653
+ get maxSeconds() {
654
+ const parsed = parseTimeString(this.max);
655
+ return parsed ? timePartsToSeconds(parsed) : SECONDS_PER_DAY - 1;
656
+ }
657
+ get computedTriggerClass() {
658
+ return cn(timePickerTriggerVariants({ size: this.size, invalid: this.invalid }), this.class);
659
+ }
660
+ /* ---------------- open / close ---------------- */
661
+ toggle() {
662
+ this.isOpen ? this.close() : this.open();
663
+ }
664
+ open() {
665
+ if (this.disabled || this.isOpen)
666
+ return;
667
+ this.isOpen = true;
668
+ this.opened.emit();
669
+ this.cdr.markForCheck();
670
+ setTimeout(() => {
671
+ this.updatePosition();
672
+ this.columnsCmp?.scrollSelectedIntoView();
673
+ this.columnsCmp?.focusFirstColumn();
674
+ document.addEventListener('pointerdown', this.outsideClickHandler, true);
675
+ document.addEventListener('keydown', this.escapeHandler, true);
676
+ });
677
+ }
678
+ close() {
679
+ if (!this.isOpen)
680
+ return;
681
+ this.isOpen = false;
682
+ this.closed.emit();
683
+ this.onTouched();
684
+ this.teardown();
685
+ this.cdr.markForCheck();
686
+ }
687
+ onTriggerKeyDown(event) {
688
+ if (['ArrowDown', 'ArrowUp', 'Enter', ' '].includes(event.key) && !this.isOpen) {
689
+ event.preventDefault();
690
+ this.open();
691
+ }
692
+ }
693
+ /* ---------------- value ---------------- */
694
+ onTimeChange(parts) {
695
+ this.hour = parts.hour;
696
+ this.minute = parts.minute;
697
+ this.second = parts.second;
698
+ this.emit();
699
+ this.cdr.markForCheck();
700
+ }
701
+ emit() {
702
+ const value = this.currentValue();
703
+ this.onChange(value);
704
+ this.valueChange.emit(value);
705
+ }
706
+ currentValue() {
707
+ const parts = this.parts;
708
+ if (!parts)
709
+ return null;
710
+ if (this.valueType === 'date') {
711
+ const base = this.dateAnchor ?? new Date();
712
+ return new Date(base.getFullYear(), base.getMonth(), base.getDate(), parts.hour, parts.minute, parts.second, 0);
713
+ }
714
+ return formatTimeString(parts, this.showSeconds);
715
+ }
716
+ updatePosition() {
717
+ const trigger = this.triggerEl?.nativeElement;
718
+ const panel = this.panelEl?.nativeElement;
719
+ if (!trigger || !panel)
720
+ return;
721
+ this.cleanup = autoUpdate(trigger, panel, () => {
722
+ computePosition(trigger, panel, {
723
+ strategy: 'fixed',
724
+ placement: 'bottom-start',
725
+ middleware: [offset(4), flip(), shift({ padding: 8 })],
726
+ }).then(({ x, y }) => {
727
+ Object.assign(panel.style, {
728
+ left: x + 'px',
729
+ top: y + 'px',
730
+ visibility: 'visible',
731
+ });
732
+ });
733
+ });
734
+ }
735
+ teardown() {
736
+ this.cleanup?.();
737
+ this.cleanup = undefined;
738
+ document.removeEventListener('pointerdown', this.outsideClickHandler, true);
739
+ document.removeEventListener('keydown', this.escapeHandler, true);
740
+ }
741
+ ngOnDestroy() {
742
+ this.teardown();
743
+ }
744
+ /* ---------------- ControlValueAccessor ---------------- */
745
+ writeValue(value) {
746
+ let parts = null;
747
+ if (value instanceof Date && !isNaN(value.getTime())) {
748
+ this.dateAnchor = value;
749
+ parts = { hour: value.getHours(), minute: value.getMinutes(), second: value.getSeconds() };
750
+ }
751
+ else if (typeof value === 'string') {
752
+ parts = parseTimeString(value);
753
+ }
754
+ this.hour = parts ? parts.hour : null;
755
+ this.minute = parts ? parts.minute : null;
756
+ this.second = parts ? parts.second : null;
757
+ this.cdr.markForCheck();
758
+ }
759
+ registerOnChange(fn) {
760
+ this.onChange = fn;
761
+ }
762
+ registerOnTouched(fn) {
763
+ this.onTouched = fn;
764
+ }
765
+ setDisabledState(isDisabled) {
766
+ this.disabled = isDisabled;
767
+ if (isDisabled)
768
+ this.close();
769
+ this.cdr.markForCheck();
770
+ }
771
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimePickerComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
772
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TimePickerComponent, isStandalone: true, selector: "tolle-time-picker", inputs: { placeholder: "placeholder", disabled: "disabled", use12Hours: "use12Hours", showSeconds: "showSeconds", minuteStep: "minuteStep", secondStep: "secondStep", min: "min", max: "max", size: "size", invalid: "invalid", ariaLabel: "ariaLabel", valueType: "valueType", class: "class" }, outputs: { valueChange: "valueChange", opened: "opened", closed: "closed" }, providers: [
773
+ {
774
+ provide: NG_VALUE_ACCESSOR,
775
+ useExisting: forwardRef(() => TimePickerComponent),
776
+ multi: true,
777
+ },
778
+ ], viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["trigger"], descendants: true }, { propertyName: "panelEl", first: true, predicate: ["panel"], descendants: true }, { propertyName: "columnsCmp", first: true, predicate: ["columns"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
779
+ <button
780
+ #trigger
781
+ type="button"
782
+ aria-haspopup="dialog"
783
+ [attr.aria-expanded]="isOpen"
784
+ [attr.aria-controls]="isOpen ? panelId : null"
785
+ [attr.aria-label]="ariaLabel || null"
786
+ [attr.data-state]="isOpen ? 'open' : 'closed'"
787
+ [disabled]="disabled"
788
+ [class]="computedTriggerClass"
789
+ (click)="toggle()"
790
+ (keydown)="onTriggerKeyDown($event)"
791
+ >
792
+ <span [class]="cn('truncate', displayValue ? 'text-foreground' : 'text-muted-foreground')">
793
+ {{ displayValue || placeholder }}
794
+ </span>
795
+ <i class="ri-time-line shrink-0 text-muted-foreground" aria-hidden="true"></i>
796
+ </button>
797
+
798
+ <div
799
+ *ngIf="isOpen"
800
+ #panel
801
+ role="dialog"
802
+ [id]="panelId"
803
+ [attr.aria-label]="ariaLabel || 'Choose a time'"
804
+ class="fixed left-0 top-0 z-[9999]"
805
+ style="visibility: hidden"
806
+ >
807
+ <div class="rounded-md border border-border bg-popover p-2 text-popover-foreground shadow-md">
808
+ <tolle-time-columns
809
+ #columns
810
+ [hour]="hour"
811
+ [minute]="minute"
812
+ [second]="second"
813
+ [use12Hours]="use12Hours"
814
+ [showSeconds]="showSeconds"
815
+ [minuteStep]="minuteStep"
816
+ [secondStep]="secondStep"
817
+ [minSeconds]="minSeconds"
818
+ [maxSeconds]="maxSeconds"
819
+ [size]="size"
820
+ (timeChange)="onTimeChange($event)"
821
+ ></tolle-time-columns>
822
+ </div>
823
+ </div>
824
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TimeColumnsComponent, selector: "tolle-time-columns", inputs: ["hour", "minute", "second", "use12Hours", "showSeconds", "minuteStep", "secondStep", "minSeconds", "maxSeconds", "size", "class"], outputs: ["timeChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
825
+ }
826
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimePickerComponent, decorators: [{
827
+ type: Component,
828
+ args: [{ selector: 'tolle-time-picker', standalone: true, imports: [CommonModule, TimeColumnsComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
829
+ {
830
+ provide: NG_VALUE_ACCESSOR,
831
+ useExisting: forwardRef(() => TimePickerComponent),
832
+ multi: true,
833
+ },
834
+ ], template: `
835
+ <button
836
+ #trigger
837
+ type="button"
838
+ aria-haspopup="dialog"
839
+ [attr.aria-expanded]="isOpen"
840
+ [attr.aria-controls]="isOpen ? panelId : null"
841
+ [attr.aria-label]="ariaLabel || null"
842
+ [attr.data-state]="isOpen ? 'open' : 'closed'"
843
+ [disabled]="disabled"
844
+ [class]="computedTriggerClass"
845
+ (click)="toggle()"
846
+ (keydown)="onTriggerKeyDown($event)"
847
+ >
848
+ <span [class]="cn('truncate', displayValue ? 'text-foreground' : 'text-muted-foreground')">
849
+ {{ displayValue || placeholder }}
850
+ </span>
851
+ <i class="ri-time-line shrink-0 text-muted-foreground" aria-hidden="true"></i>
852
+ </button>
853
+
854
+ <div
855
+ *ngIf="isOpen"
856
+ #panel
857
+ role="dialog"
858
+ [id]="panelId"
859
+ [attr.aria-label]="ariaLabel || 'Choose a time'"
860
+ class="fixed left-0 top-0 z-[9999]"
861
+ style="visibility: hidden"
862
+ >
863
+ <div class="rounded-md border border-border bg-popover p-2 text-popover-foreground shadow-md">
864
+ <tolle-time-columns
865
+ #columns
866
+ [hour]="hour"
867
+ [minute]="minute"
868
+ [second]="second"
869
+ [use12Hours]="use12Hours"
870
+ [showSeconds]="showSeconds"
871
+ [minuteStep]="minuteStep"
872
+ [secondStep]="secondStep"
873
+ [minSeconds]="minSeconds"
874
+ [maxSeconds]="maxSeconds"
875
+ [size]="size"
876
+ (timeChange)="onTimeChange($event)"
877
+ ></tolle-time-columns>
878
+ </div>
879
+ </div>
880
+ `, styles: [":host{display:block}\n"] }]
881
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { placeholder: [{
882
+ type: Input
883
+ }], disabled: [{
884
+ type: Input
885
+ }], use12Hours: [{
886
+ type: Input
887
+ }], showSeconds: [{
888
+ type: Input
889
+ }], minuteStep: [{
890
+ type: Input
891
+ }], secondStep: [{
892
+ type: Input
893
+ }], min: [{
894
+ type: Input
895
+ }], max: [{
896
+ type: Input
897
+ }], size: [{
898
+ type: Input
899
+ }], invalid: [{
900
+ type: Input
901
+ }], ariaLabel: [{
902
+ type: Input
903
+ }], valueType: [{
904
+ type: Input
905
+ }], class: [{
906
+ type: Input
907
+ }], valueChange: [{
908
+ type: Output
909
+ }], opened: [{
910
+ type: Output
911
+ }], closed: [{
912
+ type: Output
913
+ }], triggerEl: [{
914
+ type: ViewChild,
915
+ args: ['trigger']
916
+ }], panelEl: [{
917
+ type: ViewChild,
918
+ args: ['panel']
919
+ }], columnsCmp: [{
920
+ type: ViewChild,
921
+ args: ['columns']
922
+ }] } });
923
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZS1waWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdG9sbGUvc3JjL2xpYi90aW1lLXBpY2tlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQWMsU0FBUyxFQUFFLFlBQVksRUFBZ0MsdUJBQXVCLEVBQXdDLE1BQU0sZUFBZSxDQUFDO0FBQ3JOLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekUsT0FBTyxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNwRixPQUFPLEVBQUUsR0FBRyxFQUFxQixNQUFNLDBCQUEwQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxZQUFZLENBQUM7OztBQWtCaEMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFTLEVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFbkUsNERBQTREO0FBQzVELE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxLQUFnQjtJQUNqRCxPQUFPLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsRUFBRSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7QUFDOUQsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsS0FBZ0M7SUFDOUQsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDM0MsTUFBTSxLQUFLLEdBQUcsc0NBQXNDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3hFLElBQUksQ0FBQyxLQUFLO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFFeEIsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzlCLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoQyxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUU3RCxJQUFJLElBQUksR0FBRyxFQUFFLElBQUksTUFBTSxHQUFHLEVBQUUsSUFBSSxNQUFNLEdBQUcsRUFBRTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ3pELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDO0FBQ2xDLENBQUM7QUFFRCw4RUFBOEU7QUFDOUUsTUFBTSxVQUFVLGdCQUFnQixDQUFDLEtBQWdCLEVBQUUsV0FBVyxHQUFHLEtBQUs7SUFDcEUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN6RCxPQUFPLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDOUQsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQUMsTUFBYztJQUNyQyxNQUFNLFFBQVEsR0FBZ0IsTUFBTSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDeEQsTUFBTSxNQUFNLEdBQUcsTUFBTSxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztJQUNwRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxDQUFDO0FBQzlCLENBQUM7QUFFRCw4RUFBOEU7QUFDOUUsTUFBTSxVQUFVLFVBQVUsQ0FBQyxNQUFjLEVBQUUsUUFBcUI7SUFDOUQsTUFBTSxJQUFJLEdBQUcsTUFBTSxHQUFHLEVBQUUsQ0FBQyxDQUFDLDhCQUE4QjtJQUN4RCxPQUFPLFFBQVEsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUM5QyxDQUFDO0FBZ0NELE1BQU0sZUFBZSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFFbEMsTUFBTSxrQkFBa0IsR0FBRyxHQUFHLENBQzVCLHNHQUFzRztJQUNwRyx1RkFBdUYsRUFDekY7SUFDRSxRQUFRLEVBQUU7UUFDUixJQUFJLEVBQUU7WUFDSixFQUFFLEVBQUUsc0JBQXNCO1lBQzFCLEVBQUUsRUFBRSxrQkFBa0I7WUFDdEIsT0FBTyxFQUFFLG9CQUFvQjtZQUM3QixFQUFFLEVBQUUsb0JBQW9CO1NBQ3pCO1FBQ0QsUUFBUSxFQUFFO1lBQ1IsSUFBSSxFQUFFLHFEQUFxRDtZQUMzRCxLQUFLLEVBQUUsOERBQThEO1NBQ3RFO0tBQ0Y7SUFDRCxlQUFlLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUU7Q0FDdEQsQ0FDRixDQUFDO0FBS0Y7Ozs7Ozs7O0dBUUc7QUFtREgsTUFBTSxPQUFPLG9CQUFvQjtJQTJDWDtJQTFDcEIseUZBQXlGO0lBQ2hGLElBQUksR0FBa0IsSUFBSSxDQUFDO0lBQ3BDLDJFQUEyRTtJQUNsRSxNQUFNLEdBQWtCLElBQUksQ0FBQztJQUN0QywyRUFBMkU7SUFDbEUsTUFBTSxHQUFrQixJQUFJLENBQUM7SUFDdEMsd0VBQXdFO0lBQy9ELFVBQVUsR0FBRyxLQUFLLENBQUM7SUFDNUIsOENBQThDO0lBQ3JDLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFDN0IsOERBQThEO0lBQ3JELFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDeEIsOERBQThEO0lBQ3JELFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDeEIsc0VBQXNFO0lBQzdELFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDeEIsd0VBQXdFO0lBQy9ELFVBQVUsR0FBRyxlQUFlLEdBQUcsQ0FBQyxDQUFDO0lBQzFDLGtFQUFrRTtJQUN6RCxJQUFJLEdBQTZCLFNBQVMsQ0FBQztJQUNwRCxrRkFBa0Y7SUFDekUsS0FBSyxHQUFHLEVBQUUsQ0FBQztJQUVwQix5RUFBeUU7SUFDL0QsVUFBVSxHQUFHLElBQUksWUFBWSxFQUFhLENBQUM7SUFFNUIsU0FBUyxDQUFzQztJQUUvRCxTQUFTLEdBQUcsV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUUzRTs7Ozs7T0FLRztJQUNILE9BQU8sR0FBaUIsRUFBRSxDQUFDO0lBQzNCLG1FQUFtRTtJQUNuRSxXQUFXLEdBQWEsRUFBRSxDQUFDO0lBRWpCLEVBQUUsR0FBRyxFQUFFLENBQUM7SUFFbEIsWUFBb0IsR0FBc0I7UUFBdEIsUUFBRyxHQUFILEdBQUcsQ0FBbUI7SUFBRyxDQUFDO0lBRTlDLFFBQVE7UUFDTixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNO1lBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRWYsbUVBQW1FO1FBQ25FLHVEQUF1RDtRQUN2RCxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFRCxJQUFJLFdBQVc7UUFDYixRQUFRLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNsQixLQUFLLElBQUk7Z0JBQ1AsT0FBTyxlQUFlLENBQUM7WUFDekIsS0FBSyxJQUFJO2dCQUNQLE9BQU8sZUFBZSxDQUFDO1lBQ3pCLEtBQUssSUFBSTtnQkFDUCxPQUFPLGVBQWUsQ0FBQztZQUN6QjtnQkFDRSxPQUFPLGVBQWUsQ0FBQztRQUMzQixDQUFDO0lBQ0gsQ0FBQztJQUVELHlEQUF5RDtJQUVqRCxPQUFPO1FBQ2IsTUFBTSxJQUFJLEdBQUcsQ0FBQyxLQUFhLEVBQUUsUUFBZ0IsRUFBRSxFQUFFLENBQy9DLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO1FBRXRFLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzVDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzVDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDO1FBQ3pDLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQyxRQUFRLENBQUM7UUFFbEQseUVBQXlFO1FBQ3pFLGlFQUFpRTtRQUNqRSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNoRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU3QyxNQUFNLE9BQU8sR0FBaUIsRUFBRSxDQUFDO1FBRWpDLFFBQVE7UUFDUixNQUFNLFdBQVcsR0FBaUIsRUFBRSxDQUFDO1FBQ3JDLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3BCLG1DQUFtQztZQUNuQyxNQUFNLEtBQUssR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdEQsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztnQkFDekIsTUFBTSxHQUFHLEdBQUcsVUFBVSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDdkMsV0FBVyxDQUFDLElBQUksQ0FBQztvQkFDZixFQUFFLEVBQUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLEdBQUcsSUFBSTtvQkFDcEMsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUM7b0JBQ2pCLEdBQUc7b0JBQ0gsSUFBSTtvQkFDSixRQUFRLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEdBQUcsSUFBSSxFQUFFLFFBQVEsQ0FBQztpQkFDbkQsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7YUFBTSxDQUFDO1lBQ04sS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUM1QixXQUFXLENBQUMsSUFBSSxDQUFDO29CQUNmLEVBQUUsRUFBRSxJQUFJLENBQUMsU0FBUyxHQUFHLFFBQVEsR0FBRyxDQUFDO29CQUNqQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztvQkFDZCxHQUFHLEVBQUUsQ0FBQztvQkFDTixJQUFJLEVBQUUsQ0FBQztvQkFDUCxRQUFRLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLEdBQUcsSUFBSSxFQUFFLFFBQVEsQ0FBQztpQkFDakQsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBRXBFLFVBQVU7UUFDVixNQUFNLGFBQWEsR0FBaUIsRUFBRSxDQUFDO1FBQ3ZDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ3hDLE1BQU0sS0FBSyxHQUFHLGFBQWEsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUM1QyxhQUFhLENBQUMsSUFBSSxDQUFDO2dCQUNqQixFQUFFLEVBQUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFVLEdBQUcsQ0FBQztnQkFDbkMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ2QsR0FBRyxFQUFFLENBQUM7Z0JBQ04sSUFBSSxFQUFFLENBQUM7Z0JBQ1AsUUFBUSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQzthQUNoRCxDQUFDLENBQUM7UUFDTCxDQUFDO1FBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLENBQUMsQ0FBQztRQUV2RSxVQUFVO1FBQ1YsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDckIsTUFBTSxhQUFhLEdBQWlCLEVBQUUsQ0FBQztZQUN2QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsSUFBSSxVQUFVLEVBQUUsQ0FBQztnQkFDeEMsTUFBTSxFQUFFLEdBQUcsYUFBYSxHQUFHLElBQUksR0FBRyxlQUFlLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDM0QsYUFBYSxDQUFDLElBQUksQ0FBQztvQkFDakIsRUFBRSxFQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsVUFBVSxHQUFHLENBQUM7b0JBQ25DLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO29CQUNkLEdBQUcsRUFBRSxDQUFDO29CQUNOLElBQUksRUFBRSxDQUFDO29CQUNQLFFBQVEsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7aUJBQ3BDLENBQUMsQ0FBQztZQUNMLENBQUM7WUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxhQUFhLEVBQUUsQ0FBQyxDQUFDO1FBQ3pFLENBQUM7UUFFRCxXQUFXO1FBQ1gsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDcEIsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDLE1BQU0sQ0FBQztZQUM5QyxNQUFNLGVBQWUsR0FBa0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUN6RSxNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNsQyxNQUFNLFNBQVMsR0FBRyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUM7Z0JBQzdDLE9BQU87b0JBQ0wsRUFBRSxFQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsWUFBWSxHQUFHLENBQUM7b0JBQ3JDLEtBQUssRUFBRSxDQUFDO29CQUNSLEdBQUc7b0JBQ0gsSUFBSSxFQUFFLENBQUMsRUFBRSxpQkFBaUI7b0JBQzFCLFFBQVEsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxFQUFFLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQztpQkFDdkQsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLENBQUMsQ0FBQztRQUMvRSxDQUFDO1FBRUQsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7SUFDL0IsQ0FBQztJQUVEOzs7T0FHRztJQUNLLGFBQWEsQ0FBQyxLQUFhLEVBQUUsSUFBWTtRQUMvQyxPQUFPLEtBQUssR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUNuRSxDQUFDO0lBRU8scUJBQXFCO1FBQzNCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUM3QyxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4RSxJQUFJLEdBQUcsSUFBSSxDQUFDO2dCQUFFLE9BQU8sR0FBRyxDQUFDO1lBQ3pCLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNsRSxPQUFPLFlBQVksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGlEQUFpRDtJQUVqRCxVQUFVLENBQUMsTUFBa0IsRUFBRSxNQUFrQjtRQUMvQyxRQUFRLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNwQixLQUFLLE1BQU07Z0JBQ1QsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUk7b0JBQUUsT0FBTyxLQUFLLENBQUM7Z0JBQ3JDLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEtBQUssTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxNQUFNLENBQUMsSUFBSSxDQUFDO1lBQ2xHLEtBQUssUUFBUTtnQkFDWCxPQUFPLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssTUFBTSxDQUFDLElBQUksQ0FBQztZQUM3RCxLQUFLLFFBQVE7Z0JBQ1gsT0FBTyxJQUFJLENBQUMsTUFBTSxLQUFLLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxJQUFJLENBQUM7WUFDN0QsS0FBSyxVQUFVO2dCQUNiLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJO29CQUFFLE9BQU8sS0FBSyxDQUFDO2dCQUNyQyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLE1BQU0sQ0FBQyxJQUFJLENBQUM7UUFDM0UsQ0FBQztJQUNILENBQUM7SUFFRCxRQUFRLENBQUMsV0FBbUIsRUFBRSxNQUFrQjtRQUM5QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFDMUIsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUMsS0FBSyxNQUFNLENBQUM7SUFDbEUsQ0FBQztJQUVELG1CQUFtQixDQUFDLFdBQW1CO1FBQ3JDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDekMsT0FBTyxNQUFNLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUMsRUFBRSxFQUFFLElBQUksSUFBSSxDQUFDO0lBQ3BFLENBQUM7SUFFRCxXQUFXLENBQUMsTUFBa0IsRUFBRSxNQUFrQixFQUFFLFdBQW1CO1FBQ3JFLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2pELE9BQU8sRUFBRSxDQUNQLGtCQUFrQixDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7UUFDakQseUVBQXlFO1FBQ3pFLGdFQUFnRTtRQUNoRSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsSUFBSSxrQ0FBa0MsQ0FDdEYsQ0FBQztJQUNKLENBQUM7SUFFRCx5RUFBeUU7SUFDekUsTUFBTSxDQUFDLE1BQWtCLEVBQUUsTUFBa0IsRUFBRSxXQUFtQjtRQUNoRSxJQUFJLE1BQU0sQ0FBQyxRQUFRO1lBQUUsT0FBTztRQUU1QixNQUFNLElBQUksR0FBYztZQUN0QixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDO1lBQ3BCLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUM7WUFDeEIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQztTQUN6QixDQUFDO1FBRUYsUUFBUSxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDcEIsS0FBSyxNQUFNLENBQUM7WUFDWixLQUFLLFVBQVU7Z0JBQ2IsSUFBSSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDO2dCQUN2QixNQUFNO1lBQ1IsS0FBSyxRQUFRO2dCQUNYLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQztnQkFDekIsTUFBTTtZQUNSLEtBQUssUUFBUTtnQkFDWCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUM7Z0JBQ3pCLE1BQU07UUFDVixDQUFDO1FBRUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFRCxnREFBZ0Q7SUFFaEQsZUFBZSxDQUFDLEtBQW9CLEVBQUUsV0FBbUI7UUFDdkQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUN6QyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU87UUFFcEIsUUFBUSxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDbEIsS0FBSyxXQUFXO2dCQUNkLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ2hDLE1BQU07WUFDUixLQUFLLFNBQVM7Z0JBQ1osS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNqQyxNQUFNO1lBQ1IsS0FBSyxNQUFNO2dCQUNULEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNsQyxNQUFNO1lBQ1IsS0FBSyxLQUFLO2dCQUNSLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNELE1BQU07WUFDUixLQUFLLFdBQVc7Z0JBQ2QsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDbEMsTUFBTTtZQUNSLEtBQUssWUFBWTtnQkFDZixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUNsQyxNQUFNO1lBQ1IsS0FBSyxPQUFPLENBQUM7WUFDYixLQUFLLEdBQUc7Z0JBQ04sS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN2QixDQUFDO29CQUNDLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO29CQUM3RCxJQUFJLE1BQU07d0JBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDO2dCQUN2RCxDQUFDO2dCQUNELE1BQU07WUFDUjtnQkFDRSxPQUFPO1FBQ1gsQ0FBQztJQUNILENBQUM7SUFFTyxVQUFVLENBQUMsV0FBbUIsRUFBRSxLQUFhO1FBQ25ELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLE9BQU8sR0FBRyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVELGdGQUFnRjtJQUN4RSxTQUFTLENBQUMsV0FBbUIsRUFBRSxLQUFhLEVBQUUsU0FBaUI7UUFDckUsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUN6QyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU87UUFFcEIsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoRSxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUM7WUFDbkMsQ0FBQyxJQUFJLFNBQVMsQ0FBQztZQUNmLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNO2dCQUFFLE9BQU8sQ0FBQyw0QkFBNEI7UUFDL0UsQ0FBQztRQUVELElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRU8sV0FBVyxDQUFDLFdBQW1CO1FBQ3JDLElBQUksV0FBVyxHQUFHLENBQUMsSUFBSSxXQUFXLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNO1lBQUUsT0FBTztRQUNsRSxJQUFJLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDMUQsQ0FBQztJQUVELDREQUE0RDtJQUM1RCxnQkFBZ0I7UUFDZCxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3RCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsc0JBQXNCO1FBQ3BCLElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDOUIsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLGFBQWEsQ0FBQztZQUMvQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLHdCQUF3QixDQUF1QixDQUFDO1lBQ3BGLElBQUksQ0FBQyxRQUFRO2dCQUFFLE9BQU87WUFDdEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO1FBQzFGLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLG9CQUFvQixDQUFDLFdBQW1CLEVBQUUsV0FBbUI7UUFDbkUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsV0FBVyxDQUFDLEVBQUUsYUFBYSxDQUFDO1FBQzdELElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUNsQixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBNEIsQ0FBQztRQUNqRSxJQUFJLENBQUMsRUFBRTtZQUFFLE9BQU87UUFFaEIsSUFBSSxFQUFFLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUM7UUFDaEMsQ0FBQzthQUFNLElBQUksRUFBRSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQy9FLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7UUFDdEUsQ0FBQztJQUNILENBQUM7SUFFRCxXQUFXLEdBQUcsQ0FBQyxDQUFTLEVBQUUsTUFBa0IsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUM3RCxXQUFXLEdBQUcsQ0FBQyxDQUFTLEVBQUUsTUFBa0IsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQzt3R0FsV2hELG9CQUFvQjs0RkFBcEIsb0JBQW9CLDZkQTVDckI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBDVCwrRkE1Q1MsWUFBWTs7NEZBOENYLG9CQUFvQjtrQkFsRGhDLFNBQVM7K0JBQ0Usb0JBQW9CLGNBRWxCLElBQUksV0FDUCxDQUFDLFlBQVksQ0FBQyxtQkFDTix1QkFBdUIsQ0FBQyxNQUFNLFlBQ3JDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwQ1Q7c0ZBSVEsSUFBSTtzQkFBWixLQUFLO2dCQUVHLE1BQU07c0JBQWQsS0FBSztnQkFFRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsVUFBVTtzQkFBbEIsS0FBSztnQkFFRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBRUcsVUFBVTtzQkFBbEIsS0FBSztnQkFFRyxVQUFVO3NCQUFsQixLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBRUcsSUFBSTtzQkFBWixLQUFLO2dCQUVHLEtBQUs7c0JBQWIsS0FBSztnQkFHSSxVQUFVO3NCQUFuQixNQUFNO2dCQUVrQixTQUFTO3NCQUFqQyxZQUFZO3VCQUFDLFNBQVM7O0FBMFV6Qjs7d0VBRXdFO0FBRXhFLE1BQU0seUJBQXlCLEdBQUcsR0FBRyxDQUNuQywwSUFBMEk7SUFDeEkscUdBQXFHO0lBQ3JHLGlEQUFpRCxFQUNuRDtJQUNFLFFBQVEsRUFBRTtRQUNSLElBQUksRUFBRTtZQUNKLEVBQUUsRUFBRSxrQkFBa0I7WUFDdEIsRUFBRSxFQUFFLGtCQUFrQjtZQUN0QixPQUFPLEVBQUUsbUJBQW1CO1lBQzVCLEVBQUUsRUFBRSxxQkFBcUI7U0FDMUI7UUFDRCxPQUFPLEVBQUU7WUFDUCxJQUFJLEVBQUUsMEZBQTBGO1lBQ2hHLEtBQUssRUFBRSxFQUFFO1NBQ1Y7S0FDRjtJQUNELGVBQWUsRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRTtDQUNyRCxDQUNGLENBQUM7QUFLRjs7Ozs7Ozs7Ozs7OztHQWFHO0FBOERILE1BQU0sT0FBTyxtQkFBbUI7SUFnRVY7SUE5RHBCOzs7O09BSUc7SUFDSCxXQUFXO1FBQ1QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQsbUZBQW1GO0lBQzFFLFdBQVcsR0FBRyxlQUFlLENBQUM7SUFDdkMsMkNBQTJDO0lBQ2xDLFFBQVEsR0FBRyxLQUFLLENBQUM7SUFDMUIsbUdBQW1HO0lBQzFGLFVBQVUsR0FBRyxLQUFLLENBQUM7SUFDNUIsaUVBQWlFO0lBQ3hELFdBQVcsR0FBRyxLQUFLLENBQUM7SUFDN0IsOERBQThEO0lBQ3JELFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDeEIsOERBQThEO0lBQ3JELFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDeEIsMEZBQTBGO0lBQ2pGLEdBQUcsQ0FBVTtJQUN0QixzRkFBc0Y7SUFDN0UsR0FBRyxDQUFVO0lBQ3RCLDBFQUEwRTtJQUNqRSxJQUFJLEdBQTRCLFNBQVMsQ0FBQztJQUNuRCxvRUFBb0U7SUFDM0QsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUN6Qiw2RUFBNkU7SUFDcEUsU0FBUyxHQUFHLEVBQUUsQ0FBQztJQUN4QixxR0FBcUc7SUFDNUYsU0FBUyxHQUFzQixRQUFRLENBQUM7SUFDakQsNkVBQTZFO0lBQ3BFLEtBQUssR0FBRyxFQUFFLENBQUM7SUFFcEIsd0RBQXdEO0lBQzlDLFdBQVcsR0FBRyxJQUFJLFlBQVksRUFBd0IsQ0FBQztJQUNqRSxvQ0FBb0M7SUFDMUIsTUFBTSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7SUFDNUMscUNBQXFDO0lBQzNCLE1BQU0sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO0lBRXRCLFNBQVMsQ0FBMkI7SUFDdEMsT0FBTyxDQUEyQjtJQUNoQyxVQUFVLENBQXdCO0lBRS9DLE9BQU8sR0FBRyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFFbEYsSUFBSSxHQUFrQixJQUFJLENBQUM7SUFDM0IsTUFBTSxHQUFrQixJQUFJLENBQUM7SUFDN0IsTUFBTSxHQUFrQixJQUFJLENBQUM7SUFDN0IsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUVMLEVBQUUsR0FBRyxFQUFFLENBQUM7SUFFVixPQUFPLENBQWM7SUFDN0IscUZBQXFGO0lBQzdFLFVBQVUsR0FBZ0IsSUFBSSxDQUFDO0lBQy9CLFFBQVEsR0FBMEMsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDO0lBQzNELFNBQVMsR0FBZSxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7SUFFekMsWUFBb0IsR0FBc0I7UUFBdEIsUUFBRyxHQUFILEdBQUcsQ0FBbUI7SUFBRyxDQUFDO0lBRTdCLG1CQUFtQixHQUFHLENBQUMsS0FBaUIsRUFBRSxFQUFFO1FBQzNELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFjLENBQUM7UUFDcEMsSUFDRSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsYUFBYSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7WUFDL0MsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLGFBQWEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQzdDLENBQUM7WUFDRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQyxDQUFDO0lBRWUsYUFBYSxHQUFHLENBQUMsS0FBb0IsRUFBRSxFQUFFO1FBQ3hELElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxRQUFRLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzFDLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsU0FBUyxFQUFFLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN4QyxDQUFDO0lBQ0gsQ0FBQyxDQUFDO0lBRUYsK0NBQStDO0lBRS9DLDRFQUE0RTtJQUM1RSxJQUFJLEtBQUs7UUFDUCxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQzVELE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztJQUM1RSxDQUFDO0lBRUQsSUFBSSxZQUFZO1FBQ2QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUN6QixJQUFJLENBQUMsS0FBSztZQUFFLE9BQU8sRUFBRSxDQUFDO1FBRXRCLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3BCLE1BQU0sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNsRCxNQUFNLElBQUksR0FDUixNQUFNLENBQUMsTUFBTSxDQUFDO2dCQUNkLEdBQUc7Z0JBQ0gsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7Z0JBQ2xCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3JELE9BQU8sSUFBSSxHQUFHLEdBQUcsR0FBRyxRQUFRLENBQUM7UUFDL0IsQ0FBQztRQUNELE9BQU8sZ0JBQWdCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQsSUFBSSxVQUFVO1FBQ1osTUFBTSxNQUFNLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QyxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQsSUFBSSxVQUFVO1FBQ1osTUFBTSxNQUFNLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QyxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGVBQWUsR0FBRyxDQUFDLENBQUM7SUFDbkUsQ0FBQztJQUVELElBQUksb0JBQW9CO1FBQ3RCLE9BQU8sRUFBRSxDQUFDLHlCQUF5QixDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMvRixDQUFDO0lBRUQsb0RBQW9EO0lBRXBELE1BQU07UUFDSixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMzQyxDQUFDO0lBRUQsSUFBSTtRQUNGLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU87UUFDekMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7UUFDbkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBRXhCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDdEIsSUFBSSxDQUFDLFVBQVUsRUFBRSxzQkFBc0IsRUFBRSxDQUFDO1lBQzFDLElBQUksQ0FBQyxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQztZQUNwQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUN6RSxRQUFRLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDakUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsS0FBSztRQUNILElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU87UUFDekIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7UUFDcEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDakIsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2hCLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVELGdCQUFnQixDQUFDLEtBQW9CO1FBQ25DLElBQUksQ0FBQyxXQUFXLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQy9FLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVELDZDQUE2QztJQUU3QyxZQUFZLENBQUMsS0FBZ0I7UUFDM0IsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUMzQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDM0IsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ1osSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRU8sSUFBSTtRQUNWLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNsQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQy9CLENBQUM7SUFFTyxZQUFZO1FBQ2xCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDekIsSUFBSSxDQUFDLEtBQUs7WUFBRSxPQUFPLElBQUksQ0FBQztRQUN4QixJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDOUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLElBQUksRUFBRSxDQUFDO1lBQzNDLE9BQU8sSUFBSSxJQUFJLENBQ2IsSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUNsQixJQUFJLENBQUMsUUFBUSxFQUFFLEVBQ2YsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUNkLEtBQUssQ0FBQyxJQUFJLEVBQ1YsS0FBSyxDQUFDLE1BQU0sRUFDWixLQUFLLENBQUMsTUFBTSxFQUNaLENBQUMsQ0FDRixDQUFDO1FBQ0osQ0FBQztRQUNELE9BQU8sZ0JBQWdCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRU8sY0FBYztRQUNwQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLGFBQWEsQ0FBQztRQUM5QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLGFBQWEsQ0FBQztRQUMxQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsS0FBSztZQUFFLE9BQU87UUFFL0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxVQUFVLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUU7WUFDN0MsZUFBZSxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUU7Z0JBQzlCLFFBQVEsRUFBRSxPQUFPO2dCQUNqQixTQUFTLEVBQUUsY0FBYztnQkFDekIsVUFBVSxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLEtBQUssQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ3ZELENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFO2dCQUNuQixNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUU7b0JBQ3pCLElBQUksRUFBRSxDQUFDLEdBQUcsSUFBSTtvQkFDZCxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUk7b0JBQ2IsVUFBVSxFQUFFLFNBQVM7aUJBQ3RCLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sUUFBUTtRQUNkLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDO1FBQ3pCLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzVFLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNsQixDQUFDO0lBRUQsNERBQTREO0lBRTVELFVBQVUsQ0FBQyxLQUF1QztRQUNoRCxJQUFJLEtBQUssR0FBcUIsSUFBSSxDQUFDO1FBRW5DLElBQUksS0FBSyxZQUFZLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ3JELElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1lBQ3hCLEtBQUssR0FBRyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxVQUFVLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUM7UUFDN0YsQ0FBQzthQUFNLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDckMsS0FBSyxHQUFHLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqQyxDQUFDO1FBRUQsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUN0QyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQzFDLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDMUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQsZ0JBQWdCLENBQUMsRUFBeUM7UUFDeEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUM7SUFDckIsQ0FBQztJQUVELGlCQUFpQixDQUFDLEVBQWM7UUFDOUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVELGdCQUFnQixDQUFDLFVBQW1CO1FBQ2xDLElBQUksQ0FBQyxRQUFRLEdBQUcsVUFBVSxDQUFDO1FBQzNCLElBQUksVUFBVTtZQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzFCLENBQUM7d0dBOVBVLG1CQUFtQjs0RkFBbkIsbUJBQW1CLCthQXZEbkI7WUFDVDtnQkFDRSxPQUFPLEVBQUUsaUJBQWlCO2dCQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLG1CQUFtQixDQUFDO2dCQUNsRCxLQUFLLEVBQUUsSUFBSTthQUNaO1NBQ0YsZ1VBQ1M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4Q1QsK0ZBdkRTLFlBQVksbUlBblpYLG9CQUFvQjs7NEZBNGNwQixtQkFBbUI7a0JBN0QvQixTQUFTOytCQUNFLG1CQUFtQixjQUVqQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLEVBQUUsb0JBQW9CLENBQUMsbUJBQzVCLHVCQUF1QixDQUFDLE1BQU0sYUFDcEM7d0JBQ1Q7NEJBQ0UsT0FBTyxFQUFFLGlCQUFpQjs0QkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsb0JBQW9CLENBQUM7NEJBQ2xELEtBQUssRUFBRSxJQUFJO3lCQUNaO3FCQUNGLFlBQ1M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4Q1Q7c0ZBY1EsV0FBVztzQkFBbkIsS0FBSztnQkFFRyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBRUcsV0FBVztzQkFBbkIsS0FBSztnQkFFRyxVQUFVO3NCQUFsQixLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBRUcsR0FBRztzQkFBWCxLQUFLO2dCQUVHLEdBQUc7c0JBQVgsS0FBSztnQkFFRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsT0FBTztzQkFBZixLQUFLO2dCQUVHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRUcsU0FBUztzQkFBakIsS0FBSztnQkFFRyxLQUFLO3NCQUFiLEtBQUs7Z0JBR0ksV0FBVztzQkFBcEIsTUFBTTtnQkFFRyxNQUFNO3NCQUFmLE1BQU07Z0JBRUcsTUFBTTtzQkFBZixNQUFNO2dCQUVlLFNBQVM7c0JBQTlCLFNBQVM7dUJBQUMsU0FBUztnQkFDQSxPQUFPO3NCQUExQixTQUFTO3VCQUFDLE9BQU87Z0JBQ0ksVUFBVTtzQkFBL0IsU0FBUzt1QkFBQyxTQUFTIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIGZvcndhcmRSZWYsIEVsZW1lbnRSZWYsIFZpZXdDaGlsZCwgVmlld0NoaWxkcmVuLCBRdWVyeUxpc3QsIENoYW5nZURldGVjdG9yUmVmLCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgT25EZXN0cm95LCBPbkluaXQsIE9uQ2hhbmdlcywgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgY29tcHV0ZVBvc2l0aW9uLCBmbGlwLCBzaGlmdCwgb2Zmc2V0LCBhdXRvVXBkYXRlIH0gZnJvbSAnQGZsb2F0aW5nLXVpL2RvbSc7XG5pbXBvcnQgeyBjdmEsIHR5cGUgVmFyaWFudFByb3BzIH0gZnJvbSAnY2xhc3MtdmFyaWFuY2UtYXV0aG9yaXR5JztcbmltcG9ydCB7IGNuIH0gZnJvbSAnLi91dGlscy9jbic7XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqXG4gKiBQdXJlIHRpbWUgaGVscGVyc1xuICpcbiAqIFRoZSB3aXJlIGZvcm1hdCBpcyBhIDI0LWhvdXIgYEhIOm1tYCAvIGBISDptbTpzc2Agc3RyaW5nLiBJdCBpc1xuICogdGltZXpvbmUtZnJlZSBhbmQgc3RhYmxlIGFjcm9zcyBzZXJpYWxpc2F0aW9uLCB3aGljaCBhIGBEYXRlYCBpcyBub3Q6XG4gKiBhIGBEYXRlYCBjYXJyaWVzIGEgY2FsZW5kYXIgZGF5IGFuZCBhIFVUQyBvZmZzZXQgdGhhdCBub2JvZHkgY2hvc2Ugd2hlblxuICogYWxsIHRoZSB1c2VyIGRpZCB3YXMgcGljayBcIjI6MzAgUE1cIi5cbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKiogQSB3YWxsLWNsb2NrIHRpbWUgd2l0aCBubyBkYXRlIGFuZCBubyB0aW1lem9uZSBhdHRhY2hlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGltZVBhcnRzIHtcbiAgaG91cjogbnVtYmVyO1xuICBtaW51dGU6IG51bWJlcjtcbiAgc2Vjb25kOiBudW1iZXI7XG59XG5cbmNvbnN0IHBhZDIgPSAobjogbnVtYmVyKTogc3RyaW5nID0+IChuIDwgMTAgPyAnMCcgKyBuIDogU3RyaW5nKG4pKTtcblxuLyoqIFNlY29uZHMgZWxhcHNlZCBzaW5jZSBtaWRuaWdodCBmb3IgYSB3YWxsLWNsb2NrIHRpbWUuICovXG5leHBvcnQgZnVuY3Rpb24gdGltZVBhcnRzVG9TZWNvbmRzKHBhcnRzOiBUaW1lUGFydHMpOiBudW1iZXIge1xuICByZXR1cm4gcGFydHMuaG91ciAqIDM2MDAgKyBwYXJ0cy5taW51dGUgKiA2MCArIHBhcnRzLnNlY29uZDtcbn1cblxuLyoqXG4gKiBQYXJzZXMgYEhIOm1tYCBvciBgSEg6bW06c3NgICgyNC1ob3VyKS4gUmV0dXJucyBgbnVsbGAgZm9yIGFueXRoaW5nIHRoYXRcbiAqIGlzIG5vdCBhIHdlbGwtZm9ybWVkLCBpbi1yYW5nZSB0aW1lIOKAlCBjYWxsZXJzIHRyZWF0IHRoYXQgYXMgXCJubyB2YWx1ZVwiLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VUaW1lU3RyaW5nKHZhbHVlOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogVGltZVBhcnRzIHwgbnVsbCB7XG4gIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgbWF0Y2ggPSAvXihcXGR7MSwyfSk6KFxcZHsxLDJ9KSg/OjooXFxkezEsMn0pKT8kLy5leGVjKHZhbHVlLnRyaW0oKSk7XG4gIGlmICghbWF0Y2gpIHJldHVybiBudWxsO1xuXG4gIGNvbnN0IGhvdXIgPSBOdW1iZXIobWF0Y2hbMV0pO1xuICBjb25zdCBtaW51dGUgPSBOdW1iZXIobWF0Y2hbMl0pO1xuICBjb25zdCBzZWNvbmQgPSBtYXRjaFszXSA9PT0gdW5kZWZpbmVkID8gMCA6IE51bWJlcihtYXRjaFszXSk7XG5cbiAgaWYgKGhvdXIgPiAyMyB8fCBtaW51dGUgPiA1OSB8fCBzZWNvbmQgPiA1OSkgcmV0dXJuIG51bGw7XG4gIHJldHVybiB7IGhvdXIsIG1pbnV0ZSwgc2Vjb25kIH07XG59XG5cbi8qKiBSZW5kZXJzIGEgd2FsbC1jbG9jayB0aW1lIGFzIGBISDptbWAsIG9yIGBISDptbTpzc2Agd2hlbiBgd2l0aFNlY29uZHNgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdFRpbWVTdHJpbmcocGFydHM6IFRpbWVQYXJ0cywgd2l0aFNlY29uZHMgPSBmYWxzZSk6IHN0cmluZyB7XG4gIGNvbnN0IGJhc2UgPSBwYWQyKHBhcnRzLmhvdXIpICsgJzonICsgcGFkMihwYXJ0cy5taW51dGUpO1xuICByZXR1cm4gd2l0aFNlY29uZHMgPyBiYXNlICsgJzonICsgcGFkMihwYXJ0cy5zZWNvbmQpIDogYmFzZTtcbn1cblxuLyoqXG4gKiAyNC1ob3VyIGhvdXIgdG8gaXRzIDEyLWhvdXIgY2xvY2sgZmFjZS4gTWlkbmlnaHQgaXMgYDEyIEFNYCBhbmQgbm9vbiBpc1xuICogYDEyIFBNYCDigJQgdGhlIHR3byB2YWx1ZXMgdGhhdCBhIG5haXZlIGBob3VyICUgMTJgIGdldHMgd3JvbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0bzEySG91cihob3VyMjQ6IG51bWJlcik6IHsgaG91cjEyOiBudW1iZXI7IG1lcmlkaWVtOiAnQU0nIHwgJ1BNJyB9IHtcbiAgY29uc3QgbWVyaWRpZW06ICdBTScgfCAnUE0nID0gaG91cjI0IDwgMTIgPyAnQU0nIDogJ1BNJztcbiAgY29uc3QgaG91cjEyID0gaG91cjI0ICUgMTIgPT09IDAgPyAxMiA6IGhvdXIyNCAlIDEyO1xuICByZXR1cm4geyBob3VyMTIsIG1lcmlkaWVtIH07XG59XG5cbi8qKiAxMi1ob3VyIGNsb2NrIGZhY2UgYmFjayB0byBhIDI0LWhvdXIgaG91ci4gYDEyIEFNYCBpcyAwLCBgMTIgUE1gIGlzIDEyLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZyb20xMkhvdXIoaG91cjEyOiBudW1iZXIsIG1lcmlkaWVtOiAnQU0nIHwgJ1BNJyk6IG51bWJlciB7XG4gIGNvbnN0IGJhc2UgPSBob3VyMTIgJSAxMjsgLy8gMTIgLT4gMCwgbGVhdmVzIDEuLjExIGFsb25lXG4gIHJldHVybiBtZXJpZGllbSA9PT0gJ1BNJyA/IGJhc2UgKyAxMiA6IGJhc2U7XG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqXG4gKiBDb2x1bW4gbW9kZWxcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKiogV2hpY2ggdW5pdCBhIGNvbHVtbiBvZiB0aGUgcGlja2VyIHNjcm9sbHMgdGhyb3VnaC4gKi9cbmV4cG9ydCB0eXBlIFRpbWVDb2x1bW5LaW5kID0gJ2hvdXInIHwgJ21pbnV0ZScgfCAnc2Vjb25kJyB8ICdtZXJpZGllbSc7XG5cbi8qKiBPbmUgZW50cnkgaW5zaWRlIGEgdGltZSBjb2x1bW4uICovXG5leHBvcnQgaW50ZXJmYWNlIFRpbWVPcHRpb24ge1xuICAvKiogU3RhYmxlIGlkZW50aXR5IGZvciBgdHJhY2tCeWAgYW5kIGBhcmlhLWFjdGl2ZWRlc2NlbmRhbnRgLiAqL1xuICBpZDogc3RyaW5nO1xuICAvKiogVGV4dCBzaG93biB0byB0aGUgdXNlci4gKi9cbiAgbGFiZWw6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSAyNC1ob3VyIHZhbHVlIHRoaXMgZW50cnkgY29tbWl0cyBmb3IgaXRzIGNvbHVtbi4gRm9yIGEgYG1lcmlkaWVtYFxuICAgKiBjb2x1bW4gdGhpcyBpcyB0aGUgcmVzdWx0aW5nIDI0LWhvdXIgKmhvdXIqLlxuICAgKi9cbiAgcmF3OiBudW1iZXI7XG4gIC8qKiBWYWx1ZSB1c2VkIGZvciB0aGUgc2VsZWN0ZWQgY29tcGFyaXNvbiAoY2xvY2stZmFjZSB2YWx1ZSBmb3IgaG91cnMpLiAqL1xuICBmYWNlOiBudW1iZXI7XG4gIGRpc2FibGVkOiBib29sZWFuO1xufVxuXG4vKiogQSBzY3JvbGxhYmxlIGNvbHVtbiBvZiB0aGUgcGlja2VyLiAqL1xuZXhwb3J0IGludGVyZmFjZSBUaW1lQ29sdW1uIHtcbiAga2luZDogVGltZUNvbHVtbktpbmQ7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIG9wdGlvbnM6IFRpbWVPcHRpb25bXTtcbn1cblxuY29uc3QgU0VDT05EU19QRVJfREFZID0gMjQgKiAzNjAwO1xuXG5jb25zdCB0aW1lT3B0aW9uVmFyaWFudHMgPSBjdmEoXG4gICdmbGV4IHctZnVsbCBzaHJpbmstMCBjdXJzb3ItcG9pbnRlciBzZWxlY3Qtbm9uZSBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcm91bmRlZC1tZCB0YWJ1bGFyLW51bXMgJyArXG4gICAgJ3RyYW5zaXRpb24tY29sb3JzIGZvY3VzOm91dGxpbmUtbm9uZSBkaXNhYmxlZDpwb2ludGVyLWV2ZW50cy1ub25lIGRpc2FibGVkOm9wYWNpdHktNDAnLFxuICB7XG4gICAgdmFyaWFudHM6IHtcbiAgICAgIHNpemU6IHtcbiAgICAgICAgeHM6ICdoLTYgcHgtMiB0ZXh0LVsxMXB4XScsXG4gICAgICAgIHNtOiAnaC03IHB4LTIgdGV4dC14cycsXG4gICAgICAgIGRlZmF1bHQ6ICdoLTggcHgtMi41IHRleHQtc20nLFxuICAgICAgICBsZzogJ2gtOSBweC0zIHRleHQtYmFzZScsXG4gICAgICB9LFxuICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgdHJ1ZTogJ2JnLXByaW1hcnkgdGV4dC1wcmltYXJ5LWZvcmVncm91bmQgaG92ZXI6YmctcHJpbWFyeScsXG4gICAgICAgIGZhbHNlOiAndGV4dC1mb3JlZ3JvdW5kIGhvdmVyOmJnLWFjY2VudCBob3Zlcjp0ZXh0LWFjY2VudC1mb3JlZ3JvdW5kJyxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBkZWZhdWx0VmFyaWFudHM6IHsgc2l6ZTogJ2RlZmF1bHQnLCBzZWxlY3RlZDogZmFsc2UgfSxcbiAgfVxuKTtcblxuLyoqIFZhcmlhbnQgcHJvcHMgZm9yIHRoZSBvcHRpb24gcm93cyBpbnNpZGUgYSB0aW1lIGNvbHVtbi4gKi9cbmV4cG9ydCB0eXBlIFRpbWVDb2x1bW5zUHJvcHMgPSBWYXJpYW50UHJvcHM8dHlwZW9mIHRpbWVPcHRpb25WYXJpYW50cz47XG5cbi8qKlxuICogVGhlIGJhcmUgc2Nyb2xsYWJsZSBob3VyIC8gbWludXRlIC8gc2Vjb25kIC8gQU0tUE0gY29sdW1ucywgd2l0aCBubyB0cmlnZ2VyXG4gKiBhbmQgbm8gcG9wb3ZlciBvZiBpdHMgb3duLlxuICpcbiAqIGB0b2xsZS10aW1lLXBpY2tlcmAgd3JhcHMgdGhpcyBpbiBhIGZsb2F0aW5nIHBhbmVsLCBhbmRcbiAqIGB0b2xsZS1kYXRlLXRpbWUtcGlja2VyYCBzaXRzIGl0IGJlc2lkZSBhIGNhbGVuZGFyIOKAlCBzbyB0aGUgb3B0aW9uXG4gKiBnZW5lcmF0aW9uLCB0aGUgbWluL21heCBkaXNhYmxpbmcgYW5kIHRoZSByb3Zpbmcga2V5Ym9hcmQgbW9kZWwgbGl2ZSBoZXJlXG4gKiBvbmNlIGluc3RlYWQgb2YgaW4gYm90aC5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtdGltZS1jb2x1bW5zJyxcbiAgc3R5bGVzOiBbJzpob3N0IHsgZGlzcGxheTogYmxvY2s7IH0nXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgW2NsYXNzXT1cImNuKCdmbGV4IGl0ZW1zLXN0cmV0Y2ggZ2FwLTEnLCBjbGFzcylcIj5cbiAgICAgIDxkaXZcbiAgICAgICAgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBjb2x1bW5zOyBsZXQgY2kgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tDb2x1bW5cIlxuICAgICAgICBjbGFzcz1cImZsZXggZmxleC1jb2xcIlxuICAgICAgPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBwYi0xIHRleHQtY2VudGVyIHRleHQtWzEwcHhdIGZvbnQtbWVkaXVtIHVwcGVyY2FzZSB0cmFja2luZy13aWRlIHRleHQtbXV0ZWQtZm9yZWdyb3VuZFwiPlxuICAgICAgICAgIHt7IGNvbHVtbi5sYWJlbCB9fVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdlxuICAgICAgICAgICNsaXN0Ym94XG4gICAgICAgICAgcm9sZT1cImxpc3Rib3hcIlxuICAgICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJjb2x1bW4ubGFiZWxcIlxuICAgICAgICAgIFthdHRyLmFyaWEtYWN0aXZlZGVzY2VuZGFudF09XCJhY3RpdmVEZXNjZW5kYW50Rm9yKGNpKVwiXG4gICAgICAgICAgKGtleWRvd24pPVwib25Db2x1bW5LZXlkb3duKCRldmVudCwgY2kpXCJcbiAgICAgICAgICBbY2xhc3NdPVwiY24oXG4gICAgICAgICAgICAnZmxleCBmbGV4LWNvbCBnYXAtMC41IG92ZXJmbG93LXktYXV0byBzY3JvbGwtc21vb3RoIHJvdW5kZWQtbWQgcC0xJyxcbiAgICAgICAgICAgICdmb2N1czpvdXRsaW5lLW5vbmUgZm9jdXMtdmlzaWJsZTpyaW5nLTIgZm9jdXMtdmlzaWJsZTpyaW5nLXJpbmcnLFxuICAgICAgICAgICAgY29sdW1uLmtpbmQgPT09ICdtZXJpZGllbScgPyAndy0xNCcgOiAndy0xNCcsXG4gICAgICAgICAgICBoZWlnaHRDbGFzc1xuICAgICAgICAgIClcIlxuICAgICAgICA+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBjb2x1bW4ub3B0aW9uczsgdHJhY2tCeTogdHJhY2tPcHRpb25cIlxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICByb2xlPVwib3B0aW9uXCJcbiAgICAgICAgICAgIHRhYmluZGV4PVwiLTFcIlxuICAgICAgICAgICAgW2lkXT1cIm9wdGlvbi5pZFwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLXNlbGVjdGVkXT1cImlzU2VsZWN0ZWQoY29sdW1uLCBvcHRpb24pXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtZGlzYWJsZWRdPVwib3B0aW9uLmRpc2FibGVkXCJcbiAgICAgICAgICAgIFthdHRyLmRhdGEtc2VsZWN0ZWRdPVwiaXNTZWxlY3RlZChjb2x1bW4sIG9wdGlvbilcIlxuICAgICAgICAgICAgW2F0dHIuZGF0YS1hY3RpdmVdPVwiaXNBY3RpdmUoY2ksIG9wdGlvbilcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cIm9wdGlvbi5kaXNhYmxlZFwiXG4gICAgICAgICAgICBbY2xhc3NdPVwib3B0aW9uQ2xhc3MoY29sdW1uLCBvcHRpb24sIGNpKVwiXG4gICAgICAgICAgICAoY2xpY2spPVwiY2hvb3NlKGNvbHVtbiwgb3B0aW9uLCBjaSlcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIHt7IG9wdGlvbi5sYWJlbCB9fVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBUaW1lQ29sdW1uc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcbiAgLyoqIFNlbGVjdGVkIGhvdXIgaW4gMjQtaG91ciBmb3JtLCBvciBgbnVsbGAgd2hlbiBub3RoaW5nIGlzIGNob3NlbiB5ZXQuIEBkZWZhdWx0IG51bGwgKi9cbiAgQElucHV0KCkgaG91cjogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBTZWxlY3RlZCBtaW51dGUsIG9yIGBudWxsYCB3aGVuIG5vdGhpbmcgaXMgY2hvc2VuIHlldC4gQGRlZmF1bHQgbnVsbCAqL1xuICBASW5wdXQoKSBtaW51dGU6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICAvKiogU2VsZWN0ZWQgc2Vjb25kLCBvciBgbnVsbGAgd2hlbiBub3RoaW5nIGlzIGNob3NlbiB5ZXQuIEBkZWZhdWx0IG51bGwgKi9cbiAgQElucHV0KCkgc2Vjb25kOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIFJlbmRlcnMgYSAxMi1ob3VyIGNsb2NrIGZhY2Ugd2l0aCBhbiBBTS9QTSBjb2x1bW4uIEBkZWZhdWx0IGZhbHNlICovXG4gIEBJbnB1dCgpIHVzZTEySG91cnMgPSBmYWxzZTtcbiAgLyoqIEFkZHMgdGhlIHNlY29uZHMgY29sdW1uLiBAZGVmYXVsdCBmYWxzZSAqL1xuICBASW5wdXQoKSBzaG93U2Vjb25kcyA9IGZhbHNlO1xuICAvKiogSW50ZXJ2YWwgYmV0d2VlbiBtaW51dGUgZW50cmllcywgaW4gbWludXRlcy4gQGRlZmF1bHQgMSAqL1xuICBASW5wdXQoKSBtaW51dGVTdGVwID0gMTtcbiAgLyoqIEludGVydmFsIGJldHdlZW4gc2Vjb25kIGVudHJpZXMsIGluIHNlY29uZHMuIEBkZWZhdWx0IDEgKi9cbiAgQElucHV0KCkgc2Vjb25kU3RlcCA9IDE7XG4gIC8qKiBFYXJsaWVzdCBzZWxlY3RhYmxlIHRpbWUsIGFzIHNlY29uZHMgc2luY2UgbWlkbmlnaHQuIEBkZWZhdWx0IDAgKi9cbiAgQElucHV0KCkgbWluU2Vjb25kcyA9IDA7XG4gIC8qKiBMYXRlc3Qgc2VsZWN0YWJsZSB0aW1lLCBhcyBzZWNvbmRzIHNpbmNlIG1pZG5pZ2h0LiBAZGVmYXVsdCA4NjM5OSAqL1xuICBASW5wdXQoKSBtYXhTZWNvbmRzID0gU0VDT05EU19QRVJfREFZIC0gMTtcbiAgLyoqIFJvdyBoZWlnaHQgYW5kIHRleHQgc2l6ZSBvZiB0aGUgZW50cmllcy4gQGRlZmF1bHQgJ2RlZmF1bHQnICovXG4gIEBJbnB1dCgpIHNpemU6IFRpbWVDb2x1bW5zUHJvcHNbJ3NpemUnXSA9ICdkZWZhdWx0JztcbiAgLyoqIEV4dHJhIFRhaWx3aW5kIGNsYXNzZXMgbWVyZ2VkIG9udG8gdGhlIGNvbHVtbiBzdHJpcCB2aWEgYGNuKClgIChsYXN0LXdpbnMpLiAqL1xuICBASW5wdXQoKSBjbGFzcyA9ICcnO1xuXG4gIC8qKiBFbWl0dGVkIHdpdGggdGhlIGZ1bGwgd2FsbC1jbG9jayB0aW1lIHdoZW5ldmVyIGFuIGVudHJ5IGlzIGNob3Nlbi4gKi9cbiAgQE91dHB1dCgpIHRpbWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFRpbWVQYXJ0cz4oKTtcblxuICBAVmlld0NoaWxkcmVuKCdsaXN0Ym94JykgbGlzdGJveGVzPzogUXVlcnlMaXN0PEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+PjtcblxuICByZWFkb25seSBjb2x1bW5zSWQgPSAndGltZS1jb2wtJyArIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnNsaWNlKDIsIDExKTtcblxuICAvKipcbiAgICogQnVpbHQgb25jZSBwZXIgaW5wdXQgY2hhbmdlIHJhdGhlciB0aGFuIHJlYWQgZnJvbSBhIGdldHRlcjogYSBnZXR0ZXIgd291bGRcbiAgICogaGFuZCBgKm5nRm9yYCBhIGZyZXNoIGFycmF5IG9uIGV2ZXJ5IGNoYW5nZS1kZXRlY3Rpb24gcGFzcywgc28gZXZlcnkgcm93IOKAlFxuICAgKiBlYWNoIGNhcnJ5aW5nIGEgY2xpY2sgaGFuZGxlciDigJQgd291bGQgYmUgdG9ybiBkb3duIGFuZCByZWJ1aWx0IG9uIGV2ZXJ5XG4gICAqIHBhc3MuXG4gICAqL1xuICBjb2x1bW5zOiBUaW1lQ29sdW1uW10gPSBbXTtcbiAgLyoqIFJvdmluZyBhY3RpdmUgZW50cnkgcGVyIGNvbHVtbiwgZm9yIGBhcmlhLWFjdGl2ZWRlc2NlbmRhbnRgLiAqL1xuICBhY3RpdmVJbmRleDogbnVtYmVyW10gPSBbXTtcblxuICBwcm90ZWN0ZWQgY24gPSBjbjtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmNvbHVtbnMubGVuZ3RoKSB0aGlzLnJlYnVpbGQoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIHRoaXMucmVidWlsZCgpO1xuICBcbiAgICAvLyBBIGJvdW5kIGBjbGFzc2AgaW5wdXQgaXMgd3JpdHRlbiB0aHJvdWdoIEFuZ3VsYXIncyBzdHlsaW5nIHBhdGgsXG4gICAgLy8gd2hpY2ggZG9lcyBub3QgbWFyayBhbiBPblB1c2ggdmlldyBkaXJ0eSBvbiBpdHMgb3duLlxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgZ2V0IGhlaWdodENsYXNzKCk6IHN0cmluZyB7XG4gICAgc3dpdGNoICh0aGlzLnNpemUpIHtcbiAgICAgIGNhc2UgJ3hzJzpcbiAgICAgICAgcmV0dXJuICdtYXgtaC1bMTQ0cHhdJztcbiAgICAgIGNhc2UgJ3NtJzpcbiAgICAgICAgcmV0dXJuICdtYXgtaC1bMTY4cHhdJztcbiAgICAgIGNhc2UgJ2xnJzpcbiAgICAgICAgcmV0dXJuICdtYXgtaC1bMjE2cHhdJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAnbWF4LWgtWzE5MnB4XSc7XG4gICAgfVxuICB9XG5cbiAgLyogLS0tLS0tLS0tLS0tLS0tLSBvcHRpb24gZ2VuZXJhdGlvbiAtLS0tLS0tLS0tLS0tLS0tICovXG5cbiAgcHJpdmF0ZSByZWJ1aWxkKCk6IHZvaWQge1xuICAgIGNvbnN0IHN0ZXAgPSAodmFsdWU6IG51bWJlciwgZmFsbGJhY2s6IG51bWJlcikgPT5cbiAgICAgIE51bWJlci5pc0Zpbml0ZSh2YWx1ZSkgJiYgdmFsdWUgPj0gMSA/IE1hdGguZmxvb3IodmFsdWUpIDogZmFsbGJhY2s7XG5cbiAgICBjb25zdCBtaW51dGVTdGVwID0gc3RlcCh0aGlzLm1pbnV0ZVN0ZXAsIDEpO1xuICAgIGNvbnN0IHNlY29uZFN0ZXAgPSBzdGVwKHRoaXMuc2Vjb25kU3RlcCwgMSk7XG4gICAgY29uc3QgZWZmZWN0aXZlSG91ciA9IHRoaXMuaG91ciA/PyAwO1xuICAgIGNvbnN0IGVmZmVjdGl2ZU1pbnV0ZSA9IHRoaXMubWludXRlID8/IDA7XG4gICAgY29uc3QgbWVyaWRpZW0gPSB0bzEySG91cihlZmZlY3RpdmVIb3VyKS5tZXJpZGllbTtcblxuICAgIC8vIEhvdyBmYXIgYSBwYXJ0aWFsbHktc3BlY2lmaWVkIHRpbWUgY2FuIHN0cmV0Y2guIFdpdGggbm8gc2Vjb25kcyBjb2x1bW5cbiAgICAvLyB0aGUgc2Vjb25kcyBhcmUgcGlubmVkIHRvIDowMCwgc28gYW4gaG91ciBvbmx5IHJlYWNoZXMgOjU5OjAwLlxuICAgIGNvbnN0IGhvdXJTcGFuID0gdGhpcy5zaG93U2Vjb25kcyA/IDM1OTkgOiAzNTQwO1xuICAgIGNvbnN0IG1pbnV0ZVNwYW4gPSB0aGlzLnNob3dTZWNvbmRzID8gNTkgOiAwO1xuXG4gICAgY29uc3QgY29sdW1uczogVGltZUNvbHVtbltdID0gW107XG5cbiAgICAvLyBIb3Vyc1xuICAgIGNvbnN0IGhvdXJPcHRpb25zOiBUaW1lT3B0aW9uW10gPSBbXTtcbiAgICBpZiAodGhpcy51c2UxMkhvdXJzKSB7XG4gICAgICAvLyBDbG9jay1mYWNlIG9yZGVyOiAxMiwgMSwgMiDigKYgMTEuXG4gICAgICBjb25zdCBmYWNlcyA9IFsxMiwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExXTtcbiAgICAgIGZvciAoY29uc3QgZmFjZSBvZiBmYWNlcykge1xuICAgICAgICBjb25zdCByYXcgPSBmcm9tMTJIb3VyKGZhY2UsIG1lcmlkaWVtKTtcbiAgICAgICAgaG91ck9wdGlvbnMucHVzaCh7XG4gICAgICAgICAgaWQ6IHRoaXMuY29sdW1uc0lkICsgJy1ob3VyLScgKyBmYWNlLFxuICAgICAgICAgIGxhYmVsOiBwYWQyKGZhY2UpLFxuICAgICAgICAgIHJhdyxcbiAgICAgICAgICBmYWNlLFxuICAgICAgICAgIGRpc2FibGVkOiB0aGlzLnJhbmdlRGlzYWJsZWQocmF3ICogMzYwMCwgaG91clNwYW4pLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChsZXQgaCA9IDA7IGggPCAyNDsgaCsrKSB7XG4gICAgICAgIGhvdXJPcHRpb25zLnB1c2goe1xuICAgICAgICAgIGlkOiB0aGlzLmNvbHVtbnNJZCArICctaG91ci0nICsgaCxcbiAgICAgICAgICBsYWJlbDogcGFkMihoKSxcbiAgICAgICAgICByYXc6IGgsXG4gICAgICAgICAgZmFjZTogaCxcbiAgICAgICAgICBkaXNhYmxlZDogdGhpcy5yYW5nZURpc2FibGVkKGggKiAzNjAwLCBob3VyU3BhbiksXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICBjb2x1bW5zLnB1c2goeyBraW5kOiAnaG91cicsIGxhYmVsOiAnSG91cicsIG9wdGlvbnM6IGhvdXJPcHRpb25zIH0pO1xuXG4gICAgLy8gTWludXRlc1xuICAgIGNvbnN0IG1pbnV0ZU9wdGlvbnM6IFRpbWVPcHRpb25bXSA9IFtdO1xuICAgIGZvciAobGV0IG0gPSAwOyBtIDwgNjA7IG0gKz0gbWludXRlU3RlcCkge1xuICAgICAgY29uc3Qgc3RhcnQgPSBlZmZlY3RpdmVIb3VyICogMzYwMCArIG0gKiA2MDtcbiAgICAgIG1pbnV0ZU9wdGlvbnMucHVzaCh7XG4gICAgICAgIGlkOiB0aGlzLmNvbHVtbnNJZCArICctbWludXRlLScgKyBtLFxuICAgICAgICBsYWJlbDogcGFkMihtKSxcbiAgICAgICAgcmF3OiBtLFxuICAgICAgICBmYWNlOiBtLFxuICAgICAgICBkaXNhYmxlZDogdGhpcy5yYW5nZURpc2FibGVkKHN0YXJ0LCBtaW51dGVTcGFuKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjb2x1bW5zLnB1c2goeyBraW5kOiAnbWludXRlJywgbGFiZWw6ICdNaW4nLCBvcHRpb25zOiBtaW51dGVPcHRpb25zIH0pO1xuXG4gICAgLy8gU2Vjb25kc1xuICAgIGlmICh0aGlzLnNob3dTZWNvbmRzKSB7XG4gICAgICBjb25zdCBzZWNvbmRPcHRpb25zOiBUaW1lT3B0aW9uW10gPSBbXTtcbiAgICAgIGZvciAobGV0IHMgPSAwOyBzIDwgNjA7IHMgKz0gc2Vjb25kU3RlcCkge1xuICAgICAgICBjb25zdCBhdCA9IGVmZmVjdGl2ZUhvdXIgKiAzNjAwICsgZWZmZWN0aXZlTWludXRlICogNjAgKyBzO1xuICAgICAgICBzZWNvbmRPcHRpb25zLnB1c2goe1xuICAgICAgICAgIGlkOiB0aGlzLmNvbHVtbnNJZCArICctc2Vjb25kLScgKyBzLFxuICAgICAgICAgIGxhYmVsOiBwYWQyKHMpLFxuICAgICAgICAgIHJhdzogcyxcbiAgICAgICAgICBmYWNlOiBzLFxuICAgICAgICAgIGRpc2FibGVkOiB0aGlzLnJhbmdlRGlzYWJsZWQoYXQsIDApLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbHVtbnMucHVzaCh7IGtpbmQ6ICdzZWNvbmQnLCBsYWJlbDogJ1NlYycsIG9wdGlvbnM6IHNlY29uZE9wdGlvbnMgfSk7XG4gICAgfVxuXG4gICAgLy8gTWVyaWRpZW1cbiAgICBpZiAodGhpcy51c2UxMkhvdXJzKSB7XG4gICAgICBjb25zdCBmYWNlMTIgPSB0bzEySG91cihlZmZlY3RpdmVIb3VyKS5ob3VyMTI7XG4gICAgICBjb25zdCBtZXJpZGllbU9wdGlvbnM6IFRpbWVPcHRpb25bXSA9IChbJ0FNJywgJ1BNJ10gYXMgY29uc3QpLm1hcCgobSwgaSkgPT4ge1xuICAgICAgICBjb25zdCByYXcgPSBmcm9tMTJIb3VyKGZhY2UxMiwgbSk7XG4gICAgICAgIGNvbnN0IGhhbGZTdGFydCA9IG0gPT09ICdBTScgPyAwIDogMTIgKiAzNjAwO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGlkOiB0aGlzLmNvbHVtbnNJZCArICctbWVyaWRpZW0tJyArIG0sXG4gICAgICAgICAgbGFiZWw6IG0sXG4gICAgICAgICAgcmF3LFxuICAgICAgICAgIGZhY2U6IGksIC8vIDAgPSBBTSwgMSA9IFBNXG4gICAgICAgICAgZGlzYWJsZWQ6IHRoaXMucmFuZ2VEaXNhYmxlZChoYWxmU3RhcnQsIDEyICogMzYwMCAtIDEpLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgICBjb2x1bW5zLnB1c2goeyBraW5kOiAnbWVyaWRpZW0nLCBsYWJlbDogJ0FNL1BNJywgb3B0aW9uczogbWVyaWRpZW1PcHRpb25zIH0pO1xuICAgIH1cblxuICAgIHRoaXMuY29sdW1ucyA9IGNvbHVtbnM7XG4gICAgdGhpcy5zeW5jQWN0aXZlVG9TZWxlY3Rpb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcnVlIHdoZW4gbm90aGluZyBpbiBgW3N0YXJ0LCBzdGFydCArIHNwYW5dYCBmYWxscyBpbnNpZGUgdGhlIGFsbG93ZWRcbiAgICogd2luZG93IOKAlCBpLmUuIHBpY2tpbmcgdGhpcyBlbnRyeSBjb3VsZCBub3QgcHJvZHVjZSBhIGxlZ2FsIHRpbWUuXG4gICAqL1xuICBwcml2YXRlIHJhbmdlRGlzYWJsZWQoc3RhcnQ6IG51bWJlciwgc3BhbjogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHN0YXJ0ICsgc3BhbiA8IHRoaXMubWluU2Vjb25kcyB8fCBzdGFydCA+IHRoaXMubWF4U2Vjb25kcztcbiAgfVxuXG4gIHByaXZhdGUgc3luY0FjdGl2ZVRvU2VsZWN0aW9uKCk6IHZvaWQge1xuICAgIHRoaXMuYWN0aXZlSW5kZXggPSB0aGlzLmNvbHVtbnMubWFwKChjb2x1bW4pID0+IHtcbiAgICAgIGNvbnN0IGlkeCA9IGNvbHVtbi5vcHRpb25zLmZpbmRJbmRleCgobykgPT4gdGhpcy5pc1NlbGVjdGVkKGNvbHVtbiwgbykpO1xuICAgICAgaWYgKGlkeCA+PSAwKSByZXR1cm4gaWR4O1xuICAgICAgY29uc3QgZmlyc3RFbmFibGVkID0gY29sdW1uLm9wdGlvbnMuZmluZEluZGV4KChvKSA9PiAhby5kaXNhYmxlZCk7XG4gICAgICByZXR1cm4gZmlyc3RFbmFibGVkID49IDAgPyBmaXJzdEVuYWJsZWQgOiAwO1xuICAgIH0pO1xuICB9XG5cbiAgLyogLS0tLS0tLS0tLS0tLS0tLSBzZWxlY3Rpb24gLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4gIGlzU2VsZWN0ZWQoY29sdW1uOiBUaW1lQ29sdW1uLCBvcHRpb246IFRpbWVPcHRpb24pOiBib29sZWFuIHtcbiAgICBzd2l0Y2ggKGNvbHVtbi5raW5kKSB7XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgaWYgKHRoaXMuaG91ciA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gdGhpcy51c2UxMkhvdXJzID8gdG8xMkhvdXIodGhpcy5ob3VyKS5ob3VyMTIgPT09IG9wdGlvbi5mYWNlIDogdGhpcy5ob3VyID09PSBvcHRpb24uZmFjZTtcbiAgICAgIGNhc2UgJ21pbnV0ZSc6XG4gICAgICAgIHJldHVybiB0aGlzLm1pbnV0ZSAhPT0gbnVsbCAmJiB0aGlzLm1pbnV0ZSA9PT0gb3B0aW9uLmZhY2U7XG4gICAgICBjYXNlICdzZWNvbmQnOlxuICAgICAgICByZXR1cm4gdGhpcy5zZWNvbmQgIT09IG51bGwgJiYgdGhpcy5zZWNvbmQgPT09IG9wdGlvbi5mYWNlO1xuICAgICAgY2FzZSAnbWVyaWRpZW0nOlxuICAgICAgICBpZiAodGhpcy5ob3VyID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiAodG8xMkhvdXIodGhpcy5ob3VyKS5tZXJpZGllbSA9PT0gJ0FNJyA/IDAgOiAxKSA9PT0gb3B0aW9uLmZhY2U7XG4gICAgfVxuICB9XG5cbiAgaXNBY3RpdmUoY29sdW1uSW5kZXg6IG51bWJlciwgb3B0aW9uOiBUaW1lT3B0aW9uKTogYm9vbGVhbiB7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5jb2x1bW5zW2NvbHVtbkluZGV4XTtcbiAgICBpZiAoIWNvbHVtbikgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiBjb2x1bW4ub3B0aW9uc1t0aGlzLmFjdGl2ZUluZGV4W2NvbHVtbkluZGV4XV0gPT09IG9wdGlvbjtcbiAgfVxuXG4gIGFjdGl2ZURlc2NlbmRhbnRGb3IoY29sdW1uSW5kZXg6IG51bWJlcik6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuY29sdW1uc1tjb2x1bW5JbmRleF07XG4gICAgcmV0dXJuIGNvbHVtbj8ub3B0aW9uc1t0aGlzLmFjdGl2ZUluZGV4W2NvbHVtbkluZGV4XV0/LmlkID8/IG51bGw7XG4gIH1cblxuICBvcHRpb25DbGFzcyhjb2x1bW46IFRpbWVDb2x1bW4sIG9wdGlvbjogVGltZU9wdGlvbiwgY29sdW1uSW5kZXg6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3Qgc2VsZWN0ZWQgPSB0aGlzLmlzU2VsZWN0ZWQoY29sdW1uLCBvcHRpb24pO1xuICAgIHJldHVybiBjbihcbiAgICAgIHRpbWVPcHRpb25WYXJpYW50cyh7IHNpemU6IHRoaXMuc2l6ZSwgc2VsZWN0ZWQgfSksXG4gICAgICAvLyBUaGUgcm92aW5nIGhpZ2hsaWdodCBoYXMgdG8gcmVhZCBhcyBkaXN0aW5jdCBmcm9tIHRoZSBjb21taXR0ZWQgdmFsdWUsXG4gICAgICAvLyBvdGhlcndpc2UgYXJyb3dpbmcgYXJvdW5kIGxvb2tzIGxpa2UgaXQgaXMgYWxyZWFkeSBzZWxlY3RpbmcuXG4gICAgICAhc2VsZWN0ZWQgJiYgdGhpcy5pc0FjdGl2ZShjb2x1bW5JbmRleCwgb3B0aW9uKSAmJiAnYmctYWNjZW50IHRleHQtYWNjZW50LWZvcmVncm91bmQnXG4gICAgKTtcbiAgfVxuXG4gIC8qKiBDb21taXRzIGBvcHRpb25gIGluIGl0cyBjb2x1bW4gYW5kIGVtaXRzIHRoZSByZXN1bHRpbmcgd2hvbGUgdGltZS4gKi9cbiAgY2hvb3NlKGNvbHVtbjogVGltZUNvbHVtbiwgb3B0aW9uOiBUaW1lT3B0aW9uLCBjb2x1bW5JbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKG9wdGlvbi5kaXNhYmxlZCkgcmV0dXJuO1xuXG4gICAgY29uc3QgbmV4dDogVGltZVBhcnRzID0ge1xuICAgICAgaG91cjogdGhpcy5ob3VyID8/IDAsXG4gICAgICBtaW51dGU6IHRoaXMubWludXRlID8/IDAsXG4gICAgICBzZWNvbmQ6IHRoaXMuc2Vjb25kID8/IDAsXG4gICAgfTtcblxuICAgIHN3aXRjaCAoY29sdW1uLmtpbmQpIHtcbiAgICAgIGNhc2UgJ2hvdXInOlxuICAgICAgY2FzZSAnbWVyaWRpZW0nOlxuICAgICAgICBuZXh0LmhvdXIgPSBvcHRpb24ucmF3O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ21pbnV0ZSc6XG4gICAgICAgIG5leHQubWludXRlID0gb3B0aW9uLnJhdztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdzZWNvbmQnOlxuICAgICAgICBuZXh0LnNlY29uZCA9IG9wdGlvbi5yYXc7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHRoaXMuYWN0aXZlSW5kZXhbY29sdW1uSW5kZXhdID0gY29sdW1uLm9wdGlvbnMuaW5kZXhPZihvcHRpb24pO1xuICAgIHRoaXMudGltZUNoYW5nZS5lbWl0KG5leHQpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyogLS0tLS0tLS0tLS0tLS0tLSBrZXlib2FyZCAtLS0tLS0tLS0tLS0tLS0tICovXG5cbiAgb25Db2x1bW5LZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50LCBjb2x1bW5JbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5jb2x1bW5zW2NvbHVtbkluZGV4XTtcbiAgICBpZiAoIWNvbHVtbikgcmV0dXJuO1xuXG4gICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgIGNhc2UgJ0Fycm93RG93bic6XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMubW92ZUFjdGl2ZShjb2x1bW5JbmRleCwgMSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnQXJyb3dVcCc6XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMubW92ZUFjdGl2ZShjb2x1bW5JbmRleCwgLTEpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0hvbWUnOlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnNldEFjdGl2ZShjb2x1bW5JbmRleCwgMCwgMSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnRW5kJzpcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5zZXRBY3RpdmUoY29sdW1uSW5kZXgsIGNvbHVtbi5vcHRpb25zLmxlbmd0aCAtIDEsIC0xKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdBcnJvd0xlZnQnOlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmZvY3VzQ29sdW1uKGNvbHVtbkluZGV4IC0gMSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnQXJyb3dSaWdodCc6XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuZm9jdXNDb2x1bW4oY29sdW1uSW5kZXggKyAxKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdFbnRlcic6XG4gICAgICBjYXNlICcgJzpcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAge1xuICAgICAgICAgIGNvbnN0IG9wdGlvbiA9IGNvbHVtbi5vcHRpb25zW3RoaXMuYWN0aXZlSW5kZXhbY29sdW1uSW5kZXhdXTtcbiAgICAgICAgICBpZiAob3B0aW9uKSB0aGlzLmNob29zZShjb2x1bW4sIG9wdGlvbiwgY29sdW1uSW5kZXgpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbW92ZUFjdGl2ZShjb2x1bW5JbmRleDogbnVtYmVyLCBkZWx0YTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuYWN0aXZlSW5kZXhbY29sdW1uSW5kZXhdID8/IDA7XG4gICAgdGhpcy5zZXRBY3RpdmUoY29sdW1uSW5kZXgsIGN1cnJlbnQgKyBkZWx0YSwgZGVsdGEpO1xuICB9XG5cbiAgLyoqIExhbmRzIG9uIHRoZSBmaXJzdCBlbmFibGVkIGVudHJ5IGF0IG9yIHBhc3QgYGluZGV4YCwgd2Fsa2luZyBgZGlyZWN0aW9uYC4gKi9cbiAgcHJpdmF0ZSBzZXRBY3RpdmUoY29sdW1uSW5kZXg6IG51bWJlciwgaW5kZXg6IG51bWJlciwgZGlyZWN0aW9uOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmNvbHVtbnNbY29sdW1uSW5kZXhdO1xuICAgIGlmICghY29sdW1uKSByZXR1cm47XG5cbiAgICBsZXQgaSA9IE1hdGgubWF4KDAsIE1hdGgubWluKGluZGV4LCBjb2x1bW4ub3B0aW9ucy5sZW5ndGggLSAxKSk7XG4gICAgd2hpbGUgKGNvbHVtbi5vcHRpb25zW2ldPy5kaXNhYmxlZCkge1xuICAgICAgaSArPSBkaXJlY3Rpb247XG4gICAgICBpZiAoaSA8IDAgfHwgaSA+PSBjb2x1bW4ub3B0aW9ucy5sZW5ndGgpIHJldHVybjsgLy8gbm8gZW5hYmxlZCBlbnRyeSB0aGF0IHdheVxuICAgIH1cblxuICAgIHRoaXMuYWN0aXZlSW5kZXhbY29sdW1uSW5kZXhdID0gaTtcbiAgICB0aGlzLnNjcm9sbE9wdGlvbkludG9WaWV3KGNvbHVtbkluZGV4LCBpKTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByaXZhdGUgZm9jdXNDb2x1bW4oY29sdW1uSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmIChjb2x1bW5JbmRleCA8IDAgfHwgY29sdW1uSW5kZXggPj0gdGhpcy5jb2x1bW5zLmxlbmd0aCkgcmV0dXJuO1xuICAgIHRoaXMubGlzdGJveGVzPy5nZXQoY29sdW1uSW5kZXgpPy5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gIH1cblxuICAvKiogRm9jdXNlcyB0aGUgZmlyc3QgY29sdW1uIOKAlCB1c2VkIHdoZW4gdGhlIHBhbmVsIG9wZW5zLiAqL1xuICBmb2N1c0ZpcnN0Q29sdW1uKCk6IHZvaWQge1xuICAgIHRoaXMuZm9jdXNDb2x1bW4oMCk7XG4gIH1cblxuICAvKipcbiAgICogQ2VudHJlcyBlYWNoIGNvbHVtbiBvbiBpdHMgc2VsZWN0ZWQgZW50cnkuIFNjcm9sbHMgdGhlIGxpc3Rib3ggZGlyZWN0bHlcbiAgICogcmF0aGVyIHRoYW4gY2FsbGluZyBgc2Nyb2xsSW50b1ZpZXdgLCB3aGljaCB3b3VsZCBhbHNvIHNjcm9sbCB0aGUgcGFnZVxuICAgKiBiZWhpbmQgYSBmaXhlZC1wb3NpdGlvbiBwYW5lbC5cbiAgICovXG4gIHNjcm9sbFNlbGVjdGVkSW50b1ZpZXcoKTogdm9pZCB7XG4gICAgdGhpcy5saXN0Ym94ZXM/LmZvckVhY2goKHJlZikgPT4ge1xuICAgICAgY29uc3QgbGlzdCA9IHJlZi5uYXRpdmVFbGVtZW50O1xuICAgICAgY29uc3Qgc2VsZWN0ZWQgPSBsaXN0LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXNlbGVjdGVkPVwidHJ1ZVwiXScpIGFzIEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICAgIGlmICghc2VsZWN0ZWQpIHJldHVybjtcbiAgICAgIGxpc3Quc2Nyb2xsVG9wID0gc2VsZWN0ZWQub2Zmc2V0VG9wIC0gbGlzdC5jbGllbnRIZWlnaHQgLyAyICsgc2VsZWN0ZWQuY2xpZW50SGVpZ2h0IC8gMjtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2Nyb2xsT3B0aW9uSW50b1ZpZXcoY29sdW1uSW5kZXg6IG51bWJlciwgb3B0aW9uSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGxpc3QgPSB0aGlzLmxpc3Rib3hlcz8uZ2V0KGNvbHVtbkluZGV4KT8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIWxpc3QpIHJldHVybjtcbiAgICBjb25zdCBlbCA9IGxpc3QuY2hpbGRyZW5bb3B0aW9uSW5kZXhdIGFzIEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkO1xuICAgIGlmICghZWwpIHJldHVybjtcblxuICAgIGlmIChlbC5vZmZzZXRUb3AgPCBsaXN0LnNjcm9sbFRvcCkge1xuICAgICAgbGlzdC5zY3JvbGxUb3AgPSBlbC5vZmZzZXRUb3A7XG4gICAgfSBlbHNlIGlmIChlbC5vZmZzZXRUb3AgKyBlbC5jbGllbnRIZWlnaHQgPiBsaXN0LnNjcm9sbFRvcCArIGxpc3QuY2xpZW50SGVpZ2h0KSB7XG4gICAgICBsaXN0LnNjcm9sbFRvcCA9IGVsLm9mZnNldFRvcCArIGVsLmNsaWVudEhlaWdodCAtIGxpc3QuY2xpZW50SGVpZ2h0O1xuICAgIH1cbiAgfVxuXG4gIHRyYWNrQ29sdW1uID0gKF86IG51bWJlciwgY29sdW1uOiBUaW1lQ29sdW1uKSA9PiBjb2x1bW4ua2luZDtcbiAgdHJhY2tPcHRpb24gPSAoXzogbnVtYmVyLCBvcHRpb246IFRpbWVPcHRpb24pID0+IG9wdGlvbi5pZDtcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICpcbiAqIFRoZSBwaWNrZXJcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5jb25zdCB0aW1lUGlja2VyVHJpZ2dlclZhcmlhbnRzID0gY3ZhKFxuICAnZmxleCB3LWZ1bGwgaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlbiBnYXAtMiByb3VuZGVkLW1kIGJvcmRlciBib3JkZXItaW5wdXQgYmctYmFja2dyb3VuZCB0ZXh0LWZvcmVncm91bmQgc2hhZG93LXNtIHRyYW5zaXRpb24tY29sb3JzICcgK1xuICAgICdmb2N1czpvdXRsaW5lLW5vbmUgZm9jdXMtdmlzaWJsZTpib3JkZXItcHJpbWFyeS84MCBmb2N1cy12aXNpYmxlOnJpbmctNCBmb2N1cy12aXNpYmxlOnJpbmctcmluZy8zMCAnICtcbiAgICAnZGlzYWJsZWQ6Y3Vyc29yLW5vdC1hbGxvd2VkIGRpc2FibGVkOm9wYWNpdHktNTAnLFxuICB7XG4gICAgdmFyaWFudHM6IHtcbiAgICAgIHNpemU6IHtcbiAgICAgICAgeHM6ICdoLTggcHgtMiB0ZXh0LXhzJyxcbiAgICAgICAgc206ICdoLTkgcHgtMyB0ZXh0LXNtJyxcbiAgICAgICAgZGVmYXVsdDogJ2gtMTAgcHgtMyB0ZXh0LXNtJyxcbiAgICAgICAgbGc6ICdoLTExIHB4LTQgdGV4dC1iYXNlJyxcbiAgICAgIH0sXG4gICAgICBpbnZhbGlkOiB7XG4gICAgICAgIHRydWU6ICdib3JkZXItZGVzdHJ1Y3RpdmUgZm9jdXMtdmlzaWJsZTpib3JkZXItZGVzdHJ1Y3RpdmUvODAgZm9jdXMtdmlzaWJsZTpyaW5nLWRlc3RydWN0aXZlLzMwJyxcbiAgICAgICAgZmFsc2U6ICcnLFxuICAgICAgfSxcbiAgICB9LFxuICAgIGRlZmF1bHRWYXJpYW50czogeyBzaXplOiAnZGVmYXVsdCcsIGludmFsaWQ6IGZhbHNlIH0sXG4gIH1cbik7XG5cbi8qKiBWYXJpYW50IHByb3BzIGZvciB0aGUgdGltZSBwaWNrZXIgdHJpZ2dlci4gKi9cbmV4cG9ydCB0eXBlIFRpbWVQaWNrZXJQcm9wcyA9IFZhcmlhbnRQcm9wczx0eXBlb2YgdGltZVBpY2tlclRyaWdnZXJWYXJpYW50cz47XG5cbi8qKlxuICogQSB0cmlnZ2VyIHRoYXQgb3BlbnMgc2Nyb2xsYWJsZSBob3VyIC8gbWludXRlIC8gc2Vjb25kIGNvbHVtbnMgaW4gYSBmbG9hdGluZ1xuICogcGFuZWwuXG4gKlxuICogVGhlIHZhbHVlIGlzIGEgKioyNC1ob3VyIGBISDptbWAgc3RyaW5nKiogKG9yIGBISDptbTpzc2Agd2hlbiBgc2hvd1NlY29uZHNgKSxcbiAqIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgZmFjZSBpcyByZW5kZXJlZCBhcyAxMi1ob3VyIOKAlCBhIHdhbGwtY2xvY2sgdGltZSBoYXNcbiAqIG5vIGRhdGUgYW5kIG5vIHRpbWV6b25lLCBhbmQgYSBgRGF0ZWAgd291bGQgaW52ZW50IGJvdGguIFNldFxuICogYHZhbHVlVHlwZT1cImRhdGVcImAgdG8gZXhjaGFuZ2UgYERhdGVgIG9iamVjdHMgaW5zdGVhZCwgaW4gd2hpY2ggY2FzZSB0aGUgdGltZVxuICogaXMgd3JpdHRlbiBvbnRvIHRvZGF5J3MgZGF0ZSAob3Igb250byB0aGUgZGF0ZSBhbHJlYWR5IGhlbGQgYnkgdGhlIGNvbnRyb2wpLlxuICpcbiAqIEltcGxlbWVudHMgYENvbnRyb2xWYWx1ZUFjY2Vzc29yYCwgc28gaXQgd29ya3Mgd2l0aCBgbmdNb2RlbGAgYW5kIHJlYWN0aXZlXG4gKiBmb3Jtcy4gVXNlIGB0b2xsZS1kYXRlLXRpbWUtcGlja2VyYCB3aGVuIGEgZGF0ZSBpcyBuZWVkZWQgYWxvbmdzaWRlLlxuICogQG5ld1xuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0b2xsZS10aW1lLXBpY2tlcicsXG4gIHN0eWxlczogWyc6aG9zdCB7IGRpc3BsYXk6IGJsb2NrOyB9J10sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIFRpbWVDb2x1bW5zQ29tcG9uZW50XSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gVGltZVBpY2tlckNvbXBvbmVudCksXG4gICAgICBtdWx0aTogdHJ1ZSxcbiAgICB9LFxuICBdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxidXR0b25cbiAgICAgICN0cmlnZ2VyXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIGFyaWEtaGFzcG9wdXA9XCJkaWFsb2dcIlxuICAgICAgW2F0dHIuYXJpYS1leHBhbmRlZF09XCJpc09wZW5cIlxuICAgICAgW2F0dHIuYXJpYS1jb250cm9sc109XCJpc09wZW4gPyBwYW5lbElkIDogbnVsbFwiXG4gICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImFyaWFMYWJlbCB8fCBudWxsXCJcbiAgICAgIFthdHRyLmRhdGEtc3RhdGVdPVwiaXNPcGVuID8gJ29wZW4nIDogJ2Nsb3NlZCdcIlxuICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgIFtjbGFzc109XCJjb21wdXRlZFRyaWdnZXJDbGFzc1wiXG4gICAgICAoY2xpY2spPVwidG9nZ2xlKClcIlxuICAgICAgKGtleWRvd24pPVwib25UcmlnZ2VyS2V5RG93bigkZXZlbnQpXCJcbiAgICA+XG4gICAgICA8c3BhbiBbY2xhc3NdPVwiY24oJ3RydW5jYXRlJywgZGlzcGxheVZhbHVlID8gJ3RleHQtZm9yZWdyb3VuZCcgOiAndGV4dC1tdXRlZC1mb3JlZ3JvdW5kJylcIj5cbiAgICAgICAge3sgZGlzcGxheVZhbHVlIHx8IHBsYWNlaG9sZGVyIH19XG4gICAgICA8L3NwYW4+XG4gICAgICA8aSBjbGFzcz1cInJpLXRpbWUtbGluZSBzaHJpbmstMCB0ZXh0LW11dGVkLWZvcmVncm91bmRcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgPC9idXR0b24+XG5cbiAgICA8ZGl2XG4gICAgICAqbmdJZj1cImlzT3BlblwiXG4gICAgICAjcGFuZWxcbiAgICAgIHJvbGU9XCJkaWFsb2dcIlxuICAgICAgW2lkXT1cInBhbmVsSWRcIlxuICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJhcmlhTGFiZWwgfHwgJ0Nob29zZSBhIHRpbWUnXCJcbiAgICAgIGNsYXNzPVwiZml4ZWQgbGVmdC0wIHRvcC0wIHotWzk5OTldXCJcbiAgICAgIHN0eWxlPVwidmlzaWJpbGl0eTogaGlkZGVuXCJcbiAgICA+XG4gICAgICA8ZGl2IGNsYXNzPVwicm91bmRlZC1tZCBib3JkZXIgYm9yZGVyLWJvcmRlciBiZy1wb3BvdmVyIHAtMiB0ZXh0LXBvcG92ZXItZm9yZWdyb3VuZCBzaGFkb3ctbWRcIj5cbiAgICAgICAgPHRvbGxlLXRpbWUtY29sdW1uc1xuICAgICAgICAgICNjb2x1bW5zXG4gICAgICAgICAgW2hvdXJdPVwiaG91clwiXG4gICAgICAgICAgW21pbnV0ZV09XCJtaW51dGVcIlxuICAgICAgICAgIFtzZWNvbmRdPVwic2Vjb25kXCJcbiAgICAgICAgICBbdXNlMTJIb3Vyc109XCJ1c2UxMkhvdXJzXCJcbiAgICAgICAgICBbc2hvd1NlY29uZHNdPVwic2hvd1NlY29uZHNcIlxuICAgICAgICAgIFttaW51dGVTdGVwXT1cIm1pbnV0ZVN0ZXBcIlxuICAgICAgICAgIFtzZWNvbmRTdGVwXT1cInNlY29uZFN0ZXBcIlxuICAgICAgICAgIFttaW5TZWNvbmRzXT1cIm1pblNlY29uZHNcIlxuICAgICAgICAgIFttYXhTZWNvbmRzXT1cIm1heFNlY29uZHNcIlxuICAgICAgICAgIFtzaXplXT1cInNpemVcIlxuICAgICAgICAgICh0aW1lQ2hhbmdlKT1cIm9uVGltZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgPjwvdG9sbGUtdGltZS1jb2x1bW5zPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIFRpbWVQaWNrZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMsIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkRlc3Ryb3kge1xuXG4gIC8qKlxuICAgKiBBbmd1bGFyIHdyaXRlcyBhIGJvdW5kIGBjbGFzc2AgaW5wdXQgdGhyb3VnaCBpdHMgc3R5bGluZyBwYXRoLCB3aGljaCBkb2VzXG4gICAqIG5vdCBtYXJrIGFuIE9uUHVzaCBjb21wb25lbnQgZGlydHkg4oCUIHdpdGhvdXQgdGhpcyBob29rIHRoZSBjb21wb25lbnQga2VlcHNcbiAgICogcmVuZGVyaW5nIHRoZSBjbGFzcyBpdCB3YXMgYm9ybiB3aXRoLlxuICAgKi9cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKiogVGV4dCBzaG93biBvbiB0aGUgdHJpZ2dlciB3aGVuIG5vIHRpbWUgaXMgc2VsZWN0ZWQuIEBkZWZhdWx0ICdTZWxlY3QgYSB0aW1lJyAqL1xuICBASW5wdXQoKSBwbGFjZWhvbGRlciA9ICdTZWxlY3QgYSB0aW1lJztcbiAgLyoqIERpc2FibGVzIHRoZSBjb250cm9sLiBAZGVmYXVsdCBmYWxzZSAqL1xuICBASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xuICAvKiogUmVuZGVycyBhIDEyLWhvdXIgZmFjZSB3aXRoIGFuIEFNL1BNIGNvbHVtbi4gVGhlIGVtaXR0ZWQgdmFsdWUgc3RheXMgMjQtaG91ci4gQGRlZmF1bHQgZmFsc2UgKi9cbiAgQElucHV0KCkgdXNlMTJIb3VycyA9IGZhbHNlO1xuICAvKiogQWRkcyBhIHNlY29uZHMgY29sdW1uIGFuZCBlbWl0cyBgSEg6bW06c3NgLiBAZGVmYXVsdCBmYWxzZSAqL1xuICBASW5wdXQoKSBzaG93U2Vjb25kcyA9IGZhbHNlO1xuICAvKiogSW50ZXJ2YWwgYmV0d2VlbiBtaW51dGUgZW50cmllcywgaW4gbWludXRlcy4gQGRlZmF1bHQgMSAqL1xuICBASW5wdXQoKSBtaW51dGVTdGVwID0gMTtcbiAgLyoqIEludGVydmFsIGJldHdlZW4gc2Vjb25kIGVudHJpZXMsIGluIHNlY29uZHMuIEBkZWZhdWx0IDEgKi9cbiAgQElucHV0KCkgc2Vjb25kU3RlcCA9IDE7XG4gIC8qKiBFYXJsaWVzdCBzZWxlY3RhYmxlIHRpbWUgYXMgYSAyNC1ob3VyIGBISDptbWAgc3RyaW5nOyBlYXJsaWVyIGVudHJpZXMgYXJlIGRpc2FibGVkLiAqL1xuICBASW5wdXQoKSBtaW4/OiBzdHJpbmc7XG4gIC8qKiBMYXRlc3Qgc2VsZWN0YWJsZSB0aW1lIGFzIGEgMjQtaG91ciBgSEg6bW1gIHN0cmluZzsgbGF0ZXIgZW50cmllcyBhcmUgZGlzYWJsZWQuICovXG4gIEBJbnB1dCgpIG1heD86IHN0cmluZztcbiAgLyoqIEhlaWdodCBhbmQgdGV4dCBzaXplIG9mIHRoZSB0cmlnZ2VyIGFuZCBlbnRyaWVzLiBAZGVmYXVsdCAnZGVmYXVsdCcgKi9cbiAgQElucHV0KCkgc2l6ZTogVGltZVBpY2tlclByb3BzWydzaXplJ10gPSAnZGVmYXVsdCc7XG4gIC8qKiBBcHBsaWVzIHRoZSBkZXN0cnVjdGl2ZSBib3JkZXIgYW5kIGZvY3VzIHJpbmcuIEBkZWZhdWx0IGZhbHNlICovXG4gIEBJbnB1dCgpIGludmFsaWQgPSBmYWxzZTtcbiAgLyoqIEFjY2Vzc2libGUgbmFtZSB3aGVuIHRoZXJlIGlzIG5vIGFzc29jaWF0ZWQgdmlzaWJsZSBsYWJlbC4gQGRlZmF1bHQgJycgKi9cbiAgQElucHV0KCkgYXJpYUxhYmVsID0gJyc7XG4gIC8qKiBFeGNoYW5nZSBgRGF0ZWAgb2JqZWN0cyBpbnN0ZWFkIG9mIGBISDptbWAgc3RyaW5ncyB0aHJvdWdoIHRoZSBmb3JtIGNvbnRyb2wuIEBkZWZhdWx0ICdzdHJpbmcnICovXG4gIEBJbnB1dCgpIHZhbHVlVHlwZTogJ3N0cmluZycgfCAnZGF0ZScgPSAnc3RyaW5nJztcbiAgLyoqIEV4dHJhIFRhaWx3aW5kIGNsYXNzZXMgbWVyZ2VkIG9udG8gdGhlIHRyaWdnZXIgdmlhIGBjbigpYCAobGFzdC13aW5zKS4gKi9cbiAgQElucHV0KCkgY2xhc3MgPSAnJztcblxuICAvKiogRW1pdHRlZCB3aXRoIHRoZSBjaG9zZW4gdGltZSB3aGVuZXZlciBpdCBjaGFuZ2VzLiAqL1xuICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZyB8IERhdGUgfCBudWxsPigpO1xuICAvKiogRW1pdHRlZCB3aGVuIHRoZSBwYW5lbCBvcGVucy4gKi9cbiAgQE91dHB1dCgpIG9wZW5lZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIEVtaXR0ZWQgd2hlbiB0aGUgcGFuZWwgY2xvc2VzLiAqL1xuICBAT3V0cHV0KCkgY2xvc2VkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIEBWaWV3Q2hpbGQoJ3RyaWdnZXInKSB0cmlnZ2VyRWw/OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcbiAgQFZpZXdDaGlsZCgncGFuZWwnKSBwYW5lbEVsPzogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG4gIEBWaWV3Q2hpbGQoJ2NvbHVtbnMnKSBjb2x1bW5zQ21wPzogVGltZUNvbHVtbnNDb21wb25lbnQ7XG5cbiAgcmVhZG9ubHkgcGFuZWxJZCA9ICd0aW1lLXBpY2tlci1wYW5lbC0nICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMiwgMTEpO1xuXG4gIGhvdXI6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICBtaW51dGU6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICBzZWNvbmQ6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICBpc09wZW4gPSBmYWxzZTtcblxuICBwcm90ZWN0ZWQgY24gPSBjbjtcblxuICBwcml2YXRlIGNsZWFudXA/OiAoKSA9PiB2b2lkO1xuICAvKiogVGhlIGRhdGUgaGFsZiBvZiBhIGBEYXRlYCB2YWx1ZSwga2VwdCBzbyByb3VuZC10cmlwcGluZyBkb2VzIG5vdCBtb3ZlIHRoZSBkYXkuICovXG4gIHByaXZhdGUgZGF0ZUFuY2hvcjogRGF0ZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIG9uQ2hhbmdlOiAodmFsdWU6IHN0cmluZyB8IERhdGUgfCBudWxsKSA9PiB2b2lkID0gKCkgPT4ge307XG4gIHByaXZhdGUgb25Ub3VjaGVkOiAoKSA9PiB2b2lkID0gKCkgPT4ge307XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgb3V0c2lkZUNsaWNrSGFuZGxlciA9IChldmVudDogTW91c2VFdmVudCkgPT4ge1xuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBOb2RlO1xuICAgIGlmIChcbiAgICAgICF0aGlzLnRyaWdnZXJFbD8ubmF0aXZlRWxlbWVudC5jb250YWlucyh0YXJnZXQpICYmXG4gICAgICAhdGhpcy5wYW5lbEVsPy5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKHRhcmdldClcbiAgICApIHtcbiAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSByZWFkb25seSBlc2NhcGVIYW5kbGVyID0gKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VzY2FwZScgJiYgdGhpcy5pc09wZW4pIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICB0aGlzLnRyaWdnZXJFbD8ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgIH1cbiAgfTtcblxuICAvKiAtLS0tLS0tLS0tLS0tLS0tIGRlcml2ZWQgLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4gIC8qKiBUaGUgY3VycmVudCBzZWxlY3Rpb24gYXMgd2FsbC1jbG9jayBwYXJ0cywgb3IgYG51bGxgIHdoZW4gaW5jb21wbGV0ZS4gKi9cbiAgZ2V0IHBhcnRzKCk6IFRpbWVQYXJ0cyB8IG51bGwge1xuICAgIGlmICh0aGlzLmhvdXIgPT09IG51bGwgfHwgdGhpcy5taW51dGUgPT09IG51bGwpIHJldHVybiBudWxsO1xuICAgIHJldHVybiB7IGhvdXI6IHRoaXMuaG91ciwgbWludXRlOiB0aGlzLm1pbnV0ZSwgc2Vjb25kOiB0aGlzLnNlY29uZCA/PyAwIH07XG4gIH1cblxuICBnZXQgZGlzcGxheVZhbHVlKCk6IHN0cmluZyB7XG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzO1xuICAgIGlmICghcGFydHMpIHJldHVybiAnJztcblxuICAgIGlmICh0aGlzLnVzZTEySG91cnMpIHtcbiAgICAgIGNvbnN0IHsgaG91cjEyLCBtZXJpZGllbSB9ID0gdG8xMkhvdXIocGFydHMuaG91cik7XG4gICAgICBjb25zdCBib2R5ID1cbiAgICAgICAgU3RyaW5nKGhvdXIxMikgK1xuICAgICAgICAnOicgK1xuICAgICAgICBwYWQyKHBhcnRzLm1pbnV0ZSkgK1xuICAgICAgICAodGhpcy5zaG93U2Vjb25kcyA/ICc6JyArIHBhZDIocGFydHMuc2Vjb25kKSA6ICcnKTtcbiAgICAgIHJldHVybiBib2R5ICsgJyAnICsgbWVyaWRpZW07XG4gICAgfVxuICAgIHJldHVybiBmb3JtYXRUaW1lU3RyaW5nKHBhcnRzLCB0aGlzLnNob3dTZWNvbmRzKTtcbiAgfVxuXG4gIGdldCBtaW5TZWNvbmRzKCk6IG51bWJlciB7XG4gICAgY29uc3QgcGFyc2VkID0gcGFyc2VUaW1lU3RyaW5nKHRoaXMubWluKTtcbiAgICByZXR1cm4gcGFyc2VkID8gdGltZVBhcnRzVG9TZWNvbmRzKHBhcnNlZCkgOiAwO1xuICB9XG5cbiAgZ2V0IG1heFNlY29uZHMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBwYXJzZWQgPSBwYXJzZVRpbWVTdHJpbmcodGhpcy5tYXgpO1xuICAgIHJldHVybiBwYXJzZWQgPyB0aW1lUGFydHNUb1NlY29uZHMocGFyc2VkKSA6IFNFQ09ORFNfUEVSX0RBWSAtIDE7XG4gIH1cblxuICBnZXQgY29tcHV0ZWRUcmlnZ2VyQ2xhc3MoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gY24odGltZVBpY2tlclRyaWdnZXJWYXJpYW50cyh7IHNpemU6IHRoaXMuc2l6ZSwgaW52YWxpZDogdGhpcy5pbnZhbGlkIH0pLCB0aGlzLmNsYXNzKTtcbiAgfVxuXG4gIC8qIC0tLS0tLS0tLS0tLS0tLS0gb3BlbiAvIGNsb3NlIC0tLS0tLS0tLS0tLS0tLS0gKi9cblxuICB0b2dnbGUoKTogdm9pZCB7XG4gICAgdGhpcy5pc09wZW4gPyB0aGlzLmNsb3NlKCkgOiB0aGlzLm9wZW4oKTtcbiAgfVxuXG4gIG9wZW4oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQgfHwgdGhpcy5pc09wZW4pIHJldHVybjtcbiAgICB0aGlzLmlzT3BlbiA9IHRydWU7XG4gICAgdGhpcy5vcGVuZWQuZW1pdCgpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnVwZGF0ZVBvc2l0aW9uKCk7XG4gICAgICB0aGlzLmNvbHVtbnNDbXA/LnNjcm9sbFNlbGVjdGVkSW50b1ZpZXcoKTtcbiAgICAgIHRoaXMuY29sdW1uc0NtcD8uZm9jdXNGaXJzdENvbHVtbigpO1xuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCB0aGlzLm91dHNpZGVDbGlja0hhbmRsZXIsIHRydWUpO1xuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMuZXNjYXBlSGFuZGxlciwgdHJ1ZSk7XG4gICAgfSk7XG4gIH1cblxuICBjbG9zZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNPcGVuKSByZXR1cm47XG4gICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcbiAgICB0aGlzLmNsb3NlZC5lbWl0KCk7XG4gICAgdGhpcy5vblRvdWNoZWQoKTtcbiAgICB0aGlzLnRlYXJkb3duKCk7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBvblRyaWdnZXJLZXlEb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKFsnQXJyb3dEb3duJywgJ0Fycm93VXAnLCAnRW50ZXInLCAnICddLmluY2x1ZGVzKGV2ZW50LmtleSkgJiYgIXRoaXMuaXNPcGVuKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdGhpcy5vcGVuKCk7XG4gICAgfVxuICB9XG5cbiAgLyogLS0tLS0tLS0tLS0tLS0tLSB2YWx1ZSAtLS0tLS0tLS0tLS0tLS0tICovXG5cbiAgb25UaW1lQ2hhbmdlKHBhcnRzOiBUaW1lUGFydHMpOiB2b2lkIHtcbiAgICB0aGlzLmhvdXIgPSBwYXJ0cy5ob3VyO1xuICAgIHRoaXMubWludXRlID0gcGFydHMubWludXRlO1xuICAgIHRoaXMuc2Vjb25kID0gcGFydHMuc2Vjb25kO1xuICAgIHRoaXMuZW1pdCgpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0KCk6IHZvaWQge1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5jdXJyZW50VmFsdWUoKTtcbiAgICB0aGlzLm9uQ2hhbmdlKHZhbHVlKTtcbiAgICB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQodmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBjdXJyZW50VmFsdWUoKTogc3RyaW5nIHwgRGF0ZSB8IG51bGwge1xuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cztcbiAgICBpZiAoIXBhcnRzKSByZXR1cm4gbnVsbDtcbiAgICBpZiAodGhpcy52YWx1ZVR5cGUgPT09ICdkYXRlJykge1xuICAgICAgY29uc3QgYmFzZSA9IHRoaXMuZGF0ZUFuY2hvciA/PyBuZXcgRGF0ZSgpO1xuICAgICAgcmV0dXJuIG5ldyBEYXRlKFxuICAgICAgICBiYXNlLmdldEZ1bGxZZWFyKCksXG4gICAgICAgIGJhc2UuZ2V0TW9udGgoKSxcbiAgICAgICAgYmFzZS5nZXREYXRlKCksXG4gICAgICAgIHBhcnRzLmhvdXIsXG4gICAgICAgIHBhcnRzLm1pbnV0ZSxcbiAgICAgICAgcGFydHMuc2Vjb25kLFxuICAgICAgICAwXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gZm9ybWF0VGltZVN0cmluZyhwYXJ0cywgdGhpcy5zaG93U2Vjb25kcyk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVBvc2l0aW9uKCk6IHZvaWQge1xuICAgIGNvbnN0IHRyaWdnZXIgPSB0aGlzLnRyaWdnZXJFbD8ubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCBwYW5lbCA9IHRoaXMucGFuZWxFbD8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIXRyaWdnZXIgfHwgIXBhbmVsKSByZXR1cm47XG5cbiAgICB0aGlzLmNsZWFudXAgPSBhdXRvVXBkYXRlKHRyaWdnZXIsIHBhbmVsLCAoKSA9PiB7XG4gICAgICBjb21wdXRlUG9zaXRpb24odHJpZ2dlciwgcGFuZWwsIHtcbiAgICAgICAgc3RyYXRlZ3k6ICdmaXhlZCcsXG4gICAgICAgIHBsYWNlbWVudDogJ2JvdHRvbS1zdGFydCcsXG4gICAgICAgIG1pZGRsZXdhcmU6IFtvZmZzZXQoNCksIGZsaXAoKSwgc2hpZnQoeyBwYWRkaW5nOiA4IH0pXSxcbiAgICAgIH0pLnRoZW4oKHsgeCwgeSB9KSA9PiB7XG4gICAgICAgIE9iamVjdC5hc3NpZ24ocGFuZWwuc3R5bGUsIHtcbiAgICAgICAgICBsZWZ0OiB4ICsgJ3B4JyxcbiAgICAgICAgICB0b3A6IHkgKyAncHgnLFxuICAgICAgICAgIHZpc2liaWxpdHk6ICd2aXNpYmxlJyxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdGVhcmRvd24oKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhbnVwPy4oKTtcbiAgICB0aGlzLmNsZWFudXAgPSB1bmRlZmluZWQ7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCB0aGlzLm91dHNpZGVDbGlja0hhbmRsZXIsIHRydWUpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLmVzY2FwZUhhbmRsZXIsIHRydWUpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy50ZWFyZG93bigpO1xuICB9XG5cbiAgLyogLS0tLS0tLS0tLS0tLS0tLSBDb250cm9sVmFsdWVBY2Nlc3NvciAtLS0tLS0tLS0tLS0tLS0tICovXG5cbiAgd3JpdGVWYWx1ZSh2YWx1ZTogc3RyaW5nIHwgRGF0ZSB8IG51bGwgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgICBsZXQgcGFydHM6IFRpbWVQYXJ0cyB8IG51bGwgPSBudWxsO1xuXG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSAmJiAhaXNOYU4odmFsdWUuZ2V0VGltZSgpKSkge1xuICAgICAgdGhpcy5kYXRlQW5jaG9yID0gdmFsdWU7XG4gICAgICBwYXJ0cyA9IHsgaG91cjogdmFsdWUuZ2V0SG91cnMoKSwgbWludXRlOiB2YWx1ZS5nZXRNaW51dGVzKCksIHNlY29uZDogdmFsdWUuZ2V0U2Vjb25kcygpIH07XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBwYXJ0cyA9IHBhcnNlVGltZVN0cmluZyh2YWx1ZSk7XG4gICAgfVxuXG4gICAgdGhpcy5ob3VyID0gcGFydHMgPyBwYXJ0cy5ob3VyIDogbnVsbDtcbiAgICB0aGlzLm1pbnV0ZSA9IHBhcnRzID8gcGFydHMubWludXRlIDogbnVsbDtcbiAgICB0aGlzLnNlY29uZCA9IHBhcnRzID8gcGFydHMuc2Vjb25kIDogbnVsbDtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46ICh2YWx1ZTogc3RyaW5nIHwgRGF0ZSB8IG51bGwpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIH1cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gIH1cblxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgICBpZiAoaXNEaXNhYmxlZCkgdGhpcy5jbG9zZSgpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG59XG4iXX0=