@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.
- package/esm2022/lib/accordion-item.component.mjs +5 -11
- package/esm2022/lib/accordion.component.mjs +4 -9
- package/esm2022/lib/alert-dialog-dynamic.component.mjs +5 -10
- package/esm2022/lib/alert-dialog.component.mjs +44 -59
- package/esm2022/lib/alert.component.mjs +5 -11
- package/esm2022/lib/aspect-ratio.component.mjs +119 -0
- package/esm2022/lib/attachment.component.mjs +334 -0
- package/esm2022/lib/avatar-fallback.component.mjs +3 -3
- package/esm2022/lib/avatar.component.mjs +4 -9
- package/esm2022/lib/badge.component.mjs +4 -9
- package/esm2022/lib/breadcrumb-item.component.mjs +3 -3
- package/esm2022/lib/breadcrumb-link.component.mjs +3 -3
- package/esm2022/lib/breadcrumb-separator.component.mjs +3 -3
- package/esm2022/lib/breadcrumb.component.mjs +3 -3
- package/esm2022/lib/bubble.component.mjs +301 -0
- package/esm2022/lib/button.component.mjs +5 -11
- package/esm2022/lib/calendar.component.mjs +5 -11
- package/esm2022/lib/card.component.mjs +14 -43
- package/esm2022/lib/carousel/carousel.component.mjs +5 -12
- package/esm2022/lib/chain-of-thought.component.mjs +380 -0
- package/esm2022/lib/chart-pie.component.mjs +386 -0
- package/esm2022/lib/chart.component.mjs +1146 -0
- package/esm2022/lib/chart.service.mjs +555 -0
- package/esm2022/lib/checkbox.component.mjs +5 -11
- package/esm2022/lib/checkpoint.component.mjs +134 -0
- package/esm2022/lib/collapsible.component.mjs +4 -11
- package/esm2022/lib/combobox.component.mjs +372 -0
- package/esm2022/lib/command-dialog.component.mjs +164 -0
- package/esm2022/lib/command.component.mjs +514 -0
- package/esm2022/lib/command.service.mjs +130 -0
- package/esm2022/lib/confirmation.component.mjs +219 -0
- package/esm2022/lib/context-menu-trigger.directive.mjs +36 -0
- package/esm2022/lib/context-menu.component.mjs +460 -0
- package/esm2022/lib/context-menu.service.mjs +121 -0
- package/esm2022/lib/context.component.mjs +377 -0
- package/esm2022/lib/conversation.component.mjs +442 -0
- package/esm2022/lib/country-selector.component.mjs +5 -11
- package/esm2022/lib/data-table.component.mjs +63 -12
- package/esm2022/lib/date-picker.component.mjs +251 -198
- package/esm2022/lib/date-range-picker.component.mjs +224 -116
- package/esm2022/lib/date-time-picker.component.mjs +506 -0
- package/esm2022/lib/direction.component.mjs +79 -0
- package/esm2022/lib/dropdown-item.component.mjs +3 -3
- package/esm2022/lib/dropdown-label.component.mjs +3 -3
- package/esm2022/lib/dropdown-menu.component.mjs +3 -3
- package/esm2022/lib/dropdown-separator.component.mjs +3 -3
- package/esm2022/lib/dropdown-trigger.directive.mjs +6 -4
- package/esm2022/lib/empty-state.component.mjs +4 -9
- package/esm2022/lib/field.component.mjs +394 -0
- package/esm2022/lib/hover-card.component.mjs +6 -16
- package/esm2022/lib/inline-citation.component.mjs +263 -0
- package/esm2022/lib/input-group.component.mjs +418 -0
- package/esm2022/lib/input.component.mjs +5 -11
- package/esm2022/lib/item.component.mjs +243 -0
- package/esm2022/lib/kbd.component.mjs +82 -0
- package/esm2022/lib/label.component.mjs +4 -9
- package/esm2022/lib/marker.component.mjs +135 -0
- package/esm2022/lib/masked-input.component.mjs +5 -11
- package/esm2022/lib/menubar.component.mjs +683 -0
- package/esm2022/lib/message-scroller.component.mjs +353 -0
- package/esm2022/lib/message-scroller.service.mjs +157 -0
- package/esm2022/lib/message.component.mjs +228 -0
- package/esm2022/lib/model-selector.component.mjs +310 -0
- package/esm2022/lib/multi-select.component.mjs +155 -72
- package/esm2022/lib/native-select.component.mjs +201 -0
- package/esm2022/lib/navigation-menu.component.mjs +642 -0
- package/esm2022/lib/otp-group.component.mjs +3 -3
- package/esm2022/lib/otp-slot.component.mjs +4 -9
- package/esm2022/lib/otp.component.mjs +5 -11
- package/esm2022/lib/pagination.component.mjs +7 -10
- package/esm2022/lib/plan.component.mjs +335 -0
- package/esm2022/lib/popover-content.component.mjs +4 -9
- package/esm2022/lib/popover.component.mjs +15 -13
- package/esm2022/lib/progress.component.mjs +4 -9
- package/esm2022/lib/prompt-input.component.mjs +526 -0
- package/esm2022/lib/queue.component.mjs +280 -0
- package/esm2022/lib/radio-group.component.mjs +6 -13
- package/esm2022/lib/radio-item.component.mjs +4 -9
- package/esm2022/lib/range-calendar.component.mjs +5 -11
- package/esm2022/lib/reasoning.component.mjs +335 -0
- package/esm2022/lib/resizable.component.mjs +219 -0
- package/esm2022/lib/segment.component.mjs +17 -7
- package/esm2022/lib/select-group.component.mjs +4 -8
- package/esm2022/lib/select-item.component.mjs +4 -9
- package/esm2022/lib/select-separator.component.mjs +4 -8
- package/esm2022/lib/select.component.mjs +133 -49
- package/esm2022/lib/separator.component.mjs +4 -9
- package/esm2022/lib/sheet.component.mjs +38 -56
- package/esm2022/lib/shimmer.component.mjs +84 -0
- package/esm2022/lib/sidebar.component.mjs +11 -1
- package/esm2022/lib/skeleton.component.mjs +4 -9
- package/esm2022/lib/sources.component.mjs +452 -0
- package/esm2022/lib/spinner.component.mjs +68 -0
- package/esm2022/lib/suggestion.component.mjs +207 -0
- package/esm2022/lib/switch.component.mjs +5 -11
- package/esm2022/lib/table.component.mjs +213 -0
- package/esm2022/lib/tabs.component.mjs +4 -11
- package/esm2022/lib/tag-input.component.mjs +5 -11
- package/esm2022/lib/task.component.mjs +359 -0
- package/esm2022/lib/textarea.component.mjs +5 -11
- package/esm2022/lib/theme.service.mjs +17 -6
- package/esm2022/lib/time-picker.component.mjs +923 -0
- package/esm2022/lib/toast.service.mjs +3 -2
- package/esm2022/lib/toaster.component.mjs +76 -39
- package/esm2022/lib/toggle-group.component.mjs +4 -9
- package/esm2022/lib/toggle.component.mjs +5 -11
- package/esm2022/lib/tool.component.mjs +462 -0
- package/esm2022/lib/typography.component.mjs +83 -0
- package/esm2022/lib/utils/color.mjs +140 -19
- package/esm2022/public-api.mjs +61 -1
- package/fesm2022/tolle-ui.mjs +16457 -1024
- package/fesm2022/tolle-ui.mjs.map +1 -1
- package/lib/alert-dialog.component.d.ts +10 -2
- package/lib/aspect-ratio.component.d.ts +20 -0
- package/lib/attachment.component.d.ts +101 -0
- package/lib/bubble.component.d.ts +112 -0
- package/lib/chain-of-thought.component.d.ts +166 -0
- package/lib/chart-pie.component.d.ts +108 -0
- package/lib/chart.component.d.ts +369 -0
- package/lib/chart.service.d.ts +222 -0
- package/lib/checkpoint.component.d.ts +51 -0
- package/lib/combobox.component.d.ts +90 -0
- package/lib/command-dialog.component.d.ts +53 -0
- package/lib/command.component.d.ts +189 -0
- package/lib/command.service.d.ts +67 -0
- package/lib/confirmation.component.d.ts +70 -0
- package/lib/context-menu-trigger.directive.d.ts +12 -0
- package/lib/context-menu.component.d.ts +41 -0
- package/lib/context-menu.service.d.ts +38 -0
- package/lib/context.component.d.ts +134 -0
- package/lib/conversation.component.d.ts +165 -0
- package/lib/data-table.component.d.ts +27 -1
- package/lib/date-picker.component.d.ts +72 -11
- package/lib/date-range-picker.component.d.ts +63 -6
- package/lib/date-time-picker.component.d.ts +119 -0
- package/lib/direction.component.d.ts +45 -0
- package/lib/field.component.d.ts +201 -0
- package/lib/inline-citation.component.d.ts +103 -0
- package/lib/input-group.component.d.ts +150 -0
- package/lib/item.component.d.ts +154 -0
- package/lib/kbd.component.d.ts +50 -0
- package/lib/marker.component.d.ts +58 -0
- package/lib/menubar.component.d.ts +247 -0
- package/lib/message-scroller.component.d.ts +159 -0
- package/lib/message-scroller.service.d.ts +73 -0
- package/lib/message.component.d.ts +128 -0
- package/lib/model-selector.component.d.ts +103 -0
- package/lib/multi-select.component.d.ts +66 -14
- package/lib/native-select.component.d.ts +57 -0
- package/lib/navigation-menu.component.d.ts +230 -0
- package/lib/plan.component.d.ts +120 -0
- package/lib/popover.component.d.ts +1 -0
- package/lib/prompt-input.component.d.ts +194 -0
- package/lib/queue.component.d.ts +106 -0
- package/lib/reasoning.component.d.ts +127 -0
- package/lib/resizable.component.d.ts +43 -0
- package/lib/segment.component.d.ts +13 -3
- package/lib/select.component.d.ts +37 -5
- package/lib/sheet.component.d.ts +3 -0
- package/lib/shimmer.component.d.ts +38 -0
- package/lib/sidebar.component.d.ts +2 -0
- package/lib/sources.component.d.ts +156 -0
- package/lib/spinner.component.d.ts +29 -0
- package/lib/suggestion.component.d.ts +96 -0
- package/lib/table.component.d.ts +106 -0
- package/lib/task.component.d.ts +151 -0
- package/lib/theme.service.d.ts +9 -0
- package/lib/time-picker.component.d.ts +243 -0
- package/lib/toast.service.d.ts +3 -1
- package/lib/toaster.component.d.ts +26 -9
- package/lib/tool.component.d.ts +158 -0
- package/lib/typography.component.d.ts +32 -0
- package/lib/utils/color.d.ts +19 -5
- package/package.json +1 -1
- package/public-api.d.ts +50 -0
- package/registry/docs-content.json +8497 -1553
- package/registry/llms-full.txt +2679 -318
- package/registry/llms.txt +43 -4
- package/registry/manifest.json +9093 -1739
- package/registry/r/accordion-item.json +1 -1
- package/registry/r/accordion.json +1 -1
- package/registry/r/alert-dialog-dynamic.json +1 -1
- package/registry/r/alert-dialog.json +1 -1
- package/registry/r/alert.json +1 -1
- package/registry/r/attachment.json +23 -0
- package/registry/r/avatar-fallback.json +1 -1
- package/registry/r/avatar.json +1 -1
- package/registry/r/badge.json +1 -1
- package/registry/r/breadcrumb-item.json +1 -1
- package/registry/r/breadcrumb-link.json +1 -1
- package/registry/r/breadcrumb-separator.json +1 -1
- package/registry/r/breadcrumb.json +1 -1
- package/registry/r/bubble.json +23 -0
- package/registry/r/button.json +1 -1
- package/registry/r/calendar.json +1 -1
- package/registry/r/card.json +1 -1
- package/registry/r/carousel.json +1 -1
- package/registry/r/chain-of-thought.json +23 -0
- package/registry/r/chart-pie.json +30 -0
- package/registry/r/chart.json +28 -0
- package/registry/r/checkbox.json +1 -1
- package/registry/r/checkpoint.json +23 -0
- package/registry/r/collapsible.json +1 -1
- package/registry/r/combobox.json +31 -0
- package/registry/r/command-dialog.json +21 -0
- package/registry/r/command.json +26 -0
- package/registry/r/confirmation.json +23 -0
- package/registry/r/context.json +26 -0
- package/registry/r/conversation.json +23 -0
- package/registry/r/country-selector.json +1 -1
- package/registry/r/data-table.json +1 -1
- package/registry/r/date-picker.json +4 -4
- package/registry/r/date-range-picker.json +3 -3
- package/registry/r/date-time-picker.json +28 -0
- package/registry/r/direction.json +16 -0
- package/registry/r/dropdown-item.json +1 -1
- package/registry/r/dropdown-label.json +1 -1
- package/registry/r/dropdown-menu.json +1 -1
- package/registry/r/dropdown-separator.json +1 -1
- package/registry/r/dropdown-trigger.json +1 -1
- package/registry/r/empty-state.json +1 -1
- package/registry/r/field.json +23 -0
- package/registry/r/hover-card.json +1 -1
- package/registry/r/inline-citation.json +26 -0
- package/registry/r/input-group.json +23 -0
- package/registry/r/input.json +1 -1
- package/registry/r/item.json +23 -0
- package/registry/r/kbd.json +23 -0
- package/registry/r/label.json +1 -1
- package/registry/r/marker.json +23 -0
- package/registry/r/masked-input.json +1 -1
- package/registry/r/menubar.json +24 -0
- package/registry/r/message-scroller.json +26 -0
- package/registry/r/message.json +23 -0
- package/registry/r/model-selector.json +32 -0
- package/registry/r/multi-select.json +2 -2
- package/registry/r/native-select.json +23 -0
- package/registry/r/navigation-menu.json +24 -0
- package/registry/r/otp-group.json +1 -1
- package/registry/r/otp-slot.json +1 -1
- package/registry/r/otp.json +1 -1
- package/registry/r/pagination.json +3 -2
- package/registry/r/plan.json +23 -0
- package/registry/r/popover-content.json +1 -1
- package/registry/r/popover.json +1 -1
- package/registry/r/progress.json +1 -1
- package/registry/r/prompt-input.json +23 -0
- package/registry/r/queue.json +23 -0
- package/registry/r/radio-group.json +1 -1
- package/registry/r/radio-item.json +1 -1
- package/registry/r/range-calendar.json +1 -1
- package/registry/r/reasoning.json +23 -0
- package/registry/r/segment.json +1 -1
- package/registry/r/select-group.json +1 -1
- package/registry/r/select-item.json +1 -1
- package/registry/r/select-separator.json +1 -1
- package/registry/r/select.json +4 -3
- package/registry/r/separator.json +1 -1
- package/registry/r/sheet.json +1 -1
- package/registry/r/shimmer.json +23 -0
- package/registry/r/sidebar.json +1 -1
- package/registry/r/skeleton.json +1 -1
- package/registry/r/sources.json +23 -0
- package/registry/r/spinner.json +23 -0
- package/registry/r/suggestion.json +23 -0
- package/registry/r/switch.json +1 -1
- package/registry/r/table.json +21 -0
- package/registry/r/tabs.json +1 -1
- package/registry/r/tag-input.json +1 -1
- package/registry/r/task.json +23 -0
- package/registry/r/textarea.json +1 -1
- package/registry/r/time-picker.json +24 -0
- package/registry/r/toaster.json +2 -2
- package/registry/r/toggle-group.json +1 -1
- package/registry/r/toggle.json +1 -1
- package/registry/r/tool.json +23 -0
- package/registry/r/typography.json +23 -0
- package/registry/registry.json +915 -22
- package/theme.css +109 -8
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Injectable, Input, Output, ViewChild, forwardRef, inject } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
4
|
+
import { BehaviorSubject, Subject, Subscription } from 'rxjs';
|
|
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 promptInputVariants = cva('flex w-full flex-col gap-2 rounded-lg border bg-background p-2 shadow-sm transition-colors focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-offset-background', {
|
|
10
|
+
variants: {
|
|
11
|
+
status: {
|
|
12
|
+
ready: 'border-input focus-within:ring-ring',
|
|
13
|
+
streaming: 'border-info focus-within:ring-info',
|
|
14
|
+
error: 'border-destructive focus-within:ring-destructive',
|
|
15
|
+
},
|
|
16
|
+
size: {
|
|
17
|
+
sm: 'p-1.5 text-xs',
|
|
18
|
+
default: 'p-2 text-sm',
|
|
19
|
+
lg: 'p-3 text-base',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
defaultVariants: {
|
|
23
|
+
status: 'ready',
|
|
24
|
+
size: 'default',
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* Coordinates a `tolle-prompt-input` with its projected toolbar controls.
|
|
29
|
+
*
|
|
30
|
+
* The submit button is an OnPush child that must flip to a stop button the
|
|
31
|
+
* moment the status changes, so the composer publishes its state here instead
|
|
32
|
+
* of the button reading the parent's fields.
|
|
33
|
+
*
|
|
34
|
+
* Provided on `PromptInputComponent`, so each composer gets its own instance.
|
|
35
|
+
*/
|
|
36
|
+
export class PromptInputService {
|
|
37
|
+
statusSource = new BehaviorSubject('ready');
|
|
38
|
+
/** Emits the composer's current status. */
|
|
39
|
+
status$ = this.statusSource.asObservable();
|
|
40
|
+
canSubmitSource = new BehaviorSubject(false);
|
|
41
|
+
/** Emits whether there is submittable text and the composer is enabled. */
|
|
42
|
+
canSubmit$ = this.canSubmitSource.asObservable();
|
|
43
|
+
submitSource = new Subject();
|
|
44
|
+
/** Emits when a toolbar control asks the composer to submit. */
|
|
45
|
+
submit$ = this.submitSource.asObservable();
|
|
46
|
+
stopSource = new Subject();
|
|
47
|
+
/** Emits when a toolbar control asks the composer to stop streaming. */
|
|
48
|
+
stop$ = this.stopSource.asObservable();
|
|
49
|
+
/** The composer's current status. */
|
|
50
|
+
get status() {
|
|
51
|
+
return this.statusSource.value;
|
|
52
|
+
}
|
|
53
|
+
/** True when the composer has submittable text. */
|
|
54
|
+
get canSubmit() {
|
|
55
|
+
return this.canSubmitSource.value;
|
|
56
|
+
}
|
|
57
|
+
setStatus(status) {
|
|
58
|
+
if (this.statusSource.value !== status)
|
|
59
|
+
this.statusSource.next(status);
|
|
60
|
+
}
|
|
61
|
+
setCanSubmit(value) {
|
|
62
|
+
if (this.canSubmitSource.value !== value)
|
|
63
|
+
this.canSubmitSource.next(value);
|
|
64
|
+
}
|
|
65
|
+
requestSubmit() {
|
|
66
|
+
this.submitSource.next();
|
|
67
|
+
}
|
|
68
|
+
requestStop() {
|
|
69
|
+
this.stopSource.next();
|
|
70
|
+
}
|
|
71
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PromptInputService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
72
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PromptInputService });
|
|
73
|
+
}
|
|
74
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PromptInputService, decorators: [{
|
|
75
|
+
type: Injectable
|
|
76
|
+
}] });
|
|
77
|
+
/**
|
|
78
|
+
* A message composer: an auto-growing textarea plus a toolbar, wired as a
|
|
79
|
+
* `ControlValueAccessor` so it drops into template- or reactive-driven forms.
|
|
80
|
+
*
|
|
81
|
+
* Enter submits and Shift+Enter inserts a newline (swap with `submitOnEnter`).
|
|
82
|
+
* While `status` is 'streaming' the projected `tolle-prompt-input-submit`
|
|
83
|
+
* becomes a stop button that emits `stopped`.
|
|
84
|
+
* @new
|
|
85
|
+
*/
|
|
86
|
+
export class PromptInputComponent {
|
|
87
|
+
/** Placeholder shown while the composer is empty. @default 'Send a message…' */
|
|
88
|
+
placeholder = 'Send a message…';
|
|
89
|
+
/** Blocks typing and submission. @default false */
|
|
90
|
+
disabled = false;
|
|
91
|
+
/** Rows the textarea may grow to before it starts scrolling. @default 8 */
|
|
92
|
+
maxRows = 8;
|
|
93
|
+
/** Lifecycle of the response being composed. @default 'ready' */
|
|
94
|
+
status = 'ready';
|
|
95
|
+
/** Size scale of the composer. @default 'default' */
|
|
96
|
+
size = 'default';
|
|
97
|
+
/** Submit on Enter, keeping Shift+Enter for newlines. @default true */
|
|
98
|
+
submitOnEnter = true;
|
|
99
|
+
/** Clears the composer after a successful submit. @default true */
|
|
100
|
+
clearOnSubmit = true;
|
|
101
|
+
/** Accessible name for the textarea. @default '' */
|
|
102
|
+
ariaLabel = '';
|
|
103
|
+
/** Extra Tailwind classes merged onto the composer via `cn()` (last-wins). */
|
|
104
|
+
class = '';
|
|
105
|
+
/** Extra Tailwind classes merged onto the textarea via `cn()` (last-wins). */
|
|
106
|
+
textareaClass = '';
|
|
107
|
+
/** Emitted with the trimmed message text when the user submits. */
|
|
108
|
+
submitted = new EventEmitter();
|
|
109
|
+
/** Emitted when the user cancels an in-flight streaming response. */
|
|
110
|
+
stopped = new EventEmitter();
|
|
111
|
+
/** Emitted with the message text whenever it changes. */
|
|
112
|
+
valueChange = new EventEmitter();
|
|
113
|
+
textarea;
|
|
114
|
+
service = inject(PromptInputService);
|
|
115
|
+
cdr = inject(ChangeDetectorRef);
|
|
116
|
+
subscriptions = new Subscription();
|
|
117
|
+
value = '';
|
|
118
|
+
onChange = () => { };
|
|
119
|
+
onTouched = () => { };
|
|
120
|
+
ngOnInit() {
|
|
121
|
+
this.syncService();
|
|
122
|
+
this.subscriptions.add(this.service.submit$.subscribe(() => this.submit()));
|
|
123
|
+
this.subscriptions.add(this.service.stop$.subscribe(() => this.stop()));
|
|
124
|
+
}
|
|
125
|
+
ngOnChanges() {
|
|
126
|
+
this.syncService();
|
|
127
|
+
// A bound `class` input is written through Angular's styling path,
|
|
128
|
+
// which does not mark an OnPush view dirty on its own.
|
|
129
|
+
this.cdr.markForCheck();
|
|
130
|
+
}
|
|
131
|
+
ngAfterViewInit() {
|
|
132
|
+
this.resize();
|
|
133
|
+
}
|
|
134
|
+
ngOnDestroy() {
|
|
135
|
+
this.subscriptions.unsubscribe();
|
|
136
|
+
}
|
|
137
|
+
get computedClass() {
|
|
138
|
+
return cn(promptInputVariants({ status: this.status, size: this.size }), this.disabled && 'cursor-not-allowed opacity-60', this.class);
|
|
139
|
+
}
|
|
140
|
+
get textareaComputedClass() {
|
|
141
|
+
return cn('w-full resize-none bg-transparent px-2 py-1.5 text-sm text-foreground outline-none', 'placeholder:text-muted-foreground disabled:cursor-not-allowed', this.textareaClass);
|
|
142
|
+
}
|
|
143
|
+
onInput(event) {
|
|
144
|
+
const next = event.target.value;
|
|
145
|
+
this.setValue(next);
|
|
146
|
+
this.resize();
|
|
147
|
+
}
|
|
148
|
+
onKeyDown(event) {
|
|
149
|
+
if (event.key !== 'Enter' || !this.submitOnEnter)
|
|
150
|
+
return;
|
|
151
|
+
// Shift+Enter is the newline escape hatch; modifier chords and IME
|
|
152
|
+
// composition must never steal the keystroke.
|
|
153
|
+
if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey)
|
|
154
|
+
return;
|
|
155
|
+
if (event.isComposing)
|
|
156
|
+
return;
|
|
157
|
+
event.preventDefault();
|
|
158
|
+
this.submit();
|
|
159
|
+
}
|
|
160
|
+
onBlur() {
|
|
161
|
+
this.onTouched();
|
|
162
|
+
}
|
|
163
|
+
/** Submits the current text, unless the composer is empty, disabled or busy. */
|
|
164
|
+
submit() {
|
|
165
|
+
if (this.disabled || this.status === 'streaming')
|
|
166
|
+
return;
|
|
167
|
+
const text = this.value.trim();
|
|
168
|
+
if (!text)
|
|
169
|
+
return;
|
|
170
|
+
this.submitted.emit(text);
|
|
171
|
+
if (this.clearOnSubmit) {
|
|
172
|
+
this.setValue('');
|
|
173
|
+
if (this.textarea)
|
|
174
|
+
this.textarea.nativeElement.value = '';
|
|
175
|
+
this.resize();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/** Cancels an in-flight streaming response. */
|
|
179
|
+
stop() {
|
|
180
|
+
this.stopped.emit();
|
|
181
|
+
}
|
|
182
|
+
/** Moves focus into the textarea. */
|
|
183
|
+
focus() {
|
|
184
|
+
this.textarea?.nativeElement.focus();
|
|
185
|
+
}
|
|
186
|
+
writeValue(value) {
|
|
187
|
+
this.value = value ?? '';
|
|
188
|
+
if (this.textarea)
|
|
189
|
+
this.textarea.nativeElement.value = this.value;
|
|
190
|
+
this.service.setCanSubmit(this.canSubmit);
|
|
191
|
+
this.cdr.markForCheck();
|
|
192
|
+
this.resize();
|
|
193
|
+
}
|
|
194
|
+
registerOnChange(fn) {
|
|
195
|
+
this.onChange = fn;
|
|
196
|
+
}
|
|
197
|
+
registerOnTouched(fn) {
|
|
198
|
+
this.onTouched = fn;
|
|
199
|
+
}
|
|
200
|
+
setDisabledState(isDisabled) {
|
|
201
|
+
this.disabled = isDisabled;
|
|
202
|
+
this.syncService();
|
|
203
|
+
this.cdr.markForCheck();
|
|
204
|
+
}
|
|
205
|
+
get canSubmit() {
|
|
206
|
+
return !this.disabled && this.value.trim().length > 0;
|
|
207
|
+
}
|
|
208
|
+
setValue(next) {
|
|
209
|
+
this.value = next;
|
|
210
|
+
this.onChange(next);
|
|
211
|
+
this.valueChange.emit(next);
|
|
212
|
+
this.service.setCanSubmit(this.canSubmit);
|
|
213
|
+
}
|
|
214
|
+
syncService() {
|
|
215
|
+
this.service.setStatus(this.status);
|
|
216
|
+
this.service.setCanSubmit(this.canSubmit);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Grows the textarea with its content up to `maxRows`, then lets it scroll.
|
|
220
|
+
* Measured from the computed line height so it tracks the inherited font.
|
|
221
|
+
*/
|
|
222
|
+
resize() {
|
|
223
|
+
const el = this.textarea?.nativeElement;
|
|
224
|
+
if (!el)
|
|
225
|
+
return;
|
|
226
|
+
el.style.height = 'auto';
|
|
227
|
+
const styles = getComputedStyle(el);
|
|
228
|
+
const parsedLineHeight = parseFloat(styles.lineHeight);
|
|
229
|
+
const lineHeight = Number.isFinite(parsedLineHeight)
|
|
230
|
+
? parsedLineHeight
|
|
231
|
+
: parseFloat(styles.fontSize) * 1.5 || 20;
|
|
232
|
+
const vertical = parseFloat(styles.paddingTop || '0') +
|
|
233
|
+
parseFloat(styles.paddingBottom || '0') +
|
|
234
|
+
parseFloat(styles.borderTopWidth || '0') +
|
|
235
|
+
parseFloat(styles.borderBottomWidth || '0');
|
|
236
|
+
const max = lineHeight * Math.max(1, this.maxRows) + vertical;
|
|
237
|
+
const next = Math.min(el.scrollHeight, max);
|
|
238
|
+
el.style.height = next + 'px';
|
|
239
|
+
el.style.overflowY = el.scrollHeight > max ? 'auto' : 'hidden';
|
|
240
|
+
}
|
|
241
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PromptInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
242
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: PromptInputComponent, isStandalone: true, selector: "tolle-prompt-input", inputs: { placeholder: "placeholder", disabled: "disabled", maxRows: "maxRows", status: "status", size: "size", submitOnEnter: "submitOnEnter", clearOnSubmit: "clearOnSubmit", ariaLabel: "ariaLabel", class: "class", textareaClass: "textareaClass" }, outputs: { submitted: "submitted", stopped: "stopped", valueChange: "valueChange" }, providers: [
|
|
243
|
+
PromptInputService,
|
|
244
|
+
{
|
|
245
|
+
provide: NG_VALUE_ACCESSOR,
|
|
246
|
+
useExisting: forwardRef(() => PromptInputComponent),
|
|
247
|
+
multi: true,
|
|
248
|
+
},
|
|
249
|
+
], viewQueries: [{ propertyName: "textarea", first: true, predicate: ["textarea"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
250
|
+
<div [class]="computedClass">
|
|
251
|
+
<textarea
|
|
252
|
+
#textarea
|
|
253
|
+
data-prompt-input-textarea
|
|
254
|
+
rows="1"
|
|
255
|
+
[value]="value"
|
|
256
|
+
[attr.placeholder]="placeholder"
|
|
257
|
+
[disabled]="disabled"
|
|
258
|
+
[attr.aria-label]="ariaLabel || placeholder || 'Message'"
|
|
259
|
+
[attr.aria-invalid]="status === 'error' ? 'true' : null"
|
|
260
|
+
[class]="textareaComputedClass"
|
|
261
|
+
(input)="onInput($event)"
|
|
262
|
+
(keydown)="onKeyDown($event)"
|
|
263
|
+
(blur)="onBlur()"
|
|
264
|
+
></textarea>
|
|
265
|
+
|
|
266
|
+
<ng-content></ng-content>
|
|
267
|
+
</div>
|
|
268
|
+
`, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
269
|
+
}
|
|
270
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PromptInputComponent, decorators: [{
|
|
271
|
+
type: Component,
|
|
272
|
+
args: [{ selector: 'tolle-prompt-input', standalone: true, imports: [CommonModule], providers: [
|
|
273
|
+
PromptInputService,
|
|
274
|
+
{
|
|
275
|
+
provide: NG_VALUE_ACCESSOR,
|
|
276
|
+
useExisting: forwardRef(() => PromptInputComponent),
|
|
277
|
+
multi: true,
|
|
278
|
+
},
|
|
279
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
280
|
+
<div [class]="computedClass">
|
|
281
|
+
<textarea
|
|
282
|
+
#textarea
|
|
283
|
+
data-prompt-input-textarea
|
|
284
|
+
rows="1"
|
|
285
|
+
[value]="value"
|
|
286
|
+
[attr.placeholder]="placeholder"
|
|
287
|
+
[disabled]="disabled"
|
|
288
|
+
[attr.aria-label]="ariaLabel || placeholder || 'Message'"
|
|
289
|
+
[attr.aria-invalid]="status === 'error' ? 'true' : null"
|
|
290
|
+
[class]="textareaComputedClass"
|
|
291
|
+
(input)="onInput($event)"
|
|
292
|
+
(keydown)="onKeyDown($event)"
|
|
293
|
+
(blur)="onBlur()"
|
|
294
|
+
></textarea>
|
|
295
|
+
|
|
296
|
+
<ng-content></ng-content>
|
|
297
|
+
</div>
|
|
298
|
+
`, styles: [":host{display:block}\n"] }]
|
|
299
|
+
}], propDecorators: { placeholder: [{
|
|
300
|
+
type: Input
|
|
301
|
+
}], disabled: [{
|
|
302
|
+
type: Input
|
|
303
|
+
}], maxRows: [{
|
|
304
|
+
type: Input
|
|
305
|
+
}], status: [{
|
|
306
|
+
type: Input
|
|
307
|
+
}], size: [{
|
|
308
|
+
type: Input
|
|
309
|
+
}], submitOnEnter: [{
|
|
310
|
+
type: Input
|
|
311
|
+
}], clearOnSubmit: [{
|
|
312
|
+
type: Input
|
|
313
|
+
}], ariaLabel: [{
|
|
314
|
+
type: Input
|
|
315
|
+
}], class: [{
|
|
316
|
+
type: Input
|
|
317
|
+
}], textareaClass: [{
|
|
318
|
+
type: Input
|
|
319
|
+
}], submitted: [{
|
|
320
|
+
type: Output
|
|
321
|
+
}], stopped: [{
|
|
322
|
+
type: Output
|
|
323
|
+
}], valueChange: [{
|
|
324
|
+
type: Output
|
|
325
|
+
}], textarea: [{
|
|
326
|
+
type: ViewChild,
|
|
327
|
+
args: ['textarea']
|
|
328
|
+
}] } });
|
|
329
|
+
/** Bottom bar of a `tolle-prompt-input`: tools on the left, submit on the right. */
|
|
330
|
+
export class PromptInputToolbarComponent {
|
|
331
|
+
cdr = inject(ChangeDetectorRef);
|
|
332
|
+
/**
|
|
333
|
+
* Angular writes a bound `class` input through its styling path, which does
|
|
334
|
+
* not mark an OnPush component dirty — without this hook the component keeps
|
|
335
|
+
* rendering the class it was born with.
|
|
336
|
+
*/
|
|
337
|
+
ngOnChanges() {
|
|
338
|
+
this.cdr.markForCheck();
|
|
339
|
+
}
|
|
340
|
+
/** Extra Tailwind classes merged onto the toolbar via `cn()` (last-wins). */
|
|
341
|
+
class = '';
|
|
342
|
+
get computedClass() {
|
|
343
|
+
return cn('flex items-center justify-between gap-2 px-1', this.class);
|
|
344
|
+
}
|
|
345
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PromptInputToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
346
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: PromptInputToolbarComponent, isStandalone: true, selector: "tolle-prompt-input-toolbar", inputs: { class: "class" }, usesOnChanges: true, ngImport: i0, template: `
|
|
347
|
+
<div [class]="computedClass">
|
|
348
|
+
<ng-content></ng-content>
|
|
349
|
+
</div>
|
|
350
|
+
`, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
351
|
+
}
|
|
352
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PromptInputToolbarComponent, decorators: [{
|
|
353
|
+
type: Component,
|
|
354
|
+
args: [{ selector: 'tolle-prompt-input-toolbar', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
355
|
+
<div [class]="computedClass">
|
|
356
|
+
<ng-content></ng-content>
|
|
357
|
+
</div>
|
|
358
|
+
`, styles: [":host{display:block}\n"] }]
|
|
359
|
+
}], propDecorators: { class: [{
|
|
360
|
+
type: Input
|
|
361
|
+
}] } });
|
|
362
|
+
/** Left-aligned cluster of tool buttons inside a `tolle-prompt-input-toolbar`. */
|
|
363
|
+
export class PromptInputToolsComponent {
|
|
364
|
+
cdr = inject(ChangeDetectorRef);
|
|
365
|
+
/**
|
|
366
|
+
* Angular writes a bound `class` input through its styling path, which does
|
|
367
|
+
* not mark an OnPush component dirty — without this hook the component keeps
|
|
368
|
+
* rendering the class it was born with.
|
|
369
|
+
*/
|
|
370
|
+
ngOnChanges() {
|
|
371
|
+
this.cdr.markForCheck();
|
|
372
|
+
}
|
|
373
|
+
/** Extra Tailwind classes merged onto the tool row via `cn()` (last-wins). */
|
|
374
|
+
class = '';
|
|
375
|
+
get computedClass() {
|
|
376
|
+
return cn('flex flex-1 items-center gap-1 text-muted-foreground', this.class);
|
|
377
|
+
}
|
|
378
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PromptInputToolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
379
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: PromptInputToolsComponent, isStandalone: true, selector: "tolle-prompt-input-tools", inputs: { class: "class" }, usesOnChanges: true, ngImport: i0, template: `
|
|
380
|
+
<div [class]="computedClass">
|
|
381
|
+
<ng-content></ng-content>
|
|
382
|
+
</div>
|
|
383
|
+
`, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
384
|
+
}
|
|
385
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PromptInputToolsComponent, decorators: [{
|
|
386
|
+
type: Component,
|
|
387
|
+
args: [{ selector: 'tolle-prompt-input-tools', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
388
|
+
<div [class]="computedClass">
|
|
389
|
+
<ng-content></ng-content>
|
|
390
|
+
</div>
|
|
391
|
+
`, styles: [":host{display:block}\n"] }]
|
|
392
|
+
}], propDecorators: { class: [{
|
|
393
|
+
type: Input
|
|
394
|
+
}] } });
|
|
395
|
+
const promptInputSubmitVariants = cva('inline-flex shrink-0 items-center justify-center gap-1.5 rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50', {
|
|
396
|
+
variants: {
|
|
397
|
+
variant: {
|
|
398
|
+
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
|
399
|
+
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
|
400
|
+
ghost: 'text-foreground hover:bg-accent hover:text-accent-foreground',
|
|
401
|
+
},
|
|
402
|
+
size: {
|
|
403
|
+
sm: 'h-7 px-2 text-xs',
|
|
404
|
+
default: 'size-8 text-sm',
|
|
405
|
+
lg: 'h-10 px-4 text-sm',
|
|
406
|
+
},
|
|
407
|
+
},
|
|
408
|
+
defaultVariants: {
|
|
409
|
+
variant: 'default',
|
|
410
|
+
size: 'default',
|
|
411
|
+
},
|
|
412
|
+
});
|
|
413
|
+
/**
|
|
414
|
+
* Send button for a `tolle-prompt-input`. Turns into a stop button while the
|
|
415
|
+
* composer's status is 'streaming', so one control covers both directions.
|
|
416
|
+
*/
|
|
417
|
+
export class PromptInputSubmitComponent {
|
|
418
|
+
/**
|
|
419
|
+
* Angular writes a bound `class` input through its styling path, which does
|
|
420
|
+
* not mark an OnPush component dirty — without this hook the component keeps
|
|
421
|
+
* rendering the class it was born with.
|
|
422
|
+
*/
|
|
423
|
+
ngOnChanges() {
|
|
424
|
+
this.cdr.markForCheck();
|
|
425
|
+
}
|
|
426
|
+
/** Visual style of the button. @default 'default' */
|
|
427
|
+
variant = 'default';
|
|
428
|
+
/** Size of the button. @default 'default' */
|
|
429
|
+
size = 'default';
|
|
430
|
+
/** Accessible name while the composer is idle. @default 'Send message' */
|
|
431
|
+
submitLabel = 'Send message';
|
|
432
|
+
/** Accessible name while the composer is streaming. @default 'Stop generating' */
|
|
433
|
+
stopLabel = 'Stop generating';
|
|
434
|
+
/** Renders the label next to the icon. @default false */
|
|
435
|
+
showLabel = false;
|
|
436
|
+
/** Extra Tailwind classes merged onto the button via `cn()` (last-wins). */
|
|
437
|
+
class = '';
|
|
438
|
+
service = inject(PromptInputService);
|
|
439
|
+
cdr = inject(ChangeDetectorRef);
|
|
440
|
+
subscriptions = new Subscription();
|
|
441
|
+
status = 'ready';
|
|
442
|
+
canSubmit = false;
|
|
443
|
+
ngOnInit() {
|
|
444
|
+
this.subscriptions.add(this.service.status$.subscribe((status) => {
|
|
445
|
+
this.status = status;
|
|
446
|
+
this.cdr.markForCheck();
|
|
447
|
+
}));
|
|
448
|
+
this.subscriptions.add(this.service.canSubmit$.subscribe((canSubmit) => {
|
|
449
|
+
this.canSubmit = canSubmit;
|
|
450
|
+
this.cdr.markForCheck();
|
|
451
|
+
}));
|
|
452
|
+
}
|
|
453
|
+
ngOnDestroy() {
|
|
454
|
+
this.subscriptions.unsubscribe();
|
|
455
|
+
}
|
|
456
|
+
/** True while the button is showing its stop affordance. */
|
|
457
|
+
get isStreaming() {
|
|
458
|
+
return this.status === 'streaming';
|
|
459
|
+
}
|
|
460
|
+
get currentIcon() {
|
|
461
|
+
return this.isStreaming ? 'ri-stop-circle-line' : 'ri-send-plane-2-fill';
|
|
462
|
+
}
|
|
463
|
+
get currentLabel() {
|
|
464
|
+
return this.isStreaming ? this.stopLabel : this.submitLabel;
|
|
465
|
+
}
|
|
466
|
+
/** Stopping stays available with an empty composer; sending does not. */
|
|
467
|
+
get isDisabled() {
|
|
468
|
+
return !this.isStreaming && !this.canSubmit;
|
|
469
|
+
}
|
|
470
|
+
get computedClass() {
|
|
471
|
+
return cn(promptInputSubmitVariants({ variant: this.variant, size: this.size }), this.isStreaming && 'bg-destructive text-destructive-foreground hover:bg-destructive/90', this.class);
|
|
472
|
+
}
|
|
473
|
+
onClick() {
|
|
474
|
+
if (this.isStreaming) {
|
|
475
|
+
this.service.requestStop();
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
this.service.requestSubmit();
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PromptInputSubmitComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
482
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: PromptInputSubmitComponent, isStandalone: true, selector: "tolle-prompt-input-submit", inputs: { variant: "variant", size: "size", submitLabel: "submitLabel", stopLabel: "stopLabel", showLabel: "showLabel", class: "class" }, usesOnChanges: true, ngImport: i0, template: `
|
|
483
|
+
<button
|
|
484
|
+
type="button"
|
|
485
|
+
data-prompt-input-submit
|
|
486
|
+
[attr.data-state]="status"
|
|
487
|
+
[attr.aria-label]="currentLabel"
|
|
488
|
+
[disabled]="isDisabled"
|
|
489
|
+
[class]="computedClass"
|
|
490
|
+
(click)="onClick()"
|
|
491
|
+
>
|
|
492
|
+
<i [class]="currentIcon" aria-hidden="true"></i>
|
|
493
|
+
<span *ngIf="showLabel">{{ currentLabel }}</span>
|
|
494
|
+
</button>
|
|
495
|
+
`, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
496
|
+
}
|
|
497
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PromptInputSubmitComponent, decorators: [{
|
|
498
|
+
type: Component,
|
|
499
|
+
args: [{ selector: 'tolle-prompt-input-submit', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
500
|
+
<button
|
|
501
|
+
type="button"
|
|
502
|
+
data-prompt-input-submit
|
|
503
|
+
[attr.data-state]="status"
|
|
504
|
+
[attr.aria-label]="currentLabel"
|
|
505
|
+
[disabled]="isDisabled"
|
|
506
|
+
[class]="computedClass"
|
|
507
|
+
(click)="onClick()"
|
|
508
|
+
>
|
|
509
|
+
<i [class]="currentIcon" aria-hidden="true"></i>
|
|
510
|
+
<span *ngIf="showLabel">{{ currentLabel }}</span>
|
|
511
|
+
</button>
|
|
512
|
+
`, styles: [":host{display:block}\n"] }]
|
|
513
|
+
}], propDecorators: { variant: [{
|
|
514
|
+
type: Input
|
|
515
|
+
}], size: [{
|
|
516
|
+
type: Input
|
|
517
|
+
}], submitLabel: [{
|
|
518
|
+
type: Input
|
|
519
|
+
}], stopLabel: [{
|
|
520
|
+
type: Input
|
|
521
|
+
}], showLabel: [{
|
|
522
|
+
type: Input
|
|
523
|
+
}], class: [{
|
|
524
|
+
type: Input
|
|
525
|
+
}] } });
|
|
526
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvbXB0LWlucHV0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RvbGxlL3NyYy9saWIvcHJvbXB0LWlucHV0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWlCLHVCQUF1QixFQUFFLGlCQUFpQixFQUFFLFNBQVMsRUFBYyxZQUFZLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBZ0MsTUFBTSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZOLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekUsT0FBTyxFQUFFLGVBQWUsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzlELE9BQU8sRUFBRSxHQUFHLEVBQXFCLE1BQU0sMEJBQTBCLENBQUM7QUFDbEUsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLFlBQVksQ0FBQzs7O0FBRWhDLE1BQU0sbUJBQW1CLEdBQUcsR0FBRyxDQUM3QiwrS0FBK0ssRUFDL0s7SUFDRSxRQUFRLEVBQUU7UUFDUixNQUFNLEVBQUU7WUFDTixLQUFLLEVBQUUscUNBQXFDO1lBQzVDLFNBQVMsRUFBRSxvQ0FBb0M7WUFDL0MsS0FBSyxFQUFFLGtEQUFrRDtTQUMxRDtRQUNELElBQUksRUFBRTtZQUNKLEVBQUUsRUFBRSxlQUFlO1lBQ25CLE9BQU8sRUFBRSxhQUFhO1lBQ3RCLEVBQUUsRUFBRSxlQUFlO1NBQ3BCO0tBQ0Y7SUFDRCxlQUFlLEVBQUU7UUFDZixNQUFNLEVBQUUsT0FBTztRQUNmLElBQUksRUFBRSxTQUFTO0tBQ2hCO0NBQ0YsQ0FDRixDQUFDO0FBT0Y7Ozs7Ozs7O0dBUUc7QUFFSCxNQUFNLE9BQU8sa0JBQWtCO0lBQ1osWUFBWSxH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LCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBZnRlclZpZXdJbml0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbmplY3RhYmxlLCBJbnB1dCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3V0cHV0LCBWaWV3Q2hpbGQsIGZvcndhcmRSZWYsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjdmEsIHR5cGUgVmFyaWFudFByb3BzIH0gZnJvbSAnY2xhc3MtdmFyaWFuY2UtYXV0aG9yaXR5JztcbmltcG9ydCB7IGNuIH0gZnJvbSAnLi91dGlscy9jbic7XG5cbmNvbnN0IHByb21wdElucHV0VmFyaWFudHMgPSBjdmEoXG4gICdmbGV4IHctZnVsbCBmbGV4LWNvbCBnYXAtMiByb3VuZGVkLWxnIGJvcmRlciBiZy1iYWNrZ3JvdW5kIHAtMiBzaGFkb3ctc20gdHJhbnNpdGlvbi1jb2xvcnMgZm9jdXMtd2l0aGluOnJpbmctMiBmb2N1cy13aXRoaW46cmluZy1vZmZzZXQtMiBmb2N1cy13aXRoaW46cmluZy1vZmZzZXQtYmFja2dyb3VuZCcsXG4gIHtcbiAgICB2YXJpYW50czoge1xuICAgICAgc3RhdHVzOiB7XG4gICAgICAgIHJlYWR5OiAnYm9yZGVyLWlucHV0IGZvY3VzLXdpdGhpbjpyaW5nLXJpbmcnLFxuICAgICAgICBzdHJlYW1pbmc6ICdib3JkZXItaW5mbyBmb2N1cy13aXRoaW46cmluZy1pbmZvJyxcbiAgICAgICAgZXJyb3I6ICdib3JkZXItZGVzdHJ1Y3RpdmUgZm9jdXMtd2l0aGluOnJpbmctZGVzdHJ1Y3RpdmUnLFxuICAgICAgfSxcbiAgICAgIHNpemU6IHtcbiAgICAgICAgc206ICdwLTEuNSB0ZXh0LXhzJyxcbiAgICAgICAgZGVmYXVsdDogJ3AtMiB0ZXh0LXNtJyxcbiAgICAgICAgbGc6ICdwLTMgdGV4dC1iYXNlJyxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBkZWZhdWx0VmFyaWFudHM6IHtcbiAgICAgIHN0YXR1czogJ3JlYWR5JyxcbiAgICAgIHNpemU6ICdkZWZhdWx0JyxcbiAgICB9LFxuICB9XG4pO1xuXG5leHBvcnQgdHlwZSBQcm9tcHRJbnB1dFByb3BzID0gVmFyaWFudFByb3BzPHR5cGVvZiBwcm9tcHRJbnB1dFZhcmlhbnRzPjtcblxuLyoqIExpZmVjeWNsZSBvZiB0aGUgcmVzcG9uc2UgdGhlIGNvbXBvc2VyIGlzIGRyaXZpbmcuICovXG5leHBvcnQgdHlwZSBQcm9tcHRJbnB1dFN0YXR1cyA9IE5vbk51bGxhYmxlPFByb21wdElucHV0UHJvcHNbJ3N0YXR1cyddPjtcblxuLyoqXG4gKiBDb29yZGluYXRlcyBhIGB0b2xsZS1wcm9tcHQtaW5wdXRgIHdpdGggaXRzIHByb2plY3RlZCB0b29sYmFyIGNvbnRyb2xzLlxuICpcbiAqIFRoZSBzdWJtaXQgYnV0dG9uIGlzIGFuIE9uUHVzaCBjaGlsZCB0aGF0IG11c3QgZmxpcCB0byBhIHN0b3AgYnV0dG9uIHRoZVxuICogbW9tZW50IHRoZSBzdGF0dXMgY2hhbmdlcywgc28gdGhlIGNvbXBvc2VyIHB1Ymxpc2hlcyBpdHMgc3RhdGUgaGVyZSBpbnN0ZWFkXG4gKiBvZiB0aGUgYnV0dG9uIHJlYWRpbmcgdGhlIHBhcmVudCdzIGZpZWxkcy5cbiAqXG4gKiBQcm92aWRlZCBvbiBgUHJvbXB0SW5wdXRDb21wb25lbnRgLCBzbyBlYWNoIGNvbXBvc2VyIGdldHMgaXRzIG93biBpbnN0YW5jZS5cbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFByb21wdElucHV0U2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3RhdHVzU291cmNlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxQcm9tcHRJbnB1dFN0YXR1cz4oJ3JlYWR5Jyk7XG4gIC8qKiBFbWl0cyB0aGUgY29tcG9zZXIncyBjdXJyZW50IHN0YXR1cy4gKi9cbiAgcmVhZG9ubHkgc3RhdHVzJCA9IHRoaXMuc3RhdHVzU291cmNlLmFzT2JzZXJ2YWJsZSgpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY2FuU3VibWl0U291cmNlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG4gIC8qKiBFbWl0cyB3aGV0aGVyIHRoZXJlIGlzIHN1Ym1pdHRhYmxlIHRleHQgYW5kIHRoZSBjb21wb3NlciBpcyBlbmFibGVkLiAqL1xuICByZWFkb25seSBjYW5TdWJtaXQkID0gdGhpcy5jYW5TdWJtaXRTb3VyY2UuYXNPYnNlcnZhYmxlKCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBzdWJtaXRTb3VyY2UgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICAvKiogRW1pdHMgd2hlbiBhIHRvb2xiYXIgY29udHJvbCBhc2tzIHRoZSBjb21wb3NlciB0byBzdWJtaXQuICovXG4gIHJlYWRvbmx5IHN1Ym1pdCQgPSB0aGlzLnN1Ym1pdFNvdXJjZS5hc09ic2VydmFibGUoKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IHN0b3BTb3VyY2UgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICAvKiogRW1pdHMgd2hlbiBhIHRvb2xiYXIgY29udHJvbCBhc2tzIHRoZSBjb21wb3NlciB0byBzdG9wIHN0cmVhbWluZy4gKi9cbiAgcmVhZG9ubHkgc3RvcCQgPSB0aGlzLnN0b3BTb3VyY2UuYXNPYnNlcnZhYmxlKCk7XG5cbiAgLyoqIFRoZSBjb21wb3NlcidzIGN1cnJlbnQgc3RhdHVzLiAqL1xuICBnZXQgc3RhdHVzKCk6IFByb21wdElucHV0U3RhdHVzIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0dXNTb3VyY2UudmFsdWU7XG4gIH1cblxuICAvKiogVHJ1ZSB3aGVuIHRoZSBjb21wb3NlciBoYXMgc3VibWl0dGFibGUgdGV4dC4gKi9cbiAgZ2V0IGNhblN1Ym1pdCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jYW5TdWJtaXRTb3VyY2UudmFsdWU7XG4gIH1cblxuICBzZXRTdGF0dXMoc3RhdHVzOiBQcm9tcHRJbnB1dFN0YXR1cyk6IHZvaWQge1xuICAgIGlmICh0aGlzLnN0YXR1c1NvdXJjZS52YWx1ZSAhPT0gc3RhdHVzKSB0aGlzLnN0YXR1c1NvdXJjZS5uZXh0KHN0YXR1cyk7XG4gIH1cblxuICBzZXRDYW5TdWJtaXQodmFsdWU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jYW5TdWJtaXRTb3VyY2UudmFsdWUgIT09IHZhbHVlKSB0aGlzLmNhblN1Ym1pdFNvdXJjZS5uZXh0KHZhbHVlKTtcbiAgfVxuXG4gIHJlcXVlc3RTdWJtaXQoKTogdm9pZCB7XG4gICAgdGhpcy5zdWJtaXRTb3VyY2UubmV4dCgpO1xuICB9XG5cbiAgcmVxdWVzdFN0b3AoKTogdm9pZCB7XG4gICAgdGhpcy5zdG9wU291cmNlLm5leHQoKTtcbiAgfVxufVxuXG4vKipcbiAqIEEgbWVzc2FnZSBjb21wb3NlcjogYW4gYXV0by1ncm93aW5nIHRleHRhcmVhIHBsdXMgYSB0b29sYmFyLCB3aXJlZCBhcyBhXG4gKiBgQ29udHJvbFZhbHVlQWNjZXNzb3JgIHNvIGl0IGRyb3BzIGludG8gdGVtcGxhdGUtIG9yIHJlYWN0aXZlLWRyaXZlbiBmb3Jtcy5cbiAqXG4gKiBFbnRlciBzdWJtaXRzIGFuZCBTaGlmdCtFbnRlciBpbnNlcnRzIGEgbmV3bGluZSAoc3dhcCB3aXRoIGBzdWJtaXRPbkVudGVyYCkuXG4gKiBXaGlsZSBgc3RhdHVzYCBpcyAnc3RyZWFtaW5nJyB0aGUgcHJvamVjdGVkIGB0b2xsZS1wcm9tcHQtaW5wdXQtc3VibWl0YFxuICogYmVjb21lcyBhIHN0b3AgYnV0dG9uIHRoYXQgZW1pdHMgYHN0b3BwZWRgLlxuICogQG5ld1xuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0b2xsZS1wcm9tcHQtaW5wdXQnLFxuICBzdHlsZXM6IFsnOmhvc3QgeyBkaXNwbGF5OiBibG9jazsgfSddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgcHJvdmlkZXJzOiBbXG4gICAgUHJvbXB0SW5wdXRTZXJ2aWNlLFxuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gUHJvbXB0SW5wdXRDb21wb25lbnQpLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgfSxcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBbY2xhc3NdPVwiY29tcHV0ZWRDbGFzc1wiPlxuICAgICAgPHRleHRhcmVhXG4gICAgICAgICN0ZXh0YXJlYVxuICAgICAgICBkYXRhLXByb21wdC1pbnB1dC10ZXh0YXJlYVxuICAgICAgICByb3dzPVwiMVwiXG4gICAgICAgIFt2YWx1ZV09XCJ2YWx1ZVwiXG4gICAgICAgIFthdHRyLnBsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJhcmlhTGFiZWwgfHwgcGxhY2Vob2xkZXIgfHwgJ01lc3NhZ2UnXCJcbiAgICAgICAgW2F0dHIuYXJpYS1pbnZhbGlkXT1cInN0YXR1cyA9PT0gJ2Vycm9yJyA/ICd0cnVlJyA6IG51bGxcIlxuICAgICAgICBbY2xhc3NdPVwidGV4dGFyZWFDb21wdXRlZENsYXNzXCJcbiAgICAgICAgKGlucHV0KT1cIm9uSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgIChrZXlkb3duKT1cIm9uS2V5RG93bigkZXZlbnQpXCJcbiAgICAgICAgKGJsdXIpPVwib25CbHVyKClcIlxuICAgICAgPjwvdGV4dGFyZWE+XG5cbiAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICA8L2Rpdj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgUHJvbXB0SW5wdXRDb21wb25lbnRcbiAgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25Jbml0LCBPbkNoYW5nZXMsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveVxue1xuICAvKiogUGxhY2Vob2xkZXIgc2hvd24gd2hpbGUgdGhlIGNvbXBvc2VyIGlzIGVtcHR5LiBAZGVmYXVsdCAnU2VuZCBhIG1lc3NhZ2XigKYnICovXG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyID0gJ1NlbmQgYSBtZXNzYWdl4oCmJztcbiAgLyoqIEJsb2NrcyB0eXBpbmcgYW5kIHN1Ym1pc3Npb24uIEBkZWZhdWx0IGZhbHNlICovXG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG4gIC8qKiBSb3dzIHRoZSB0ZXh0YXJlYSBtYXkgZ3JvdyB0byBiZWZvcmUgaXQgc3RhcnRzIHNjcm9sbGluZy4gQGRlZmF1bHQgOCAqL1xuICBASW5wdXQoKSBtYXhSb3dzID0gODtcbiAgLyoqIExpZmVjeWNsZSBvZiB0aGUgcmVzcG9uc2UgYmVpbmcgY29tcG9zZWQuIEBkZWZhdWx0ICdyZWFkeScgKi9cbiAgQElucHV0KCkgc3RhdHVzOiBQcm9tcHRJbnB1dFN0YXR1cyA9ICdyZWFkeSc7XG4gIC8qKiBTaXplIHNjYWxlIG9mIHRoZSBjb21wb3Nlci4gQGRlZmF1bHQgJ2RlZmF1bHQnICovXG4gIEBJbnB1dCgpIHNpemU6IFByb21wdElucHV0UHJvcHNbJ3NpemUnXSA9ICdkZWZhdWx0JztcbiAgLyoqIFN1Ym1pdCBvbiBFbnRlciwga2VlcGluZyBTaGlmdCtFbnRlciBmb3IgbmV3bGluZXMuIEBkZWZhdWx0IHRydWUgKi9cbiAgQElucHV0KCkgc3VibWl0T25FbnRlciA9IHRydWU7XG4gIC8qKiBDbGVhcnMgdGhlIGNvbXBvc2VyIGFmdGVyIGEgc3VjY2Vzc2Z1bCBzdWJtaXQuIEBkZWZhdWx0IHRydWUgKi9cbiAgQElucHV0KCkgY2xlYXJPblN1Ym1pdCA9IHRydWU7XG4gIC8qKiBBY2Nlc3NpYmxlIG5hbWUgZm9yIHRoZSB0ZXh0YXJlYS4gQGRlZmF1bHQgJycgKi9cbiAgQElucHV0KCkgYXJpYUxhYmVsID0gJyc7XG4gIC8qKiBFeHRyYSBUYWlsd2luZCBjbGFzc2VzIG1lcmdlZCBvbnRvIHRoZSBjb21wb3NlciB2aWEgYGNuKClgIChsYXN0LXdpbnMpLiAqL1xuICBASW5wdXQoKSBjbGFzcyA9ICcnO1xuICAvKiogRXh0cmEgVGFpbHdpbmQgY2xhc3NlcyBtZXJnZWQgb250byB0aGUgdGV4dGFyZWEgdmlhIGBjbigpYCAobGFzdC13aW5zKS4gKi9cbiAgQElucHV0KCkgdGV4dGFyZWFDbGFzcyA9ICcnO1xuXG4gIC8qKiBFbWl0dGVkIHdpdGggdGhlIHRyaW1tZWQgbWVzc2FnZSB0ZXh0IHdoZW4gdGhlIHVzZXIgc3VibWl0cy4gKi9cbiAgQE91dHB1dCgpIHN1Ym1pdHRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogRW1pdHRlZCB3aGVuIHRoZSB1c2VyIGNhbmNlbHMgYW4gaW4tZmxpZ2h0IHN0cmVhbWluZyByZXNwb25zZS4gKi9cbiAgQE91dHB1dCgpIHN0b3BwZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBFbWl0dGVkIHdpdGggdGhlIG1lc3NhZ2UgdGV4dCB3aGVuZXZlciBpdCBjaGFuZ2VzLiAqL1xuICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcblxuICBAVmlld0NoaWxkKCd0ZXh0YXJlYScpIHByaXZhdGUgdGV4dGFyZWE/OiBFbGVtZW50UmVmPEhUTUxUZXh0QXJlYUVsZW1lbnQ+O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgc2VydmljZSA9IGluamVjdChQcm9tcHRJbnB1dFNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3Vic2NyaXB0aW9ucyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICB2YWx1ZSA9ICcnO1xuXG4gIHByaXZhdGUgb25DaGFuZ2U6ICh2YWx1ZTogc3RyaW5nKSA9PiB2b2lkID0gKCkgPT4ge307XG4gIHByaXZhdGUgb25Ub3VjaGVkOiAoKSA9PiB2b2lkID0gKCkgPT4ge307XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5zeW5jU2VydmljZSgpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQodGhpcy5zZXJ2aWNlLnN1Ym1pdCQuc3Vic2NyaWJlKCgpID0+IHRoaXMuc3VibWl0KCkpKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKHRoaXMuc2VydmljZS5zdG9wJC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5zdG9wKCkpKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIHRoaXMuc3luY1NlcnZpY2UoKTtcbiAgXG4gICAgLy8gQSBib3VuZCBgY2xhc3NgIGlucHV0IGlzIHdyaXR0ZW4gdGhyb3VnaCBBbmd1bGFyJ3Mgc3R5bGluZyBwYXRoLFxuICAgIC8vIHdoaWNoIGRvZXMgbm90IG1hcmsgYW4gT25QdXNoIHZpZXcgZGlydHkgb24gaXRzIG93bi5cbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnJlc2l6ZSgpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBnZXQgY29tcHV0ZWRDbGFzcygpIHtcbiAgICByZXR1cm4gY24oXG4gICAgICBwcm9tcHRJbnB1dFZhcmlhbnRzKHsgc3RhdHVzOiB0aGlzLnN0YXR1cywgc2l6ZTogdGhpcy5zaXplIH0pLFxuICAgICAgdGhpcy5kaXNhYmxlZCAmJiAnY3Vyc29yLW5vdC1hbGxvd2VkIG9wYWNpdHktNjAnLFxuICAgICAgdGhpcy5jbGFzc1xuICAgICk7XG4gIH1cblxuICBnZXQgdGV4dGFyZWFDb21wdXRlZENsYXNzKCkge1xuICAgIHJldHVybiBjbihcbiAgICAgICd3LWZ1bGwgcmVzaXplLW5vbmUgYmctdHJhbnNwYXJlbnQgcHgtMiBweS0xLjUgdGV4dC1zbSB0ZXh0LWZvcmVncm91bmQgb3V0bGluZS1ub25lJyxcbiAgICAgICdwbGFjZWhvbGRlcjp0ZXh0LW11dGVkLWZvcmVncm91bmQgZGlzYWJsZWQ6Y3Vyc29yLW5vdC1hbGxvd2VkJyxcbiAgICAgIHRoaXMudGV4dGFyZWFDbGFzc1xuICAgICk7XG4gIH1cblxuICBvbklucHV0KGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IG5leHQgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxUZXh0QXJlYUVsZW1lbnQpLnZhbHVlO1xuICAgIHRoaXMuc2V0VmFsdWUobmV4dCk7XG4gICAgdGhpcy5yZXNpemUoKTtcbiAgfVxuXG4gIG9uS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmIChldmVudC5rZXkgIT09ICdFbnRlcicgfHwgIXRoaXMuc3VibWl0T25FbnRlcikgcmV0dXJuO1xuICAgIC8vIFNoaWZ0K0VudGVyIGlzIHRoZSBuZXdsaW5lIGVzY2FwZSBoYXRjaDsgbW9kaWZpZXIgY2hvcmRzIGFuZCBJTUVcbiAgICAvLyBjb21wb3NpdGlvbiBtdXN0IG5ldmVyIHN0ZWFsIHRoZSBrZXlzdHJva2UuXG4gICAgaWYgKGV2ZW50LnNoaWZ0S2V5IHx8IGV2ZW50LmFsdEtleSB8fCBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkpIHJldHVybjtcbiAgICBpZiAoKGV2ZW50IGFzIEtleWJvYXJkRXZlbnQgJiB7IGlzQ29tcG9zaW5nPzogYm9vbGVhbiB9KS5pc0NvbXBvc2luZykgcmV0dXJuO1xuXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLnN1Ym1pdCgpO1xuICB9XG5cbiAgb25CbHVyKCk6IHZvaWQge1xuICAgIHRoaXMub25Ub3VjaGVkKCk7XG4gIH1cblxuICAvKiogU3VibWl0cyB0aGUgY3VycmVudCB0ZXh0LCB1bmxlc3MgdGhlIGNvbXBvc2VyIGlzIGVtcHR5LCBkaXNhYmxlZCBvciBidXN5LiAqL1xuICBzdWJtaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQgfHwgdGhpcy5zdGF0dXMgPT09ICdzdHJlYW1pbmcnKSByZXR1cm47XG4gICAgY29uc3QgdGV4dCA9IHRoaXMudmFsdWUudHJpbSgpO1xuICAgIGlmICghdGV4dCkgcmV0dXJuO1xuXG4gICAgdGhpcy5zdWJtaXR0ZWQuZW1pdCh0ZXh0KTtcblxuICAgIGlmICh0aGlzLmNsZWFyT25TdWJtaXQpIHtcbiAgICAgIHRoaXMuc2V0VmFsdWUoJycpO1xuICAgICAgaWYgKHRoaXMudGV4dGFyZWEpIHRoaXMudGV4dGFyZWEubmF0aXZlRWxlbWVudC52YWx1ZSA9ICcnO1xuICAgICAgdGhpcy5yZXNpemUoKTtcbiAgICB9XG4gIH1cblxuICAvKiogQ2FuY2VscyBhbiBpbi1mbGlnaHQgc3RyZWFtaW5nIHJlc3BvbnNlLiAqL1xuICBzdG9wKCk6IHZvaWQge1xuICAgIHRoaXMuc3RvcHBlZC5lbWl0KCk7XG4gIH1cblxuICAvKiogTW92ZXMgZm9jdXMgaW50byB0aGUgdGV4dGFyZWEuICovXG4gIGZvY3VzKCk6IHZvaWQge1xuICAgIHRoaXMudGV4dGFyZWE/Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgfVxuXG4gIHdyaXRlVmFsdWUodmFsdWU6IHN0cmluZyB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWUgPz8gJyc7XG4gICAgaWYgKHRoaXMudGV4dGFyZWEpIHRoaXMudGV4dGFyZWEubmF0aXZlRWxlbWVudC52YWx1ZSA9IHRoaXMudmFsdWU7XG4gICAgdGhpcy5zZXJ2aWNlLnNldENhblN1Ym1pdCh0aGlzLmNhblN1Ym1pdCk7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgdGhpcy5yZXNpemUoKTtcbiAgfVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46ICh2YWx1ZTogc3RyaW5nKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xuICB9XG5cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICB9XG5cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gICAgdGhpcy5zeW5jU2VydmljZSgpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgY2FuU3VibWl0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhdGhpcy5kaXNhYmxlZCAmJiB0aGlzLnZhbHVlLnRyaW0oKS5sZW5ndGggPiAwO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRWYWx1ZShuZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlID0gbmV4dDtcbiAgICB0aGlzLm9uQ2hhbmdlKG5leHQpO1xuICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdChuZXh0KTtcbiAgICB0aGlzLnNlcnZpY2Uuc2V0Q2FuU3VibWl0KHRoaXMuY2FuU3VibWl0KTtcbiAgfVxuXG4gIHByaXZhdGUgc3luY1NlcnZpY2UoKTogdm9pZCB7XG4gICAgdGhpcy5zZXJ2aWNlLnNldFN0YXR1cyh0aGlzLnN0YXR1cyk7XG4gICAgdGhpcy5zZXJ2aWNlLnNldENhblN1Ym1pdCh0aGlzLmNhblN1Ym1pdCk7XG4gIH1cblxuICAvKipcbiAgICogR3Jvd3MgdGhlIHRleHRhcmVhIHdpdGggaXRzIGNvbnRlbnQgdXAgdG8gYG1heFJvd3NgLCB0aGVuIGxldHMgaXQgc2Nyb2xsLlxuICAgKiBNZWFzdXJlZCBmcm9tIHRoZSBjb21wdXRlZCBsaW5lIGhlaWdodCBzbyBpdCB0cmFja3MgdGhlIGluaGVyaXRlZCBmb250LlxuICAgKi9cbiAgcHJpdmF0ZSByZXNpemUoKTogdm9pZCB7XG4gICAgY29uc3QgZWwgPSB0aGlzLnRleHRhcmVhPy5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghZWwpIHJldHVybjtcblxuICAgIGVsLnN0eWxlLmhlaWdodCA9ICdhdXRvJztcblxuICAgIGNvbnN0IHN0eWxlcyA9IGdldENvbXB1dGVkU3R5bGUoZWwpO1xuICAgIGNvbnN0IHBhcnNlZExpbmVIZWlnaHQgPSBwYXJzZUZsb2F0KHN0eWxlcy5saW5lSGVpZ2h0KTtcbiAgICBjb25zdCBsaW5lSGVpZ2h0ID0gTnVtYmVyLmlzRmluaXRlKHBhcnNlZExpbmVIZWlnaHQpXG4gICAgICA/IHBhcnNlZExpbmVIZWlnaHRcbiAgICAgIDogcGFyc2VGbG9hdChzdHlsZXMuZm9udFNpemUpICogMS41IHx8IDIwO1xuICAgIGNvbnN0IHZlcnRpY2FsID1cbiAgICAgIHBhcnNlRmxvYXQoc3R5bGVzLnBhZGRpbmdUb3AgfHwgJzAnKSArXG4gICAgICBwYXJzZUZsb2F0KHN0eWxlcy5wYWRkaW5nQm90dG9tIHx8ICcwJykgK1xuICAgICAgcGFyc2VGbG9hdChzdHlsZXMuYm9yZGVyVG9wV2lkdGggfHwgJzAnKSArXG4gICAgICBwYXJzZUZsb2F0KHN0eWxlcy5ib3JkZXJCb3R0b21XaWR0aCB8fCAnMCcpO1xuICAgIGNvbnN0IG1heCA9IGxpbmVIZWlnaHQgKiBNYXRoLm1heCgxLCB0aGlzLm1heFJvd3MpICsgdmVydGljYWw7XG5cbiAgICBjb25zdCBuZXh0ID0gTWF0aC5taW4oZWwuc2Nyb2xsSGVpZ2h0LCBtYXgpO1xuICAgIGVsLnN0eWxlLmhlaWdodCA9IG5leHQgKyAncHgnO1xuICAgIGVsLnN0eWxlLm92ZXJmbG93WSA9IGVsLnNjcm9sbEhlaWdodCA+IG1heCA/ICdhdXRvJyA6ICdoaWRkZW4nO1xuICB9XG59XG5cbi8qKiBCb3R0b20gYmFyIG9mIGEgYHRvbGxlLXByb21wdC1pbnB1dGA6IHRvb2xzIG9uIHRoZSBsZWZ0LCBzdWJtaXQgb24gdGhlIHJpZ2h0LiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtcHJvbXB0LWlucHV0LXRvb2xiYXInLFxuICBzdHlsZXM6IFsnOmhvc3QgeyBkaXNwbGF5OiBibG9jazsgfSddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBbY2xhc3NdPVwiY29tcHV0ZWRDbGFzc1wiPlxuICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBQcm9tcHRJbnB1dFRvb2xiYXJDb21wb25lbnQgIGltcGxlbWVudHMgT25DaGFuZ2Vze1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgLyoqXG4gICAqIEFuZ3VsYXIgd3JpdGVzIGEgYm91bmQgYGNsYXNzYCBpbnB1dCB0aHJvdWdoIGl0cyBzdHlsaW5nIHBhdGgsIHdoaWNoIGRvZXNcbiAgICogbm90IG1hcmsgYW4gT25QdXNoIGNvbXBvbmVudCBkaXJ0eSDigJQgd2l0aG91dCB0aGlzIGhvb2sgdGhlIGNvbXBvbmVudCBrZWVwc1xuICAgKiByZW5kZXJpbmcgdGhlIGNsYXNzIGl0IHdhcyBib3JuIHdpdGguXG4gICAqL1xuICBuZ09uQ2hhbmdlcygpOiB2b2lkIHtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKiBFeHRyYSBUYWlsd2luZCBjbGFzc2VzIG1lcmdlZCBvbnRvIHRoZSB0b29sYmFyIHZpYSBgY24oKWAgKGxhc3Qtd2lucykuICovXG4gIEBJbnB1dCgpIGNsYXNzID0gJyc7XG5cbiAgZ2V0IGNvbXB1dGVkQ2xhc3MoKSB7XG4gICAgcmV0dXJuIGNuKCdmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWJldHdlZW4gZ2FwLTIgcHgtMScsIHRoaXMuY2xhc3MpO1xuICB9XG59XG5cbi8qKiBMZWZ0LWFsaWduZWQgY2x1c3RlciBvZiB0b29sIGJ1dHRvbnMgaW5zaWRlIGEgYHRvbGxlLXByb21wdC1pbnB1dC10b29sYmFyYC4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3RvbGxlLXByb21wdC1pbnB1dC10b29scycsXG4gIHN0eWxlczogWyc6aG9zdCB7IGRpc3BsYXk6IGJsb2NrOyB9J10sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IFtjbGFzc109XCJjb21wdXRlZENsYXNzXCI+XG4gICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgPC9kaXY+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIFByb21wdElucHV0VG9vbHNDb21wb25lbnQgIGltcGxlbWVudHMgT25DaGFuZ2Vze1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgLyoqXG4gICAqIEFuZ3VsYXIgd3JpdGVzIGEgYm91bmQgYGNsYXNzYCBpbnB1dCB0aHJvdWdoIGl0cyBzdHlsaW5nIHBhdGgsIHdoaWNoIGRvZXNcbiAgICogbm90IG1hcmsgYW4gT25QdXNoIGNvbXBvbmVudCBkaXJ0eSDigJQgd2l0aG91dCB0aGlzIGhvb2sgdGhlIGNvbXBvbmVudCBrZWVwc1xuICAgKiByZW5kZXJpbmcgdGhlIGNsYXNzIGl0IHdhcyBib3JuIHdpdGguXG4gICAqL1xuICBuZ09uQ2hhbmdlcygpOiB2b2lkIHtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKiBFeHRyYSBUYWlsd2luZCBjbGFzc2VzIG1lcmdlZCBvbnRvIHRoZSB0b29sIHJvdyB2aWEgYGNuKClgIChsYXN0LXdpbnMpLiAqL1xuICBASW5wdXQoKSBjbGFzcyA9ICcnO1xuXG4gIGdldCBjb21wdXRlZENsYXNzKCkge1xuICAgIHJldHVybiBjbignZmxleCBmbGV4LTEgaXRlbXMtY2VudGVyIGdhcC0xIHRleHQtbXV0ZWQtZm9yZWdyb3VuZCcsIHRoaXMuY2xhc3MpO1xuICB9XG59XG5cbmNvbnN0IHByb21wdElucHV0U3VibWl0VmFyaWFudHMgPSBjdmEoXG4gICdpbmxpbmUtZmxleCBzaHJpbmstMCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgZ2FwLTEuNSByb3VuZGVkLW1kIGZvbnQtbWVkaXVtIHRyYW5zaXRpb24tY29sb3JzIGZvY3VzLXZpc2libGU6b3V0bGluZS1ub25lIGZvY3VzLXZpc2libGU6cmluZy0yIGZvY3VzLXZpc2libGU6cmluZy1yaW5nIGZvY3VzLXZpc2libGU6cmluZy1vZmZzZXQtMiBmb2N1cy12aXNpYmxlOnJpbmctb2Zmc2V0LWJhY2tncm91bmQgZGlzYWJsZWQ6cG9pbnRlci1ldmVudHMtbm9uZSBkaXNhYmxlZDpvcGFjaXR5LTUwJyxcbiAge1xuICAgIHZhcmlhbnRzOiB7XG4gICAgICB2YXJpYW50OiB7XG4gICAgICAgIGRlZmF1bHQ6ICdiZy1wcmltYXJ5IHRleHQtcHJpbWFyeS1mb3JlZ3JvdW5kIGhvdmVyOmJnLXByaW1hcnkvOTAnLFxuICAgICAgICBzZWNvbmRhcnk6ICdiZy1zZWNvbmRhcnkgdGV4dC1zZWNvbmRhcnktZm9yZWdyb3VuZCBob3ZlcjpiZy1zZWNvbmRhcnkvODAnLFxuICAgICAgICBnaG9zdDogJ3RleHQtZm9yZWdyb3VuZCBob3ZlcjpiZy1hY2NlbnQgaG92ZXI6dGV4dC1hY2NlbnQtZm9yZWdyb3VuZCcsXG4gICAgICB9LFxuICAgICAgc2l6ZToge1xuICAgICAgICBzbTogJ2gtNyBweC0yIHRleHQteHMnLFxuICAgICAgICBkZWZhdWx0OiAnc2l6ZS04IHRleHQtc20nLFxuICAgICAgICBsZzogJ2gtMTAgcHgtNCB0ZXh0LXNtJyxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBkZWZhdWx0VmFyaWFudHM6IHtcbiAgICAgIHZhcmlhbnQ6ICdkZWZhdWx0JyxcbiAgICAgIHNpemU6ICdkZWZhdWx0JyxcbiAgICB9LFxuICB9XG4pO1xuXG5leHBvcnQgdHlwZSBQcm9tcHRJbnB1dFN1Ym1pdFByb3BzID0gVmFyaWFudFByb3BzPHR5cGVvZiBwcm9tcHRJbnB1dFN1Ym1pdFZhcmlhbnRzPjtcblxuLyoqXG4gKiBTZW5kIGJ1dHRvbiBmb3IgYSBgdG9sbGUtcHJvbXB0LWlucHV0YC4gVHVybnMgaW50byBhIHN0b3AgYnV0dG9uIHdoaWxlIHRoZVxuICogY29tcG9zZXIncyBzdGF0dXMgaXMgJ3N0cmVhbWluZycsIHNvIG9uZSBjb250cm9sIGNvdmVycyBib3RoIGRpcmVjdGlvbnMuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3RvbGxlLXByb21wdC1pbnB1dC1zdWJtaXQnLFxuICBzdHlsZXM6IFsnOmhvc3QgeyBkaXNwbGF5OiBibG9jazsgfSddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBkYXRhLXByb21wdC1pbnB1dC1zdWJtaXRcbiAgICAgIFthdHRyLmRhdGEtc3RhdGVdPVwic3RhdHVzXCJcbiAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiY3VycmVudExhYmVsXCJcbiAgICAgIFtkaXNhYmxlZF09XCJpc0Rpc2FibGVkXCJcbiAgICAgIFtjbGFzc109XCJjb21wdXRlZENsYXNzXCJcbiAgICAgIChjbGljayk9XCJvbkNsaWNrKClcIlxuICAgID5cbiAgICAgIDxpIFtjbGFzc109XCJjdXJyZW50SWNvblwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgIDxzcGFuICpuZ0lmPVwic2hvd0xhYmVsXCI+e3sgY3VycmVudExhYmVsIH19PC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBQcm9tcHRJbnB1dFN1Ym1pdENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0LCBPbkRlc3Ryb3kge1xuXG4gIC8qKlxuICAgKiBBbmd1bGFyIHdyaXRlcyBhIGJvdW5kIGBjbGFzc2AgaW5wdXQgdGhyb3VnaCBpdHMgc3R5bGluZyBwYXRoLCB3aGljaCBkb2VzXG4gICAqIG5vdCBtYXJrIGFuIE9uUHVzaCBjb21wb25lbnQgZGlydHkg4oCUIHdpdGhvdXQgdGhpcyBob29rIHRoZSBjb21wb25lbnQga2VlcHNcbiAgICogcmVuZGVyaW5nIHRoZSBjbGFzcyBpdCB3YXMgYm9ybiB3aXRoLlxuICAgKi9cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKiogVmlzdWFsIHN0eWxlIG9mIHRoZSBidXR0b24uIEBkZWZhdWx0ICdkZWZhdWx0JyAqL1xuICBASW5wdXQoKSB2YXJpYW50OiBQcm9tcHRJbnB1dFN1Ym1pdFByb3BzWyd2YXJpYW50J10gPSAnZGVmYXVsdCc7XG4gIC8qKiBTaXplIG9mIHRoZSBidXR0b24uIEBkZWZhdWx0ICdkZWZhdWx0JyAqL1xuICBASW5wdXQoKSBzaXplOiBQcm9tcHRJbnB1dFN1Ym1pdFByb3BzWydzaXplJ10gPSAnZGVmYXVsdCc7XG4gIC8qKiBBY2Nlc3NpYmxlIG5hbWUgd2hpbGUgdGhlIGNvbXBvc2VyIGlzIGlkbGUuIEBkZWZhdWx0ICdTZW5kIG1lc3NhZ2UnICovXG4gIEBJbnB1dCgpIHN1Ym1pdExhYmVsID0gJ1NlbmQgbWVzc2FnZSc7XG4gIC8qKiBBY2Nlc3NpYmxlIG5hbWUgd2hpbGUgdGhlIGNvbXBvc2VyIGlzIHN0cmVhbWluZy4gQGRlZmF1bHQgJ1N0b3AgZ2VuZXJhdGluZycgKi9cbiAgQElucHV0KCkgc3RvcExhYmVsID0gJ1N0b3AgZ2VuZXJhdGluZyc7XG4gIC8qKiBSZW5kZXJzIHRoZSBsYWJlbCBuZXh0IHRvIHRoZSBpY29uLiBAZGVmYXVsdCBmYWxzZSAqL1xuICBASW5wdXQoKSBzaG93TGFiZWwgPSBmYWxzZTtcbiAgLyoqIEV4dHJhIFRhaWx3aW5kIGNsYXNzZXMgbWVyZ2VkIG9udG8gdGhlIGJ1dHRvbiB2aWEgYGNuKClgIChsYXN0LXdpbnMpLiAqL1xuICBASW5wdXQoKSBjbGFzcyA9ICcnO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgc2VydmljZSA9IGluamVjdChQcm9tcHRJbnB1dFNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3Vic2NyaXB0aW9ucyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICBzdGF0dXM6IFByb21wdElucHV0U3RhdHVzID0gJ3JlYWR5JztcbiAgY2FuU3VibWl0ID0gZmFsc2U7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgIHRoaXMuc2VydmljZS5zdGF0dXMkLnN1YnNjcmliZSgoc3RhdHVzKSA9PiB7XG4gICAgICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgdGhpcy5zZXJ2aWNlLmNhblN1Ym1pdCQuc3Vic2NyaWJlKChjYW5TdWJtaXQpID0+IHtcbiAgICAgICAgdGhpcy5jYW5TdWJtaXQgPSBjYW5TdWJtaXQ7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICAvKiogVHJ1ZSB3aGlsZSB0aGUgYnV0dG9uIGlzIHNob3dpbmcgaXRzIHN0b3AgYWZmb3JkYW5jZS4gKi9cbiAgZ2V0IGlzU3RyZWFtaW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YXR1cyA9PT0gJ3N0cmVhbWluZyc7XG4gIH1cblxuICBnZXQgY3VycmVudEljb24oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5pc1N0cmVhbWluZyA/ICdyaS1zdG9wLWNpcmNsZS1saW5lJyA6ICdyaS1zZW5kLXBsYW5lLTItZmlsbCc7XG4gIH1cblxuICBnZXQgY3VycmVudExhYmVsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuaXNTdHJlYW1pbmcgPyB0aGlzLnN0b3BMYWJlbCA6IHRoaXMuc3VibWl0TGFiZWw7XG4gIH1cblxuICAvKiogU3RvcHBpbmcgc3RheXMgYXZhaWxhYmxlIHdpdGggYW4gZW1wdHkgY29tcG9zZXI7IHNlbmRpbmcgZG9lcyBub3QuICovXG4gIGdldCBpc0Rpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhdGhpcy5pc1N0cmVhbWluZyAmJiAhdGhpcy5jYW5TdWJtaXQ7XG4gIH1cblxuICBnZXQgY29tcHV0ZWRDbGFzcygpIHtcbiAgICByZXR1cm4gY24oXG4gICAgICBwcm9tcHRJbnB1dFN1Ym1pdFZhcmlhbnRzKHsgdmFyaWFudDogdGhpcy52YXJpYW50LCBzaXplOiB0aGlzLnNpemUgfSksXG4gICAgICB0aGlzLmlzU3RyZWFtaW5nICYmICdiZy1kZXN0cnVjdGl2ZSB0ZXh0LWRlc3RydWN0aXZlLWZvcmVncm91bmQgaG92ZXI6YmctZGVzdHJ1Y3RpdmUvOTAnLFxuICAgICAgdGhpcy5jbGFzc1xuICAgICk7XG4gIH1cblxuICBvbkNsaWNrKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzU3RyZWFtaW5nKSB7XG4gICAgICB0aGlzLnNlcnZpY2UucmVxdWVzdFN0b3AoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZXJ2aWNlLnJlcXVlc3RTdWJtaXQoKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|