genassist-chat-react 1.0.40 → 1.0.41
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/README.md +3 -0
- package/dist/components/BubbleDock.d.ts +19 -0
- package/dist/components/BubbleDock.js +129 -0
- package/dist/components/GenAgentChat.js +321 -245
- package/dist/components/GenAgentConfigPanel.d.ts +2 -0
- package/dist/components/GenAgentConfigPanel.js +4 -2
- package/dist/hooks/useViewportManager.d.ts +2 -0
- package/dist/hooks/useViewportManager.js +14 -1
- package/dist/styles/genAgentChatStyles.d.ts +13 -7
- package/dist/styles/genAgentChatStyles.js +127 -43
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -93,12 +93,15 @@ export default App;
|
|
|
93
93
|
| headerTitle | string | No | 'Chat' | Title displayed in the chat header |
|
|
94
94
|
| placeholder | string | No | 'Type a message...' | Placeholder text for the input |
|
|
95
95
|
| description | string | No | 'Support' | A short agent description text below header title |
|
|
96
|
+
| logoUrl | string | No | - | Custom logo URL shown in the header — the small circular logo beside the title |
|
|
97
|
+
| brandLogoUrl | string | No | - | Full brand logo/wordmark URL. When set, the header shows only this image instead of the small logo + title + description |
|
|
96
98
|
| serverUnavailableMessage | string | No | 'The agent is currently offline, please check back later. Thank you!' | Custom message for when agent is offline (Agent is off or server is down) |
|
|
97
99
|
| serverUnavailableContactUrl | string | No | - | Url to redirect user for contact support |
|
|
98
100
|
| serverUnavailableContactLabel | string | No | Contact support | Label for contact support |
|
|
99
101
|
| useWS | boolean | false | true | 'Enable or disable websocket...' |
|
|
100
102
|
| useAudio | boolean | false | false | 'Enable or disable audio on chat input...' |
|
|
101
103
|
| useFile | boolean | false | false | 'Enable or disable file attachments on chat input...' |
|
|
104
|
+
| quickInput | boolean | No | false | Opt-in. In floating mode, shows a quick-message input beside the launcher bubble during an ongoing conversation while the chat panel is closed |
|
|
102
105
|
| reCaptchaKey | string | false | undefined | 'Use google reCaptchaV3 site-key...' |
|
|
103
106
|
| mode | string | true | flotaing | 'Chat mode, floating or fullscreen' |
|
|
104
107
|
| allowedExtensions | string[] | false | undefined | 'Look for type AllowedExtension and see the supported list of extensions' |
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface BubbleDockProps {
|
|
3
|
+
primaryColor: string;
|
|
4
|
+
position: string;
|
|
5
|
+
offsetX: number;
|
|
6
|
+
offsetY: number;
|
|
7
|
+
windowWidth: number;
|
|
8
|
+
placeholder: string;
|
|
9
|
+
fontFamily: string;
|
|
10
|
+
fontSize: string;
|
|
11
|
+
chatBubbleIcon?: 'message' | 'sparkles' | 'x';
|
|
12
|
+
/** When false, only the launcher bubble is rendered (quick input hidden/dismissed). */
|
|
13
|
+
showQuickInput: boolean;
|
|
14
|
+
onOpen: () => void;
|
|
15
|
+
onSend: (text: string) => void;
|
|
16
|
+
onDismissQuickInput: () => void;
|
|
17
|
+
}
|
|
18
|
+
export declare const BubbleDock: React.FC<BubbleDockProps>;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
13
|
+
import { useRef, useState } from 'react';
|
|
14
|
+
import { ArrowUp, X } from 'lucide-react';
|
|
15
|
+
import { ChatBubble } from './ChatBubble';
|
|
16
|
+
var BUBBLE = 60;
|
|
17
|
+
var GAP = 12;
|
|
18
|
+
var INPUT_H = 52;
|
|
19
|
+
var DEFAULT_W = 240;
|
|
20
|
+
export var BubbleDock = function (_a) {
|
|
21
|
+
var _b, _c;
|
|
22
|
+
var primaryColor = _a.primaryColor, position = _a.position, offsetX = _a.offsetX, offsetY = _a.offsetY, windowWidth = _a.windowWidth, placeholder = _a.placeholder, fontFamily = _a.fontFamily, fontSize = _a.fontSize, chatBubbleIcon = _a.chatBubbleIcon, showQuickInput = _a.showQuickInput, onOpen = _a.onOpen, onSend = _a.onSend, onDismissQuickInput = _a.onDismissQuickInput;
|
|
23
|
+
var _d = useState(''), value = _d[0], setValue = _d[1];
|
|
24
|
+
var _e = useState(false), focused = _e[0], setFocused = _e[1];
|
|
25
|
+
var inputRef = useRef(null);
|
|
26
|
+
var isLeft = position.endsWith('left');
|
|
27
|
+
var isTop = position.startsWith('top');
|
|
28
|
+
var hSide = isLeft ? 'left' : 'right';
|
|
29
|
+
var vSide = isTop ? 'top' : 'bottom';
|
|
30
|
+
// Touch/mobile has no hover, so keep the remove (X) affordance always visible there.
|
|
31
|
+
var isMobile = windowWidth <= 768;
|
|
32
|
+
// Keep everything within the viewport on narrow screens.
|
|
33
|
+
var maxDockW = Math.max(160, windowWidth - offsetX * 2);
|
|
34
|
+
var collapsedW = Math.min(DEFAULT_W, maxDockW - BUBBLE - GAP);
|
|
35
|
+
var coverW = Math.min(collapsedW + BUBBLE + GAP, maxDockW);
|
|
36
|
+
var hasText = value.trim().length > 0;
|
|
37
|
+
var positionStyle = function () { return ({
|
|
38
|
+
position: 'fixed',
|
|
39
|
+
top: isTop ? offsetY : 'auto',
|
|
40
|
+
bottom: isTop ? 'auto' : offsetY,
|
|
41
|
+
left: isLeft ? offsetX : 'auto',
|
|
42
|
+
right: isLeft ? 'auto' : offsetX,
|
|
43
|
+
}); };
|
|
44
|
+
var submit = function () {
|
|
45
|
+
var _a;
|
|
46
|
+
var text = value.trim();
|
|
47
|
+
if (!text)
|
|
48
|
+
return;
|
|
49
|
+
onSend(text);
|
|
50
|
+
setValue('');
|
|
51
|
+
setFocused(false);
|
|
52
|
+
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
53
|
+
};
|
|
54
|
+
var bubbleStyle = __assign(__assign({}, positionStyle()), { opacity: focused ? 0 : 1, transform: focused ? 'scale(0.85)' : 'scale(1)', pointerEvents: focused ? 'none' : 'auto', transition: 'opacity 200ms ease, transform 200ms ease',
|
|
55
|
+
// `backwards` (not `both`) so the entrance doesn't pin opacity at 1 and block the focus fade-out.
|
|
56
|
+
animation: 'ga-bubble-in 220ms cubic-bezier(0.16, 1, 0.3, 1) backwards' });
|
|
57
|
+
// Pill anchors to the bubble's corner; the outer edge stays fixed while it grows over the bubble on focus.
|
|
58
|
+
var pillStyle = (_b = {
|
|
59
|
+
position: 'fixed'
|
|
60
|
+
},
|
|
61
|
+
_b[vSide] = offsetY + (BUBBLE - INPUT_H) / 2,
|
|
62
|
+
_b[hSide] = focused ? offsetX : offsetX + BUBBLE + GAP,
|
|
63
|
+
_b.width = focused ? coverW : collapsedW,
|
|
64
|
+
_b.height = INPUT_H,
|
|
65
|
+
_b.zIndex = 50,
|
|
66
|
+
_b.display = 'flex',
|
|
67
|
+
_b.alignItems = 'center',
|
|
68
|
+
_b.boxSizing = 'border-box',
|
|
69
|
+
_b.background = '#ffffff',
|
|
70
|
+
_b.border = focused ? '1.5px solid #111111' : '1px solid #e5e7eb',
|
|
71
|
+
_b.borderRadius = 999,
|
|
72
|
+
_b.padding = '0 6px',
|
|
73
|
+
_b.boxShadow = focused ? '0 8px 24px rgba(0, 0, 0, 0.16)' : '0 2px 10px rgba(0, 0, 0, 0.10)',
|
|
74
|
+
_b.transition = 'right 300ms cubic-bezier(0.16, 1, 0.3, 1), left 300ms cubic-bezier(0.16, 1, 0.3, 1), width 300ms cubic-bezier(0.16, 1, 0.3, 1), border-color 200ms ease, box-shadow 200ms ease',
|
|
75
|
+
_b.animation = 'ga-quickinput-in 320ms cubic-bezier(0.16, 1, 0.3, 1) 200ms both',
|
|
76
|
+
_b);
|
|
77
|
+
var dismissStyle = (_c = {
|
|
78
|
+
position: 'absolute',
|
|
79
|
+
top: -8
|
|
80
|
+
},
|
|
81
|
+
_c[isLeft ? 'right' : 'left'] = 10,
|
|
82
|
+
_c.width = 22,
|
|
83
|
+
_c.height = 22,
|
|
84
|
+
_c.borderRadius = '50%',
|
|
85
|
+
_c.background = '#111111',
|
|
86
|
+
_c.color = '#ffffff',
|
|
87
|
+
_c.border = '2px solid #ffffff',
|
|
88
|
+
_c.display = 'flex',
|
|
89
|
+
_c.alignItems = 'center',
|
|
90
|
+
_c.justifyContent = 'center',
|
|
91
|
+
_c.cursor = 'pointer',
|
|
92
|
+
_c.padding = 0,
|
|
93
|
+
_c.zIndex = 51,
|
|
94
|
+
_c);
|
|
95
|
+
var sendStyle = {
|
|
96
|
+
width: 38,
|
|
97
|
+
height: 38,
|
|
98
|
+
borderRadius: '50%',
|
|
99
|
+
flexShrink: 0,
|
|
100
|
+
border: 'none',
|
|
101
|
+
display: 'flex',
|
|
102
|
+
alignItems: 'center',
|
|
103
|
+
justifyContent: 'center',
|
|
104
|
+
cursor: hasText ? 'pointer' : 'default',
|
|
105
|
+
background: hasText ? primaryColor : '#eef0f2',
|
|
106
|
+
transition: 'background-color 180ms ease',
|
|
107
|
+
marginLeft: 6,
|
|
108
|
+
};
|
|
109
|
+
return (_jsxs(_Fragment, { children: [_jsx(ChatBubble, { showChat: false, onClick: onOpen, primaryColor: primaryColor, style: bubbleStyle, chatBubbleIcon: chatBubbleIcon }), showQuickInput && (_jsxs("div", { className: "ga-quick", style: pillStyle, children: [_jsx("button", { type: "button", className: "ga-quick-x", style: isMobile ? __assign(__assign({}, dismissStyle), { opacity: 1, transform: 'scale(1)', pointerEvents: 'auto' }) : dismissStyle, title: "Remove", "aria-label": "Remove quick message", onClick: function (e) {
|
|
110
|
+
e.stopPropagation();
|
|
111
|
+
onDismissQuickInput();
|
|
112
|
+
}, children: _jsx(X, { size: 12, strokeWidth: 3 }) }), _jsx("input", { ref: inputRef, type: "text", value: value, placeholder: placeholder, onChange: function (e) { return setValue(e.target.value); }, onFocus: function () { return setFocused(true); }, onBlur: function () { return setFocused(false); }, onKeyDown: function (e) {
|
|
113
|
+
if (e.key === 'Enter') {
|
|
114
|
+
e.preventDefault();
|
|
115
|
+
submit();
|
|
116
|
+
}
|
|
117
|
+
}, style: {
|
|
118
|
+
flex: 1,
|
|
119
|
+
minWidth: 0,
|
|
120
|
+
border: 'none',
|
|
121
|
+
outline: 'none',
|
|
122
|
+
background: 'transparent',
|
|
123
|
+
fontSize: fontSize,
|
|
124
|
+
fontFamily: fontFamily,
|
|
125
|
+
color: '#111111',
|
|
126
|
+
padding: '0 6px 0 12px',
|
|
127
|
+
} }), _jsx("button", { type: "button", style: sendStyle, title: "Send", "aria-label": "Send message", disabled: !hasText, onMouseDown: function (e) { return e.preventDefault(); }, onClick: submit, children: _jsx(ArrowUp, { size: 18, strokeWidth: 3, color: hasText ? '#ffffff' : '#9aa0aa' }) })] }))] }));
|
|
128
|
+
};
|
|
129
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQnViYmxlRG9jay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21wb25lbnRzL0J1YmJsZURvY2sudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLE9BQWMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBQ2hELE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFtQjFDLElBQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQztBQUNsQixJQUFNLEdBQUcsR0FBRyxFQUFFLENBQUM7QUFDZixJQUFNLE9BQU8sR0FBRyxFQUFFLENBQUM7QUFDbkIsSUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDO0FBRXRCLE1BQU0sQ0FBQyxJQUFNLFVBQVUsR0FBOEIsVUFBQyxFQWNyRDs7UUFiQyxZQUFZLGtCQUFBLEVBQ1osUUFBUSxjQUFBLEVBQ1IsT0FBTyxhQUFBLEVBQ1AsT0FBTyxhQUFBLEVBQ1AsV0FBVyxpQkFBQSxFQUNYLFdBQVcsaUJBQUEsRUFDWCxVQUFVLGdCQUFBLEVBQ1YsUUFBUSxjQUFBLEVBQ1IsY0FBYyxvQkFBQSxFQUNkLGNBQWMsb0JBQUEsRUFDZCxNQUFNLFlBQUEsRUFDTixNQUFNLFlBQUEsRUFDTixtQkFBbUIseUJBQUE7SUFFYixJQUFBLEtBQW9CLFFBQVEsQ0FBQyxFQUFFLENBQUMsRUFBL0IsS0FBSyxRQUFBLEVBQUUsUUFBUSxRQUFnQixDQUFDO0lBQ2pDLElBQUEsS0FBd0IsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUF0QyxPQUFPLFFBQUEsRUFBRSxVQUFVLFFBQW1CLENBQUM7SUFDOUMsSUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFtQixJQUFJLENBQUMsQ0FBQztJQUVoRCxJQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFD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RUFBaEIsQ0FBZ0IsRUFDL0IsTUFBTSxFQUFFLGNBQU0sT0FBQSxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQWpCLENBQWlCLEVBQy9CLFNBQVMsRUFBRSxVQUFDLENBQUM7NEJBQ1gsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLE9BQU8sRUFBRSxDQUFDO2dDQUN0QixDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7Z0NBQ25CLE1BQU0sRUFBRSxDQUFDOzRCQUNYLENBQUM7d0JBQ0gsQ0FBQyxFQUNELEtBQUssRUFBRTs0QkFDTCxJQUFJLEVBQUUsQ0FBQzs0QkFDUCxRQUFRLEVBQUUsQ0FBQzs0QkFDWCxNQUFNLEVBQUUsTUFBTTs0QkFDZCxPQUFPLEVBQUUsTUFBTTs0QkFDZixVQUFVLEVBQUUsYUFBYTs0QkFDekIsUUFBUSxVQUFBOzRCQUNSLFVBQVUsWUFBQTs0QkFDVixLQUFLLEVBQUUsU0FBUzs0QkFDaEIsT0FBTyxFQUFFLGNBQWM7eUJBQ3hCLEdBQ0QsRUFFRixpQkFDRSxJQUFJLEVBQUMsUUFBUSxFQUNiLEtBQUssRUFBRSxTQUFTLEVBQ2hCLEtBQUssRUFBQyxNQUFNLGdCQUNELGNBQWMsRUFDekIsUUFBUSxFQUFFLENBQUMsT0FBTyxFQUNsQixXQUFXLEVBQUUsVUFBQyxDQUFDLElBQUssT0FBQSxDQUFDLENBQUMsY0FBYyxFQUFFLEVBQWxCLENBQWtCLEVBQ3RDLE9BQU8sRUFBRSxNQUFNLFlBRWYsS0FBQyxPQUFPLElBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFJLEdBQ3RFLElBQ0wsQ0FDUCxJQUNBLENBQ0osQ0FBQztBQUNKLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBSZWFjdCwgeyB1c2VSZWYsIHVzZVN0YXRlIH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgQXJyb3dVcCwgWCB9IGZyb20gJ2x1Y2lkZS1yZWFjdCc7XG5pbXBvcnQgeyBDaGF0QnViYmxlIH0gZnJvbSAnLi9DaGF0QnViYmxlJztcblxuaW50ZXJmYWNlIEJ1YmJsZURvY2tQcm9wcyB7XG4gIHByaW1hcnlDb2xvcjogc3RyaW5nO1xuICBwb3NpdGlvbjogc3RyaW5nO1xuICBvZmZzZXRYOiBudW1iZXI7XG4gIG9mZnNldFk6IG51bWJlcjtcbiAgd2luZG93V2lkdGg6IG51bWJlcjtcbiAgcGxhY2Vob2xkZXI6IHN0cmluZztcbiAgZm9udEZhbWlseTogc3RyaW5nO1xuICBmb250U2l6ZTogc3RyaW5nO1xuICBjaGF0QnViYmxlSWNvbj86ICdtZXNzYWdlJyB8ICdzcGFya2xlcycgfCAneCc7XG4gIC8qKiBXaGVuIGZhbHNlLCBvbmx5IHRoZSBsYXVuY2hlciBidWJibGUgaXMgcmVuZGVyZWQgKHF1aWNrIGlucHV0IGhpZGRlbi9kaXNtaXNzZWQpLiAqL1xuICBzaG93UXVpY2tJbnB1dDogYm9vbGVhbjtcbiAgb25PcGVuOiAoKSA9PiB2b2lkO1xuICBvblNlbmQ6ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQ7XG4gIG9uRGlzbWlzc1F1aWNrSW5wdXQ6ICgpID0+IHZvaWQ7XG59XG5cbmNvbnN0IEJVQkJMRSA9IDYwO1xuY29uc3QgR0FQID0gMTI7XG5jb25zdCBJTlBVVF9IID0gNTI7XG5jb25zdCBERUZBVUxUX1cgPSAyNDA7XG5cbmV4cG9ydCBjb25zdCBCdWJibGVEb2NrOiBSZWFjdC5GQzxCdWJibGVEb2NrUHJvcHM+ID0gKHtcbiAgcHJpbWFyeUNvbG9yLFxuICBwb3NpdGlvbixcbiAgb2Zmc2V0WCxcbiAgb2Zmc2V0WSxcbiAgd2luZG93V2lkdGgsXG4gIHBsYWNlaG9sZGVyLFxuICBmb250RmFtaWx5LFxuICBmb250U2l6ZSxcbiAgY2hhdEJ1YmJsZUljb24sXG4gIHNob3dRdWlja0lucHV0LFxuICBvbk9wZW4sXG4gIG9uU2VuZCxcbiAgb25EaXNtaXNzUXVpY2tJbnB1dCxcbn0pID0+IHtcbiAgY29uc3QgW3ZhbHVlLCBzZXRWYWx1ZV0gPSB1c2VTdGF0ZSgnJyk7XG4gIGNvbnN0IFtmb2N1c2VkLCBzZXRGb2N1c2VkXSA9IHVzZVN0YXRlKGZhbHNlKTtcbiAgY29uc3QgaW5wdXRSZWYgPSB1c2VSZWY8SFRNTElucHV0RWxlbWVudD4obnVsbCk7XG5cbiAgY29uc3QgaXNMZWZ0ID0gcG9zaXRpb24uZW5kc1dpdGgoJ2xlZnQnKTtcbiAgY29uc3QgaXNUb3AgPSBwb3NpdGlvbi5zdGFydHNXaXRoKCd0b3AnKTtcbiAgY29uc3QgaFNpZGUgPSBpc0xlZnQgPyAnbGVmdCcgOiAncmlnaHQnO1xuICBjb25zdCB2U2lkZSA9IGlzVG9wID8gJ3RvcCcgOiAnYm90dG9tJztcbiAgLy8gVG91Y2gvbW9iaWxlIGhhcyBubyBob3Zlciwgc28ga2VlcCB0aGUgcmVtb3ZlIChYKSBhZmZvcmRhbmNlIGFsd2F5cyB2aXNpYmxlIHRoZXJlLlxuICBjb25zdCBpc01vYmlsZSA9IHdpbmRvd1dpZHRoIDw9IDc2ODtcblxuICAvLyBLZWVwIGV2ZXJ5dGhpbmcgd2l0aGluIHRoZSB2aWV3cG9ydCBvbiBuYXJyb3cgc2NyZWVucy5cbiAgY29uc3QgbWF4RG9ja1cgPSBNYXRoLm1heCgxNjAsIHdpbmRvd1dpZHRoIC0gb2Zmc2V0WCAqIDIpO1xuICBjb25zdCBjb2xsYXBzZWRXID0gTWF0aC5taW4oREVGQVVMVF9XLCBtYXhEb2NrVyAtIEJVQkJMRSAtIEdBUCk7XG4gIGNvbnN0IGNvdmVyVyA9IE1hdGgubWluKGNvbGxhcHNlZFcgKyBCVUJCTEUgKyBHQVAsIG1heERvY2tXKTtcbiAgY29uc3QgaGFzVGV4dCA9IHZhbHVlLnRyaW0oKS5sZW5ndGggPiAwO1xuXG4gIGNvbnN0IHBvc2l0aW9uU3R5bGUgPSAoKTogUmVhY3QuQ1NTUHJvcGVydGllcyA9PiAoe1xuICAgIHBvc2l0aW9uOiAnZml4ZWQnLFxuICAgIHRvcDogaXNUb3AgPyBvZmZzZXRZIDogJ2F1dG8nLFxuICAgIGJvdHRvbTogaXNUb3AgPyAnYXV0bycgOiBvZmZzZXRZLFxuICAgIGxlZnQ6IGlzTGVmdCA/IG9mZnNldFggOiAnYXV0bycsXG4gICAgcmlnaHQ6IGlzTGVmdCA/ICdhdXRvJyA6IG9mZnNldFgsXG4gIH0pO1xuXG4gIGNvbnN0IHN1Ym1pdCA9ICgpID0+IHtcbiAgICBjb25zdCB0ZXh0ID0gdmFsdWUudHJpbSgpO1xuICAgIGlmICghdGV4dCkgcmV0dXJuO1xuICAgIG9uU2VuZCh0ZXh0KTtcbiAgICBzZXRWYWx1ZSgnJyk7XG4gICAgc2V0Rm9jdXNlZChmYWxzZSk7XG4gICAgaW5wdXRSZWYuY3VycmVudD8uYmx1cigpO1xuICB9O1xuXG4gIGNvbnN0IGJ1YmJsZVN0eWxlOiBSZWFjdC5DU1NQcm9wZXJ0aWVzID0ge1xuICAgIC4uLnBvc2l0aW9uU3R5bGUoKSxcbiAgICBvcGFjaXR5OiBmb2N1c2VkID8gMCA6IDEsXG4gICAgdHJhbnNmb3JtOiBmb2N1c2VkID8gJ3NjYWxlKDAuODUpJyA6ICdzY2FsZSgxKScsXG4gICAgcG9pbnRlckV2ZW50czogZm9jdXNlZCA/ICdub25lJyA6ICdhdXRvJyxcbiAgICB0cmFuc2l0aW9uOiAnb3BhY2l0eSAyMDBtcyBlYXNlLCB0cmFuc2Zvcm0gMjAwbXMgZWFzZScsXG4gICAgLy8gYGJhY2t3YXJkc2AgKG5vdCBgYm90aGApIHNvIHRoZSBlbnRyYW5jZSBkb2Vzbid0IHBpbiBvcGFjaXR5IGF0IDEgYW5kIGJsb2NrIHRoZSBmb2N1cyBmYWRlLW91dC5cbiAgICBhbmltYXRpb246ICdnYS1idWJibGUtaW4gMjIwbXMgY3ViaWMtYmV6aWVyKDAuMTYsIDEsIDAuMywgMSkgYmFja3dhcmRzJyxcbiAgfTtcblxuICAvLyBQaWxsIGFuY2hvcnMgdG8gdGhlIGJ1YmJsZSdzIGNvcm5lcjsgdGhlIG91dGVyIGVkZ2Ugc3RheXMgZml4ZWQgd2hpbGUgaXQgZ3Jvd3Mgb3ZlciB0aGUgYnViYmxlIG9uIGZvY3VzLlxuICBjb25zdCBwaWxsU3R5bGU6IFJlYWN0LkNTU1Byb3BlcnRpZXMgPSB7XG4gICAgcG9zaXRpb246ICdmaXhlZCcsXG4gICAgW3ZTaWRlXTogb2Zmc2V0WSArIChCVUJCTEUgLSBJTlBVVF9IKSAvIDIsXG4gICAgW2hTaWRlXTogZm9jdXNlZCA/IG9mZnNldFggOiBvZmZzZXRYICsgQlVCQkxFICsgR0FQLFxuICAgIHdpZHRoOiBmb2N1c2VkID8gY292ZXJXIDogY29sbGFwc2VkVyxcbiAgICBoZWlnaHQ6IElOUFVUX0gsXG4gICAgekluZGV4OiA1MCxcbiAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgYWxpZ25JdGVtczogJ2NlbnRlcicsXG4gICAgYm94U2l6aW5nOiAnYm9yZGVyLWJveCcsXG4gICAgYmFja2dyb3VuZDogJyNmZmZmZmYnLFxuICAgIGJvcmRlcjogZm9jdXNlZCA/ICcxLjVweCBzb2xpZCAjMTExMTExJyA6ICcxcHggc29saWQgI2U1ZTdlYicsXG4gICAgYm9yZGVyUmFkaXVzOiA5OTksXG4gICAgcGFkZGluZzogJzAgNnB4JyxcbiAgICBib3hTaGFkb3c6IGZvY3VzZWQgPyAnMCA4cHggMjRweCByZ2JhKDAsIDAsIDAsIDAuMTYpJyA6ICcwIDJweCAxMHB4IHJnYmEoMCwgMCwgMCwgMC4xMCknLFxuICAgIHRyYW5zaXRpb246XG4gICAgICAncmlnaHQgMzAwbXMgY3ViaWMtYmV6aWVyKDAuMTYsIDEsIDAuMywgMSksIGxlZnQgMzAwbXMgY3ViaWMtYmV6aWVyKDAuMTYsIDEsIDAuMywgMSksIHdpZHRoIDMwMG1zIGN1YmljLWJlemllcigwLjE2LCAxLCAwLjMsIDEpLCBib3JkZXItY29sb3IgMjAwbXMgZWFzZSwgYm94LXNoYWRvdyAyMDBtcyBlYXNlJyxcbiAgICBhbmltYXRpb246ICdnYS1xdWlja2lucHV0LWluIDMyMG1zIGN1YmljLWJlemllcigwLjE2LCAxLCAwLjMsIDEpIDIwMG1zIGJvdGgnLFxuICB9O1xuXG4gIGNvbnN0IGRpc21pc3NTdHlsZTogUmVhY3QuQ1NTUHJvcGVydGllcyA9IHtcbiAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICB0b3A6IC04LFxuICAgIFtpc0xlZnQgPyAncmlnaHQnIDogJ2xlZnQnXTogMTAsXG4gICAgd2lkdGg6IDIyLFxuICAgIGhlaWdodDogMjIsXG4gICAgYm9yZGVyUmFkaXVzOiAnNTAlJyxcbiAgICBiYWNrZ3JvdW5kOiAnIzExMTExMScsXG4gICAgY29sb3I6ICcjZmZmZmZmJyxcbiAgICBib3JkZXI6ICcycHggc29saWQgI2ZmZmZmZicsXG4gICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgIGFsaWduSXRlbXM6ICdjZW50ZXInLFxuICAgIGp1c3RpZnlDb250ZW50OiAnY2VudGVyJyxcbiAgICBjdXJzb3I6ICdwb2ludGVyJyxcbiAgICBwYWRkaW5nOiAwLFxuICAgIHpJbmRleDogNTEsXG4gIH07XG5cbiAgY29uc3Qgc2VuZFN0eWxlOiBSZWFjdC5DU1NQcm9wZXJ0aWVzID0ge1xuICAgIHdpZHRoOiAzOCxcbiAgICBoZWlnaHQ6IDM4LFxuICAgIGJvcmRlclJhZGl1czogJzUwJScsXG4gICAgZmxleFNocmluazogMCxcbiAgICBib3JkZXI6ICdub25lJyxcbiAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgYWxpZ25JdGVtczogJ2NlbnRlcicsXG4gICAganVzdGlmeUNvbnRlbnQ6ICdjZW50ZXInLFxuICAgIGN1cnNvcjogaGFzVGV4dCA/ICdwb2ludGVyJyA6ICdkZWZhdWx0JyxcbiAgICBiYWNrZ3JvdW5kOiBoYXNUZXh0ID8gcHJpbWFyeUNvbG9yIDogJyNlZWYwZjInLFxuICAgIHRyYW5zaXRpb246ICdiYWNrZ3JvdW5kLWNvbG9yIDE4MG1zIGVhc2UnLFxuICAgIG1hcmdpbkxlZnQ6IDYsXG4gIH07XG5cbiAgcmV0dXJuIChcbiAgICA8PlxuICAgICAgPENoYXRCdWJibGVcbiAgICAgICAgc2hvd0NoYXQ9e2ZhbHNlfVxuICAgICAgICBvbkNsaWNrPXtvbk9wZW59XG4gICAgICAgIHByaW1hcnlDb2xvcj17cHJpbWFyeUNvbG9yfVxuICAgICAgICBzdHlsZT17YnViYmxlU3R5bGV9XG4gICAgICAgIGNoYXRCdWJibGVJY29uPXtjaGF0QnViYmxlSWNvbn1cbiAgICAgIC8+XG5cbiAgICAgIHtzaG93UXVpY2tJbnB1dCAmJiAoXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZ2EtcXVpY2tcIiBzdHlsZT17cGlsbFN0eWxlfT5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzTmFtZT1cImdhLXF1aWNrLXhcIlxuICAgICAgICAgICAgc3R5bGU9e2lzTW9iaWxlID8geyAuLi5kaXNtaXNzU3R5bGUsIG9wYWNpdHk6IDEsIHRyYW5zZm9ybTogJ3NjYWxlKDEpJywgcG9pbnRlckV2ZW50czogJ2F1dG8nIH0gOiBkaXNtaXNzU3R5bGV9XG4gICAgICAgICAgICB0aXRsZT1cIlJlbW92ZVwiXG4gICAgICAgICAgICBhcmlhLWxhYmVsPVwiUmVtb3ZlIHF1aWNrIG1lc3NhZ2VcIlxuICAgICAgICAgICAgb25DbGljaz17KGUpID0+IHtcbiAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgb25EaXNtaXNzUXVpY2tJbnB1dCgpO1xuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICA8WCBzaXplPXsxMn0gc3Ryb2tlV2lkdGg9ezN9IC8+XG4gICAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgIHJlZj17aW5wdXRSZWZ9XG4gICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICB2YWx1ZT17dmFsdWV9XG4gICAgICAgICAgICBwbGFjZWhvbGRlcj17cGxhY2Vob2xkZXJ9XG4gICAgICAgICAgICBvbkNoYW5nZT17KGUpID0+IHNldFZhbHVlKGUudGFyZ2V0LnZhbHVlKX1cbiAgICAgICAgICAgIG9uRm9jdXM9eygpID0+IHNldEZvY3VzZWQodHJ1ZSl9XG4gICAgICAgICAgICBvbkJsdXI9eygpID0+IHNldEZvY3VzZWQoZmFsc2UpfVxuICAgICAgICAgICAgb25LZXlEb3duPXsoZSkgPT4ge1xuICAgICAgICAgICAgICBpZiAoZS5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgc3VibWl0KCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH19XG4gICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICBmbGV4OiAxLFxuICAgICAgICAgICAgICBtaW5XaWR0aDogMCxcbiAgICAgICAgICAgICAgYm9yZGVyOiAnbm9uZScsXG4gICAgICAgICAgICAgIG91dGxpbmU6ICdub25lJyxcbiAgICAgICAgICAgICAgYmFja2dyb3VuZDogJ3RyYW5zcGFyZW50JyxcbiAgICAgICAgICAgICAgZm9udFNpemUsXG4gICAgICAgICAgICAgIGZvbnRGYW1pbHksXG4gICAgICAgICAgICAgIGNvbG9yOiAnIzExMTExMScsXG4gICAgICAgICAgICAgIHBhZGRpbmc6ICcwIDZweCAwIDEycHgnLFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICAvPlxuXG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBzdHlsZT17c2VuZFN0eWxlfVxuICAgICAgICAgICAgdGl0bGU9XCJTZW5kXCJcbiAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJTZW5kIG1lc3NhZ2VcIlxuICAgICAgICAgICAgZGlzYWJsZWQ9eyFoYXNUZXh0fVxuICAgICAgICAgICAgb25Nb3VzZURvd249eyhlKSA9PiBlLnByZXZlbnREZWZhdWx0KCl9XG4gICAgICAgICAgICBvbkNsaWNrPXtzdWJtaXR9XG4gICAgICAgICAgPlxuICAgICAgICAgICAgPEFycm93VXAgc2l6ZT17MTh9IHN0cm9rZVdpZHRoPXszfSBjb2xvcj17aGFzVGV4dCA/ICcjZmZmZmZmJyA6ICcjOWFhMGFhJ30gLz5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICApfVxuICAgIDwvPlxuICApO1xufTtcbiJdfQ==
|