@tolle_/tolle-ui 18.2.28 → 18.2.30

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 (279) 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 +5 -10
  4. package/esm2022/lib/alert-dialog.component.mjs +44 -59
  5. package/esm2022/lib/alert.component.mjs +5 -11
  6. package/esm2022/lib/aspect-ratio.component.mjs +119 -0
  7. package/esm2022/lib/attachment.component.mjs +334 -0
  8. package/esm2022/lib/avatar-fallback.component.mjs +3 -3
  9. package/esm2022/lib/avatar.component.mjs +4 -9
  10. package/esm2022/lib/badge.component.mjs +4 -9
  11. package/esm2022/lib/breadcrumb-item.component.mjs +3 -3
  12. package/esm2022/lib/breadcrumb-link.component.mjs +3 -3
  13. package/esm2022/lib/breadcrumb-separator.component.mjs +3 -3
  14. package/esm2022/lib/breadcrumb.component.mjs +3 -3
  15. package/esm2022/lib/bubble.component.mjs +301 -0
  16. package/esm2022/lib/button.component.mjs +5 -11
  17. package/esm2022/lib/calendar.component.mjs +5 -11
  18. package/esm2022/lib/card.component.mjs +14 -43
  19. package/esm2022/lib/carousel/carousel.component.mjs +5 -12
  20. package/esm2022/lib/chain-of-thought.component.mjs +380 -0
  21. package/esm2022/lib/chart-pie.component.mjs +386 -0
  22. package/esm2022/lib/chart.component.mjs +1146 -0
  23. package/esm2022/lib/chart.service.mjs +555 -0
  24. package/esm2022/lib/checkbox.component.mjs +5 -11
  25. package/esm2022/lib/checkpoint.component.mjs +134 -0
  26. package/esm2022/lib/collapsible.component.mjs +4 -11
  27. package/esm2022/lib/combobox.component.mjs +372 -0
  28. package/esm2022/lib/command-dialog.component.mjs +164 -0
  29. package/esm2022/lib/command.component.mjs +514 -0
  30. package/esm2022/lib/command.service.mjs +130 -0
  31. package/esm2022/lib/confirmation.component.mjs +219 -0
  32. package/esm2022/lib/context-menu-trigger.directive.mjs +36 -0
  33. package/esm2022/lib/context-menu.component.mjs +460 -0
  34. package/esm2022/lib/context-menu.service.mjs +121 -0
  35. package/esm2022/lib/context.component.mjs +377 -0
  36. package/esm2022/lib/conversation.component.mjs +442 -0
  37. package/esm2022/lib/country-selector.component.mjs +5 -11
  38. package/esm2022/lib/data-table.component.mjs +63 -12
  39. package/esm2022/lib/date-picker.component.mjs +251 -198
  40. package/esm2022/lib/date-range-picker.component.mjs +224 -116
  41. package/esm2022/lib/date-time-picker.component.mjs +506 -0
  42. package/esm2022/lib/direction.component.mjs +79 -0
  43. package/esm2022/lib/dropdown-item.component.mjs +3 -3
  44. package/esm2022/lib/dropdown-label.component.mjs +3 -3
  45. package/esm2022/lib/dropdown-menu.component.mjs +3 -3
  46. package/esm2022/lib/dropdown-separator.component.mjs +3 -3
  47. package/esm2022/lib/dropdown-trigger.directive.mjs +6 -4
  48. package/esm2022/lib/empty-state.component.mjs +4 -9
  49. package/esm2022/lib/field.component.mjs +394 -0
  50. package/esm2022/lib/hover-card.component.mjs +6 -16
  51. package/esm2022/lib/inline-citation.component.mjs +263 -0
  52. package/esm2022/lib/input-group.component.mjs +418 -0
  53. package/esm2022/lib/input.component.mjs +5 -11
  54. package/esm2022/lib/item.component.mjs +243 -0
  55. package/esm2022/lib/kbd.component.mjs +82 -0
  56. package/esm2022/lib/label.component.mjs +4 -9
  57. package/esm2022/lib/marker.component.mjs +135 -0
  58. package/esm2022/lib/masked-input.component.mjs +5 -11
  59. package/esm2022/lib/menubar.component.mjs +683 -0
  60. package/esm2022/lib/message-scroller.component.mjs +353 -0
  61. package/esm2022/lib/message-scroller.service.mjs +157 -0
  62. package/esm2022/lib/message.component.mjs +228 -0
  63. package/esm2022/lib/model-selector.component.mjs +310 -0
  64. package/esm2022/lib/multi-select.component.mjs +155 -72
  65. package/esm2022/lib/native-select.component.mjs +201 -0
  66. package/esm2022/lib/navigation-menu.component.mjs +642 -0
  67. package/esm2022/lib/otp-group.component.mjs +3 -3
  68. package/esm2022/lib/otp-slot.component.mjs +4 -9
  69. package/esm2022/lib/otp.component.mjs +5 -11
  70. package/esm2022/lib/pagination.component.mjs +7 -10
  71. package/esm2022/lib/plan.component.mjs +335 -0
  72. package/esm2022/lib/popover-content.component.mjs +4 -9
  73. package/esm2022/lib/popover.component.mjs +15 -13
  74. package/esm2022/lib/progress.component.mjs +4 -9
  75. package/esm2022/lib/prompt-input.component.mjs +526 -0
  76. package/esm2022/lib/queue.component.mjs +280 -0
  77. package/esm2022/lib/radio-group.component.mjs +6 -13
  78. package/esm2022/lib/radio-item.component.mjs +4 -9
  79. package/esm2022/lib/range-calendar.component.mjs +5 -11
  80. package/esm2022/lib/reasoning.component.mjs +335 -0
  81. package/esm2022/lib/resizable.component.mjs +219 -0
  82. package/esm2022/lib/segment.component.mjs +17 -7
  83. package/esm2022/lib/select-group.component.mjs +4 -8
  84. package/esm2022/lib/select-item.component.mjs +4 -9
  85. package/esm2022/lib/select-separator.component.mjs +4 -8
  86. package/esm2022/lib/select.component.mjs +133 -49
  87. package/esm2022/lib/separator.component.mjs +4 -9
  88. package/esm2022/lib/sheet.component.mjs +38 -56
  89. package/esm2022/lib/shimmer.component.mjs +84 -0
  90. package/esm2022/lib/sidebar.component.mjs +11 -1
  91. package/esm2022/lib/skeleton.component.mjs +4 -9
  92. package/esm2022/lib/sources.component.mjs +452 -0
  93. package/esm2022/lib/spinner.component.mjs +68 -0
  94. package/esm2022/lib/suggestion.component.mjs +207 -0
  95. package/esm2022/lib/switch.component.mjs +5 -11
  96. package/esm2022/lib/table.component.mjs +213 -0
  97. package/esm2022/lib/tabs.component.mjs +4 -11
  98. package/esm2022/lib/tag-input.component.mjs +5 -11
  99. package/esm2022/lib/task.component.mjs +359 -0
  100. package/esm2022/lib/textarea.component.mjs +5 -11
  101. package/esm2022/lib/theme.service.mjs +17 -6
  102. package/esm2022/lib/time-picker.component.mjs +923 -0
  103. package/esm2022/lib/toast.service.mjs +3 -2
  104. package/esm2022/lib/toaster.component.mjs +76 -39
  105. package/esm2022/lib/toggle-group.component.mjs +4 -9
  106. package/esm2022/lib/toggle.component.mjs +5 -11
  107. package/esm2022/lib/tool.component.mjs +462 -0
  108. package/esm2022/lib/typography.component.mjs +83 -0
  109. package/esm2022/lib/utils/color.mjs +140 -19
  110. package/esm2022/public-api.mjs +61 -1
  111. package/fesm2022/tolle-ui.mjs +16457 -1024
  112. package/fesm2022/tolle-ui.mjs.map +1 -1
  113. package/lib/alert-dialog.component.d.ts +10 -2
  114. package/lib/aspect-ratio.component.d.ts +20 -0
  115. package/lib/attachment.component.d.ts +101 -0
  116. package/lib/bubble.component.d.ts +112 -0
  117. package/lib/chain-of-thought.component.d.ts +166 -0
  118. package/lib/chart-pie.component.d.ts +108 -0
  119. package/lib/chart.component.d.ts +369 -0
  120. package/lib/chart.service.d.ts +222 -0
  121. package/lib/checkpoint.component.d.ts +51 -0
  122. package/lib/combobox.component.d.ts +90 -0
  123. package/lib/command-dialog.component.d.ts +53 -0
  124. package/lib/command.component.d.ts +189 -0
  125. package/lib/command.service.d.ts +67 -0
  126. package/lib/confirmation.component.d.ts +70 -0
  127. package/lib/context-menu-trigger.directive.d.ts +12 -0
  128. package/lib/context-menu.component.d.ts +41 -0
  129. package/lib/context-menu.service.d.ts +38 -0
  130. package/lib/context.component.d.ts +134 -0
  131. package/lib/conversation.component.d.ts +165 -0
  132. package/lib/data-table.component.d.ts +27 -1
  133. package/lib/date-picker.component.d.ts +72 -11
  134. package/lib/date-range-picker.component.d.ts +63 -6
  135. package/lib/date-time-picker.component.d.ts +119 -0
  136. package/lib/direction.component.d.ts +45 -0
  137. package/lib/field.component.d.ts +201 -0
  138. package/lib/inline-citation.component.d.ts +103 -0
  139. package/lib/input-group.component.d.ts +150 -0
  140. package/lib/item.component.d.ts +154 -0
  141. package/lib/kbd.component.d.ts +50 -0
  142. package/lib/marker.component.d.ts +58 -0
  143. package/lib/menubar.component.d.ts +247 -0
  144. package/lib/message-scroller.component.d.ts +159 -0
  145. package/lib/message-scroller.service.d.ts +73 -0
  146. package/lib/message.component.d.ts +128 -0
  147. package/lib/model-selector.component.d.ts +103 -0
  148. package/lib/multi-select.component.d.ts +66 -14
  149. package/lib/native-select.component.d.ts +57 -0
  150. package/lib/navigation-menu.component.d.ts +230 -0
  151. package/lib/plan.component.d.ts +120 -0
  152. package/lib/popover.component.d.ts +1 -0
  153. package/lib/prompt-input.component.d.ts +194 -0
  154. package/lib/queue.component.d.ts +106 -0
  155. package/lib/reasoning.component.d.ts +127 -0
  156. package/lib/resizable.component.d.ts +43 -0
  157. package/lib/segment.component.d.ts +13 -3
  158. package/lib/select.component.d.ts +37 -5
  159. package/lib/sheet.component.d.ts +3 -0
  160. package/lib/shimmer.component.d.ts +38 -0
  161. package/lib/sidebar.component.d.ts +2 -0
  162. package/lib/sources.component.d.ts +156 -0
  163. package/lib/spinner.component.d.ts +29 -0
  164. package/lib/suggestion.component.d.ts +96 -0
  165. package/lib/table.component.d.ts +106 -0
  166. package/lib/task.component.d.ts +151 -0
  167. package/lib/theme.service.d.ts +9 -0
  168. package/lib/time-picker.component.d.ts +243 -0
  169. package/lib/toast.service.d.ts +3 -1
  170. package/lib/toaster.component.d.ts +26 -9
  171. package/lib/tool.component.d.ts +158 -0
  172. package/lib/typography.component.d.ts +32 -0
  173. package/lib/utils/color.d.ts +19 -5
  174. package/package.json +1 -1
  175. package/public-api.d.ts +50 -0
  176. package/registry/docs-content.json +8497 -1553
  177. package/registry/llms-full.txt +2679 -318
  178. package/registry/llms.txt +43 -4
  179. package/registry/manifest.json +9093 -1739
  180. package/registry/r/accordion-item.json +1 -1
  181. package/registry/r/accordion.json +1 -1
  182. package/registry/r/alert-dialog-dynamic.json +1 -1
  183. package/registry/r/alert-dialog.json +1 -1
  184. package/registry/r/alert.json +1 -1
  185. package/registry/r/attachment.json +23 -0
  186. package/registry/r/avatar-fallback.json +1 -1
  187. package/registry/r/avatar.json +1 -1
  188. package/registry/r/badge.json +1 -1
  189. package/registry/r/breadcrumb-item.json +1 -1
  190. package/registry/r/breadcrumb-link.json +1 -1
  191. package/registry/r/breadcrumb-separator.json +1 -1
  192. package/registry/r/breadcrumb.json +1 -1
  193. package/registry/r/bubble.json +23 -0
  194. package/registry/r/button.json +1 -1
  195. package/registry/r/calendar.json +1 -1
  196. package/registry/r/card.json +1 -1
  197. package/registry/r/carousel.json +1 -1
  198. package/registry/r/chain-of-thought.json +23 -0
  199. package/registry/r/chart-pie.json +30 -0
  200. package/registry/r/chart.json +28 -0
  201. package/registry/r/checkbox.json +1 -1
  202. package/registry/r/checkpoint.json +23 -0
  203. package/registry/r/collapsible.json +1 -1
  204. package/registry/r/combobox.json +31 -0
  205. package/registry/r/command-dialog.json +21 -0
  206. package/registry/r/command.json +26 -0
  207. package/registry/r/confirmation.json +23 -0
  208. package/registry/r/context.json +26 -0
  209. package/registry/r/conversation.json +23 -0
  210. package/registry/r/country-selector.json +1 -1
  211. package/registry/r/data-table.json +1 -1
  212. package/registry/r/date-picker.json +4 -4
  213. package/registry/r/date-range-picker.json +3 -3
  214. package/registry/r/date-time-picker.json +28 -0
  215. package/registry/r/direction.json +16 -0
  216. package/registry/r/dropdown-item.json +1 -1
  217. package/registry/r/dropdown-label.json +1 -1
  218. package/registry/r/dropdown-menu.json +1 -1
  219. package/registry/r/dropdown-separator.json +1 -1
  220. package/registry/r/dropdown-trigger.json +1 -1
  221. package/registry/r/empty-state.json +1 -1
  222. package/registry/r/field.json +23 -0
  223. package/registry/r/hover-card.json +1 -1
  224. package/registry/r/inline-citation.json +26 -0
  225. package/registry/r/input-group.json +23 -0
  226. package/registry/r/input.json +1 -1
  227. package/registry/r/item.json +23 -0
  228. package/registry/r/kbd.json +23 -0
  229. package/registry/r/label.json +1 -1
  230. package/registry/r/marker.json +23 -0
  231. package/registry/r/masked-input.json +1 -1
  232. package/registry/r/menubar.json +24 -0
  233. package/registry/r/message-scroller.json +26 -0
  234. package/registry/r/message.json +23 -0
  235. package/registry/r/model-selector.json +32 -0
  236. package/registry/r/multi-select.json +2 -2
  237. package/registry/r/native-select.json +23 -0
  238. package/registry/r/navigation-menu.json +24 -0
  239. package/registry/r/otp-group.json +1 -1
  240. package/registry/r/otp-slot.json +1 -1
  241. package/registry/r/otp.json +1 -1
  242. package/registry/r/pagination.json +3 -2
  243. package/registry/r/plan.json +23 -0
  244. package/registry/r/popover-content.json +1 -1
  245. package/registry/r/popover.json +1 -1
  246. package/registry/r/progress.json +1 -1
  247. package/registry/r/prompt-input.json +23 -0
  248. package/registry/r/queue.json +23 -0
  249. package/registry/r/radio-group.json +1 -1
  250. package/registry/r/radio-item.json +1 -1
  251. package/registry/r/range-calendar.json +1 -1
  252. package/registry/r/reasoning.json +23 -0
  253. package/registry/r/segment.json +1 -1
  254. package/registry/r/select-group.json +1 -1
  255. package/registry/r/select-item.json +1 -1
  256. package/registry/r/select-separator.json +1 -1
  257. package/registry/r/select.json +4 -3
  258. package/registry/r/separator.json +1 -1
  259. package/registry/r/sheet.json +1 -1
  260. package/registry/r/shimmer.json +23 -0
  261. package/registry/r/sidebar.json +1 -1
  262. package/registry/r/skeleton.json +1 -1
  263. package/registry/r/sources.json +23 -0
  264. package/registry/r/spinner.json +23 -0
  265. package/registry/r/suggestion.json +23 -0
  266. package/registry/r/switch.json +1 -1
  267. package/registry/r/table.json +21 -0
  268. package/registry/r/tabs.json +1 -1
  269. package/registry/r/tag-input.json +1 -1
  270. package/registry/r/task.json +23 -0
  271. package/registry/r/textarea.json +1 -1
  272. package/registry/r/time-picker.json +24 -0
  273. package/registry/r/toaster.json +2 -2
  274. package/registry/r/toggle-group.json +1 -1
  275. package/registry/r/toggle.json +1 -1
  276. package/registry/r/tool.json +23 -0
  277. package/registry/r/typography.json +23 -0
  278. package/registry/registry.json +915 -22
  279. package/theme.css +109 -8
@@ -0,0 +1,506 @@
1
+ import { Component, Input, Output, EventEmitter, forwardRef, ViewChild, ChangeDetectionStrategy } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
4
+ import { computePosition, flip, shift, offset, autoUpdate } from '@floating-ui/dom';
5
+ import { cva } from 'class-variance-authority';
6
+ import { format, isSameDay, isValid, startOfDay } from 'date-fns';
7
+ import { cn } from './utils/cn';
8
+ import { CalendarComponent } from './calendar.component';
9
+ import { TimeColumnsComponent, to12Hour } from './time-picker.component';
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "@angular/common";
12
+ import * as i2 from "@angular/forms";
13
+ const SECONDS_PER_DAY = 24 * 3600;
14
+ const dateTimePickerTriggerVariants = cva('flex w-full items-center justify-between gap-2 rounded-md border border-input bg-background text-foreground shadow-sm transition-colors ' +
15
+ 'focus:outline-none focus-visible:border-primary/80 focus-visible:ring-4 focus-visible:ring-ring/30 ' +
16
+ 'disabled:cursor-not-allowed disabled:opacity-50', {
17
+ variants: {
18
+ size: {
19
+ xs: 'h-8 px-2 text-xs',
20
+ sm: 'h-9 px-3 text-sm',
21
+ default: 'h-10 px-3 text-sm',
22
+ lg: 'h-11 px-4 text-base',
23
+ },
24
+ invalid: {
25
+ true: 'border-destructive focus-visible:border-destructive/80 focus-visible:ring-destructive/30',
26
+ false: '',
27
+ },
28
+ },
29
+ defaultVariants: { size: 'default', invalid: false },
30
+ });
31
+ /**
32
+ * One control for a date *and* a time: `tolle-calendar` on the left, the
33
+ * `tolle-time-columns` strip on the right, in a single floating panel with a
34
+ * Clear / Done footer.
35
+ *
36
+ * The value is a `Date`, because a date-time genuinely is a moment. Changing
37
+ * the date preserves the chosen time and changing the time preserves the
38
+ * chosen date — the two halves are only ever recombined, never reset.
39
+ *
40
+ * Implements `ControlValueAccessor`, so it works with `ngModel` and reactive
41
+ * forms. Use `tolle-date-picker` for a date alone and `tolle-time-picker` for a
42
+ * time alone.
43
+ * @new
44
+ */
45
+ export class DateTimePickerComponent {
46
+ cdr;
47
+ /** Text shown on the trigger when nothing is selected. @default 'Select date and time' */
48
+ placeholder = 'Select date and time';
49
+ /** Disables the control. @default false */
50
+ disabled = false;
51
+ /** Renders a 12-hour face with an AM/PM column. @default false */
52
+ use12Hours = false;
53
+ /** Adds a seconds column. @default false */
54
+ showSeconds = false;
55
+ /** Interval between minute entries, in minutes. @default 1 */
56
+ minuteStep = 1;
57
+ /** Earliest selectable moment; earlier days and times are disabled. */
58
+ min;
59
+ /** Latest selectable moment; later days and times are disabled. */
60
+ max;
61
+ /** date-fns pattern used to render the value on the trigger. @default 'MMM d, yyyy h:mm a' */
62
+ displayFormat = 'MMM d, yyyy h:mm a';
63
+ /** Height and text size of the trigger and entries. @default 'default' */
64
+ size = 'default';
65
+ /** Applies the destructive border and focus ring. @default false */
66
+ invalid = false;
67
+ /** Accessible name when there is no associated visible label. @default '' */
68
+ ariaLabel = '';
69
+ /** Extra Tailwind classes merged onto the trigger via `cn()` (last-wins). */
70
+ class = '';
71
+ /** Emitted with the chosen moment, or `null` when the value is cleared. */
72
+ valueChange = new EventEmitter();
73
+ /** Emitted when the panel opens. */
74
+ opened = new EventEmitter();
75
+ /** Emitted when the panel closes. */
76
+ closed = new EventEmitter();
77
+ triggerEl;
78
+ panelEl;
79
+ columnsCmp;
80
+ panelId = 'date-time-picker-panel-' + Math.random().toString(36).slice(2, 11);
81
+ value = null;
82
+ isOpen = false;
83
+ /**
84
+ * Day-only copies of `min` / `max` for the calendar. The calendar compares
85
+ * whole `Date`s, so passing a bound that carries a time would disable its own
86
+ * day — 09:00 on the min day would look "before" a 09:30 minimum.
87
+ */
88
+ calendarMin;
89
+ calendarMax;
90
+ footerButtonClass = cn('rounded-md px-3 py-1.5 text-sm font-medium text-muted-foreground transition-colors', 'hover:bg-accent hover:text-accent-foreground', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring');
91
+ cn = cn;
92
+ cleanup;
93
+ onChange = () => { };
94
+ onTouched = () => { };
95
+ constructor(cdr) {
96
+ this.cdr = cdr;
97
+ }
98
+ ngOnChanges() {
99
+ this.calendarMin = this.min ? startOfDay(this.min) : undefined;
100
+ this.calendarMax = this.max ? startOfDay(this.max) : undefined;
101
+ // A bound `class` input is written through Angular's styling path,
102
+ // which does not mark an OnPush view dirty on its own.
103
+ this.cdr.markForCheck();
104
+ }
105
+ outsideClickHandler = (event) => {
106
+ const target = event.target;
107
+ if (!this.triggerEl?.nativeElement.contains(target) &&
108
+ !this.panelEl?.nativeElement.contains(target)) {
109
+ this.close();
110
+ }
111
+ };
112
+ escapeHandler = (event) => {
113
+ if (event.key === 'Escape' && this.isOpen) {
114
+ event.preventDefault();
115
+ this.close();
116
+ this.triggerEl?.nativeElement.focus();
117
+ }
118
+ };
119
+ /* ---------------- derived ---------------- */
120
+ get hour() {
121
+ return this.value ? this.value.getHours() : null;
122
+ }
123
+ get minute() {
124
+ return this.value ? this.value.getMinutes() : null;
125
+ }
126
+ get second() {
127
+ return this.value ? this.value.getSeconds() : null;
128
+ }
129
+ get displayValue() {
130
+ if (!this.value)
131
+ return '';
132
+ try {
133
+ return format(this.value, this.displayFormat);
134
+ }
135
+ catch {
136
+ // A bad pattern should not blank the control; fall back to something readable.
137
+ const { hour12, meridiem } = to12Hour(this.value.getHours());
138
+ return (format(this.value, 'MMM d, yyyy') +
139
+ ' ' +
140
+ hour12 +
141
+ ':' +
142
+ String(this.value.getMinutes()).padStart(2, '0') +
143
+ ' ' +
144
+ meridiem);
145
+ }
146
+ }
147
+ /**
148
+ * The time bound only bites on the boundary day itself: on the min day the
149
+ * columns start at the min time, on any later day they start at midnight.
150
+ */
151
+ get minSeconds() {
152
+ if (!this.min)
153
+ return 0;
154
+ const day = this.value ?? this.min;
155
+ if (!isSameDay(day, this.min))
156
+ return 0;
157
+ return this.min.getHours() * 3600 + this.min.getMinutes() * 60 + this.min.getSeconds();
158
+ }
159
+ get maxSeconds() {
160
+ if (!this.max)
161
+ return SECONDS_PER_DAY - 1;
162
+ const day = this.value ?? this.max;
163
+ if (!isSameDay(day, this.max))
164
+ return SECONDS_PER_DAY - 1;
165
+ return this.max.getHours() * 3600 + this.max.getMinutes() * 60 + this.max.getSeconds();
166
+ }
167
+ get computedTriggerClass() {
168
+ return cn(dateTimePickerTriggerVariants({ size: this.size, invalid: this.invalid }), this.class);
169
+ }
170
+ /* ---------------- open / close ---------------- */
171
+ toggle() {
172
+ this.isOpen ? this.close() : this.open();
173
+ }
174
+ open() {
175
+ if (this.disabled || this.isOpen)
176
+ return;
177
+ this.isOpen = true;
178
+ this.opened.emit();
179
+ this.cdr.markForCheck();
180
+ setTimeout(() => {
181
+ this.updatePosition();
182
+ this.columnsCmp?.scrollSelectedIntoView();
183
+ document.addEventListener('pointerdown', this.outsideClickHandler, true);
184
+ document.addEventListener('keydown', this.escapeHandler, true);
185
+ });
186
+ }
187
+ close() {
188
+ if (!this.isOpen)
189
+ return;
190
+ this.isOpen = false;
191
+ this.closed.emit();
192
+ this.onTouched();
193
+ this.teardown();
194
+ this.cdr.markForCheck();
195
+ }
196
+ onTriggerKeyDown(event) {
197
+ if (['ArrowDown', 'ArrowUp', 'Enter', ' '].includes(event.key) && !this.isOpen) {
198
+ event.preventDefault();
199
+ this.open();
200
+ }
201
+ }
202
+ /* ---------------- value ---------------- */
203
+ /**
204
+ * Applies a newly picked day, carrying the existing time across. With no
205
+ * time chosen yet the day starts at midnight.
206
+ */
207
+ onDateSelect(date) {
208
+ if (!date) {
209
+ this.clear();
210
+ return;
211
+ }
212
+ const previous = this.value;
213
+ this.commit(new Date(date.getFullYear(), date.getMonth(), date.getDate(), previous ? previous.getHours() : 0, previous ? previous.getMinutes() : 0, previous ? previous.getSeconds() : 0, 0));
214
+ }
215
+ /**
216
+ * Applies a newly picked time, carrying the existing day across. With no day
217
+ * chosen yet the time lands on today.
218
+ */
219
+ onTimeChange(parts) {
220
+ const base = this.value ?? new Date();
221
+ this.commit(new Date(base.getFullYear(), base.getMonth(), base.getDate(), parts.hour, parts.minute, parts.second, 0));
222
+ }
223
+ clear() {
224
+ this.commit(null);
225
+ // The calendar keeps its own selection and ignores a null written through
226
+ // the CVA, so closing is what actually returns it to a clean state — it is
227
+ // rebuilt from scratch the next time the panel opens.
228
+ this.close();
229
+ }
230
+ done() {
231
+ this.close();
232
+ this.triggerEl?.nativeElement.focus();
233
+ }
234
+ commit(next) {
235
+ this.value = next;
236
+ this.onChange(next);
237
+ this.valueChange.emit(next);
238
+ this.cdr.markForCheck();
239
+ }
240
+ updatePosition() {
241
+ const trigger = this.triggerEl?.nativeElement;
242
+ const panel = this.panelEl?.nativeElement;
243
+ if (!trigger || !panel)
244
+ return;
245
+ this.cleanup = autoUpdate(trigger, panel, () => {
246
+ computePosition(trigger, panel, {
247
+ strategy: 'fixed',
248
+ placement: 'bottom-start',
249
+ middleware: [offset(4), flip(), shift({ padding: 8 })],
250
+ }).then(({ x, y }) => {
251
+ Object.assign(panel.style, {
252
+ left: x + 'px',
253
+ top: y + 'px',
254
+ visibility: 'visible',
255
+ });
256
+ });
257
+ });
258
+ }
259
+ teardown() {
260
+ this.cleanup?.();
261
+ this.cleanup = undefined;
262
+ document.removeEventListener('pointerdown', this.outsideClickHandler, true);
263
+ document.removeEventListener('keydown', this.escapeHandler, true);
264
+ }
265
+ ngOnDestroy() {
266
+ this.teardown();
267
+ }
268
+ /* ---------------- ControlValueAccessor ---------------- */
269
+ writeValue(value) {
270
+ if (value instanceof Date && isValid(value)) {
271
+ this.value = value;
272
+ }
273
+ else if (typeof value === 'string' && value) {
274
+ const parsed = new Date(value);
275
+ this.value = isValid(parsed) ? parsed : null;
276
+ }
277
+ else {
278
+ this.value = null;
279
+ }
280
+ this.cdr.markForCheck();
281
+ }
282
+ registerOnChange(fn) {
283
+ this.onChange = fn;
284
+ }
285
+ registerOnTouched(fn) {
286
+ this.onTouched = fn;
287
+ }
288
+ setDisabledState(isDisabled) {
289
+ this.disabled = isDisabled;
290
+ if (isDisabled)
291
+ this.close();
292
+ this.cdr.markForCheck();
293
+ }
294
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DateTimePickerComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
295
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DateTimePickerComponent, isStandalone: true, selector: "tolle-date-time-picker", inputs: { placeholder: "placeholder", disabled: "disabled", use12Hours: "use12Hours", showSeconds: "showSeconds", minuteStep: "minuteStep", min: "min", max: "max", displayFormat: "displayFormat", size: "size", invalid: "invalid", ariaLabel: "ariaLabel", class: "class" }, outputs: { valueChange: "valueChange", opened: "opened", closed: "closed" }, providers: [
296
+ {
297
+ provide: NG_VALUE_ACCESSOR,
298
+ useExisting: forwardRef(() => DateTimePickerComponent),
299
+ multi: true,
300
+ },
301
+ ], 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: `
302
+ <button
303
+ #trigger
304
+ type="button"
305
+ aria-haspopup="dialog"
306
+ [attr.aria-expanded]="isOpen"
307
+ [attr.aria-controls]="isOpen ? panelId : null"
308
+ [attr.aria-label]="ariaLabel || null"
309
+ [attr.data-state]="isOpen ? 'open' : 'closed'"
310
+ [disabled]="disabled"
311
+ [class]="computedTriggerClass"
312
+ (click)="toggle()"
313
+ (keydown)="onTriggerKeyDown($event)"
314
+ >
315
+ <span [class]="cn('truncate', displayValue ? 'text-foreground' : 'text-muted-foreground')">
316
+ {{ displayValue || placeholder }}
317
+ </span>
318
+ <i class="ri-calendar-schedule-line shrink-0 text-muted-foreground" aria-hidden="true"></i>
319
+ </button>
320
+
321
+ <div
322
+ *ngIf="isOpen"
323
+ #panel
324
+ role="dialog"
325
+ [id]="panelId"
326
+ [attr.aria-label]="ariaLabel || 'Choose a date and time'"
327
+ class="fixed left-0 top-0 z-[9999]"
328
+ style="visibility: hidden"
329
+ >
330
+ <div class="rounded-md border border-border bg-popover text-popover-foreground shadow-md">
331
+ <div class="flex flex-col sm:flex-row">
332
+ <div class="p-3">
333
+ <tolle-calendar
334
+ [bordered]="false"
335
+ [showQuickActions]="false"
336
+ [minDate]="calendarMin"
337
+ [maxDate]="calendarMax"
338
+ [ngModel]="value"
339
+ (dateSelect)="onDateSelect($event)"
340
+ ></tolle-calendar>
341
+ </div>
342
+
343
+ <div class="border-t border-border p-3 sm:border-l sm:border-t-0">
344
+ <tolle-time-columns
345
+ #columns
346
+ [hour]="hour"
347
+ [minute]="minute"
348
+ [second]="second"
349
+ [use12Hours]="use12Hours"
350
+ [showSeconds]="showSeconds"
351
+ [minuteStep]="minuteStep"
352
+ [minSeconds]="minSeconds"
353
+ [maxSeconds]="maxSeconds"
354
+ [size]="size"
355
+ (timeChange)="onTimeChange($event)"
356
+ ></tolle-time-columns>
357
+ </div>
358
+ </div>
359
+
360
+ <div class="flex items-center justify-between gap-2 border-t border-border px-3 py-2">
361
+ <button
362
+ type="button"
363
+ [class]="footerButtonClass"
364
+ (click)="clear()"
365
+ >
366
+ Clear
367
+ </button>
368
+ <button
369
+ type="button"
370
+ [class]="cn(footerButtonClass, 'bg-primary text-primary-foreground hover:bg-primary/90 hover:text-primary-foreground')"
371
+ (click)="done()"
372
+ >
373
+ Done
374
+ </button>
375
+ </div>
376
+ </div>
377
+ </div>
378
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CalendarComponent, selector: "tolle-calendar", inputs: ["class", "bordered", "mode", "disablePastDates", "showQuickActions", "minDate", "maxDate", "formatMonthFn", "formatYearFn", "formatDateFn"], outputs: ["dateSelect"] }, { 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 });
379
+ }
380
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DateTimePickerComponent, decorators: [{
381
+ type: Component,
382
+ args: [{ selector: 'tolle-date-time-picker', standalone: true, imports: [CommonModule, FormsModule, CalendarComponent, TimeColumnsComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
383
+ {
384
+ provide: NG_VALUE_ACCESSOR,
385
+ useExisting: forwardRef(() => DateTimePickerComponent),
386
+ multi: true,
387
+ },
388
+ ], template: `
389
+ <button
390
+ #trigger
391
+ type="button"
392
+ aria-haspopup="dialog"
393
+ [attr.aria-expanded]="isOpen"
394
+ [attr.aria-controls]="isOpen ? panelId : null"
395
+ [attr.aria-label]="ariaLabel || null"
396
+ [attr.data-state]="isOpen ? 'open' : 'closed'"
397
+ [disabled]="disabled"
398
+ [class]="computedTriggerClass"
399
+ (click)="toggle()"
400
+ (keydown)="onTriggerKeyDown($event)"
401
+ >
402
+ <span [class]="cn('truncate', displayValue ? 'text-foreground' : 'text-muted-foreground')">
403
+ {{ displayValue || placeholder }}
404
+ </span>
405
+ <i class="ri-calendar-schedule-line shrink-0 text-muted-foreground" aria-hidden="true"></i>
406
+ </button>
407
+
408
+ <div
409
+ *ngIf="isOpen"
410
+ #panel
411
+ role="dialog"
412
+ [id]="panelId"
413
+ [attr.aria-label]="ariaLabel || 'Choose a date and time'"
414
+ class="fixed left-0 top-0 z-[9999]"
415
+ style="visibility: hidden"
416
+ >
417
+ <div class="rounded-md border border-border bg-popover text-popover-foreground shadow-md">
418
+ <div class="flex flex-col sm:flex-row">
419
+ <div class="p-3">
420
+ <tolle-calendar
421
+ [bordered]="false"
422
+ [showQuickActions]="false"
423
+ [minDate]="calendarMin"
424
+ [maxDate]="calendarMax"
425
+ [ngModel]="value"
426
+ (dateSelect)="onDateSelect($event)"
427
+ ></tolle-calendar>
428
+ </div>
429
+
430
+ <div class="border-t border-border p-3 sm:border-l sm:border-t-0">
431
+ <tolle-time-columns
432
+ #columns
433
+ [hour]="hour"
434
+ [minute]="minute"
435
+ [second]="second"
436
+ [use12Hours]="use12Hours"
437
+ [showSeconds]="showSeconds"
438
+ [minuteStep]="minuteStep"
439
+ [minSeconds]="minSeconds"
440
+ [maxSeconds]="maxSeconds"
441
+ [size]="size"
442
+ (timeChange)="onTimeChange($event)"
443
+ ></tolle-time-columns>
444
+ </div>
445
+ </div>
446
+
447
+ <div class="flex items-center justify-between gap-2 border-t border-border px-3 py-2">
448
+ <button
449
+ type="button"
450
+ [class]="footerButtonClass"
451
+ (click)="clear()"
452
+ >
453
+ Clear
454
+ </button>
455
+ <button
456
+ type="button"
457
+ [class]="cn(footerButtonClass, 'bg-primary text-primary-foreground hover:bg-primary/90 hover:text-primary-foreground')"
458
+ (click)="done()"
459
+ >
460
+ Done
461
+ </button>
462
+ </div>
463
+ </div>
464
+ </div>
465
+ `, styles: [":host{display:block}\n"] }]
466
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { placeholder: [{
467
+ type: Input
468
+ }], disabled: [{
469
+ type: Input
470
+ }], use12Hours: [{
471
+ type: Input
472
+ }], showSeconds: [{
473
+ type: Input
474
+ }], minuteStep: [{
475
+ type: Input
476
+ }], min: [{
477
+ type: Input
478
+ }], max: [{
479
+ type: Input
480
+ }], displayFormat: [{
481
+ type: Input
482
+ }], size: [{
483
+ type: Input
484
+ }], invalid: [{
485
+ type: Input
486
+ }], ariaLabel: [{
487
+ type: Input
488
+ }], class: [{
489
+ type: Input
490
+ }], valueChange: [{
491
+ type: Output
492
+ }], opened: [{
493
+ type: Output
494
+ }], closed: [{
495
+ type: Output
496
+ }], triggerEl: [{
497
+ type: ViewChild,
498
+ args: ['trigger']
499
+ }], panelEl: [{
500
+ type: ViewChild,
501
+ args: ['panel']
502
+ }], columnsCmp: [{
503
+ type: ViewChild,
504
+ args: ['columns']
505
+ }] } });
506
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS10aW1lLXBpY2tlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy90b2xsZS9zcmMvbGliL2RhdGUtdGltZS1waWNrZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFjLFNBQVMsRUFBcUIsdUJBQXVCLEVBQWdDLE1BQU0sZUFBZSxDQUFDO0FBQ3BMLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQXdCLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDcEYsT0FBTyxFQUFFLEdBQUcsRUFBcUIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDaEMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDekQsT0FBTyxFQUFFLG9CQUFvQixFQUFhLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDOzs7O0FBRXBGLE1BQU0sZUFBZSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFFbEMsTUFBTSw2QkFBNkIsR0FBRyxHQUFHLENBQ3ZDLDBJQUEwSTtJQUN4SSxxR0FBcUc7SUFDckcsaURBQWlELEVBQ25EO0lBQ0UsUUFBUSxFQUFFO1FBQ1IsSUFBSSxFQUFFO1lBQ0osRUFBRSxFQUFFLGtCQUFrQjtZQUN0QixFQUFFLEVBQUUsa0JB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QyxPQUFPO2dCQUNJLFVBQVU7c0JBQS9CLFNBQVM7dUJBQUMsU0FBUyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBmb3J3YXJkUmVmLCBFbGVtZW50UmVmLCBWaWV3Q2hpbGQsIENoYW5nZURldGVjdG9yUmVmLCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiwgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBjb21wdXRlUG9zaXRpb24sIGZsaXAsIHNoaWZ0LCBvZmZzZXQsIGF1dG9VcGRhdGUgfSBmcm9tICdAZmxvYXRpbmctdWkvZG9tJztcbmltcG9ydCB7IGN2YSwgdHlwZSBWYXJpYW50UHJvcHMgfSBmcm9tICdjbGFzcy12YXJpYW5jZS1hdXRob3JpdHknO1xuaW1wb3J0IHsgZm9ybWF0LCBpc1NhbWVEYXksIGlzVmFsaWQsIHN0YXJ0T2ZEYXkgfSBmcm9tICdkYXRlLWZucyc7XG5pbXBvcnQgeyBjbiB9IGZyb20gJy4vdXRpbHMvY24nO1xuaW1wb3J0IHsgQ2FsZW5kYXJDb21wb25lbnQgfSBmcm9tICcuL2NhbGVuZGFyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBUaW1lQ29sdW1uc0NvbXBvbmVudCwgVGltZVBhcnRzLCB0bzEySG91ciB9IGZyb20gJy4vdGltZS1waWNrZXIuY29tcG9uZW50JztcblxuY29uc3QgU0VDT05EU19QRVJfREFZID0gMjQgKiAzNjAwO1xuXG5jb25zdCBkYXRlVGltZVBpY2tlclRyaWdnZXJWYXJpYW50cyA9IGN2YShcbiAgJ2ZsZXggdy1mdWxsIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWJldHdlZW4gZ2FwLTIgcm91bmRlZC1tZCBib3JkZXIgYm9yZGVyLWlucHV0IGJnLWJhY2tncm91bmQgdGV4dC1mb3JlZ3JvdW5kIHNoYWRvdy1zbSB0cmFuc2l0aW9uLWNvbG9ycyAnICtcbiAgICAnZm9jdXM6b3V0bGluZS1ub25lIGZvY3VzLXZpc2libGU6Ym9yZGVyLXByaW1hcnkvODAgZm9jdXMtdmlzaWJsZTpyaW5nLTQgZm9jdXMtdmlzaWJsZTpyaW5nLXJpbmcvMzAgJyArXG4gICAgJ2Rpc2FibGVkOmN1cnNvci1ub3QtYWxsb3dlZCBkaXNhYmxlZDpvcGFjaXR5LTUwJyxcbiAge1xuICAgIHZhcmlhbnRzOiB7XG4gICAgICBzaXplOiB7XG4gICAgICAgIHhzOiAnaC04IHB4LTIgdGV4dC14cycsXG4gICAgICAgIHNtOiAnaC05IHB4LTMgdGV4dC1zbScsXG4gICAgICAgIGRlZmF1bHQ6ICdoLTEwIHB4LTMgdGV4dC1zbScsXG4gICAgICAgIGxnOiAnaC0xMSBweC00IHRleHQtYmFzZScsXG4gICAgICB9LFxuICAgICAgaW52YWxpZDoge1xuICAgICAgICB0cnVlOiAnYm9yZGVyLWRlc3RydWN0aXZlIGZvY3VzLXZpc2libGU6Ym9yZGVyLWRlc3RydWN0aXZlLzgwIGZvY3VzLXZpc2libGU6cmluZy1kZXN0cnVjdGl2ZS8zMCcsXG4gICAgICAgIGZhbHNlOiAnJyxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBkZWZhdWx0VmFyaWFudHM6IHsgc2l6ZTogJ2RlZmF1bHQnLCBpbnZhbGlkOiBmYWxzZSB9LFxuICB9XG4pO1xuXG4vKiogVmFyaWFudCBwcm9wcyBmb3IgdGhlIGRhdGUtdGltZSBwaWNrZXIgdHJpZ2dlci4gKi9cbmV4cG9ydCB0eXBlIERhdGVUaW1lUGlja2VyUHJvcHMgPSBWYXJpYW50UHJvcHM8dHlwZW9mIGRhdGVUaW1lUGlja2VyVHJpZ2dlclZhcmlhbnRzPjtcblxuLyoqXG4gKiBPbmUgY29udHJvbCBmb3IgYSBkYXRlICphbmQqIGEgdGltZTogYHRvbGxlLWNhbGVuZGFyYCBvbiB0aGUgbGVmdCwgdGhlXG4gKiBgdG9sbGUtdGltZS1jb2x1bW5zYCBzdHJpcCBvbiB0aGUgcmlnaHQsIGluIGEgc2luZ2xlIGZsb2F0aW5nIHBhbmVsIHdpdGggYVxuICogQ2xlYXIgLyBEb25lIGZvb3Rlci5cbiAqXG4gKiBUaGUgdmFsdWUgaXMgYSBgRGF0ZWAsIGJlY2F1c2UgYSBkYXRlLXRpbWUgZ2VudWluZWx5IGlzIGEgbW9tZW50LiBDaGFuZ2luZ1xuICogdGhlIGRhdGUgcHJlc2VydmVzIHRoZSBjaG9zZW4gdGltZSBhbmQgY2hhbmdpbmcgdGhlIHRpbWUgcHJlc2VydmVzIHRoZVxuICogY2hvc2VuIGRhdGUg4oCUIHRoZSB0d28gaGFsdmVzIGFyZSBvbmx5IGV2ZXIgcmVjb21iaW5lZCwgbmV2ZXIgcmVzZXQuXG4gKlxuICogSW1wbGVtZW50cyBgQ29udHJvbFZhbHVlQWNjZXNzb3JgLCBzbyBpdCB3b3JrcyB3aXRoIGBuZ01vZGVsYCBhbmQgcmVhY3RpdmVcbiAqIGZvcm1zLiBVc2UgYHRvbGxlLWRhdGUtcGlja2VyYCBmb3IgYSBkYXRlIGFsb25lIGFuZCBgdG9sbGUtdGltZS1waWNrZXJgIGZvciBhXG4gKiB0aW1lIGFsb25lLlxuICogQG5ld1xuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0b2xsZS1kYXRlLXRpbWUtcGlja2VyJyxcbiAgc3R5bGVzOiBbJzpob3N0IHsgZGlzcGxheTogYmxvY2s7IH0nXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRm9ybXNNb2R1bGUsIENhbGVuZGFyQ29tcG9uZW50LCBUaW1lQ29sdW1uc0NvbXBvbmVudF0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IERhdGVUaW1lUGlja2VyQ29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgIH0sXG4gIF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGJ1dHRvblxuICAgICAgI3RyaWdnZXJcbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgYXJpYS1oYXNwb3B1cD1cImRpYWxvZ1wiXG4gICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cImlzT3BlblwiXG4gICAgICBbYXR0ci5hcmlhLWNvbnRyb2xzXT1cImlzT3BlbiA/IHBhbmVsSWQgOiBudWxsXCJcbiAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiYXJpYUxhYmVsIHx8IG51bGxcIlxuICAgICAgW2F0dHIuZGF0YS1zdGF0ZV09XCJpc09wZW4gPyAnb3BlbicgOiAnY2xvc2VkJ1wiXG4gICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgW2NsYXNzXT1cImNvbXB1dGVkVHJpZ2dlckNsYXNzXCJcbiAgICAgIChjbGljayk9XCJ0b2dnbGUoKVwiXG4gICAgICAoa2V5ZG93bik9XCJvblRyaWdnZXJLZXlEb3duKCRldmVudClcIlxuICAgID5cbiAgICAgIDxzcGFuIFtjbGFzc109XCJjbigndHJ1bmNhdGUnLCBkaXNwbGF5VmFsdWUgPyAndGV4dC1mb3JlZ3JvdW5kJyA6ICd0ZXh0LW11dGVkLWZvcmVncm91bmQnKVwiPlxuICAgICAgICB7eyBkaXNwbGF5VmFsdWUgfHwgcGxhY2Vob2xkZXIgfX1cbiAgICAgIDwvc3Bhbj5cbiAgICAgIDxpIGNsYXNzPVwicmktY2FsZW5kYXItc2NoZWR1bGUtbGluZSBzaHJpbmstMCB0ZXh0LW11dGVkLWZvcmVncm91bmRcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgPC9idXR0b24+XG5cbiAgICA8ZGl2XG4gICAgICAqbmdJZj1cImlzT3BlblwiXG4gICAgICAjcGFuZWxcbiAgICAgIHJvbGU9XCJkaWFsb2dcIlxuICAgICAgW2lkXT1cInBhbmVsSWRcIlxuICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJhcmlhTGFiZWwgfHwgJ0Nob29zZSBhIGRhdGUgYW5kIHRpbWUnXCJcbiAgICAgIGNsYXNzPVwiZml4ZWQgbGVmdC0wIHRvcC0wIHotWzk5OTldXCJcbiAgICAgIHN0eWxlPVwidmlzaWJpbGl0eTogaGlkZGVuXCJcbiAgICA+XG4gICAgICA8ZGl2IGNsYXNzPVwicm91bmRlZC1tZCBib3JkZXIgYm9yZGVyLWJvcmRlciBiZy1wb3BvdmVyIHRleHQtcG9wb3Zlci1mb3JlZ3JvdW5kIHNoYWRvdy1tZFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBzbTpmbGV4LXJvd1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLTNcIj5cbiAgICAgICAgICAgIDx0b2xsZS1jYWxlbmRhclxuICAgICAgICAgICAgICBbYm9yZGVyZWRdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICBbc2hvd1F1aWNrQWN0aW9uc109XCJmYWxzZVwiXG4gICAgICAgICAgICAgIFttaW5EYXRlXT1cImNhbGVuZGFyTWluXCJcbiAgICAgICAgICAgICAgW21heERhdGVdPVwiY2FsZW5kYXJNYXhcIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ2YWx1ZVwiXG4gICAgICAgICAgICAgIChkYXRlU2VsZWN0KT1cIm9uRGF0ZVNlbGVjdCgkZXZlbnQpXCJcbiAgICAgICAgICAgID48L3RvbGxlLWNhbGVuZGFyPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImJvcmRlci10IGJvcmRlci1ib3JkZXIgcC0zIHNtOmJvcmRlci1sIHNtOmJvcmRlci10LTBcIj5cbiAgICAgICAgICAgIDx0b2xsZS10aW1lLWNvbHVtbnNcbiAgICAgICAgICAgICAgI2NvbHVtbnNcbiAgICAgICAgICAgICAgW2hvdXJdPVwiaG91clwiXG4gICAgICAgICAgICAgIFttaW51dGVdPVwibWludXRlXCJcbiAgICAgICAgICAgICAgW3NlY29uZF09XCJzZWNvbmRcIlxuICAgICAgICAgICAgICBbdXNlMTJIb3Vyc109XCJ1c2UxMkhvdXJzXCJcbiAgICAgICAgICAgICAgW3Nob3dTZWNvbmRzXT1cInNob3dTZWNvbmRzXCJcbiAgICAgICAgICAgICAgW21pbnV0ZVN0ZXBdPVwibWludXRlU3RlcFwiXG4gICAgICAgICAgICAgIFttaW5TZWNvbmRzXT1cIm1pblNlY29uZHNcIlxuICAgICAgICAgICAgICBbbWF4U2Vjb25kc109XCJtYXhTZWNvbmRzXCJcbiAgICAgICAgICAgICAgW3NpemVdPVwic2l6ZVwiXG4gICAgICAgICAgICAgICh0aW1lQ2hhbmdlKT1cIm9uVGltZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgICAgID48L3RvbGxlLXRpbWUtY29sdW1ucz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlbiBnYXAtMiBib3JkZXItdCBib3JkZXItYm9yZGVyIHB4LTMgcHktMlwiPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgW2NsYXNzXT1cImZvb3RlckJ1dHRvbkNsYXNzXCJcbiAgICAgICAgICAgIChjbGljayk9XCJjbGVhcigpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICBDbGVhclxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgW2NsYXNzXT1cImNuKGZvb3RlckJ1dHRvbkNsYXNzLCAnYmctcHJpbWFyeSB0ZXh0LXByaW1hcnktZm9yZWdyb3VuZCBob3ZlcjpiZy1wcmltYXJ5LzkwIGhvdmVyOnRleHQtcHJpbWFyeS1mb3JlZ3JvdW5kJylcIlxuICAgICAgICAgICAgKGNsaWNrKT1cImRvbmUoKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgRG9uZVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBEYXRlVGltZVBpY2tlckNvbXBvbmVudCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIC8qKiBUZXh0IHNob3duIG9uIHRoZSB0cmlnZ2VyIHdoZW4gbm90aGluZyBpcyBzZWxlY3RlZC4gQGRlZmF1bHQgJ1NlbGVjdCBkYXRlIGFuZCB0aW1lJyAqL1xuICBASW5wdXQoKSBwbGFjZWhvbGRlciA9ICdTZWxlY3QgZGF0ZSBhbmQgdGltZSc7XG4gIC8qKiBEaXNhYmxlcyB0aGUgY29udHJvbC4gQGRlZmF1bHQgZmFsc2UgKi9cbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcbiAgLyoqIFJlbmRlcnMgYSAxMi1ob3VyIGZhY2Ugd2l0aCBhbiBBTS9QTSBjb2x1bW4uIEBkZWZhdWx0IGZhbHNlICovXG4gIEBJbnB1dCgpIHVzZTEySG91cnMgPSBmYWxzZTtcbiAgLyoqIEFkZHMgYSBzZWNvbmRzIGNvbHVtbi4gQGRlZmF1bHQgZmFsc2UgKi9cbiAgQElucHV0KCkgc2hvd1NlY29uZHMgPSBmYWxzZTtcbiAgLyoqIEludGVydmFsIGJldHdlZW4gbWludXRlIGVudHJpZXMsIGluIG1pbnV0ZXMuIEBkZWZhdWx0IDEgKi9cbiAgQElucHV0KCkgbWludXRlU3RlcCA9IDE7XG4gIC8qKiBFYXJsaWVzdCBzZWxlY3RhYmxlIG1vbWVudDsgZWFybGllciBkYXlzIGFuZCB0aW1lcyBhcmUgZGlzYWJsZWQuICovXG4gIEBJbnB1dCgpIG1pbj86IERhdGU7XG4gIC8qKiBMYXRlc3Qgc2VsZWN0YWJsZSBtb21lbnQ7IGxhdGVyIGRheXMgYW5kIHRpbWVzIGFyZSBkaXNhYmxlZC4gKi9cbiAgQElucHV0KCkgbWF4PzogRGF0ZTtcbiAgLyoqIGRhdGUtZm5zIHBhdHRlcm4gdXNlZCB0byByZW5kZXIgdGhlIHZhbHVlIG9uIHRoZSB0cmlnZ2VyLiBAZGVmYXVsdCAnTU1NIGQsIHl5eXkgaDptbSBhJyAqL1xuICBASW5wdXQoKSBkaXNwbGF5Rm9ybWF0ID0gJ01NTSBkLCB5eXl5IGg6bW0gYSc7XG4gIC8qKiBIZWlnaHQgYW5kIHRleHQgc2l6ZSBvZiB0aGUgdHJpZ2dlciBhbmQgZW50cmllcy4gQGRlZmF1bHQgJ2RlZmF1bHQnICovXG4gIEBJbnB1dCgpIHNpemU6IERhdGVUaW1lUGlja2VyUHJvcHNbJ3NpemUnXSA9ICdkZWZhdWx0JztcbiAgLyoqIEFwcGxpZXMgdGhlIGRlc3RydWN0aXZlIGJvcmRlciBhbmQgZm9jdXMgcmluZy4gQGRlZmF1bHQgZmFsc2UgKi9cbiAgQElucHV0KCkgaW52YWxpZCA9IGZhbHNlO1xuICAvKiogQWNjZXNzaWJsZSBuYW1lIHdoZW4gdGhlcmUgaXMgbm8gYXNzb2NpYXRlZCB2aXNpYmxlIGxhYmVsLiBAZGVmYXVsdCAnJyAqL1xuICBASW5wdXQoKSBhcmlhTGFiZWwgPSAnJztcbiAgLyoqIEV4dHJhIFRhaWx3aW5kIGNsYXNzZXMgbWVyZ2VkIG9udG8gdGhlIHRyaWdnZXIgdmlhIGBjbigpYCAobGFzdC13aW5zKS4gKi9cbiAgQElucHV0KCkgY2xhc3MgPSAnJztcblxuICAvKiogRW1pdHRlZCB3aXRoIHRoZSBjaG9zZW4gbW9tZW50LCBvciBgbnVsbGAgd2hlbiB0aGUgdmFsdWUgaXMgY2xlYXJlZC4gKi9cbiAgQE91dHB1dCgpIHZhbHVlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxEYXRlIHwgbnVsbD4oKTtcbiAgLyoqIEVtaXR0ZWQgd2hlbiB0aGUgcGFuZWwgb3BlbnMuICovXG4gIEBPdXRwdXQoKSBvcGVuZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBFbWl0dGVkIHdoZW4gdGhlIHBhbmVsIGNsb3Nlcy4gKi9cbiAgQE91dHB1dCgpIGNsb3NlZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICBAVmlld0NoaWxkKCd0cmlnZ2VyJykgdHJpZ2dlckVsPzogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG4gIEBWaWV3Q2hpbGQoJ3BhbmVsJykgcGFuZWxFbD86IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+O1xuICBAVmlld0NoaWxkKCdjb2x1bW5zJykgY29sdW1uc0NtcD86IFRpbWVDb2x1bW5zQ29tcG9uZW50O1xuXG4gIHJlYWRvbmx5IHBhbmVsSWQgPSAnZGF0ZS10aW1lLXBpY2tlci1wYW5lbC0nICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMiwgMTEpO1xuXG4gIHZhbHVlOiBEYXRlIHwgbnVsbCA9IG51bGw7XG4gIGlzT3BlbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBEYXktb25seSBjb3BpZXMgb2YgYG1pbmAgLyBgbWF4YCBmb3IgdGhlIGNhbGVuZGFyLiBUaGUgY2FsZW5kYXIgY29tcGFyZXNcbiAgICogd2hvbGUgYERhdGVgcywgc28gcGFzc2luZyBhIGJvdW5kIHRoYXQgY2FycmllcyBhIHRpbWUgd291bGQgZGlzYWJsZSBpdHMgb3duXG4gICAqIGRheSDigJQgMDk6MDAgb24gdGhlIG1pbiBkYXkgd291bGQgbG9vayBcImJlZm9yZVwiIGEgMDk6MzAgbWluaW11bS5cbiAgICovXG4gIGNhbGVuZGFyTWluPzogRGF0ZTtcbiAgY2FsZW5kYXJNYXg/OiBEYXRlO1xuXG4gIHJlYWRvbmx5IGZvb3RlckJ1dHRvbkNsYXNzID0gY24oXG4gICAgJ3JvdW5kZWQtbWQgcHgtMyBweS0xLjUgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LW11dGVkLWZvcmVncm91bmQgdHJhbnNpdGlvbi1jb2xvcnMnLFxuICAgICdob3ZlcjpiZy1hY2NlbnQgaG92ZXI6dGV4dC1hY2NlbnQtZm9yZWdyb3VuZCcsXG4gICAgJ2ZvY3VzLXZpc2libGU6b3V0bGluZS1ub25lIGZvY3VzLXZpc2libGU6cmluZy0yIGZvY3VzLXZpc2libGU6cmluZy1yaW5nJ1xuICApO1xuXG4gIHByb3RlY3RlZCBjbiA9IGNuO1xuXG4gIHByaXZhdGUgY2xlYW51cD86ICgpID0+IHZvaWQ7XG4gIHByaXZhdGUgb25DaGFuZ2U6ICh2YWx1ZTogRGF0ZSB8IG51bGwpID0+IHZvaWQgPSAoKSA9PiB7fTtcbiAgcHJpdmF0ZSBvblRvdWNoZWQ6ICgpID0+IHZvaWQgPSAoKSA9PiB7fTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHt9XG5cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5jYWxlbmRhck1pbiA9IHRoaXMubWluID8gc3RhcnRPZkRheSh0aGlzLm1pbikgOiB1bmRlZmluZWQ7XG4gICAgdGhpcy5jYWxlbmRhck1heCA9IHRoaXMubWF4ID8gc3RhcnRPZkRheSh0aGlzLm1heCkgOiB1bmRlZmluZWQ7XG4gIFxuICAgIC8vIEEgYm91bmQgYGNsYXNzYCBpbnB1dCBpcyB3cml0dGVuIHRocm91Z2ggQW5ndWxhcidzIHN0eWxpbmcgcGF0aCxcbiAgICAvLyB3aGljaCBkb2VzIG5vdCBtYXJrIGFuIE9uUHVzaCB2aWV3IGRpcnR5IG9uIGl0cyBvd24uXG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIHJlYWRvbmx5IG91dHNpZGVDbGlja0hhbmRsZXIgPSAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgTm9kZTtcbiAgICBpZiAoXG4gICAgICAhdGhpcy50cmlnZ2VyRWw/Lm5hdGl2ZUVsZW1lbnQuY29udGFpbnModGFyZ2V0KSAmJlxuICAgICAgIXRoaXMucGFuZWxFbD8ubmF0aXZlRWxlbWVudC5jb250YWlucyh0YXJnZXQpXG4gICAgKSB7XG4gICAgICB0aGlzLmNsb3NlKCk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgZXNjYXBlSGFuZGxlciA9IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgIGlmIChldmVudC5rZXkgPT09ICdFc2NhcGUnICYmIHRoaXMuaXNPcGVuKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgdGhpcy50cmlnZ2VyRWw/Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICB9XG4gIH07XG5cbiAgLyogLS0tLS0tLS0tLS0tLS0tLSBkZXJpdmVkIC0tLS0tLS0tLS0tLS0tLS0gKi9cblxuICBnZXQgaG91cigpOiBudW1iZXIgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy52YWx1ZSA/IHRoaXMudmFsdWUuZ2V0SG91cnMoKSA6IG51bGw7XG4gIH1cblxuICBnZXQgbWludXRlKCk6IG51bWJlciB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLnZhbHVlID8gdGhpcy52YWx1ZS5nZXRNaW51dGVzKCkgOiBudWxsO1xuICB9XG5cbiAgZ2V0IHNlY29uZCgpOiBudW1iZXIgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy52YWx1ZSA/IHRoaXMudmFsdWUuZ2V0U2Vjb25kcygpIDogbnVsbDtcbiAgfVxuXG4gIGdldCBkaXNwbGF5VmFsdWUoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMudmFsdWUpIHJldHVybiAnJztcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGZvcm1hdCh0aGlzLnZhbHVlLCB0aGlzLmRpc3BsYXlGb3JtYXQpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gQSBiYWQgcGF0dGVybiBzaG91bGQgbm90IGJsYW5rIHRoZSBjb250cm9sOyBmYWxsIGJhY2sgdG8gc29tZXRoaW5nIHJlYWRhYmxlLlxuICAgICAgY29uc3QgeyBob3VyMTIsIG1lcmlkaWVtIH0gPSB0bzEySG91cih0aGlzLnZhbHVlLmdldEhvdXJzKCkpO1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgZm9ybWF0KHRoaXMudmFsdWUsICdNTU0gZCwgeXl5eScpICtcbiAgICAgICAgJyAnICtcbiAgICAgICAgaG91cjEyICtcbiAgICAgICAgJzonICtcbiAgICAgICAgU3RyaW5nKHRoaXMudmFsdWUuZ2V0TWludXRlcygpKS5wYWRTdGFydCgyLCAnMCcpICtcbiAgICAgICAgJyAnICtcbiAgICAgICAgbWVyaWRpZW1cbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB0aW1lIGJvdW5kIG9ubHkgYml0ZXMgb24gdGhlIGJvdW5kYXJ5IGRheSBpdHNlbGY6IG9uIHRoZSBtaW4gZGF5IHRoZVxuICAgKiBjb2x1bW5zIHN0YXJ0IGF0IHRoZSBtaW4gdGltZSwgb24gYW55IGxhdGVyIGRheSB0aGV5IHN0YXJ0IGF0IG1pZG5pZ2h0LlxuICAgKi9cbiAgZ2V0IG1pblNlY29uZHMoKTogbnVtYmVyIHtcbiAgICBpZiAoIXRoaXMubWluKSByZXR1cm4gMDtcbiAgICBjb25zdCBkYXkgPSB0aGlzLnZhbHVlID8/IHRoaXMubWluO1xuICAgIGlmICghaXNTYW1lRGF5KGRheSwgdGhpcy5taW4pKSByZXR1cm4gMDtcbiAgICByZXR1cm4gdGhpcy5taW4uZ2V0SG91cnMoKSAqIDM2MDAgKyB0aGlzLm1pbi5nZXRNaW51dGVzKCkgKiA2MCArIHRoaXMubWluLmdldFNlY29uZHMoKTtcbiAgfVxuXG4gIGdldCBtYXhTZWNvbmRzKCk6IG51bWJlciB7XG4gICAgaWYgKCF0aGlzLm1heCkgcmV0dXJuIFNFQ09ORFNfUEVSX0RBWSAtIDE7XG4gICAgY29uc3QgZGF5ID0gdGhpcy52YWx1ZSA/PyB0aGlzLm1heDtcbiAgICBpZiAoIWlzU2FtZURheShkYXksIHRoaXMubWF4KSkgcmV0dXJuIFNFQ09ORFNfUEVSX0RBWSAtIDE7XG4gICAgcmV0dXJuIHRoaXMubWF4LmdldEhvdXJzKCkgKiAzNjAwICsgdGhpcy5tYXguZ2V0TWludXRlcygpICogNjAgKyB0aGlzLm1heC5nZXRTZWNvbmRzKCk7XG4gIH1cblxuICBnZXQgY29tcHV0ZWRUcmlnZ2VyQ2xhc3MoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gY24oXG4gICAgICBkYXRlVGltZVBpY2tlclRyaWdnZXJWYXJpYW50cyh7IHNpemU6IHRoaXMuc2l6ZSwgaW52YWxpZDogdGhpcy5pbnZhbGlkIH0pLFxuICAgICAgdGhpcy5jbGFzc1xuICAgICk7XG4gIH1cblxuICAvKiAtLS0tLS0tLS0tLS0tLS0tIG9wZW4gLyBjbG9zZSAtLS0tLS0tLS0tLS0tLS0tICovXG5cbiAgdG9nZ2xlKCk6IHZvaWQge1xuICAgIHRoaXMuaXNPcGVuID8gdGhpcy5jbG9zZSgpIDogdGhpcy5vcGVuKCk7XG4gIH1cblxuICBvcGVuKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkIHx8IHRoaXMuaXNPcGVuKSByZXR1cm47XG4gICAgdGhpcy5pc09wZW4gPSB0cnVlO1xuICAgIHRoaXMub3BlbmVkLmVtaXQoKTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy51cGRhdGVQb3NpdGlvbigpO1xuICAgICAgdGhpcy5jb2x1bW5zQ21wPy5zY3JvbGxTZWxlY3RlZEludG9WaWV3KCk7XG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyZG93bicsIHRoaXMub3V0c2lkZUNsaWNrSGFuZGxlciwgdHJ1ZSk7XG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5lc2NhcGVIYW5kbGVyLCB0cnVlKTtcbiAgICB9KTtcbiAgfVxuXG4gIGNsb3NlKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc09wZW4pIHJldHVybjtcbiAgICB0aGlzLmlzT3BlbiA9IGZhbHNlO1xuICAgIHRoaXMuY2xvc2VkLmVtaXQoKTtcbiAgICB0aGlzLm9uVG91Y2hlZCgpO1xuICAgIHRoaXMudGVhcmRvd24oKTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG9uVHJpZ2dlcktleURvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoWydBcnJvd0Rvd24nLCAnQXJyb3dVcCcsICdFbnRlcicsICcgJ10uaW5jbHVkZXMoZXZlbnQua2V5KSAmJiAhdGhpcy5pc09wZW4pIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB0aGlzLm9wZW4oKTtcbiAgICB9XG4gIH1cblxuICAvKiAtLS0tLS0tLS0tLS0tLS0tIHZhbHVlIC0tLS0tLS0tLS0tLS0tLS0gKi9cblxuICAvKipcbiAgICogQXBwbGllcyBhIG5ld2x5IHBpY2tlZCBkYXksIGNhcnJ5aW5nIHRoZSBleGlzdGluZyB0aW1lIGFjcm9zcy4gV2l0aCBub1xuICAgKiB0aW1lIGNob3NlbiB5ZXQgdGhlIGRheSBzdGFydHMgYXQgbWlkbmlnaHQuXG4gICAqL1xuICBvbkRhdGVTZWxlY3QoZGF0ZTogRGF0ZSB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAoIWRhdGUpIHtcbiAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMudmFsdWU7XG4gICAgdGhpcy5jb21taXQoXG4gICAgICBuZXcgRGF0ZShcbiAgICAgICAgZGF0ZS5nZXRGdWxsWWVhcigpLFxuICAgICAgICBkYXRlLmdldE1vbnRoKCksXG4gICAgICAgIGRhdGUuZ2V0RGF0ZSgpLFxuICAgICAgICBwcmV2aW91cyA/IHByZXZpb3VzLmdldEhvdXJzKCkgOiAwLFxuICAgICAgICBwcmV2aW91cyA/IHByZXZpb3VzLmdldE1pbnV0ZXMoKSA6IDAsXG4gICAgICAgIHByZXZpb3VzID8gcHJldmlvdXMuZ2V0U2Vjb25kcygpIDogMCxcbiAgICAgICAgMFxuICAgICAgKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQXBwbGllcyBhIG5ld2x5IHBpY2tlZCB0aW1lLCBjYXJyeWluZyB0aGUgZXhpc3RpbmcgZGF5IGFjcm9zcy4gV2l0aCBubyBkYXlcbiAgICogY2hvc2VuIHlldCB0aGUgdGltZSBsYW5kcyBvbiB0b2RheS5cbiAgICovXG4gIG9uVGltZUNoYW5nZShwYXJ0czogVGltZVBhcnRzKTogdm9pZCB7XG4gICAgY29uc3QgYmFzZSA9IHRoaXMudmFsdWUgPz8gbmV3IERhdGUoKTtcbiAgICB0aGlzLmNvbW1pdChcbiAgICAgIG5ldyBEYXRlKFxuICAgICAgICBiYXNlLmdldEZ1bGxZZWFyKCksXG4gICAgICAgIGJhc2UuZ2V0TW9udGgoKSxcbiAgICAgICAgYmFzZS5nZXREYXRlKCksXG4gICAgICAgIHBhcnRzLmhvdXIsXG4gICAgICAgIHBhcnRzLm1pbnV0ZSxcbiAgICAgICAgcGFydHMuc2Vjb25kLFxuICAgICAgICAwXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIGNsZWFyKCk6IHZvaWQge1xuICAgIHRoaXMuY29tbWl0KG51bGwpO1xuICAgIC8vIFRoZSBjYWxlbmRhciBrZWVwcyBpdHMgb3duIHNlbGVjdGlvbiBhbmQgaWdub3JlcyBhIG51bGwgd3JpdHRlbiB0aHJvdWdoXG4gICAgLy8gdGhlIENWQSwgc28gY2xvc2luZyBpcyB3aGF0IGFjdHVhbGx5IHJldHVybnMgaXQgdG8gYSBjbGVhbiBzdGF0ZSDigJQgaXQgaXNcbiAgICAvLyByZWJ1aWx0IGZyb20gc2NyYXRjaCB0aGUgbmV4dCB0aW1lIHRoZSBwYW5lbCBvcGVucy5cbiAgICB0aGlzLmNsb3NlKCk7XG4gIH1cblxuICBkb25lKCk6IHZvaWQge1xuICAgIHRoaXMuY2xvc2UoKTtcbiAgICB0aGlzLnRyaWdnZXJFbD8ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb21taXQobmV4dDogRGF0ZSB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlID0gbmV4dDtcbiAgICB0aGlzLm9uQ2hhbmdlKG5leHQpO1xuICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdChuZXh0KTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlUG9zaXRpb24oKTogdm9pZCB7XG4gICAgY29uc3QgdHJpZ2dlciA9IHRoaXMudHJpZ2dlckVsPy5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IHBhbmVsID0gdGhpcy5wYW5lbEVsPy5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghdHJpZ2dlciB8fCAhcGFuZWwpIHJldHVybjtcblxuICAgIHRoaXMuY2xlYW51cCA9IGF1dG9VcGRhdGUodHJpZ2dlciwgcGFuZWwsICgpID0+IHtcbiAgICAgIGNvbXB1dGVQb3NpdGlvbih0cmlnZ2VyLCBwYW5lbCwge1xuICAgICAgICBzdHJhdGVneTogJ2ZpeGVkJyxcbiAgICAgICAgcGxhY2VtZW50OiAnYm90dG9tLXN0YXJ0JyxcbiAgICAgICAgbWlkZGxld2FyZTogW29mZnNldCg0KSwgZmxpcCgpLCBzaGlmdCh7IHBhZGRpbmc6IDggfSldLFxuICAgICAgfSkudGhlbigoeyB4LCB5IH0pID0+IHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihwYW5lbC5zdHlsZSwge1xuICAgICAgICAgIGxlZnQ6IHggKyAncHgnLFxuICAgICAgICAgIHRvcDogeSArICdweCcsXG4gICAgICAgICAgdmlzaWJpbGl0eTogJ3Zpc2libGUnLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB0ZWFyZG93bigpOiB2b2lkIHtcbiAgICB0aGlzLmNsZWFudXA/LigpO1xuICAgIHRoaXMuY2xlYW51cCA9IHVuZGVmaW5lZDtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVyZG93bicsIHRoaXMub3V0c2lkZUNsaWNrSGFuZGxlciwgdHJ1ZSk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMuZXNjYXBlSGFuZGxlciwgdHJ1ZSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnRlYXJkb3duKCk7XG4gIH1cblxuICAvKiAtLS0tLS0tLS0tLS0tLS0tIENvbnRyb2xWYWx1ZUFjY2Vzc29yIC0tLS0tLS0tLS0tLS0tLS0gKi9cblxuICB3cml0ZVZhbHVlKHZhbHVlOiBEYXRlIHwgc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUgJiYgaXNWYWxpZCh2YWx1ZSkpIHtcbiAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUpIHtcbiAgICAgIGNvbnN0IHBhcnNlZCA9IG5ldyBEYXRlKHZhbHVlKTtcbiAgICAgIHRoaXMudmFsdWUgPSBpc1ZhbGlkKHBhcnNlZCkgPyBwYXJzZWQgOiBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnZhbHVlID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAodmFsdWU6IERhdGUgfCBudWxsKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xuICB9XG5cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICB9XG5cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gICAgaWYgKGlzRGlzYWJsZWQpIHRoaXMuY2xvc2UoKTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxufVxuIl19
@@ -0,0 +1,79 @@
1
+ import { Directive, Injectable, Input, Output, EventEmitter, HostBinding, inject, } from '@angular/core';
2
+ import { BehaviorSubject } from 'rxjs';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Publishes the application's current writing direction so components can adapt
6
+ * without reading the DOM.
7
+ *
8
+ * Direction is not an input of most components, so an OnPush view would never be
9
+ * marked dirty by a change. Subscribe to `direction$` and call `markForCheck()`
10
+ * on emission wherever the rendered output depends on it.
11
+ */
12
+ export class DirectionService {
13
+ directionSource = new BehaviorSubject('ltr');
14
+ /** Emits the current writing direction, starting with the present value. */
15
+ direction$ = this.directionSource.asObservable();
16
+ /** The current writing direction. */
17
+ get direction() {
18
+ return this.directionSource.value;
19
+ }
20
+ /** Whether the current direction is explicitly right-to-left. */
21
+ get isRtl() {
22
+ return this.directionSource.value === 'rtl';
23
+ }
24
+ /** Sets the current direction, emitting only when it actually changes. */
25
+ setDirection(direction) {
26
+ if (this.directionSource.value !== direction)
27
+ this.directionSource.next(direction);
28
+ }
29
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DirectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
30
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DirectionService, providedIn: 'root' });
31
+ }
32
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DirectionService, decorators: [{
33
+ type: Injectable,
34
+ args: [{ providedIn: 'root' }]
35
+ }] });
36
+ /**
37
+ * Sets the `dir` attribute on its host and publishes that direction to
38
+ * `DirectionService`, so a whole chat surface can be flipped to RTL from one
39
+ * place. Put it on the outermost element of the subtree you want to flip.
40
+ * @new
41
+ */
42
+ export class DirectionDirective {
43
+ /** Writing direction applied to the host's `dir` attribute. @default 'ltr' */
44
+ tolleDirection = 'ltr';
45
+ /** Whether to publish this direction to the app-wide `DirectionService`. @default true */
46
+ tolleDirectionPublish = true;
47
+ /** Emitted with the direction whenever it changes. */
48
+ directionChange = new EventEmitter();
49
+ service = inject(DirectionService);
50
+ /** The resolved `dir` attribute value written onto the host. */
51
+ get dir() {
52
+ return this.tolleDirection ?? 'ltr';
53
+ }
54
+ ngOnChanges() {
55
+ const direction = this.dir;
56
+ if (this.tolleDirectionPublish)
57
+ this.service.setDirection(direction);
58
+ this.directionChange.emit(direction);
59
+ }
60
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DirectionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
61
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: DirectionDirective, isStandalone: true, selector: "[tolleDirection]", inputs: { tolleDirection: "tolleDirection", tolleDirectionPublish: "tolleDirectionPublish" }, outputs: { directionChange: "directionChange" }, host: { properties: { "attr.dir": "this.dir" } }, usesOnChanges: true, ngImport: i0 });
62
+ }
63
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DirectionDirective, decorators: [{
64
+ type: Directive,
65
+ args: [{
66
+ selector: '[tolleDirection]',
67
+ standalone: true,
68
+ }]
69
+ }], propDecorators: { tolleDirection: [{
70
+ type: Input
71
+ }], tolleDirectionPublish: [{
72
+ type: Input
73
+ }], directionChange: [{
74
+ type: Output
75
+ }], dir: [{
76
+ type: HostBinding,
77
+ args: ['attr.dir']
78
+ }] } });
79
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlyZWN0aW9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RvbGxlL3NyYy9saWIvZGlyZWN0aW9uLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFVBQVUsRUFDVixLQUFLLEVBQ0wsTUFBTSxFQUNOLFlBQVksRUFDWixXQUFXLEVBRVgsTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxNQUFNLENBQUM7O0FBS3ZDOzs7Ozs7O0dBT0c7QUFFSCxNQUFNLE9BQU8sZ0JBQWdCO0lBQ25CLGVBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBWSxLQUFLLENBQUMsQ0FBQztJQUVoRSw0RUFBNEU7SUFDbkUsVUFBVSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFMUQscUNBQXFDO0lBQ3JDLElBQUksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUM7SUFDcEMsQ0FBQztJQUVELGlFQUFpRTtJQUNqRSxJQUFJLEtBQUs7UUFDUCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxLQUFLLEtBQUssQ0FBQztJQUM5QyxDQUFDO0lBRUQsMEVBQTBFO0lBQzFFLFlBQVksQ0FBQyxTQUFvQjtRQUMvQixJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxLQUFLLFNBQVM7WUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNyRixDQUFDO3dHQW5CVSxnQkFBZ0I7NEdBQWhCLGdCQUFnQixjQURILE1BQU07OzRGQUNuQixnQkFBZ0I7a0JBRDVCLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFOztBQXVCbEM7Ozs7O0dBS0c7QUFLSCxNQUFNLE9BQU8sa0JBQWtCO0lBQzdCLDhFQUE4RTtJQUNyRSxjQUFjLEdBQWMsS0FBSyxDQUFDO0lBQzNDLDBGQUEwRjtJQUNqRixxQkFBcUIsR0FBRyxJQUFJLENBQUM7SUFFdEMsc0RBQXNEO0lBQzVDLGVBQWUsR0FBRyxJQUFJLFlBQVksRUFBYSxDQUFDO0lBRXpDLE9BQU8sR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUVwRCxnRUFBZ0U7SUFDaEUsSUFDSSxHQUFHO1FBQ0wsT0FBTyxJQUFJLENBQUMsY0FBYyxJQUFJLEtBQUssQ0FBQztJQUN0QyxDQUFDO0lBRUQsV0FBVztRQUNULE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7UUFDM0IsSUFBSSxJQUFJLENBQUMscUJBQXFCO1lBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdkMsQ0FBQzt3R0FyQlUsa0JBQWtCOzRGQUFsQixrQkFBa0I7OzRGQUFsQixrQkFBa0I7a0JBSjlCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGtCQUFrQjtvQkFDNUIsVUFBVSxFQUFFLElBQUk7aUJBQ2pCOzhCQUdVLGNBQWM7c0JBQXRCLEtBQUs7Z0JBRUcscUJBQXFCO3NCQUE3QixLQUFLO2dCQUdJLGVBQWU7c0JBQXhCLE1BQU07Z0JBTUgsR0FBRztzQkFETixXQUFXO3VCQUFDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBEaXJlY3RpdmUsXG4gIEluamVjdGFibGUsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSG9zdEJpbmRpbmcsXG4gIE9uQ2hhbmdlcyxcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG4vKiogV3JpdGluZyBkaXJlY3Rpb24gb2YgYSBzdWJ0cmVlOiBleHBsaWNpdCwgb3IgaW5mZXJyZWQgZnJvbSBpdHMgdGV4dC4gKi9cbmV4cG9ydCB0eXBlIERpcmVjdGlvbiA9ICdsdHInIHwgJ3J0bCcgfCAnYXV0byc7XG5cbi8qKlxuICogUHVibGlzaGVzIHRoZSBhcHBsaWNhdGlvbidzIGN1cnJlbnQgd3JpdGluZyBkaXJlY3Rpb24gc28gY29tcG9uZW50cyBjYW4gYWRhcHRcbiAqIHdpdGhvdXQgcmVhZGluZyB0aGUgRE9NLlxuICpcbiAqIERpcmVjdGlvbiBpcyBub3QgYW4gaW5wdXQgb2YgbW9zdCBjb21wb25lbnRzLCBzbyBhbiBPblB1c2ggdmlldyB3b3VsZCBuZXZlciBiZVxuICogbWFya2VkIGRpcnR5IGJ5IGEgY2hhbmdlLiBTdWJzY3JpYmUgdG8gYGRpcmVjdGlvbiRgIGFuZCBjYWxsIGBtYXJrRm9yQ2hlY2soKWBcbiAqIG9uIGVtaXNzaW9uIHdoZXJldmVyIHRoZSByZW5kZXJlZCBvdXRwdXQgZGVwZW5kcyBvbiBpdC5cbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBEaXJlY3Rpb25TZXJ2aWNlIHtcbiAgcHJpdmF0ZSBkaXJlY3Rpb25Tb3VyY2UgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PERpcmVjdGlvbj4oJ2x0cicpO1xuXG4gIC8qKiBFbWl0cyB0aGUgY3VycmVudCB3cml0aW5nIGRpcmVjdGlvbiwgc3RhcnRpbmcgd2l0aCB0aGUgcHJlc2VudCB2YWx1ZS4gKi9cbiAgcmVhZG9ubHkgZGlyZWN0aW9uJCA9IHRoaXMuZGlyZWN0aW9uU291cmNlLmFzT2JzZXJ2YWJsZSgpO1xuXG4gIC8qKiBUaGUgY3VycmVudCB3cml0aW5nIGRpcmVjdGlvbi4gKi9cbiAgZ2V0IGRpcmVjdGlvbigpOiBEaXJlY3Rpb24ge1xuICAgIHJldHVybiB0aGlzLmRpcmVjdGlvblNvdXJjZS52YWx1ZTtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIHRoZSBjdXJyZW50IGRpcmVjdGlvbiBpcyBleHBsaWNpdGx5IHJpZ2h0LXRvLWxlZnQuICovXG4gIGdldCBpc1J0bCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5kaXJlY3Rpb25Tb3VyY2UudmFsdWUgPT09ICdydGwnO1xuICB9XG5cbiAgLyoqIFNldHMgdGhlIGN1cnJlbnQgZGlyZWN0aW9uLCBlbWl0dGluZyBvbmx5IHdoZW4gaXQgYWN0dWFsbHkgY2hhbmdlcy4gKi9cbiAgc2V0RGlyZWN0aW9uKGRpcmVjdGlvbjogRGlyZWN0aW9uKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGlyZWN0aW9uU291cmNlLnZhbHVlICE9PSBkaXJlY3Rpb24pIHRoaXMuZGlyZWN0aW9uU291cmNlLm5leHQoZGlyZWN0aW9uKTtcbiAgfVxufVxuXG4vKipcbiAqIFNldHMgdGhlIGBkaXJgIGF0dHJpYnV0ZSBvbiBpdHMgaG9zdCBhbmQgcHVibGlzaGVzIHRoYXQgZGlyZWN0aW9uIHRvXG4gKiBgRGlyZWN0aW9uU2VydmljZWAsIHNvIGEgd2hvbGUgY2hhdCBzdXJmYWNlIGNhbiBiZSBmbGlwcGVkIHRvIFJUTCBmcm9tIG9uZVxuICogcGxhY2UuIFB1dCBpdCBvbiB0aGUgb3V0ZXJtb3N0IGVsZW1lbnQgb2YgdGhlIHN1YnRyZWUgeW91IHdhbnQgdG8gZmxpcC5cbiAqIEBuZXdcbiAqL1xuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW3RvbGxlRGlyZWN0aW9uXScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIERpcmVjdGlvbkRpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIC8qKiBXcml0aW5nIGRpcmVjdGlvbiBhcHBsaWVkIHRvIHRoZSBob3N0J3MgYGRpcmAgYXR0cmlidXRlLiBAZGVmYXVsdCAnbHRyJyAqL1xuICBASW5wdXQoKSB0b2xsZURpcmVjdGlvbjogRGlyZWN0aW9uID0gJ2x0cic7XG4gIC8qKiBXaGV0aGVyIHRvIHB1Ymxpc2ggdGhpcyBkaXJlY3Rpb24gdG8gdGhlIGFwcC13aWRlIGBEaXJlY3Rpb25TZXJ2aWNlYC4gQGRlZmF1bHQgdHJ1ZSAqL1xuICBASW5wdXQoKSB0b2xsZURpcmVjdGlvblB1Ymxpc2ggPSB0cnVlO1xuXG4gIC8qKiBFbWl0dGVkIHdpdGggdGhlIGRpcmVjdGlvbiB3aGVuZXZlciBpdCBjaGFuZ2VzLiAqL1xuICBAT3V0cHV0KCkgZGlyZWN0aW9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxEaXJlY3Rpb24+KCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBzZXJ2aWNlID0gaW5qZWN0KERpcmVjdGlvblNlcnZpY2UpO1xuXG4gIC8qKiBUaGUgcmVzb2x2ZWQgYGRpcmAgYXR0cmlidXRlIHZhbHVlIHdyaXR0ZW4gb250byB0aGUgaG9zdC4gKi9cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmRpcicpXG4gIGdldCBkaXIoKTogRGlyZWN0aW9uIHtcbiAgICByZXR1cm4gdGhpcy50b2xsZURpcmVjdGlvbiA/PyAnbHRyJztcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIGNvbnN0IGRpcmVjdGlvbiA9IHRoaXMuZGlyO1xuICAgIGlmICh0aGlzLnRvbGxlRGlyZWN0aW9uUHVibGlzaCkgdGhpcy5zZXJ2aWNlLnNldERpcmVjdGlvbihkaXJlY3Rpb24pO1xuICAgIHRoaXMuZGlyZWN0aW9uQ2hhbmdlLmVtaXQoZGlyZWN0aW9uKTtcbiAgfVxufVxuIl19