@copilotkitnext/angular 0.0.9-alpha.3 → 0.0.11
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/dist/esm2022/index.mjs +2 -70
- package/dist/esm2022/lib/agent.mjs +73 -0
- package/dist/esm2022/lib/chat-config.mjs +35 -0
- package/dist/esm2022/lib/chat-state.mjs +18 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-assistant-message-buttons.mjs +344 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-assistant-message-renderer.mjs +260 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-assistant-message-toolbar.mjs +22 -0
- package/dist/esm2022/{components/chat/copilot-chat-assistant-message.component.mjs → lib/components/chat/copilot-chat-assistant-message.mjs} +216 -240
- package/dist/esm2022/lib/components/chat/copilot-chat-assistant-message.types.mjs +2 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-audio-recorder.mjs +196 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-buttons.mjs +299 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-input-defaults.mjs +39 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-input.mjs +634 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-input.types.mjs +10 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-message-view-cursor.mjs +27 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-message-view.mjs +268 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-message-view.types.mjs +2 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-textarea.mjs +139 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-tool-calls-view.mjs +36 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-toolbar.mjs +20 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-tools-menu.mjs +203 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-user-message-branch-navigation.mjs +118 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-user-message-buttons.mjs +182 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-user-message-renderer.mjs +28 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-user-message-toolbar.mjs +25 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-user-message.mjs +306 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-user-message.types.mjs +2 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-view-disclaimer.mjs +48 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-view-feather.mjs +41 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-view-handlers.mjs +19 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-view-input-container.mjs +96 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-view-scroll-to-bottom-button.mjs +89 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-view-scroll-view.mjs +456 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-view.mjs +404 -0
- package/dist/esm2022/lib/components/chat/copilot-chat-view.types.mjs +2 -0
- package/dist/esm2022/lib/components/chat/copilot-chat.mjs +167 -0
- package/dist/esm2022/lib/config.mjs +9 -0
- package/dist/esm2022/lib/copilotkit.mjs +124 -0
- package/dist/esm2022/lib/directives/copilotkit-agent-context.mjs +130 -0
- package/dist/esm2022/lib/directives/stick-to-bottom.mjs +170 -0
- package/dist/esm2022/lib/directives/tooltip.mjs +217 -0
- package/dist/esm2022/lib/human-in-the-loop.mjs +19 -0
- package/dist/esm2022/lib/render-tool-calls.mjs +131 -0
- package/dist/esm2022/lib/resize-observer.mjs +152 -0
- package/dist/esm2022/lib/scroll-position.mjs +124 -0
- package/dist/esm2022/lib/slots/copilot-slot.mjs +156 -0
- package/dist/esm2022/lib/slots/index.mjs +4 -0
- package/dist/esm2022/lib/slots/slot.types.mjs +3 -3
- package/dist/esm2022/lib/slots/slot.utils.mjs +19 -15
- package/dist/esm2022/lib/tools.mjs +31 -0
- package/dist/esm2022/lib/utils.mjs +3 -3
- package/dist/esm2022/public-api.mjs +47 -0
- package/dist/fesm2022/copilotkitnext-angular.mjs +5249 -8271
- package/dist/fesm2022/copilotkitnext-angular.mjs.map +1 -1
- package/dist/index.d.ts +1 -55
- package/dist/lib/agent.d.ts +53 -0
- package/dist/{core/chat-configuration/chat-configuration.types.d.ts → lib/chat-config.d.ts} +4 -8
- package/dist/lib/chat-state.d.ts +10 -0
- package/dist/lib/components/chat/copilot-chat-assistant-message-buttons.d.ts +68 -0
- package/dist/lib/components/chat/copilot-chat-assistant-message-renderer.d.ts +26 -0
- package/dist/lib/components/chat/copilot-chat-assistant-message-toolbar.d.ts +7 -0
- package/dist/lib/components/chat/copilot-chat-assistant-message.d.ts +178 -0
- package/dist/{components → lib/components}/chat/copilot-chat-assistant-message.types.d.ts +1 -1
- package/dist/{components/chat/copilot-chat-audio-recorder.component.d.ts → lib/components/chat/copilot-chat-audio-recorder.d.ts} +10 -10
- package/dist/lib/components/chat/copilot-chat-buttons.d.ts +65 -0
- package/dist/lib/components/chat/copilot-chat-input-defaults.d.ts +38 -0
- package/dist/lib/components/chat/copilot-chat-input.d.ts +133 -0
- package/dist/{components → lib/components}/chat/copilot-chat-input.types.d.ts +11 -11
- package/dist/lib/components/chat/copilot-chat-message-view-cursor.d.ts +11 -0
- package/dist/{components/chat/copilot-chat-message-view.component.d.ts → lib/components/chat/copilot-chat-message-view.d.ts} +68 -36
- package/dist/{components → lib/components}/chat/copilot-chat-message-view.types.d.ts +2 -2
- package/dist/lib/components/chat/copilot-chat-textarea.d.ts +41 -0
- package/dist/lib/components/chat/copilot-chat-tool-calls-view.d.ts +55 -0
- package/dist/lib/components/chat/copilot-chat-toolbar.d.ts +7 -0
- package/dist/lib/components/chat/copilot-chat-tools-menu.d.ts +20 -0
- package/dist/lib/components/chat/copilot-chat-user-message-branch-navigation.d.ts +20 -0
- package/dist/lib/components/chat/copilot-chat-user-message-buttons.d.ts +35 -0
- package/dist/lib/components/chat/copilot-chat-user-message-renderer.d.ts +8 -0
- package/dist/lib/components/chat/copilot-chat-user-message-toolbar.d.ts +7 -0
- package/dist/lib/components/chat/copilot-chat-user-message.d.ts +55 -0
- package/dist/{components → lib/components}/chat/copilot-chat-user-message.types.d.ts +2 -2
- package/dist/lib/components/chat/copilot-chat-view-disclaimer.d.ts +15 -0
- package/dist/{components/chat/copilot-chat-view-feather.component.d.ts → lib/components/chat/copilot-chat-view-feather.d.ts} +6 -6
- package/dist/{components/chat/copilot-chat-view-handlers.service.d.ts → lib/components/chat/copilot-chat-view-handlers.d.ts} +3 -3
- package/dist/lib/components/chat/copilot-chat-view-input-container.d.ts +23 -0
- package/dist/lib/components/chat/copilot-chat-view-scroll-to-bottom-button.d.ts +16 -0
- package/dist/lib/components/chat/copilot-chat-view-scroll-view.d.ts +114 -0
- package/dist/lib/components/chat/copilot-chat-view.d.ts +239 -0
- package/dist/{components → lib/components}/chat/copilot-chat-view.types.d.ts +2 -2
- package/dist/lib/components/chat/copilot-chat.d.ts +67 -0
- package/dist/lib/config.d.ts +16 -0
- package/dist/lib/copilotkit.d.ts +29 -0
- package/dist/{directives/copilotkit-agent-context.directive.d.ts → lib/directives/copilotkit-agent-context.d.ts} +5 -5
- package/dist/lib/directives/stick-to-bottom.d.ts +62 -0
- package/dist/lib/directives/tooltip.d.ts +33 -0
- package/dist/lib/human-in-the-loop.d.ts +13 -0
- package/dist/lib/render-tool-calls.d.ts +75 -0
- package/dist/{services/resize-observer.service.d.ts → lib/resize-observer.d.ts} +2 -2
- package/dist/{services/scroll-position.service.d.ts → lib/scroll-position.d.ts} +6 -6
- package/dist/lib/slots/copilot-slot.d.ts +34 -0
- package/dist/lib/slots/index.d.ts +3 -0
- package/dist/lib/slots/slot.types.d.ts +1 -1
- package/dist/lib/slots/slot.utils.d.ts +6 -4
- package/dist/lib/tools.d.ts +63 -0
- package/dist/lib/utils.d.ts +1 -1
- package/dist/public-api.d.ts +46 -0
- package/dist/styles.css +0 -69
- package/package.json +5 -5
- package/dist/components/chat/copilot-chat-assistant-message-buttons.component.d.ts +0 -75
- package/dist/components/chat/copilot-chat-assistant-message-renderer.component.d.ts +0 -31
- package/dist/components/chat/copilot-chat-assistant-message-toolbar.component.d.ts +0 -8
- package/dist/components/chat/copilot-chat-assistant-message.component.d.ts +0 -132
- package/dist/components/chat/copilot-chat-buttons.component.d.ts +0 -66
- package/dist/components/chat/copilot-chat-input-defaults.d.ts +0 -37
- package/dist/components/chat/copilot-chat-input.component.d.ts +0 -133
- package/dist/components/chat/copilot-chat-message-view-cursor.component.d.ts +0 -15
- package/dist/components/chat/copilot-chat-textarea.component.d.ts +0 -45
- package/dist/components/chat/copilot-chat-tool-calls-view.component.d.ts +0 -35
- package/dist/components/chat/copilot-chat-toolbar.component.d.ts +0 -8
- package/dist/components/chat/copilot-chat-tools-menu.component.d.ts +0 -20
- package/dist/components/chat/copilot-chat-user-message-branch-navigation.component.d.ts +0 -23
- package/dist/components/chat/copilot-chat-user-message-buttons.component.d.ts +0 -39
- package/dist/components/chat/copilot-chat-user-message-renderer.component.d.ts +0 -9
- package/dist/components/chat/copilot-chat-user-message-toolbar.component.d.ts +0 -8
- package/dist/components/chat/copilot-chat-user-message.component.d.ts +0 -55
- package/dist/components/chat/copilot-chat-view-disclaimer.component.d.ts +0 -15
- package/dist/components/chat/copilot-chat-view-input-container.component.d.ts +0 -23
- package/dist/components/chat/copilot-chat-view-scroll-to-bottom-button.component.d.ts +0 -17
- package/dist/components/chat/copilot-chat-view-scroll-view.component.d.ts +0 -84
- package/dist/components/chat/copilot-chat-view.component.d.ts +0 -205
- package/dist/components/chat/copilot-chat.component.d.ts +0 -36
- package/dist/components/copilotkit-tool-render.component.d.ts +0 -25
- package/dist/core/chat-configuration/chat-configuration.providers.d.ts +0 -54
- package/dist/core/chat-configuration/chat-configuration.service.d.ts +0 -75
- package/dist/core/copilotkit.providers.d.ts +0 -13
- package/dist/core/copilotkit.service.d.ts +0 -119
- package/dist/core/copilotkit.types.d.ts +0 -81
- package/dist/directives/copilotkit-agent.directive.d.ts +0 -106
- package/dist/directives/copilotkit-chat-config.directive.d.ts +0 -84
- package/dist/directives/copilotkit-config.directive.d.ts +0 -44
- package/dist/directives/copilotkit-frontend-tool.directive.d.ts +0 -25
- package/dist/directives/copilotkit-human-in-the-loop.directive.d.ts +0 -124
- package/dist/directives/stick-to-bottom.directive.d.ts +0 -62
- package/dist/esm2022/components/chat/copilot-chat-assistant-message-buttons.component.mjs +0 -384
- package/dist/esm2022/components/chat/copilot-chat-assistant-message-renderer.component.mjs +0 -286
- package/dist/esm2022/components/chat/copilot-chat-assistant-message-toolbar.component.mjs +0 -27
- package/dist/esm2022/components/chat/copilot-chat-assistant-message.types.mjs +0 -2
- package/dist/esm2022/components/chat/copilot-chat-audio-recorder.component.mjs +0 -202
- package/dist/esm2022/components/chat/copilot-chat-buttons.component.mjs +0 -321
- package/dist/esm2022/components/chat/copilot-chat-input-defaults.mjs +0 -38
- package/dist/esm2022/components/chat/copilot-chat-input.component.mjs +0 -666
- package/dist/esm2022/components/chat/copilot-chat-input.types.mjs +0 -10
- package/dist/esm2022/components/chat/copilot-chat-message-view-cursor.component.mjs +0 -45
- package/dist/esm2022/components/chat/copilot-chat-message-view.component.mjs +0 -296
- package/dist/esm2022/components/chat/copilot-chat-message-view.types.mjs +0 -2
- package/dist/esm2022/components/chat/copilot-chat-textarea.component.mjs +0 -188
- package/dist/esm2022/components/chat/copilot-chat-tool-calls-view.component.mjs +0 -222
- package/dist/esm2022/components/chat/copilot-chat-toolbar.component.mjs +0 -25
- package/dist/esm2022/components/chat/copilot-chat-tools-menu.component.mjs +0 -199
- package/dist/esm2022/components/chat/copilot-chat-user-message-branch-navigation.component.mjs +0 -137
- package/dist/esm2022/components/chat/copilot-chat-user-message-buttons.component.mjs +0 -207
- package/dist/esm2022/components/chat/copilot-chat-user-message-renderer.component.mjs +0 -35
- package/dist/esm2022/components/chat/copilot-chat-user-message-toolbar.component.mjs +0 -34
- package/dist/esm2022/components/chat/copilot-chat-user-message.component.mjs +0 -341
- package/dist/esm2022/components/chat/copilot-chat-user-message.types.mjs +0 -2
- package/dist/esm2022/components/chat/copilot-chat-view-disclaimer.component.mjs +0 -52
- package/dist/esm2022/components/chat/copilot-chat-view-feather.component.mjs +0 -55
- package/dist/esm2022/components/chat/copilot-chat-view-handlers.service.mjs +0 -19
- package/dist/esm2022/components/chat/copilot-chat-view-input-container.component.mjs +0 -110
- package/dist/esm2022/components/chat/copilot-chat-view-scroll-to-bottom-button.component.mjs +0 -93
- package/dist/esm2022/components/chat/copilot-chat-view-scroll-view.component.mjs +0 -443
- package/dist/esm2022/components/chat/copilot-chat-view.component.mjs +0 -479
- package/dist/esm2022/components/chat/copilot-chat-view.types.mjs +0 -2
- package/dist/esm2022/components/chat/copilot-chat.component.mjs +0 -220
- package/dist/esm2022/components/copilotkit-tool-render.component.mjs +0 -150
- package/dist/esm2022/core/chat-configuration/chat-configuration.providers.mjs +0 -65
- package/dist/esm2022/core/chat-configuration/chat-configuration.service.mjs +0 -145
- package/dist/esm2022/core/chat-configuration/chat-configuration.types.mjs +0 -26
- package/dist/esm2022/core/copilotkit.providers.mjs +0 -34
- package/dist/esm2022/core/copilotkit.service.mjs +0 -411
- package/dist/esm2022/core/copilotkit.types.mjs +0 -13
- package/dist/esm2022/directives/copilotkit-agent-context.directive.mjs +0 -130
- package/dist/esm2022/directives/copilotkit-agent.directive.mjs +0 -221
- package/dist/esm2022/directives/copilotkit-chat-config.directive.mjs +0 -218
- package/dist/esm2022/directives/copilotkit-config.directive.mjs +0 -94
- package/dist/esm2022/directives/copilotkit-frontend-tool.directive.mjs +0 -128
- package/dist/esm2022/directives/copilotkit-human-in-the-loop.directive.mjs +0 -265
- package/dist/esm2022/directives/stick-to-bottom.directive.mjs +0 -181
- package/dist/esm2022/lib/directives/tooltip.directive.mjs +0 -211
- package/dist/esm2022/lib/slots/copilot-slot.component.mjs +0 -154
- package/dist/esm2022/services/resize-observer.service.mjs +0 -152
- package/dist/esm2022/services/scroll-position.service.mjs +0 -124
- package/dist/esm2022/types/frontend-tool.mjs +0 -2
- package/dist/esm2022/types/human-in-the-loop.mjs +0 -2
- package/dist/esm2022/utils/agent-context.utils.mjs +0 -114
- package/dist/esm2022/utils/agent.utils.mjs +0 -212
- package/dist/esm2022/utils/chat-config.utils.mjs +0 -186
- package/dist/esm2022/utils/copilotkit.utils.mjs +0 -20
- package/dist/esm2022/utils/frontend-tool.utils.mjs +0 -224
- package/dist/esm2022/utils/human-in-the-loop.utils.mjs +0 -293
- package/dist/lib/directives/tooltip.directive.d.ts +0 -33
- package/dist/lib/slots/copilot-slot.component.d.ts +0 -34
- package/dist/types/frontend-tool.d.ts +0 -37
- package/dist/types/human-in-the-loop.d.ts +0 -44
- package/dist/utils/agent-context.utils.d.ts +0 -75
- package/dist/utils/agent.utils.d.ts +0 -108
- package/dist/utils/chat-config.utils.d.ts +0 -166
- package/dist/utils/copilotkit.utils.d.ts +0 -16
- package/dist/utils/frontend-tool.utils.d.ts +0 -119
- package/dist/utils/human-in-the-loop.utils.d.ts +0 -92
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Component, input, output, ChangeDetectionStrategy, ViewEncapsulation, } from "@angular/core";
|
|
2
|
+
import { CommonModule } from "@angular/common";
|
|
3
|
+
import { LucideAngularModule, ChevronDown } from "lucide-angular";
|
|
4
|
+
import { cn } from "../../utils";
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "lucide-angular";
|
|
7
|
+
/**
|
|
8
|
+
* ScrollToBottomButton component for CopilotChatView
|
|
9
|
+
* Matches React implementation exactly with same Tailwind classes
|
|
10
|
+
*/
|
|
11
|
+
export class CopilotChatViewScrollToBottomButton {
|
|
12
|
+
inputClass = input();
|
|
13
|
+
disabled = input(false);
|
|
14
|
+
// Support function-style click handler via slot context
|
|
15
|
+
onClick = input();
|
|
16
|
+
// Simple, idiomatic Angular output
|
|
17
|
+
clicked = output();
|
|
18
|
+
// Icon reference
|
|
19
|
+
ChevronDown = ChevronDown;
|
|
20
|
+
// Computed class matching React exactly
|
|
21
|
+
get computedClass() {
|
|
22
|
+
return cn(
|
|
23
|
+
// Base button styles
|
|
24
|
+
"rounded-full w-10 h-10 p-0",
|
|
25
|
+
// Background colors
|
|
26
|
+
"bg-white dark:bg-gray-900",
|
|
27
|
+
// Border and shadow
|
|
28
|
+
"shadow-lg border border-gray-200 dark:border-gray-700",
|
|
29
|
+
// Hover states
|
|
30
|
+
"hover:bg-gray-50 dark:hover:bg-gray-800",
|
|
31
|
+
// Layout
|
|
32
|
+
"flex items-center justify-center cursor-pointer",
|
|
33
|
+
// Transition
|
|
34
|
+
"transition-colors",
|
|
35
|
+
// Focus states
|
|
36
|
+
"focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
|
|
37
|
+
// Custom classes
|
|
38
|
+
this.inputClass());
|
|
39
|
+
}
|
|
40
|
+
handleClick() {
|
|
41
|
+
if (!this.disabled()) {
|
|
42
|
+
// Call input handler if provided (slot-style)
|
|
43
|
+
if (this.onClick()) {
|
|
44
|
+
this.onClick()();
|
|
45
|
+
}
|
|
46
|
+
this.clicked.emit();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CopilotChatViewScrollToBottomButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
50
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: CopilotChatViewScrollToBottomButton, isStandalone: true, selector: "copilot-chat-view-scroll-to-bottom-button", inputs: { inputClass: { classPropertyName: "inputClass", publicName: "inputClass", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, onClick: { classPropertyName: "onClick", publicName: "onClick", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: `
|
|
51
|
+
<button
|
|
52
|
+
type="button"
|
|
53
|
+
[class]="computedClass"
|
|
54
|
+
[disabled]="disabled()"
|
|
55
|
+
(click)="handleClick()"
|
|
56
|
+
>
|
|
57
|
+
<lucide-angular
|
|
58
|
+
[img]="ChevronDown"
|
|
59
|
+
class="w-4 h-4 text-gray-600 dark:text-white"
|
|
60
|
+
>
|
|
61
|
+
</lucide-angular>
|
|
62
|
+
</button>
|
|
63
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
64
|
+
}
|
|
65
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CopilotChatViewScrollToBottomButton, decorators: [{
|
|
66
|
+
type: Component,
|
|
67
|
+
args: [{
|
|
68
|
+
standalone: true,
|
|
69
|
+
selector: "copilot-chat-view-scroll-to-bottom-button",
|
|
70
|
+
imports: [CommonModule, LucideAngularModule],
|
|
71
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
72
|
+
encapsulation: ViewEncapsulation.None,
|
|
73
|
+
template: `
|
|
74
|
+
<button
|
|
75
|
+
type="button"
|
|
76
|
+
[class]="computedClass"
|
|
77
|
+
[disabled]="disabled()"
|
|
78
|
+
(click)="handleClick()"
|
|
79
|
+
>
|
|
80
|
+
<lucide-angular
|
|
81
|
+
[img]="ChevronDown"
|
|
82
|
+
class="w-4 h-4 text-gray-600 dark:text-white"
|
|
83
|
+
>
|
|
84
|
+
</lucide-angular>
|
|
85
|
+
</button>
|
|
86
|
+
`,
|
|
87
|
+
}]
|
|
88
|
+
}] });
|
|
89
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29waWxvdC1jaGF0LXZpZXctc2Nyb2xsLXRvLWJvdHRvbS1idXR0b24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvY2hhdC9jb3BpbG90LWNoYXQtdmlldy1zY3JvbGwtdG8tYm90dG9tLWJ1dHRvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sdUJBQXVCLEVBQ3ZCLGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxhQUFhLENBQUM7OztBQUVqQzs7O0dBR0c7QUFzQkgsTUFBTSxPQUFPLG1DQUFtQztJQUM5QyxVQUFVLEdBQUcsS0FBSyxFQUFzQixDQUFDO0lBQ3pDLFFBQVEsR0FBRyxLQUFLLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDakMsd0RBQXdEO0lBQ3hELE9BQU8sR0FBRyxLQUFLLEVBQTRCLENBQUM7SUFFNUMsbUNBQW1DO0lBQ25DLE9BQU8sR0FBRyxNQUFNLEVBQVEsQ0FBQztJQUV6QixpQkFBaUI7SUFDRSxXQUFXLEdBQUcsV0FBVyxDQUFDO0lBRTdDLHdDQUF3QztJQUN4QyxJQUFJLGFBQWE7UUFDZixPQUFPLEVBQUU7UUFDUCxxQkFBcUI7UUFDckIsNEJBQTRCO1FBQzVCLG9CQUFvQjtRQUNwQiwyQkFBMkI7UUFDM0Isb0JBQW9CO1FBQ3BCLHVEQUF1RDtRQUN2RCxlQUFlO1FBQ2YseUNBQXlDO1FBQ3pDLFNBQVM7UUFDVCxpREFBaUQ7UUFDakQsYUFBYTtRQUNiLG1CQUFtQjtRQUNuQixlQUFlO1FBQ2YscUVBQXFFO1FBQ3JFLGlCQUFpQjtRQUNqQixJQUFJLENBQUMsVUFBVSxFQUFFLENBQ2xCLENBQUM7SUFDSixDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQztZQUNyQiw4Q0FBOEM7WUFDOUMsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztnQkFDbkIsSUFBSSxDQUFDLE9BQU8sRUFBRyxFQUFFLENBQUM7WUFDcEIsQ0FBQztZQUNELElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdEIsQ0FBQztJQUNILENBQUM7d0dBMUNVLG1DQUFtQzs0RkFBbkMsbUNBQW1DLHdoQkFmcEM7Ozs7Ozs7Ozs7Ozs7R0FhVCwyREFoQlMsWUFBWSw4QkFBRSxtQkFBbUI7OzRGQWtCaEMsbUNBQW1DO2tCQXJCL0MsU0FBUzttQkFBQztvQkFDVCxVQUFVLEVBQUUsSUFBSTtvQkFDaEIsUUFBUSxFQUFFLDJDQUEyQztvQkFDckQsT0FBTyxFQUFFLENBQUMsWUFBWSxFQUFFLG1CQUFtQixDQUFDO29CQUM1QyxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtvQkFDL0MsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7b0JBQ3JDLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7OztHQWFUO2lCQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBpbnB1dCxcbiAgb3V0cHV0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XG5pbXBvcnQgeyBMdWNpZGVBbmd1bGFyTW9kdWxlLCBDaGV2cm9uRG93biB9IGZyb20gXCJsdWNpZGUtYW5ndWxhclwiO1xuaW1wb3J0IHsgY24gfSBmcm9tIFwiLi4vLi4vdXRpbHNcIjtcblxuLyoqXG4gKiBTY3JvbGxUb0JvdHRvbUJ1dHRvbiBjb21wb25lbnQgZm9yIENvcGlsb3RDaGF0Vmlld1xuICogTWF0Y2hlcyBSZWFjdCBpbXBsZW1lbnRhdGlvbiBleGFjdGx5IHdpdGggc2FtZSBUYWlsd2luZCBjbGFzc2VzXG4gKi9cbkBDb21wb25lbnQoe1xuICBzdGFuZGFsb25lOiB0cnVlLFxuICBzZWxlY3RvcjogXCJjb3BpbG90LWNoYXQtdmlldy1zY3JvbGwtdG8tYm90dG9tLWJ1dHRvblwiLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBMdWNpZGVBbmd1bGFyTW9kdWxlXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBbY2xhc3NdPVwiY29tcHV0ZWRDbGFzc1wiXG4gICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWQoKVwiXG4gICAgICAoY2xpY2spPVwiaGFuZGxlQ2xpY2soKVwiXG4gICAgPlxuICAgICAgPGx1Y2lkZS1hbmd1bGFyXG4gICAgICAgIFtpbWddPVwiQ2hldnJvbkRvd25cIlxuICAgICAgICBjbGFzcz1cInctNCBoLTQgdGV4dC1ncmF5LTYwMCBkYXJrOnRleHQtd2hpdGVcIlxuICAgICAgPlxuICAgICAgPC9sdWNpZGUtYW5ndWxhcj5cbiAgICA8L2J1dHRvbj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgQ29waWxvdENoYXRWaWV3U2Nyb2xsVG9Cb3R0b21CdXR0b24ge1xuICBpbnB1dENsYXNzID0gaW5wdXQ8c3RyaW5nIHwgdW5kZWZpbmVkPigpO1xuICBkaXNhYmxlZCA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcbiAgLy8gU3VwcG9ydCBmdW5jdGlvbi1zdHlsZSBjbGljayBoYW5kbGVyIHZpYSBzbG90IGNvbnRleHRcbiAgb25DbGljayA9IGlucHV0PCgoKSA9PiB2b2lkKSB8IHVuZGVmaW5lZD4oKTtcblxuICAvLyBTaW1wbGUsIGlkaW9tYXRpYyBBbmd1bGFyIG91dHB1dFxuICBjbGlja2VkID0gb3V0cHV0PHZvaWQ+KCk7XG5cbiAgLy8gSWNvbiByZWZlcmVuY2VcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IENoZXZyb25Eb3duID0gQ2hldnJvbkRvd247XG5cbiAgLy8gQ29tcHV0ZWQgY2xhc3MgbWF0Y2hpbmcgUmVhY3QgZXhhY3RseVxuICBnZXQgY29tcHV0ZWRDbGFzcygpOiBzdHJpbmcge1xuICAgIHJldHVybiBjbihcbiAgICAgIC8vIEJhc2UgYnV0dG9uIHN0eWxlc1xuICAgICAgXCJyb3VuZGVkLWZ1bGwgdy0xMCBoLTEwIHAtMFwiLFxuICAgICAgLy8gQmFja2dyb3VuZCBjb2xvcnNcbiAgICAgIFwiYmctd2hpdGUgZGFyazpiZy1ncmF5LTkwMFwiLFxuICAgICAgLy8gQm9yZGVyIGFuZCBzaGFkb3dcbiAgICAgIFwic2hhZG93LWxnIGJvcmRlciBib3JkZXItZ3JheS0yMDAgZGFyazpib3JkZXItZ3JheS03MDBcIixcbiAgICAgIC8vIEhvdmVyIHN0YXRlc1xuICAgICAgXCJob3ZlcjpiZy1ncmF5LTUwIGRhcms6aG92ZXI6YmctZ3JheS04MDBcIixcbiAgICAgIC8vIExheW91dFxuICAgICAgXCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBjdXJzb3ItcG9pbnRlclwiLFxuICAgICAgLy8gVHJhbnNpdGlvblxuICAgICAgXCJ0cmFuc2l0aW9uLWNvbG9yc1wiLFxuICAgICAgLy8gRm9jdXMgc3RhdGVzXG4gICAgICBcImZvY3VzOm91dGxpbmUtbm9uZSBmb2N1cy12aXNpYmxlOnJpbmctMiBmb2N1cy12aXNpYmxlOnJpbmctb2Zmc2V0LTJcIixcbiAgICAgIC8vIEN1c3RvbSBjbGFzc2VzXG4gICAgICB0aGlzLmlucHV0Q2xhc3MoKVxuICAgICk7XG4gIH1cblxuICBoYW5kbGVDbGljaygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZGlzYWJsZWQoKSkge1xuICAgICAgLy8gQ2FsbCBpbnB1dCBoYW5kbGVyIGlmIHByb3ZpZGVkIChzbG90LXN0eWxlKVxuICAgICAgaWYgKHRoaXMub25DbGljaygpKSB7XG4gICAgICAgIHRoaXMub25DbGljaygpISgpO1xuICAgICAgfVxuICAgICAgdGhpcy5jbGlja2VkLmVtaXQoKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
import { Component, input, output, ViewChild, ElementRef, ChangeDetectionStrategy, ViewEncapsulation, signal, computed, inject, PLATFORM_ID, ChangeDetectorRef, } from "@angular/core";
|
|
2
|
+
import { CommonModule, isPlatformBrowser } from "@angular/common";
|
|
3
|
+
import { ScrollingModule } from "@angular/cdk/scrolling";
|
|
4
|
+
import { CopilotSlot } from "../../slots/copilot-slot";
|
|
5
|
+
import { CopilotChatMessageView } from "./copilot-chat-message-view";
|
|
6
|
+
import { CopilotChatViewScrollToBottomButton } from "./copilot-chat-view-scroll-to-bottom-button";
|
|
7
|
+
import { StickToBottom } from "../../directives/stick-to-bottom";
|
|
8
|
+
import { ScrollPosition } from "../../scroll-position";
|
|
9
|
+
import { cn } from "../../utils";
|
|
10
|
+
import { Subject } from "rxjs";
|
|
11
|
+
import { takeUntil } from "rxjs/operators";
|
|
12
|
+
import * as i0 from "@angular/core";
|
|
13
|
+
import * as i1 from "@angular/cdk/scrolling";
|
|
14
|
+
/**
|
|
15
|
+
* ScrollView component for CopilotChatView
|
|
16
|
+
* Handles auto-scrolling and scroll position management
|
|
17
|
+
*/
|
|
18
|
+
export class CopilotChatViewScrollView {
|
|
19
|
+
cdr = inject(ChangeDetectorRef);
|
|
20
|
+
autoScroll = input(true);
|
|
21
|
+
inputContainerHeight = input(0);
|
|
22
|
+
isResizing = input(false);
|
|
23
|
+
inputClass = input();
|
|
24
|
+
messages = input([]);
|
|
25
|
+
messageView = input();
|
|
26
|
+
messageViewClass = input();
|
|
27
|
+
showCursor = input(false);
|
|
28
|
+
// Handler availability flags removed in favor of DI service
|
|
29
|
+
// Slot inputs
|
|
30
|
+
scrollToBottomButton = input();
|
|
31
|
+
scrollToBottomButtonClass = input();
|
|
32
|
+
// Output events (bubbled from message view)
|
|
33
|
+
assistantMessageThumbsUp = output();
|
|
34
|
+
assistantMessageThumbsDown = output();
|
|
35
|
+
assistantMessageReadAloud = output();
|
|
36
|
+
assistantMessageRegenerate = output();
|
|
37
|
+
userMessageCopy = output();
|
|
38
|
+
userMessageEdit = output();
|
|
39
|
+
// ViewChild references
|
|
40
|
+
scrollContainer;
|
|
41
|
+
contentContainer;
|
|
42
|
+
stickToBottomDirective;
|
|
43
|
+
// Default components
|
|
44
|
+
defaultMessageViewComponent = CopilotChatMessageView;
|
|
45
|
+
defaultScrollToBottomButtonComponent = CopilotChatViewScrollToBottomButton;
|
|
46
|
+
// Signals
|
|
47
|
+
hasMounted = signal(false);
|
|
48
|
+
showScrollButton = signal(false);
|
|
49
|
+
isAtBottom = signal(true);
|
|
50
|
+
paddingBottom = computed(() => this.inputContainerHeight() + 32);
|
|
51
|
+
// Computed class
|
|
52
|
+
computedClass = computed(() => cn(this.inputClass()));
|
|
53
|
+
destroy$ = new Subject();
|
|
54
|
+
platformId = inject(PLATFORM_ID);
|
|
55
|
+
scrollPositionService = inject(ScrollPosition);
|
|
56
|
+
// No mirroring of inputs; derive directly via computed()
|
|
57
|
+
ngOnInit() {
|
|
58
|
+
// Check if we're in the browser
|
|
59
|
+
if (isPlatformBrowser(this.platformId)) {
|
|
60
|
+
// Set mounted after a tick to allow for hydration
|
|
61
|
+
setTimeout(() => {
|
|
62
|
+
this.hasMounted.set(true);
|
|
63
|
+
}, 0);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
ngAfterViewInit() {
|
|
67
|
+
if (!this.autoScroll()) {
|
|
68
|
+
// Wait for the view to be fully rendered after hasMounted is set
|
|
69
|
+
setTimeout(() => {
|
|
70
|
+
if (this.scrollContainer) {
|
|
71
|
+
// Check initial scroll position
|
|
72
|
+
const initialState = this.scrollPositionService.getScrollState(this.scrollContainer.nativeElement, 10);
|
|
73
|
+
this.showScrollButton.set(!initialState.isAtBottom);
|
|
74
|
+
// Monitor scroll position for manual mode
|
|
75
|
+
this.scrollPositionService
|
|
76
|
+
.monitorScrollPosition(this.scrollContainer, 10)
|
|
77
|
+
.pipe(takeUntil(this.destroy$))
|
|
78
|
+
.subscribe((state) => {
|
|
79
|
+
this.showScrollButton.set(!state.isAtBottom);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}, 100);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Handle isAtBottom change from StickToBottom directive
|
|
87
|
+
*/
|
|
88
|
+
onIsAtBottomChange(isAtBottom) {
|
|
89
|
+
this.isAtBottom.set(isAtBottom);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Scroll to bottom for manual mode
|
|
93
|
+
*/
|
|
94
|
+
scrollToBottom() {
|
|
95
|
+
if (this.scrollContainer) {
|
|
96
|
+
this.scrollPositionService.scrollToBottom(this.scrollContainer, true);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Scroll to bottom for stick-to-bottom mode
|
|
101
|
+
*/
|
|
102
|
+
scrollToBottomFromStick() {
|
|
103
|
+
if (this.stickToBottomDirective) {
|
|
104
|
+
this.stickToBottomDirective.scrollToBottom("smooth");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
ngOnDestroy() {
|
|
108
|
+
this.destroy$.next();
|
|
109
|
+
this.destroy$.complete();
|
|
110
|
+
}
|
|
111
|
+
// Output maps for slots
|
|
112
|
+
scrollToBottomOutputs = { clicked: () => this.scrollToBottom() };
|
|
113
|
+
scrollToBottomFromStickOutputs = {
|
|
114
|
+
clicked: () => this.scrollToBottomFromStick(),
|
|
115
|
+
};
|
|
116
|
+
// Context methods for templates
|
|
117
|
+
messageViewContext() {
|
|
118
|
+
return {
|
|
119
|
+
messages: this.messages(),
|
|
120
|
+
inputClass: this.messageViewClass(),
|
|
121
|
+
showCursor: this.showCursor(),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
scrollToBottomContext() {
|
|
125
|
+
return {
|
|
126
|
+
inputClass: this.scrollToBottomButtonClass(),
|
|
127
|
+
onClick: () => this.scrollToBottom(),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
scrollToBottomFromStickContext() {
|
|
131
|
+
return {
|
|
132
|
+
inputClass: this.scrollToBottomButtonClass(),
|
|
133
|
+
onClick: () => this.scrollToBottomFromStick(),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CopilotChatViewScrollView, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
137
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: CopilotChatViewScrollView, isStandalone: true, selector: "copilot-chat-view-scroll-view", inputs: { autoScroll: { classPropertyName: "autoScroll", publicName: "autoScroll", isSignal: true, isRequired: false, transformFunction: null }, inputContainerHeight: { classPropertyName: "inputContainerHeight", publicName: "inputContainerHeight", isSignal: true, isRequired: false, transformFunction: null }, isResizing: { classPropertyName: "isResizing", publicName: "isResizing", isSignal: true, isRequired: false, transformFunction: null }, inputClass: { classPropertyName: "inputClass", publicName: "inputClass", isSignal: true, isRequired: false, transformFunction: null }, messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null }, messageView: { classPropertyName: "messageView", publicName: "messageView", isSignal: true, isRequired: false, transformFunction: null }, messageViewClass: { classPropertyName: "messageViewClass", publicName: "messageViewClass", isSignal: true, isRequired: false, transformFunction: null }, showCursor: { classPropertyName: "showCursor", publicName: "showCursor", isSignal: true, isRequired: false, transformFunction: null }, scrollToBottomButton: { classPropertyName: "scrollToBottomButton", publicName: "scrollToBottomButton", isSignal: true, isRequired: false, transformFunction: null }, scrollToBottomButtonClass: { classPropertyName: "scrollToBottomButtonClass", publicName: "scrollToBottomButtonClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { assistantMessageThumbsUp: "assistantMessageThumbsUp", assistantMessageThumbsDown: "assistantMessageThumbsDown", assistantMessageReadAloud: "assistantMessageReadAloud", assistantMessageRegenerate: "assistantMessageRegenerate", userMessageCopy: "userMessageCopy", userMessageEdit: "userMessageEdit" }, providers: [ScrollPosition], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, read: ElementRef }, { propertyName: "contentContainer", first: true, predicate: ["contentContainer"], descendants: true, read: ElementRef }, { propertyName: "stickToBottomDirective", first: true, predicate: StickToBottom, descendants: true }], ngImport: i0, template: `
|
|
138
|
+
@if (!hasMounted()) {
|
|
139
|
+
<!-- SSR/Initial render without stick-to-bottom -->
|
|
140
|
+
<div
|
|
141
|
+
class="h-full max-h-full flex flex-col min-h-0 overflow-y-scroll overflow-x-hidden"
|
|
142
|
+
>
|
|
143
|
+
<div class="px-4 sm:px-0">
|
|
144
|
+
<ng-content></ng-content>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
} @else if (!autoScroll()) {
|
|
148
|
+
<!-- Manual scroll mode -->
|
|
149
|
+
<div class="h-full max-h-full flex flex-col min-h-0 relative">
|
|
150
|
+
<div
|
|
151
|
+
#scrollContainer
|
|
152
|
+
cdkScrollable
|
|
153
|
+
[class]="computedClass()"
|
|
154
|
+
class="overflow-y-scroll overflow-x-hidden"
|
|
155
|
+
>
|
|
156
|
+
<div #contentContainer class="px-4 sm:px-0">
|
|
157
|
+
<!-- Content with padding-bottom matching React -->
|
|
158
|
+
<div [style.padding-bottom.px]="paddingBottom()">
|
|
159
|
+
<div class="max-w-3xl mx-auto">
|
|
160
|
+
@if (messageView()) {
|
|
161
|
+
<copilot-slot
|
|
162
|
+
[slot]="messageView()"
|
|
163
|
+
[context]="messageViewContext()"
|
|
164
|
+
[defaultComponent]="defaultMessageViewComponent"
|
|
165
|
+
>
|
|
166
|
+
</copilot-slot>
|
|
167
|
+
} @else {
|
|
168
|
+
<copilot-chat-message-view
|
|
169
|
+
[messages]="messages()"
|
|
170
|
+
[inputClass]="messageViewClass()"
|
|
171
|
+
[showCursor]="showCursor()"
|
|
172
|
+
(assistantMessageThumbsUp)="
|
|
173
|
+
assistantMessageThumbsUp.emit($event)
|
|
174
|
+
"
|
|
175
|
+
(assistantMessageThumbsDown)="
|
|
176
|
+
assistantMessageThumbsDown.emit($event)
|
|
177
|
+
"
|
|
178
|
+
(assistantMessageReadAloud)="
|
|
179
|
+
assistantMessageReadAloud.emit($event)
|
|
180
|
+
"
|
|
181
|
+
(assistantMessageRegenerate)="
|
|
182
|
+
assistantMessageRegenerate.emit($event)
|
|
183
|
+
"
|
|
184
|
+
(userMessageCopy)="userMessageCopy.emit($event)"
|
|
185
|
+
(userMessageEdit)="userMessageEdit.emit($event)"
|
|
186
|
+
>
|
|
187
|
+
</copilot-chat-message-view>
|
|
188
|
+
}
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
<!-- Scroll to bottom button for manual mode, OUTSIDE scrollable content -->
|
|
195
|
+
@if (showScrollButton() && !isResizing()) {
|
|
196
|
+
<div
|
|
197
|
+
class="absolute inset-x-0 flex justify-center z-30"
|
|
198
|
+
[style.bottom.px]="inputContainerHeight() + 16"
|
|
199
|
+
>
|
|
200
|
+
<copilot-slot
|
|
201
|
+
[slot]="scrollToBottomButton()"
|
|
202
|
+
[context]="scrollToBottomContext()"
|
|
203
|
+
[defaultComponent]="defaultScrollToBottomButtonComponent"
|
|
204
|
+
[outputs]="scrollToBottomOutputs"
|
|
205
|
+
>
|
|
206
|
+
</copilot-slot>
|
|
207
|
+
</div>
|
|
208
|
+
}
|
|
209
|
+
</div>
|
|
210
|
+
} @else {
|
|
211
|
+
<!-- Auto-scroll mode with StickToBottom directive -->
|
|
212
|
+
<div class="h-full max-h-full flex flex-col min-h-0 relative">
|
|
213
|
+
<div
|
|
214
|
+
#scrollContainer
|
|
215
|
+
cdkScrollable
|
|
216
|
+
copilotStickToBottom
|
|
217
|
+
[enabled]="autoScroll()"
|
|
218
|
+
[threshold]="10"
|
|
219
|
+
[debounceMs]="0"
|
|
220
|
+
[initialBehavior]="'smooth'"
|
|
221
|
+
[resizeBehavior]="'smooth'"
|
|
222
|
+
(isAtBottomChange)="onIsAtBottomChange($event)"
|
|
223
|
+
[class]="computedClass()"
|
|
224
|
+
class="overflow-y-scroll overflow-x-hidden"
|
|
225
|
+
>
|
|
226
|
+
<!-- Scrollable content wrapper -->
|
|
227
|
+
<div class="px-4 sm:px-0">
|
|
228
|
+
<!-- Content with padding-bottom matching React -->
|
|
229
|
+
<div [style.padding-bottom.px]="paddingBottom()">
|
|
230
|
+
<div class="max-w-3xl mx-auto">
|
|
231
|
+
@if (messageView()) {
|
|
232
|
+
<copilot-slot
|
|
233
|
+
[slot]="messageView()"
|
|
234
|
+
[context]="messageViewContext()"
|
|
235
|
+
[defaultComponent]="defaultMessageViewComponent"
|
|
236
|
+
>
|
|
237
|
+
</copilot-slot>
|
|
238
|
+
} @else {
|
|
239
|
+
<copilot-chat-message-view
|
|
240
|
+
[messages]="messages()"
|
|
241
|
+
[inputClass]="messageViewClass()"
|
|
242
|
+
[showCursor]="showCursor()"
|
|
243
|
+
(assistantMessageThumbsUp)="
|
|
244
|
+
assistantMessageThumbsUp.emit($event)
|
|
245
|
+
"
|
|
246
|
+
(assistantMessageThumbsDown)="
|
|
247
|
+
assistantMessageThumbsDown.emit($event)
|
|
248
|
+
"
|
|
249
|
+
(assistantMessageReadAloud)="
|
|
250
|
+
assistantMessageReadAloud.emit($event)
|
|
251
|
+
"
|
|
252
|
+
(assistantMessageRegenerate)="
|
|
253
|
+
assistantMessageRegenerate.emit($event)
|
|
254
|
+
"
|
|
255
|
+
(userMessageCopy)="userMessageCopy.emit($event)"
|
|
256
|
+
(userMessageEdit)="userMessageEdit.emit($event)"
|
|
257
|
+
>
|
|
258
|
+
</copilot-chat-message-view>
|
|
259
|
+
}
|
|
260
|
+
</div>
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
|
|
265
|
+
<!-- Scroll to bottom button - hidden during resize, OUTSIDE scrollable content -->
|
|
266
|
+
@if (!isAtBottom() && !isResizing()) {
|
|
267
|
+
<div
|
|
268
|
+
class="absolute inset-x-0 flex justify-center z-30"
|
|
269
|
+
[style.bottom.px]="inputContainerHeight() + 16"
|
|
270
|
+
>
|
|
271
|
+
<copilot-slot
|
|
272
|
+
[slot]="scrollToBottomButton()"
|
|
273
|
+
[context]="scrollToBottomFromStickContext()"
|
|
274
|
+
[defaultComponent]="defaultScrollToBottomButtonComponent"
|
|
275
|
+
[outputs]="scrollToBottomFromStickOutputs"
|
|
276
|
+
>
|
|
277
|
+
</copilot-slot>
|
|
278
|
+
</div>
|
|
279
|
+
}
|
|
280
|
+
</div>
|
|
281
|
+
}
|
|
282
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "component", type: CopilotSlot, selector: "copilot-slot", inputs: ["slot", "context", "defaultComponent", "outputs"] }, { kind: "component", type: CopilotChatMessageView, selector: "copilot-chat-message-view", inputs: ["messages", "showCursor", "isLoading", "inputClass", "assistantMessageComponent", "assistantMessageTemplate", "assistantMessageClass", "userMessageComponent", "userMessageTemplate", "userMessageClass", "cursorComponent", "cursorTemplate", "cursorClass"], outputs: ["assistantMessageThumbsUp", "assistantMessageThumbsDown", "assistantMessageReadAloud", "assistantMessageRegenerate", "userMessageCopy", "userMessageEdit"] }, { kind: "directive", type: StickToBottom, selector: "[copilotStickToBottom]", inputs: ["enabled", "threshold", "initialBehavior", "resizeBehavior", "debounceMs"], outputs: ["isAtBottomChange", "scrollToBottomRequested"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
283
|
+
}
|
|
284
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CopilotChatViewScrollView, decorators: [{
|
|
285
|
+
type: Component,
|
|
286
|
+
args: [{
|
|
287
|
+
standalone: true,
|
|
288
|
+
selector: "copilot-chat-view-scroll-view",
|
|
289
|
+
imports: [
|
|
290
|
+
CommonModule,
|
|
291
|
+
ScrollingModule,
|
|
292
|
+
CopilotSlot,
|
|
293
|
+
CopilotChatMessageView,
|
|
294
|
+
StickToBottom,
|
|
295
|
+
],
|
|
296
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
297
|
+
encapsulation: ViewEncapsulation.None,
|
|
298
|
+
providers: [ScrollPosition],
|
|
299
|
+
template: `
|
|
300
|
+
@if (!hasMounted()) {
|
|
301
|
+
<!-- SSR/Initial render without stick-to-bottom -->
|
|
302
|
+
<div
|
|
303
|
+
class="h-full max-h-full flex flex-col min-h-0 overflow-y-scroll overflow-x-hidden"
|
|
304
|
+
>
|
|
305
|
+
<div class="px-4 sm:px-0">
|
|
306
|
+
<ng-content></ng-content>
|
|
307
|
+
</div>
|
|
308
|
+
</div>
|
|
309
|
+
} @else if (!autoScroll()) {
|
|
310
|
+
<!-- Manual scroll mode -->
|
|
311
|
+
<div class="h-full max-h-full flex flex-col min-h-0 relative">
|
|
312
|
+
<div
|
|
313
|
+
#scrollContainer
|
|
314
|
+
cdkScrollable
|
|
315
|
+
[class]="computedClass()"
|
|
316
|
+
class="overflow-y-scroll overflow-x-hidden"
|
|
317
|
+
>
|
|
318
|
+
<div #contentContainer class="px-4 sm:px-0">
|
|
319
|
+
<!-- Content with padding-bottom matching React -->
|
|
320
|
+
<div [style.padding-bottom.px]="paddingBottom()">
|
|
321
|
+
<div class="max-w-3xl mx-auto">
|
|
322
|
+
@if (messageView()) {
|
|
323
|
+
<copilot-slot
|
|
324
|
+
[slot]="messageView()"
|
|
325
|
+
[context]="messageViewContext()"
|
|
326
|
+
[defaultComponent]="defaultMessageViewComponent"
|
|
327
|
+
>
|
|
328
|
+
</copilot-slot>
|
|
329
|
+
} @else {
|
|
330
|
+
<copilot-chat-message-view
|
|
331
|
+
[messages]="messages()"
|
|
332
|
+
[inputClass]="messageViewClass()"
|
|
333
|
+
[showCursor]="showCursor()"
|
|
334
|
+
(assistantMessageThumbsUp)="
|
|
335
|
+
assistantMessageThumbsUp.emit($event)
|
|
336
|
+
"
|
|
337
|
+
(assistantMessageThumbsDown)="
|
|
338
|
+
assistantMessageThumbsDown.emit($event)
|
|
339
|
+
"
|
|
340
|
+
(assistantMessageReadAloud)="
|
|
341
|
+
assistantMessageReadAloud.emit($event)
|
|
342
|
+
"
|
|
343
|
+
(assistantMessageRegenerate)="
|
|
344
|
+
assistantMessageRegenerate.emit($event)
|
|
345
|
+
"
|
|
346
|
+
(userMessageCopy)="userMessageCopy.emit($event)"
|
|
347
|
+
(userMessageEdit)="userMessageEdit.emit($event)"
|
|
348
|
+
>
|
|
349
|
+
</copilot-chat-message-view>
|
|
350
|
+
}
|
|
351
|
+
</div>
|
|
352
|
+
</div>
|
|
353
|
+
</div>
|
|
354
|
+
</div>
|
|
355
|
+
|
|
356
|
+
<!-- Scroll to bottom button for manual mode, OUTSIDE scrollable content -->
|
|
357
|
+
@if (showScrollButton() && !isResizing()) {
|
|
358
|
+
<div
|
|
359
|
+
class="absolute inset-x-0 flex justify-center z-30"
|
|
360
|
+
[style.bottom.px]="inputContainerHeight() + 16"
|
|
361
|
+
>
|
|
362
|
+
<copilot-slot
|
|
363
|
+
[slot]="scrollToBottomButton()"
|
|
364
|
+
[context]="scrollToBottomContext()"
|
|
365
|
+
[defaultComponent]="defaultScrollToBottomButtonComponent"
|
|
366
|
+
[outputs]="scrollToBottomOutputs"
|
|
367
|
+
>
|
|
368
|
+
</copilot-slot>
|
|
369
|
+
</div>
|
|
370
|
+
}
|
|
371
|
+
</div>
|
|
372
|
+
} @else {
|
|
373
|
+
<!-- Auto-scroll mode with StickToBottom directive -->
|
|
374
|
+
<div class="h-full max-h-full flex flex-col min-h-0 relative">
|
|
375
|
+
<div
|
|
376
|
+
#scrollContainer
|
|
377
|
+
cdkScrollable
|
|
378
|
+
copilotStickToBottom
|
|
379
|
+
[enabled]="autoScroll()"
|
|
380
|
+
[threshold]="10"
|
|
381
|
+
[debounceMs]="0"
|
|
382
|
+
[initialBehavior]="'smooth'"
|
|
383
|
+
[resizeBehavior]="'smooth'"
|
|
384
|
+
(isAtBottomChange)="onIsAtBottomChange($event)"
|
|
385
|
+
[class]="computedClass()"
|
|
386
|
+
class="overflow-y-scroll overflow-x-hidden"
|
|
387
|
+
>
|
|
388
|
+
<!-- Scrollable content wrapper -->
|
|
389
|
+
<div class="px-4 sm:px-0">
|
|
390
|
+
<!-- Content with padding-bottom matching React -->
|
|
391
|
+
<div [style.padding-bottom.px]="paddingBottom()">
|
|
392
|
+
<div class="max-w-3xl mx-auto">
|
|
393
|
+
@if (messageView()) {
|
|
394
|
+
<copilot-slot
|
|
395
|
+
[slot]="messageView()"
|
|
396
|
+
[context]="messageViewContext()"
|
|
397
|
+
[defaultComponent]="defaultMessageViewComponent"
|
|
398
|
+
>
|
|
399
|
+
</copilot-slot>
|
|
400
|
+
} @else {
|
|
401
|
+
<copilot-chat-message-view
|
|
402
|
+
[messages]="messages()"
|
|
403
|
+
[inputClass]="messageViewClass()"
|
|
404
|
+
[showCursor]="showCursor()"
|
|
405
|
+
(assistantMessageThumbsUp)="
|
|
406
|
+
assistantMessageThumbsUp.emit($event)
|
|
407
|
+
"
|
|
408
|
+
(assistantMessageThumbsDown)="
|
|
409
|
+
assistantMessageThumbsDown.emit($event)
|
|
410
|
+
"
|
|
411
|
+
(assistantMessageReadAloud)="
|
|
412
|
+
assistantMessageReadAloud.emit($event)
|
|
413
|
+
"
|
|
414
|
+
(assistantMessageRegenerate)="
|
|
415
|
+
assistantMessageRegenerate.emit($event)
|
|
416
|
+
"
|
|
417
|
+
(userMessageCopy)="userMessageCopy.emit($event)"
|
|
418
|
+
(userMessageEdit)="userMessageEdit.emit($event)"
|
|
419
|
+
>
|
|
420
|
+
</copilot-chat-message-view>
|
|
421
|
+
}
|
|
422
|
+
</div>
|
|
423
|
+
</div>
|
|
424
|
+
</div>
|
|
425
|
+
</div>
|
|
426
|
+
|
|
427
|
+
<!-- Scroll to bottom button - hidden during resize, OUTSIDE scrollable content -->
|
|
428
|
+
@if (!isAtBottom() && !isResizing()) {
|
|
429
|
+
<div
|
|
430
|
+
class="absolute inset-x-0 flex justify-center z-30"
|
|
431
|
+
[style.bottom.px]="inputContainerHeight() + 16"
|
|
432
|
+
>
|
|
433
|
+
<copilot-slot
|
|
434
|
+
[slot]="scrollToBottomButton()"
|
|
435
|
+
[context]="scrollToBottomFromStickContext()"
|
|
436
|
+
[defaultComponent]="defaultScrollToBottomButtonComponent"
|
|
437
|
+
[outputs]="scrollToBottomFromStickOutputs"
|
|
438
|
+
>
|
|
439
|
+
</copilot-slot>
|
|
440
|
+
</div>
|
|
441
|
+
}
|
|
442
|
+
</div>
|
|
443
|
+
}
|
|
444
|
+
`,
|
|
445
|
+
}]
|
|
446
|
+
}], propDecorators: { scrollContainer: [{
|
|
447
|
+
type: ViewChild,
|
|
448
|
+
args: ["scrollContainer", { read: ElementRef }]
|
|
449
|
+
}], contentContainer: [{
|
|
450
|
+
type: ViewChild,
|
|
451
|
+
args: ["contentContainer", { read: ElementRef }]
|
|
452
|
+
}], stickToBottomDirective: [{
|
|
453
|
+
type: ViewChild,
|
|
454
|
+
args: [StickToBottom]
|
|
455
|
+
}] } });
|
|
456
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29waWxvdC1jaGF0LXZpZXctc2Nyb2xsLXZpZXcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvY2hhdC9jb3BpbG90LWNoYXQtdmlldy1zY3JvbGwtdmlldy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sU0FBUyxFQUNULFVBQVUsRUFDVix1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLE1BQU0sRUFDTixRQUFRLEVBSVIsTUFBTSxFQUNOLFdBQVcsRUFDWCxpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdkQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxFQUFFLG1DQUFtQyxFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDbEcsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUV2RCxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7QUFFM0M7OztHQUdHO0FBaUtILE1BQU0sT0FBTyx5QkFBeUI7SUFHNUIsR0FBRyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBRXhDLFVBQVUsR0FBRyxLQUFLLENBQVUsSUFBSSxDQUFDLENB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TTtvQkFDL0MsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7b0JBQ3JDLFNBQVMsRUFBRSxDQUFDLGNBQWMsQ0FBQztvQkFDM0IsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUpUO2lCQUNGOzhCQWlDQyxlQUFlO3NCQURkLFNBQVM7dUJBQUMsaUJBQWlCLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO2dCQUdsRCxnQkFBZ0I7c0JBRGYsU0FBUzt1QkFBQyxrQkFBa0IsRUFBRSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUU7Z0JBRXpCLHNCQUFzQjtzQkFBL0MsU0FBUzt1QkFBQyxhQUFhIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBpbnB1dCxcbiAgb3V0cHV0LFxuICBWaWV3Q2hpbGQsXG4gIEVsZW1lbnRSZWYsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbiAgc2lnbmFsLFxuICBjb21wdXRlZCxcbiAgT25Jbml0LFxuICBBZnRlclZpZXdJbml0LFxuICBPbkRlc3Ryb3ksXG4gIGluamVjdCxcbiAgUExBVEZPUk1fSUQsXG4gIENoYW5nZURldGVjdG9yUmVmLFxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlLCBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gXCJAYW5ndWxhci9jb21tb25cIjtcbmltcG9ydCB7IFNjcm9sbGluZ01vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9jZGsvc2Nyb2xsaW5nXCI7XG5pbXBvcnQgeyBDb3BpbG90U2xvdCB9IGZyb20gXCIuLi8uLi9zbG90cy9jb3BpbG90LXNsb3RcIjtcbmltcG9ydCB7IENvcGlsb3RDaGF0TWVzc2FnZVZpZXcgfSBmcm9tIFwiLi9jb3BpbG90LWNoYXQtbWVzc2FnZS12aWV3XCI7XG5pbXBvcnQgeyBDb3BpbG90Q2hhdFZpZXdTY3JvbGxUb0JvdHRvbUJ1dHRvbiB9IGZyb20gXCIuL2NvcGlsb3QtY2hhdC12aWV3LXNjcm9sbC10by1ib3R0b20tYnV0dG9uXCI7XG5pbXBvcnQgeyBTdGlja1RvQm90dG9tIH0gZnJvbSBcIi4uLy4uL2RpcmVjdGl2ZXMvc3RpY2stdG8tYm90dG9tXCI7XG5pbXBvcnQgeyBTY3JvbGxQb3NpdGlvbiB9IGZyb20gXCIuLi8uLi9zY3JvbGwtcG9zaXRpb25cIjtcbmltcG9ydCB7IE1lc3NhZ2UgfSBmcm9tIFwiQGFnLXVpL2NsaWVudFwiO1xuaW1wb3J0IHsgY24gfSBmcm9tIFwiLi4vLi4vdXRpbHNcIjtcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5cbi8qKlxuICogU2Nyb2xsVmlldyBjb21wb25lbnQgZm9yIENvcGlsb3RDaGF0Vmlld1xuICogSGFuZGxlcyBhdXRvLXNjcm9sbGluZyBhbmQgc2Nyb2xsIHBvc2l0aW9uIG1hbmFnZW1lbnRcbiAqL1xuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHNlbGVjdG9yOiBcImNvcGlsb3QtY2hhdC12aWV3LXNjcm9sbC12aWV3XCIsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgU2Nyb2xsaW5nTW9kdWxlLFxuICAgIENvcGlsb3RTbG90LFxuICAgIENvcGlsb3RDaGF0TWVzc2FnZVZpZXcsXG4gICAgU3RpY2tUb0JvdHRvbSxcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHByb3ZpZGVyczogW1Njcm9sbFBvc2l0aW9uXSxcbiAgdGVtcGxhdGU6IGBcbiAgICBAaWYgKCFoYXNNb3VudGVkKCkpIHtcbiAgICAgIDwhLS0gU1NSL0luaXRpYWwgcmVuZGVyIHdpdGhvdXQgc3RpY2stdG8tYm90dG9tIC0tPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cImgtZnVsbCBtYXgtaC1mdWxsIGZsZXggZmxleC1jb2wgbWluLWgtMCBvdmVyZmxvdy15LXNjcm9sbCBvdmVyZmxvdy14LWhpZGRlblwiXG4gICAgICA+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJweC00IHNtOnB4LTBcIj5cbiAgICAgICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgfSBAZWxzZSBpZiAoIWF1dG9TY3JvbGwoKSkge1xuICAgICAgPCEtLSBNYW51YWwgc2Nyb2xsIG1vZGUgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiaC1mdWxsIG1heC1oLWZ1bGwgZmxleCBmbGV4LWNvbCBtaW4taC0wIHJlbGF0aXZlXCI+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICAjc2Nyb2xsQ29udGFpbmVyXG4gICAgICAgICAgY2RrU2Nyb2xsYWJsZVxuICAgICAgICAgIFtjbGFzc109XCJjb21wdXRlZENsYXNzKClcIlxuICAgICAgICAgIGNsYXNzPVwib3ZlcmZsb3cteS1zY3JvbGwgb3ZlcmZsb3cteC1oaWRkZW5cIlxuICAgICAgICA+XG4gICAgICAgICAgPGRpdiAjY29udGVudENvbnRhaW5lciBjbGFzcz1cInB4LTQgc206cHgtMFwiPlxuICAgICAgICAgICAgPCEtLSBDb250ZW50IHdpdGggcGFkZGluZy1ib3R0b20gbWF0Y2hpbmcgUmVhY3QgLS0+XG4gICAgICAgICAgICA8ZGl2IFtzdHlsZS5wYWRkaW5nLWJvdHRvbS5weF09XCJwYWRkaW5nQm90dG9tKClcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1heC13LTN4bCBteC1hdXRvXCI+XG4gICAgICAgICAgICAgICAgQGlmIChtZXNzYWdlVmlldygpKSB7XG4gICAgICAgICAgICAgICAgICA8Y29waWxvdC1zbG90XG4gICAgICAgICAgICAgICAgICAgIFtzbG90XT1cIm1lc3NhZ2VWaWV3KClcIlxuICAgICAgICAgICAgICAgICAgICBbY29udGV4dF09XCJtZXNzYWdlVmlld0NvbnRleHQoKVwiXG4gICAgICAgICAgICAgICAgICAgIFtkZWZhdWx0Q29tcG9uZW50XT1cImRlZmF1bHRNZXNzYWdlVmlld0NvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8L2NvcGlsb3Qtc2xvdD5cbiAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIDxjb3BpbG90LWNoYXQtbWVzc2FnZS12aWV3XG4gICAgICAgICAgICAgICAgICAgIFttZXNzYWdlc109XCJtZXNzYWdlcygpXCJcbiAgICAgICAgICAgICAgICAgICAgW2lucHV0Q2xhc3NdPVwibWVzc2FnZVZpZXdDbGFzcygpXCJcbiAgICAgICAgICAgICAgICAgICAgW3Nob3dDdXJzb3JdPVwic2hvd0N1cnNvcigpXCJcbiAgICAgICAgICAgICAgICAgICAgKGFzc2lzdGFudE1lc3NhZ2VUaHVtYnNVcCk9XCJcbiAgICAgICAgICAgICAgICAgICAgICBhc3Npc3RhbnRNZXNzYWdlVGh1bWJzVXAuZW1pdCgkZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgIChhc3Npc3RhbnRNZXNzYWdlVGh1bWJzRG93bik9XCJcbiAgICAgICAgICAgICAgICAgICAgICBhc3Npc3RhbnRNZXNzYWdlVGh1bWJzRG93bi5lbWl0KCRldmVudClcbiAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgKGFzc2lzdGFudE1lc3NhZ2VSZWFkQWxvdWQpPVwiXG4gICAgICAgICAgICAgICAgICAgICAgYXNzaXN0YW50TWVzc2FnZVJlYWRBbG91ZC5lbWl0KCRldmVudClcbiAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgKGFzc2lzdGFudE1lc3NhZ2VSZWdlbmVyYXRlKT1cIlxuICAgICAgICAgICAgICAgICAgICAgIGFzc2lzdGFudE1lc3NhZ2VSZWdlbmVyYXRlLmVtaXQoJGV2ZW50KVxuICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAodXNlck1lc3NhZ2VDb3B5KT1cInVzZXJNZXNzYWdlQ29weS5lbWl0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAodXNlck1lc3NhZ2VFZGl0KT1cInVzZXJNZXNzYWdlRWRpdC5lbWl0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPC9jb3BpbG90LWNoYXQtbWVzc2FnZS12aWV3PlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBTY3JvbGwgdG8gYm90dG9tIGJ1dHRvbiBmb3IgbWFudWFsIG1vZGUsIE9VVFNJREUgc2Nyb2xsYWJsZSBjb250ZW50IC0tPlxuICAgICAgICBAaWYgKHNob3dTY3JvbGxCdXR0b24oKSAmJiAhaXNSZXNpemluZygpKSB7XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJhYnNvbHV0ZSBpbnNldC14LTAgZmxleCBqdXN0aWZ5LWNlbnRlciB6LTMwXCJcbiAgICAgICAgICAgIFtzdHlsZS5ib3R0b20ucHhdPVwiaW5wdXRDb250YWluZXJIZWlnaHQoKSArIDE2XCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8Y29waWxvdC1zbG90XG4gICAgICAgICAgICAgIFtzbG90XT1cInNjcm9sbFRvQm90dG9tQnV0dG9uKClcIlxuICAgICAgICAgICAgICBbY29udGV4dF09XCJzY3JvbGxUb0JvdHRvbUNvbnRleHQoKVwiXG4gICAgICAgICAgICAgIFtkZWZhdWx0Q29tcG9uZW50XT1cImRlZmF1bHRTY3JvbGxUb0JvdHRvbUJ1dHRvbkNvbXBvbmVudFwiXG4gICAgICAgICAgICAgIFtvdXRwdXRzXT1cInNjcm9sbFRvQm90dG9tT3V0cHV0c1wiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICA8L2NvcGlsb3Qtc2xvdD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG4gICAgfSBAZWxzZSB7XG4gICAgICA8IS0tIEF1dG8tc2Nyb2xsIG1vZGUgd2l0aCBTdGlja1RvQm90dG9tIGRpcmVjdGl2ZSAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJoLWZ1bGwgbWF4LWgtZnVsbCBmbGV4IGZsZXgtY29sIG1pbi1oLTAgcmVsYXRpdmVcIj5cbiAgICAgICAgPGRpdlxuICAgICAgICAgICNzY3JvbGxDb250YWluZXJcbiAgICAgICAgICBjZGtTY3JvbGxhYmxlXG4gICAgICAgICAgY29waWxvdFN0aWNrVG9Cb3R0b21cbiAgICAgICAgICBbZW5hYmxlZF09XCJhdXRvU2Nyb2xsKClcIlxuICAgICAgICAgIFt0aHJlc2hvbGRdPVwiMTBcIlxuICAgICAgICAgIFtkZWJvdW5jZU1zXT1cIjBcIlxuICAgICAgICAgIFtpbml0aWFsQmVoYXZpb3JdPVwiJ3Ntb290aCdcIlxuICAgICAgICAgIFtyZXNpemVCZWhhdmlvcl09XCInc21vb3RoJ1wiXG4gICAgICAgICAgKGlzQXRCb3R0b21DaGFuZ2UpPVwib25Jc0F0Qm90dG9tQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgIFtjbGFzc109XCJjb21wdXRlZENsYXNzKClcIlxuICAgICAgICAgIGNsYXNzPVwib3ZlcmZsb3cteS1zY3JvbGwgb3ZlcmZsb3cteC1oaWRkZW5cIlxuICAgICAgICA+XG4gICAgICAgICAgPCEtLSBTY3JvbGxhYmxlIGNvbnRlbnQgd3JhcHBlciAtLT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtNCBzbTpweC0wXCI+XG4gICAgICAgICAgICA8IS0tIENvbnRlbnQgd2l0aCBwYWRkaW5nLWJvdHRvbSBtYXRjaGluZyBSZWFjdCAtLT5cbiAgICAgICAgICAgIDxkaXYgW3N0eWxlLnBhZGRpbmctYm90dG9tLnB4XT1cInBhZGRpbmdCb3R0b20oKVwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWF4LXctM3hsIG14LWF1dG9cIj5cbiAgICAgICAgICAgICAgICBAaWYgKG1lc3NhZ2VWaWV3KCkpIHtcbiAgICAgICAgICAgICAgICAgIDxjb3BpbG90LXNsb3RcbiAgICAgICAgICAgICAgICAgICAgW3Nsb3RdPVwibWVzc2FnZVZpZXcoKVwiXG4gICAgICAgICAgICAgICAgICAgIFtjb250ZXh0XT1cIm1lc3NhZ2VWaWV3Q29udGV4dCgpXCJcbiAgICAgICAgICAgICAgICAgICAgW2RlZmF1bHRDb21wb25lbnRdPVwiZGVmYXVsdE1lc3NhZ2VWaWV3Q29tcG9uZW50XCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDwvY29waWxvdC1zbG90PlxuICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgPGNvcGlsb3QtY2hhdC1tZXNzYWdlLXZpZXdcbiAgICAgICAgICAgICAgICAgICAgW21lc3NhZ2VzXT1cIm1lc3NhZ2VzKClcIlxuICAgICAgICAgICAgICAgICAgICBbaW5wdXRDbGFzc109XCJtZXNzYWdlVmlld0NsYXNzKClcIlxuICAgICAgICAgICAgICAgICAgICBbc2hvd0N1cnNvcl09XCJzaG93Q3Vyc29yKClcIlxuICAgICAgICAgICAgICAgICAgICAoYXNzaXN0YW50TWVzc2FnZVRodW1ic1VwKT1cIlxuICAgICAgICAgICAgICAgICAgICAgIGFzc2lzdGFudE1lc3NhZ2VUaHVtYnNVcC5lbWl0KCRldmVudClcbiAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgKGFzc2lzdGFudE1lc3NhZ2VUaHVtYnNEb3duKT1cIlxuICAgICAgICAgICAgICAgICAgICAgIGFzc2lzdGFudE1lc3NhZ2VUaHVtYnNEb3duLmVtaXQoJGV2ZW50KVxuICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAoYXNzaXN0YW50TWVzc2FnZVJlYWRBbG91ZCk9XCJcbiAgICAgICAgICAgICAgICAgICAgICBhc3Npc3RhbnRNZXNzYWdlUmVhZEFsb3VkLmVtaXQoJGV2ZW50KVxuICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAoYXNzaXN0YW50TWVzc2FnZVJlZ2VuZXJhdGUpPVwiXG4gICAgICAgICAgICAgICAgICAgICAgYXNzaXN0YW50TWVzc2FnZVJlZ2VuZXJhdGUuZW1pdCgkZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICh1c2VyTWVzc2FnZUNvcHkpPVwidXNlck1lc3NhZ2VDb3B5LmVtaXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICh1c2VyTWVzc2FnZUVkaXQpPVwidXNlck1lc3NhZ2VFZGl0LmVtaXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8L2NvcGlsb3QtY2hhdC1tZXNzYWdlLXZpZXc+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIFNjcm9sbCB0byBib3R0b20gYnV0dG9uIC0gaGlkZGVuIGR1cmluZyByZXNpemUsIE9VVFNJREUgc2Nyb2xsYWJsZSBjb250ZW50IC0tPlxuICAgICAgICBAaWYgKCFpc0F0Qm90dG9tKCkgJiYgIWlzUmVzaXppbmcoKSkge1xuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIGNsYXNzPVwiYWJzb2x1dGUgaW5zZXQteC0wIGZsZXgganVzdGlmeS1jZW50ZXIgei0zMFwiXG4gICAgICAgICAgICBbc3R5bGUuYm90dG9tLnB4XT1cImlucHV0Q29udGFpbmVySGVpZ2h0KCkgKyAxNlwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGNvcGlsb3Qtc2xvdFxuICAgICAgICAgICAgICBbc2xvdF09XCJzY3JvbGxUb0JvdHRvbUJ1dHRvbigpXCJcbiAgICAgICAgICAgICAgW2NvbnRleHRdPVwic2Nyb2xsVG9Cb3R0b21Gcm9tU3RpY2tDb250ZXh0KClcIlxuICAgICAgICAgICAgICBbZGVmYXVsdENvbXBvbmVudF09XCJkZWZhdWx0U2Nyb2xsVG9Cb3R0b21CdXR0b25Db21wb25lbnRcIlxuICAgICAgICAgICAgICBbb3V0cHV0c109XCJzY3JvbGxUb0JvdHRvbUZyb21TdGlja091dHB1dHNcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9jb3BpbG90LXNsb3Q+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgIH1cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgQ29waWxvdENoYXRWaWV3U2Nyb2xsVmlld1xuICBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95XG57XG4gIHByaXZhdGUgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblxuICBhdXRvU2Nyb2xsID0gaW5wdXQ8Ym9vbGVhbj4odHJ1ZSk7XG5cbiAgaW5wdXRDb250YWluZXJIZWlnaHQgPSBpbnB1dDxudW1iZXI+KDApO1xuXG4gIGlzUmVzaXppbmcgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XG4gIGlucHV0Q2xhc3MgPSBpbnB1dDxzdHJpbmcgfCB1bmRlZmluZWQ+KCk7XG4gIG1lc3NhZ2VzID0gaW5wdXQ8TWVzc2FnZVtdPihbXSk7XG4gIG1lc3NhZ2VWaWV3ID0gaW5wdXQ8YW55IHwgdW5kZWZpbmVkPigpO1xuICBtZXNzYWdlVmlld0NsYXNzID0gaW5wdXQ8c3RyaW5nIHwgdW5kZWZpbmVkPigpO1xuICBzaG93Q3Vyc29yID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xuXG4gIC8vIEhhbmRsZXIgYXZhaWxhYmlsaXR5IGZsYWdzIHJlbW92ZWQgaW4gZmF2b3Igb2YgREkgc2VydmljZVxuXG4gIC8vIFNsb3QgaW5wdXRzXG4gIHNjcm9sbFRvQm90dG9tQnV0dG9uID0gaW5wdXQ8YW55IHwgdW5kZWZpbmVkPigpO1xuICBzY3JvbGxUb0JvdHRvbUJ1dHRvbkNsYXNzID0gaW5wdXQ8c3RyaW5nIHwgdW5kZWZpbmVkPigpO1xuXG4gIC8vIE91dHB1dCBldmVudHMgKGJ1YmJsZWQgZnJvbSBtZXNzYWdlIHZpZXcpXG4gIGFzc2lzdGFudE1lc3NhZ2VUaHVtYnNVcCA9IG91dHB1dDx7IG1lc3NhZ2U6IE1lc3NhZ2UgfT4oKTtcbiAgYXNzaXN0YW50TWVzc2FnZVRodW1ic0Rvd24gPSBvdXRwdXQ8eyBtZXNzYWdlOiBNZXNzYWdlIH0+KCk7XG4gIGFzc2lzdGFudE1lc3NhZ2VSZWFkQWxvdWQgPSBvdXRwdXQ8eyBtZXNzYWdlOiBNZXNzYWdlIH0+KCk7XG4gIGFzc2lzdGFudE1lc3NhZ2VSZWdlbmVyYXRlID0gb3V0cHV0PHsgbWVzc2FnZTogTWVzc2FnZSB9PigpO1xuICB1c2VyTWVzc2FnZUNvcHkgPSBvdXRwdXQ8eyBtZXNzYWdlOiBNZXNzYWdlIH0+KCk7XG4gIHVzZXJNZXNzYWdlRWRpdCA9IG91dHB1dDx7IG1lc3NhZ2U6IE1lc3NhZ2UgfT4oKTtcblxuICAvLyBWaWV3Q2hpbGQgcmVmZXJlbmNlc1xuICBAVmlld0NoaWxkKFwic2Nyb2xsQ29udGFpbmVyXCIsIHsgcmVhZDogRWxlbWVudFJlZiB9KVxuICBzY3JvbGxDb250YWluZXI/OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcbiAgQFZpZXdDaGlsZChcImNvbnRlbnRDb250YWluZXJcIiwgeyByZWFkOiBFbGVtZW50UmVmIH0pXG4gIGNvbnRlbnRDb250YWluZXI/OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcbiAgQFZpZXdDaGlsZChTdGlja1RvQm90dG9tKSBzdGlja1RvQm90dG9tRGlyZWN0aXZlPzogU3RpY2tUb0JvdHRvbTtcblxuICAvLyBEZWZhdWx0IGNvbXBvbmVudHNcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGRlZmF1bHRNZXNzYWdlVmlld0NvbXBvbmVudCA9IENvcGlsb3RDaGF0TWVzc2FnZVZpZXc7XG4gIHByb3RlY3RlZCByZWFkb25seSBkZWZhdWx0U2Nyb2xsVG9Cb3R0b21CdXR0b25Db21wb25lbnQgPVxuICAgIENvcGlsb3RDaGF0Vmlld1Njcm9sbFRvQm90dG9tQnV0dG9uO1xuXG4gIC8vIFNpZ25hbHNcbiAgcHJvdGVjdGVkIGhhc01vdW50ZWQgPSBzaWduYWwoZmFsc2UpO1xuICBwcm90ZWN0ZWQgc2hvd1Njcm9sbEJ1dHRvbiA9IHNpZ25hbChmYWxzZSk7XG4gIHByb3RlY3RlZCBpc0F0Qm90dG9tID0gc2lnbmFsKHRydWUpO1xuICBwcm90ZWN0ZWQgcGFkZGluZ0JvdHRvbSA9IGNvbXB1dGVkKCgpID0+IHRoaXMuaW5wdXRDb250YWluZXJIZWlnaHQoKSArIDMyKTtcblxuICAvLyBDb21wdXRlZCBjbGFzc1xuICBwcm90ZWN0ZWQgY29tcHV0ZWRDbGFzcyA9IGNvbXB1dGVkKCgpID0+IGNuKHRoaXMuaW5wdXRDbGFzcygpKSk7XG5cbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgcGxhdGZvcm1JZCA9IGluamVjdChQTEFURk9STV9JRCk7XG4gIHByaXZhdGUgc2Nyb2xsUG9zaXRpb25TZXJ2aWNlID0gaW5qZWN0KFNjcm9sbFBvc2l0aW9uKTtcblxuICAvLyBObyBtaXJyb3Jpbmcgb2YgaW5wdXRzOyBkZXJpdmUgZGlyZWN0bHkgdmlhIGNvbXB1dGVkKClcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAvLyBDaGVjayBpZiB3ZSdyZSBpbiB0aGUgYnJvd3NlclxuICAgIGlmIChpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICAvLyBTZXQgbW91bnRlZCBhZnRlciBhIHRpY2sgdG8gYWxsb3cgZm9yIGh5ZHJhdGlvblxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuaGFzTW91bnRlZC5zZXQodHJ1ZSk7XG4gICAgICB9LCAwKTtcbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmF1dG9TY3JvbGwoKSkge1xuICAgICAgLy8gV2FpdCBmb3IgdGhlIHZpZXcgdG8gYmUgZnVsbHkgcmVuZGVyZWQgYWZ0ZXIgaGFzTW91bnRlZCBpcyBzZXRcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5zY3JvbGxDb250YWluZXIpIHtcbiAgICAgICAgICAvLyBDaGVjayBpbml0aWFsIHNjcm9sbCBwb3NpdGlvblxuICAgICAgICAgIGNvbnN0IGluaXRpYWxTdGF0ZSA9IHRoaXMuc2Nyb2xsUG9zaXRpb25TZXJ2aWNlLmdldFNjcm9sbFN0YXRlKFxuICAgICAgICAgICAgdGhpcy5zY3JvbGxDb250YWluZXIubmF0aXZlRWxlbWVudCxcbiAgICAgICAgICAgIDEwXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLnNob3dTY3JvbGxCdXR0b24uc2V0KCFpbml0aWFsU3RhdGUuaXNBdEJvdHRvbSk7XG5cbiAgICAgICAgICAvLyBNb25pdG9yIHNjcm9sbCBwb3NpdGlvbiBmb3IgbWFudWFsIG1vZGVcbiAgICAgICAgICB0aGlzLnNjcm9sbFBvc2l0aW9uU2VydmljZVxuICAgICAgICAgICAgLm1vbml0b3JTY3JvbGxQb3NpdGlvbih0aGlzLnNjcm9sbENvbnRhaW5lciwgMTApXG4gICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChzdGF0ZSkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnNob3dTY3JvbGxCdXR0b24uc2V0KCFzdGF0ZS5pc0F0Qm90dG9tKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9LCAxMDApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgaXNBdEJvdHRvbSBjaGFuZ2UgZnJvbSBTdGlja1RvQm90dG9tIGRpcmVjdGl2ZVxuICAgKi9cbiAgb25Jc0F0Qm90dG9tQ2hhbmdlKGlzQXRCb3R0b206IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmlzQXRCb3R0b20uc2V0KGlzQXRCb3R0b20pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNjcm9sbCB0byBib3R0b20gZm9yIG1hbnVhbCBtb2RlXG4gICAqL1xuICBzY3JvbGxUb0JvdHRvbSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zY3JvbGxDb250YWluZXIpIHtcbiAgICAgIHRoaXMuc2Nyb2xsUG9zaXRpb25TZXJ2aWNlLnNjcm9sbFRvQm90dG9tKHRoaXMuc2Nyb2xsQ29udGFpbmVyLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2Nyb2xsIHRvIGJvdHRvbSBmb3Igc3RpY2stdG8tYm90dG9tIG1vZGVcbiAgICovXG4gIHNjcm9sbFRvQm90dG9tRnJvbVN0aWNrKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnN0aWNrVG9Cb3R0b21EaXJlY3RpdmUpIHtcbiAgICAgIHRoaXMuc3RpY2tUb0JvdHRvbURpcmVjdGl2ZS5zY3JvbGxUb0JvdHRvbShcInNtb290aFwiKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICAvLyBPdXRwdXQgbWFwcyBmb3Igc2xvdHNcbiAgc2Nyb2xsVG9Cb3R0b21PdXRwdXRzID0geyBjbGlja2VkOiAoKSA9PiB0aGlzLnNjcm9sbFRvQm90dG9tKCkgfTtcbiAgc2Nyb2xsVG9Cb3R0b21Gcm9tU3RpY2tPdXRwdXRzID0ge1xuICAgIGNsaWNrZWQ6ICgpID0+IHRoaXMuc2Nyb2xsVG9Cb3R0b21Gcm9tU3RpY2soKSxcbiAgfTtcblxuICAvLyBDb250ZXh0IG1ldGhvZHMgZm9yIHRlbXBsYXRlc1xuICBtZXNzYWdlVmlld0NvbnRleHQoKTogYW55IHtcbiAgICByZXR1cm4ge1xuICAgICAgbWVzc2FnZXM6IHRoaXMubWVzc2FnZXMoKSxcbiAgICAgIGlucHV0Q2xhc3M6IHRoaXMubWVzc2FnZVZpZXdDbGFzcygpLFxuICAgICAgc2hvd0N1cnNvcjogdGhpcy5zaG93Q3Vyc29yKCksXG4gICAgfTtcbiAgfVxuXG4gIHNjcm9sbFRvQm90dG9tQ29udGV4dCgpOiBhbnkge1xuICAgIHJldHVybiB7XG4gICAgICBpbnB1dENsYXNzOiB0aGlzLnNjcm9sbFRvQm90dG9tQnV0dG9uQ2xhc3MoKSxcbiAgICAgIG9uQ2xpY2s6ICgpID0+IHRoaXMuc2Nyb2xsVG9Cb3R0b20oKSxcbiAgICB9O1xuICB9XG5cbiAgc2Nyb2xsVG9Cb3R0b21Gcm9tU3RpY2tDb250ZXh0KCk6IGFueSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlucHV0Q2xhc3M6IHRoaXMuc2Nyb2xsVG9Cb3R0b21CdXR0b25DbGFzcygpLFxuICAgICAgb25DbGljazogKCkgPT4gdGhpcy5zY3JvbGxUb0JvdHRvbUZyb21TdGljaygpLFxuICAgIH07XG4gIH1cbn1cbiJdfQ==
|