@hanzo/browser-extension 1.7.6 → 1.9.33
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/LICENSE +9 -18
- package/dist/browser-extension/content-script.js +1642 -123
- package/images/icon128.png +0 -0
- package/images/icon16.png +0 -0
- package/images/icon48.png +0 -0
- package/manifest.json +7 -2
- package/package.json +28 -10
- package/src/answer/AnswerEngine.tsx +553 -0
- package/src/chat-widget.tsx +96 -0
- package/src/gui-primitives.tsx +116 -0
- package/src/icon128.png +0 -0
- package/src/icon16.png +0 -0
- package/src/icon32.png +0 -0
- package/src/icon48.png +0 -0
- package/src/manifest-firefox.json +32 -13
- package/src/manifest.json +35 -11
- package/src/newtab.css +277 -0
- package/src/newtab.html +13 -0
- package/src/package.json +1 -1
- package/src/popup.css +352 -110
- package/src/popup.html +186 -47
- package/src/popup.js +196 -0
- package/src/sidebar.css +772 -156
- package/src/sidebar.html +268 -85
- package/src/sidebar.js +885 -0
- package/.github/workflows/docs.yml +0 -44
- package/.github/workflows/release.yml +0 -55
- package/README.md +0 -126
- package/dist/browser-extension/README.md +0 -43
- package/dist/browser-extension/ai-worker.js +0 -30
- package/dist/browser-extension/background-firefox.js +0 -875
- package/dist/browser-extension/background.js +0 -2732
- package/dist/browser-extension/browser-control.js +0 -683
- package/dist/browser-extension/cdp-bridge-server.js +0 -444
- package/dist/browser-extension/chrome/ai-worker.js +0 -571
- package/dist/browser-extension/chrome/background.js +0 -2732
- package/dist/browser-extension/chrome/callback.html +0 -17
- package/dist/browser-extension/chrome/content-script.js +0 -1270
- package/dist/browser-extension/chrome/icon128.png +0 -0
- package/dist/browser-extension/chrome/icon16.png +0 -0
- package/dist/browser-extension/chrome/icon32.png +0 -0
- package/dist/browser-extension/chrome/icon48.png +0 -0
- package/dist/browser-extension/chrome/manifest.json +0 -57
- package/dist/browser-extension/chrome/popup.css +0 -519
- package/dist/browser-extension/chrome/popup.html +0 -242
- package/dist/browser-extension/chrome/popup.js +0 -278
- package/dist/browser-extension/chrome/sidebar.css +0 -1176
- package/dist/browser-extension/chrome/sidebar.html +0 -280
- package/dist/browser-extension/chrome/sidebar.js +0 -779
- package/dist/browser-extension/cli.js +0 -233
- package/dist/browser-extension/firefox/ai-worker.js +0 -571
- package/dist/browser-extension/firefox/background.js +0 -875
- package/dist/browser-extension/firefox/callback.html +0 -17
- package/dist/browser-extension/firefox/content-script.js +0 -1270
- package/dist/browser-extension/firefox/icon128.png +0 -0
- package/dist/browser-extension/firefox/icon16.png +0 -0
- package/dist/browser-extension/firefox/icon32.png +0 -0
- package/dist/browser-extension/firefox/icon48.png +0 -0
- package/dist/browser-extension/firefox/manifest.json +0 -66
- package/dist/browser-extension/firefox/popup.css +0 -519
- package/dist/browser-extension/firefox/popup.html +0 -242
- package/dist/browser-extension/firefox/popup.js +0 -278
- package/dist/browser-extension/firefox/sidebar.css +0 -1176
- package/dist/browser-extension/firefox/sidebar.html +0 -280
- package/dist/browser-extension/firefox/sidebar.js +0 -779
- package/dist/browser-extension/hanzo-browser-extension-firefox-1.1.0.zip +0 -0
- package/dist/browser-extension/icon128.png +0 -0
- package/dist/browser-extension/icon16.png +0 -0
- package/dist/browser-extension/icon32.png +0 -0
- package/dist/browser-extension/icon48.png +0 -0
- package/dist/browser-extension/manifest.json +0 -57
- package/dist/browser-extension/package.json +0 -41
- package/dist/browser-extension/popup.css +0 -468
- package/dist/browser-extension/popup.html +0 -191
- package/dist/browser-extension/popup.js +0 -278
- package/dist/browser-extension/safari/Info.plist +0 -21
- package/dist/browser-extension/safari/ai-worker.js +0 -571
- package/dist/browser-extension/safari/background.js +0 -2732
- package/dist/browser-extension/safari/callback.html +0 -17
- package/dist/browser-extension/safari/content-script.js +0 -1270
- package/dist/browser-extension/safari/icon128.png +0 -0
- package/dist/browser-extension/safari/icon16.png +0 -0
- package/dist/browser-extension/safari/icon32.png +0 -0
- package/dist/browser-extension/safari/icon48.png +0 -0
- package/dist/browser-extension/safari/popup.css +0 -519
- package/dist/browser-extension/safari/popup.html +0 -242
- package/dist/browser-extension/safari/popup.js +0 -278
- package/dist/browser-extension/safari/sidebar.css +0 -1176
- package/dist/browser-extension/safari/sidebar.html +0 -280
- package/dist/browser-extension/safari/sidebar.js +0 -779
- package/dist/browser-extension/sidebar.css +0 -718
- package/dist/browser-extension/sidebar.html +0 -184
- package/dist/browser-extension/sidebar.js +0 -779
- package/dist/browser-extension/webgpu-ai.js +0 -495
- package/dist/cdp-bridge-server.js +0 -411
- package/dist/hanzo-ai-chrome-1.7.2.zip +0 -0
- package/dist/hanzo-ai-chrome-1.7.3.zip +0 -0
- package/dist/hanzo-ai-firefox-1.7.2.zip +0 -0
- package/dist/hanzo-ai-firefox-1.7.3.zip +0 -0
- package/dist/safari/Hanzo AI/Hanzo AI.xcodeproj/project.pbxproj +0 -1047
- package/dist/safari/Hanzo AI/Hanzo AI.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AccentColor.colorset/Contents.json +0 -11
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -98
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-128@1x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-128@2x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-16@1x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-16@2x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-256@1x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-256@2x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-32@1x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-32@2x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-512@1x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-512@2x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/universal-icon-1024@1x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/Contents.json +0 -6
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/LargeIcon.imageset/Contents.json +0 -21
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/LargeIcon.imageset/icon128.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Resources/Base.lproj/Main.html +0 -20
- package/dist/safari/Hanzo AI/Shared (App)/Resources/Icon.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Resources/Script.js +0 -24
- package/dist/safari/Hanzo AI/Shared (App)/Resources/Style.css +0 -61
- package/dist/safari/Hanzo AI/Shared (App)/ViewController.swift +0 -81
- package/dist/safari/Hanzo AI/Shared (Extension)/SafariWebExtensionHandler.swift +0 -42
- package/dist/safari/Hanzo AI/iOS (App)/AppDelegate.swift +0 -24
- package/dist/safari/Hanzo AI/iOS (App)/Base.lproj/LaunchScreen.storyboard +0 -36
- package/dist/safari/Hanzo AI/iOS (App)/Base.lproj/Main.storyboard +0 -38
- package/dist/safari/Hanzo AI/iOS (App)/Info.plist +0 -27
- package/dist/safari/Hanzo AI/iOS (App)/SceneDelegate.swift +0 -18
- package/dist/safari/Hanzo AI/iOS (Extension)/Info.plist +0 -13
- package/dist/safari/Hanzo AI/macOS (App)/AppDelegate.swift +0 -21
- package/dist/safari/Hanzo AI/macOS (App)/Base.lproj/Main.storyboard +0 -124
- package/dist/safari/Hanzo AI/macOS (App)/Info.plist +0 -8
- package/dist/safari/Hanzo AI/macOS (Extension)/Info.plist +0 -13
- package/docs/_config.yml +0 -13
- package/docs/_layouts/default.html +0 -435
- package/docs/index.md +0 -54
- package/hanzo-ai-chrome-v1.7.6.zip +0 -0
- package/hanzo-ai-firefox-v1.7.6.zip +0 -0
- package/install-extension.sh +0 -75
- package/test/claude-integration.test.ts +0 -251
- package/test/server-frameworks-edge-cases.test.ts +0 -145
- package/test/server-frameworks.test.ts +0 -395
- package/test-cdp-connection.js +0 -140
- package/tsconfig.json +0 -19
|
@@ -1,1270 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
(() => {
|
|
3
|
-
// src/content-script.ts
|
|
4
|
-
var HanzoContentScript = class {
|
|
5
|
-
constructor() {
|
|
6
|
-
this.setupClickHandler();
|
|
7
|
-
this.injectHelpers();
|
|
8
|
-
this.setupMessageHandlers();
|
|
9
|
-
}
|
|
10
|
-
setupClickHandler() {
|
|
11
|
-
document.addEventListener("click", (e) => {
|
|
12
|
-
if (!e.altKey) return;
|
|
13
|
-
e.preventDefault();
|
|
14
|
-
e.stopPropagation();
|
|
15
|
-
const element = e.target;
|
|
16
|
-
const source = this.extractSourceLocation(element);
|
|
17
|
-
const domPath = this.getDOMPath(element);
|
|
18
|
-
const event = {
|
|
19
|
-
event: "elementSelected",
|
|
20
|
-
framework: this.detectFramework(),
|
|
21
|
-
domPath,
|
|
22
|
-
source,
|
|
23
|
-
fallbackId: element.getAttribute("data-hanzo-id") || void 0
|
|
24
|
-
};
|
|
25
|
-
chrome.runtime.sendMessage({ action: "elementSelected", data: event });
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
setupMessageHandlers() {
|
|
29
|
-
chrome.runtime.onMessage.addListener((request, _sender, sendResponse) => {
|
|
30
|
-
var _a;
|
|
31
|
-
switch (request.action) {
|
|
32
|
-
case "ai.control.start":
|
|
33
|
-
aiOverlay.show(request.task || "AI is controlling this page");
|
|
34
|
-
sendResponse({ success: true });
|
|
35
|
-
return true;
|
|
36
|
-
case "ai.control.stop":
|
|
37
|
-
aiOverlay.hide();
|
|
38
|
-
sendResponse({ success: true });
|
|
39
|
-
return true;
|
|
40
|
-
case "ai.control.cursor":
|
|
41
|
-
aiOverlay.moveCursor(request.x, request.y);
|
|
42
|
-
sendResponse({ success: true });
|
|
43
|
-
return true;
|
|
44
|
-
case "ai.control.highlight":
|
|
45
|
-
aiOverlay.highlight(request.selector);
|
|
46
|
-
sendResponse({ success: true });
|
|
47
|
-
return true;
|
|
48
|
-
case "ai.control.status":
|
|
49
|
-
aiOverlay.updateStatus(request.text);
|
|
50
|
-
sendResponse({ success: true });
|
|
51
|
-
return true;
|
|
52
|
-
case "page.overlay.toggle":
|
|
53
|
-
sendResponse({
|
|
54
|
-
success: true,
|
|
55
|
-
open: pageOverlay.toggle()
|
|
56
|
-
});
|
|
57
|
-
return true;
|
|
58
|
-
case "page.overlay.show":
|
|
59
|
-
pageOverlay.show();
|
|
60
|
-
sendResponse({ success: true, open: true });
|
|
61
|
-
return true;
|
|
62
|
-
case "page.overlay.hide":
|
|
63
|
-
pageOverlay.hide();
|
|
64
|
-
sendResponse({ success: true, open: false });
|
|
65
|
-
return true;
|
|
66
|
-
case "page.overlay.status":
|
|
67
|
-
sendResponse({ success: true, open: pageOverlay.isOpen() });
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
if (request.action === "getContent") {
|
|
71
|
-
sendResponse({ content: ((_a = document.documentElement) == null ? void 0 : _a.outerHTML) || "" });
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
if (request.action === "setContent") {
|
|
75
|
-
if (typeof request.content === "string") {
|
|
76
|
-
document.open();
|
|
77
|
-
document.write(request.content);
|
|
78
|
-
document.close();
|
|
79
|
-
}
|
|
80
|
-
sendResponse({ success: true });
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
return false;
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
extractSourceLocation(element) {
|
|
87
|
-
const framework = this.detectFramework();
|
|
88
|
-
switch (framework) {
|
|
89
|
-
case "react":
|
|
90
|
-
return this.extractReactSource(element);
|
|
91
|
-
case "vue":
|
|
92
|
-
return this.extractVueSource(element);
|
|
93
|
-
case "svelte":
|
|
94
|
-
return this.extractSvelteSource(element);
|
|
95
|
-
default:
|
|
96
|
-
return void 0;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
extractReactSource(element) {
|
|
100
|
-
var _a, _b;
|
|
101
|
-
const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
|
102
|
-
if (!hook) return void 0;
|
|
103
|
-
const fiber = this.findReactFiber(element);
|
|
104
|
-
if (!fiber) return void 0;
|
|
105
|
-
const source = fiber._debugSource || ((_a = fiber.pendingProps) == null ? void 0 : _a.__source) || ((_b = fiber.memoizedProps) == null ? void 0 : _b.__source);
|
|
106
|
-
if (source && source.fileName) {
|
|
107
|
-
return {
|
|
108
|
-
file: source.fileName,
|
|
109
|
-
line: source.lineNumber,
|
|
110
|
-
column: source.columnNumber
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
return void 0;
|
|
114
|
-
}
|
|
115
|
-
findReactFiber(element) {
|
|
116
|
-
const key = Object.keys(element).find(
|
|
117
|
-
(candidate) => candidate.startsWith("__reactInternalInstance$") || candidate.startsWith("__reactFiber$")
|
|
118
|
-
);
|
|
119
|
-
return key ? element[key] : null;
|
|
120
|
-
}
|
|
121
|
-
extractVueSource(element) {
|
|
122
|
-
var _a, _b;
|
|
123
|
-
const hook = window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
|
|
124
|
-
if (!hook) return void 0;
|
|
125
|
-
let instance = element.__vueParentComponent;
|
|
126
|
-
if (!instance) {
|
|
127
|
-
instance = element.__vue__;
|
|
128
|
-
}
|
|
129
|
-
if ((_a = instance == null ? void 0 : instance.type) == null ? void 0 : _a.__file) {
|
|
130
|
-
const location2 = {
|
|
131
|
-
file: instance.type.__file,
|
|
132
|
-
line: 1
|
|
133
|
-
};
|
|
134
|
-
if ((_b = instance.vnode) == null ? void 0 : _b.loc) {
|
|
135
|
-
location2.line = instance.vnode.loc.start.line;
|
|
136
|
-
location2.column = instance.vnode.loc.start.column;
|
|
137
|
-
}
|
|
138
|
-
return location2;
|
|
139
|
-
}
|
|
140
|
-
return void 0;
|
|
141
|
-
}
|
|
142
|
-
extractSvelteSource(element) {
|
|
143
|
-
var _a, _b;
|
|
144
|
-
const component = element.__svelte_component;
|
|
145
|
-
if ((_b = (_a = component == null ? void 0 : component.$$) == null ? void 0 : _a.ctx) == null ? void 0 : _b.$$_location) {
|
|
146
|
-
return component.$$.ctx.$$_location;
|
|
147
|
-
}
|
|
148
|
-
return void 0;
|
|
149
|
-
}
|
|
150
|
-
detectFramework() {
|
|
151
|
-
if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) return "react";
|
|
152
|
-
if (window.__VUE_DEVTOOLS_GLOBAL_HOOK__) return "vue";
|
|
153
|
-
if (window.__svelte) return "svelte";
|
|
154
|
-
return null;
|
|
155
|
-
}
|
|
156
|
-
getDOMPath(element) {
|
|
157
|
-
const path = [];
|
|
158
|
-
let current = element;
|
|
159
|
-
while (current && current !== document.body) {
|
|
160
|
-
let selector = current.tagName.toLowerCase();
|
|
161
|
-
if (current.id) {
|
|
162
|
-
selector += `#${current.id}`;
|
|
163
|
-
} else if (current.className) {
|
|
164
|
-
selector += `.${current.className.split(" ").join(".")}`;
|
|
165
|
-
}
|
|
166
|
-
path.unshift(selector);
|
|
167
|
-
current = current.parentElement;
|
|
168
|
-
}
|
|
169
|
-
return path.join(" > ");
|
|
170
|
-
}
|
|
171
|
-
injectHelpers() {
|
|
172
|
-
const style = document.createElement("style");
|
|
173
|
-
style.textContent = `
|
|
174
|
-
[data-hanzo-hover] {
|
|
175
|
-
outline: 2px dashed #ff6b6b !important;
|
|
176
|
-
outline-offset: 2px !important;
|
|
177
|
-
}
|
|
178
|
-
`;
|
|
179
|
-
document.head.appendChild(style);
|
|
180
|
-
document.addEventListener("mousemove", (e) => {
|
|
181
|
-
document.querySelectorAll("[data-hanzo-hover]").forEach((el) => {
|
|
182
|
-
el.removeAttribute("data-hanzo-hover");
|
|
183
|
-
});
|
|
184
|
-
if (e.altKey && e.target instanceof HTMLElement) {
|
|
185
|
-
e.target.setAttribute("data-hanzo-hover", "true");
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
var aiOverlay = /* @__PURE__ */ (() => {
|
|
191
|
-
let overlay = null;
|
|
192
|
-
let cursor = null;
|
|
193
|
-
let statusEl = null;
|
|
194
|
-
let cancelBtn = null;
|
|
195
|
-
let highlightEl = null;
|
|
196
|
-
let trailNodes = [];
|
|
197
|
-
let interactionBlockActive = false;
|
|
198
|
-
const OVERLAY_ID = "hanzo-ai-overlay";
|
|
199
|
-
const STYLES_ID = "hanzo-ai-overlay-styles";
|
|
200
|
-
const BLOCKED_EVENTS = [
|
|
201
|
-
"click",
|
|
202
|
-
"dblclick",
|
|
203
|
-
"mousedown",
|
|
204
|
-
"mouseup",
|
|
205
|
-
"contextmenu",
|
|
206
|
-
"pointerdown",
|
|
207
|
-
"pointerup",
|
|
208
|
-
"touchstart",
|
|
209
|
-
"touchmove",
|
|
210
|
-
"touchend",
|
|
211
|
-
"wheel",
|
|
212
|
-
"keydown",
|
|
213
|
-
"keyup",
|
|
214
|
-
"keypress"
|
|
215
|
-
];
|
|
216
|
-
function injectStyles() {
|
|
217
|
-
if (document.getElementById(STYLES_ID)) return;
|
|
218
|
-
const style = document.createElement("style");
|
|
219
|
-
style.id = STYLES_ID;
|
|
220
|
-
style.textContent = `
|
|
221
|
-
/* ---- Overlay backdrop ---- */
|
|
222
|
-
#${OVERLAY_ID} {
|
|
223
|
-
position: fixed;
|
|
224
|
-
inset: 0;
|
|
225
|
-
z-index: 2147483646;
|
|
226
|
-
pointer-events: all;
|
|
227
|
-
background:
|
|
228
|
-
radial-gradient(90vw 90vh at 15% 8%, rgba(56, 189, 248, 0.10), transparent 55%),
|
|
229
|
-
radial-gradient(65vw 65vh at 84% 82%, rgba(99, 102, 241, 0.10), transparent 60%),
|
|
230
|
-
rgba(2, 4, 10, 0.42);
|
|
231
|
-
backdrop-filter: blur(1.5px);
|
|
232
|
-
opacity: 0;
|
|
233
|
-
transition: opacity 300ms ease;
|
|
234
|
-
}
|
|
235
|
-
#${OVERLAY_ID}.hanzo-visible {
|
|
236
|
-
opacity: 1;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/* ---- Pulsing cyan glow cursor ---- */
|
|
240
|
-
.hanzo-ai-cursor {
|
|
241
|
-
position: fixed;
|
|
242
|
-
width: 24px;
|
|
243
|
-
height: 24px;
|
|
244
|
-
z-index: 2147483647;
|
|
245
|
-
pointer-events: none;
|
|
246
|
-
border-radius: 50%;
|
|
247
|
-
border: 2px solid rgba(6, 182, 212, 0.95);
|
|
248
|
-
box-shadow:
|
|
249
|
-
0 0 8px 2px rgba(6, 182, 212, 0.45),
|
|
250
|
-
0 0 24px 6px rgba(6, 182, 212, 0.18);
|
|
251
|
-
transform: translate(-50%, -50%);
|
|
252
|
-
transition: left 0.18s ease-out, top 0.18s ease-out;
|
|
253
|
-
animation: hanzo-cursor-pulse 1.6s ease-in-out infinite;
|
|
254
|
-
opacity: 0;
|
|
255
|
-
}
|
|
256
|
-
.hanzo-ai-cursor.hanzo-visible {
|
|
257
|
-
opacity: 1;
|
|
258
|
-
transition: left 0.18s ease-out, top 0.18s ease-out, opacity 300ms ease;
|
|
259
|
-
}
|
|
260
|
-
@keyframes hanzo-cursor-pulse {
|
|
261
|
-
0%, 100% {
|
|
262
|
-
box-shadow:
|
|
263
|
-
0 0 8px 2px rgba(6, 182, 212, 0.45),
|
|
264
|
-
0 0 24px 6px rgba(6, 182, 212, 0.18);
|
|
265
|
-
}
|
|
266
|
-
50% {
|
|
267
|
-
box-shadow:
|
|
268
|
-
0 0 14px 4px rgba(6, 182, 212, 0.65),
|
|
269
|
-
0 0 36px 10px rgba(6, 182, 212, 0.28);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/* ---- Cursor trail ---- */
|
|
274
|
-
.hanzo-cursor-trail {
|
|
275
|
-
position: fixed;
|
|
276
|
-
width: 6px;
|
|
277
|
-
height: 6px;
|
|
278
|
-
border-radius: 50%;
|
|
279
|
-
background: rgba(6, 182, 212, 0.7);
|
|
280
|
-
z-index: 2147483646;
|
|
281
|
-
pointer-events: none;
|
|
282
|
-
transform: translate(-50%, -50%);
|
|
283
|
-
animation: hanzo-trail-fade 0.4s ease-out forwards;
|
|
284
|
-
}
|
|
285
|
-
@keyframes hanzo-trail-fade {
|
|
286
|
-
from { opacity: 0.7; transform: translate(-50%, -50%) scale(1); }
|
|
287
|
-
to { opacity: 0; transform: translate(-50%, -50%) scale(0.15); }
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/* ---- Status banner (top center pill) ---- */
|
|
291
|
-
.hanzo-ai-status {
|
|
292
|
-
position: fixed;
|
|
293
|
-
top: 16px;
|
|
294
|
-
left: 50%;
|
|
295
|
-
transform: translateX(-50%);
|
|
296
|
-
z-index: 2147483647;
|
|
297
|
-
display: flex;
|
|
298
|
-
align-items: center;
|
|
299
|
-
gap: 10px;
|
|
300
|
-
max-width: 90vw;
|
|
301
|
-
padding: 10px 14px;
|
|
302
|
-
border-radius: 16px;
|
|
303
|
-
background: linear-gradient(135deg, rgba(8, 12, 20, 0.94), rgba(10, 16, 24, 0.96));
|
|
304
|
-
border: 1px solid rgba(56, 189, 248, 0.26);
|
|
305
|
-
color: #f3f4f6;
|
|
306
|
-
font: 13px/1.4 -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
307
|
-
box-shadow:
|
|
308
|
-
0 10px 36px rgba(0, 0, 0, 0.46),
|
|
309
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
310
|
-
opacity: 0;
|
|
311
|
-
transition: opacity 300ms ease;
|
|
312
|
-
overflow: hidden;
|
|
313
|
-
}
|
|
314
|
-
.hanzo-ai-status::before {
|
|
315
|
-
content: '';
|
|
316
|
-
position: absolute;
|
|
317
|
-
inset: -2px auto -2px -20%;
|
|
318
|
-
width: 40%;
|
|
319
|
-
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.16), transparent);
|
|
320
|
-
transform: skewX(-18deg);
|
|
321
|
-
animation: hanzo-status-sheen 3.6s ease-in-out infinite;
|
|
322
|
-
pointer-events: none;
|
|
323
|
-
}
|
|
324
|
-
@keyframes hanzo-status-sheen {
|
|
325
|
-
0%, 68% { left: -30%; opacity: 0; }
|
|
326
|
-
72% { opacity: 0.4; }
|
|
327
|
-
100% { left: 130%; opacity: 0; }
|
|
328
|
-
}
|
|
329
|
-
.hanzo-ai-status > * {
|
|
330
|
-
position: relative;
|
|
331
|
-
}
|
|
332
|
-
.hanzo-ai-status.hanzo-visible {
|
|
333
|
-
opacity: 1;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
.hanzo-ai-status .hanzo-brand-bubble {
|
|
337
|
-
display: inline-flex;
|
|
338
|
-
align-items: center;
|
|
339
|
-
justify-content: center;
|
|
340
|
-
height: 20px;
|
|
341
|
-
min-width: 30px;
|
|
342
|
-
padding: 0 8px;
|
|
343
|
-
border-radius: 9999px;
|
|
344
|
-
font-size: 10px;
|
|
345
|
-
letter-spacing: 0.25px;
|
|
346
|
-
font-weight: 700;
|
|
347
|
-
text-transform: uppercase;
|
|
348
|
-
color: #e0f2fe;
|
|
349
|
-
background: linear-gradient(180deg, rgba(14, 116, 144, 0.95), rgba(15, 23, 42, 0.95));
|
|
350
|
-
border: 1px solid rgba(56, 189, 248, 0.35);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
.hanzo-ai-status .hanzo-pulse-dot {
|
|
354
|
-
width: 8px;
|
|
355
|
-
height: 8px;
|
|
356
|
-
border-radius: 9999px;
|
|
357
|
-
background: #06b6d4;
|
|
358
|
-
animation: hanzo-dot-pulse 1.4s ease-in-out infinite;
|
|
359
|
-
}
|
|
360
|
-
@keyframes hanzo-dot-pulse {
|
|
361
|
-
0%, 100% { opacity: 1; }
|
|
362
|
-
50% { opacity: 0.4; }
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
.hanzo-ai-status .hanzo-label {
|
|
366
|
-
max-width: 46vw;
|
|
367
|
-
overflow: hidden;
|
|
368
|
-
text-overflow: ellipsis;
|
|
369
|
-
white-space: nowrap;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
.hanzo-ai-status .hanzo-dots::after {
|
|
373
|
-
content: '';
|
|
374
|
-
animation: hanzo-animated-dots 1.5s steps(4) infinite;
|
|
375
|
-
}
|
|
376
|
-
@keyframes hanzo-animated-dots {
|
|
377
|
-
0% { content: ''; }
|
|
378
|
-
25% { content: '.'; }
|
|
379
|
-
50% { content: '..'; }
|
|
380
|
-
75% { content: '...'; }
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
.hanzo-ai-status .hanzo-stop-btn {
|
|
384
|
-
border: 1px solid rgba(255, 255, 255, 0.24);
|
|
385
|
-
background: rgba(0, 0, 0, 0.18);
|
|
386
|
-
color: #f8fafc;
|
|
387
|
-
border-radius: 10px;
|
|
388
|
-
padding: 4px 12px;
|
|
389
|
-
font-size: 12px;
|
|
390
|
-
cursor: pointer;
|
|
391
|
-
transition: background 0.15s, border-color 0.15s;
|
|
392
|
-
}
|
|
393
|
-
.hanzo-ai-status .hanzo-stop-btn:hover {
|
|
394
|
-
background: rgba(220, 38, 38, 0.28);
|
|
395
|
-
border-color: rgba(248, 113, 113, 0.6);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
/* ---- "Take Back Control" button (bottom-right) ---- */
|
|
399
|
-
.hanzo-ai-cancel {
|
|
400
|
-
position: fixed;
|
|
401
|
-
bottom: 24px;
|
|
402
|
-
right: 24px;
|
|
403
|
-
z-index: 2147483647;
|
|
404
|
-
padding: 12px 24px;
|
|
405
|
-
border-radius: 10px;
|
|
406
|
-
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
407
|
-
background: rgba(15, 18, 24, 0.95);
|
|
408
|
-
color: #f3f4f6;
|
|
409
|
-
font: 600 14px/1.4 -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
410
|
-
cursor: pointer;
|
|
411
|
-
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
|
|
412
|
-
pointer-events: auto;
|
|
413
|
-
opacity: 0;
|
|
414
|
-
transition: opacity 300ms ease, background 0.15s;
|
|
415
|
-
}
|
|
416
|
-
.hanzo-ai-cancel.hanzo-visible {
|
|
417
|
-
opacity: 1;
|
|
418
|
-
}
|
|
419
|
-
.hanzo-ai-cancel:hover {
|
|
420
|
-
background: rgba(220, 38, 38, 0.35);
|
|
421
|
-
border-color: rgba(220, 38, 38, 0.5);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
/* ---- Element highlight ---- */
|
|
425
|
-
.hanzo-ai-highlight {
|
|
426
|
-
position: fixed;
|
|
427
|
-
z-index: 2147483647;
|
|
428
|
-
pointer-events: none;
|
|
429
|
-
border: 2px solid rgba(6, 182, 212, 0.85);
|
|
430
|
-
border-radius: 6px;
|
|
431
|
-
box-shadow: 0 0 0 3px rgba(6, 182, 212, 0.15);
|
|
432
|
-
transition: left 0.15s, top 0.15s, width 0.15s, height 0.15s;
|
|
433
|
-
}
|
|
434
|
-
`;
|
|
435
|
-
document.head.appendChild(style);
|
|
436
|
-
}
|
|
437
|
-
function isOverlayElement(target) {
|
|
438
|
-
if (!(target instanceof Node)) return false;
|
|
439
|
-
return !!((overlay == null ? void 0 : overlay.contains(target)) || (statusEl == null ? void 0 : statusEl.contains(target)) || (cancelBtn == null ? void 0 : cancelBtn.contains(target)) || (cursor == null ? void 0 : cursor.contains(target)) || (highlightEl == null ? void 0 : highlightEl.contains(target)));
|
|
440
|
-
}
|
|
441
|
-
function blockInteraction(event) {
|
|
442
|
-
if (!interactionBlockActive) return;
|
|
443
|
-
if (event instanceof KeyboardEvent && event.key === "Escape") {
|
|
444
|
-
chrome.runtime.sendMessage({ action: "ai.control.cancel" });
|
|
445
|
-
hide();
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
if (isOverlayElement(event.target)) return;
|
|
449
|
-
event.preventDefault();
|
|
450
|
-
event.stopPropagation();
|
|
451
|
-
event.stopImmediatePropagation();
|
|
452
|
-
}
|
|
453
|
-
function setInteractionBlock(active) {
|
|
454
|
-
if (interactionBlockActive === active) return;
|
|
455
|
-
interactionBlockActive = active;
|
|
456
|
-
for (const eventName of BLOCKED_EVENTS) {
|
|
457
|
-
if (active) {
|
|
458
|
-
document.addEventListener(eventName, blockInteraction, true);
|
|
459
|
-
} else {
|
|
460
|
-
document.removeEventListener(eventName, blockInteraction, true);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
function show(task) {
|
|
465
|
-
var _a;
|
|
466
|
-
if (overlay) hide();
|
|
467
|
-
injectStyles();
|
|
468
|
-
setInteractionBlock(true);
|
|
469
|
-
overlay = document.createElement("div");
|
|
470
|
-
overlay.id = OVERLAY_ID;
|
|
471
|
-
document.body.appendChild(overlay);
|
|
472
|
-
cursor = document.createElement("div");
|
|
473
|
-
cursor.className = "hanzo-ai-cursor";
|
|
474
|
-
cursor.style.left = `${window.innerWidth / 2}px`;
|
|
475
|
-
cursor.style.top = `${window.innerHeight / 2}px`;
|
|
476
|
-
document.body.appendChild(cursor);
|
|
477
|
-
statusEl = document.createElement("div");
|
|
478
|
-
statusEl.className = "hanzo-ai-status";
|
|
479
|
-
statusEl.innerHTML = `
|
|
480
|
-
<span class="hanzo-brand-bubble">AI</span>
|
|
481
|
-
<div class="hanzo-pulse-dot"></div>
|
|
482
|
-
<span class="hanzo-label">${escapeHtml(task || "Hanzo AI is controlling this tab")}</span><span class="hanzo-dots"></span>
|
|
483
|
-
<button class="hanzo-stop-btn">Stop</button>
|
|
484
|
-
`;
|
|
485
|
-
document.body.appendChild(statusEl);
|
|
486
|
-
(_a = statusEl.querySelector(".hanzo-stop-btn")) == null ? void 0 : _a.addEventListener("click", () => {
|
|
487
|
-
chrome.runtime.sendMessage({ action: "ai.control.cancel" });
|
|
488
|
-
hide();
|
|
489
|
-
});
|
|
490
|
-
cancelBtn = document.createElement("button");
|
|
491
|
-
cancelBtn.className = "hanzo-ai-cancel";
|
|
492
|
-
cancelBtn.textContent = "Take Back Control";
|
|
493
|
-
cancelBtn.addEventListener("click", () => {
|
|
494
|
-
chrome.runtime.sendMessage({ action: "ai.control.cancel" });
|
|
495
|
-
hide();
|
|
496
|
-
});
|
|
497
|
-
document.body.appendChild(cancelBtn);
|
|
498
|
-
requestAnimationFrame(() => {
|
|
499
|
-
overlay == null ? void 0 : overlay.classList.add("hanzo-visible");
|
|
500
|
-
cursor == null ? void 0 : cursor.classList.add("hanzo-visible");
|
|
501
|
-
statusEl == null ? void 0 : statusEl.classList.add("hanzo-visible");
|
|
502
|
-
cancelBtn == null ? void 0 : cancelBtn.classList.add("hanzo-visible");
|
|
503
|
-
});
|
|
504
|
-
}
|
|
505
|
-
function hide() {
|
|
506
|
-
overlay == null ? void 0 : overlay.classList.remove("hanzo-visible");
|
|
507
|
-
cursor == null ? void 0 : cursor.classList.remove("hanzo-visible");
|
|
508
|
-
statusEl == null ? void 0 : statusEl.classList.remove("hanzo-visible");
|
|
509
|
-
cancelBtn == null ? void 0 : cancelBtn.classList.remove("hanzo-visible");
|
|
510
|
-
const refs = { overlay, cursor, statusEl, cancelBtn, highlightEl };
|
|
511
|
-
const trails = [...trailNodes];
|
|
512
|
-
setTimeout(() => {
|
|
513
|
-
var _a, _b, _c, _d, _e;
|
|
514
|
-
(_a = refs.overlay) == null ? void 0 : _a.remove();
|
|
515
|
-
(_b = refs.cursor) == null ? void 0 : _b.remove();
|
|
516
|
-
(_c = refs.statusEl) == null ? void 0 : _c.remove();
|
|
517
|
-
(_d = refs.cancelBtn) == null ? void 0 : _d.remove();
|
|
518
|
-
(_e = refs.highlightEl) == null ? void 0 : _e.remove();
|
|
519
|
-
for (const node of trails) {
|
|
520
|
-
node.remove();
|
|
521
|
-
}
|
|
522
|
-
}, 320);
|
|
523
|
-
setInteractionBlock(false);
|
|
524
|
-
overlay = null;
|
|
525
|
-
cursor = null;
|
|
526
|
-
statusEl = null;
|
|
527
|
-
cancelBtn = null;
|
|
528
|
-
highlightEl = null;
|
|
529
|
-
trailNodes = [];
|
|
530
|
-
}
|
|
531
|
-
function moveCursor(x, y) {
|
|
532
|
-
var _a;
|
|
533
|
-
if (!cursor) return;
|
|
534
|
-
const clampedX = Math.max(0, Math.min(window.innerWidth, Number.isFinite(x) ? x : 0));
|
|
535
|
-
const clampedY = Math.max(0, Math.min(window.innerHeight, Number.isFinite(y) ? y : 0));
|
|
536
|
-
const trail = document.createElement("div");
|
|
537
|
-
trail.className = "hanzo-cursor-trail";
|
|
538
|
-
trail.style.left = `${clampedX}px`;
|
|
539
|
-
trail.style.top = `${clampedY}px`;
|
|
540
|
-
document.body.appendChild(trail);
|
|
541
|
-
trailNodes.push(trail);
|
|
542
|
-
setTimeout(() => {
|
|
543
|
-
trail.remove();
|
|
544
|
-
trailNodes = trailNodes.filter((node) => node !== trail);
|
|
545
|
-
}, 400);
|
|
546
|
-
while (trailNodes.length > 10) {
|
|
547
|
-
(_a = trailNodes.shift()) == null ? void 0 : _a.remove();
|
|
548
|
-
}
|
|
549
|
-
cursor.style.left = `${clampedX}px`;
|
|
550
|
-
cursor.style.top = `${clampedY}px`;
|
|
551
|
-
}
|
|
552
|
-
function highlight(selector) {
|
|
553
|
-
highlightEl == null ? void 0 : highlightEl.remove();
|
|
554
|
-
highlightEl = null;
|
|
555
|
-
if (!selector || typeof selector !== "string") return;
|
|
556
|
-
try {
|
|
557
|
-
const target = document.querySelector(selector);
|
|
558
|
-
if (!target) return;
|
|
559
|
-
const rect = target.getBoundingClientRect();
|
|
560
|
-
if (rect.width === 0 && rect.height === 0) return;
|
|
561
|
-
highlightEl = document.createElement("div");
|
|
562
|
-
highlightEl.className = "hanzo-ai-highlight";
|
|
563
|
-
highlightEl.style.left = `${Math.max(0, rect.left - 4)}px`;
|
|
564
|
-
highlightEl.style.top = `${Math.max(0, rect.top - 4)}px`;
|
|
565
|
-
highlightEl.style.width = `${rect.width + 8}px`;
|
|
566
|
-
highlightEl.style.height = `${rect.height + 8}px`;
|
|
567
|
-
document.body.appendChild(highlightEl);
|
|
568
|
-
} catch {
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
function updateStatus(text) {
|
|
572
|
-
if (!statusEl) return;
|
|
573
|
-
const label = statusEl.querySelector(".hanzo-label");
|
|
574
|
-
if (label) {
|
|
575
|
-
label.textContent = text || "Hanzo AI is controlling this tab";
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
function escapeHtml(text) {
|
|
579
|
-
const div = document.createElement("div");
|
|
580
|
-
div.textContent = text;
|
|
581
|
-
return div.innerHTML;
|
|
582
|
-
}
|
|
583
|
-
return { show, hide, moveCursor, highlight, updateStatus };
|
|
584
|
-
})();
|
|
585
|
-
var HanzoPageOverlay = class {
|
|
586
|
-
constructor() {
|
|
587
|
-
this.mounted = false;
|
|
588
|
-
this.enabled = false;
|
|
589
|
-
this.open = false;
|
|
590
|
-
this.sending = false;
|
|
591
|
-
this.watchMode = false;
|
|
592
|
-
this.editMode = false;
|
|
593
|
-
this.modelsLoaded = false;
|
|
594
|
-
this.messages = [];
|
|
595
|
-
this.selectedContext = null;
|
|
596
|
-
this.hoveredElement = null;
|
|
597
|
-
this.editingElement = null;
|
|
598
|
-
this.root = null;
|
|
599
|
-
this.launcher = null;
|
|
600
|
-
this.panel = null;
|
|
601
|
-
this.messagesEl = null;
|
|
602
|
-
this.inputEl = null;
|
|
603
|
-
this.sendBtn = null;
|
|
604
|
-
this.modelEl = null;
|
|
605
|
-
this.contextEl = null;
|
|
606
|
-
this.watchBtn = null;
|
|
607
|
-
this.editBtn = null;
|
|
608
|
-
this.statusEl = null;
|
|
609
|
-
this.highlightBox = null;
|
|
610
|
-
this.injectStyles();
|
|
611
|
-
this.mount();
|
|
612
|
-
this.bindGlobalEvents();
|
|
613
|
-
}
|
|
614
|
-
toggle() {
|
|
615
|
-
if (!this.enabled || !this.open) {
|
|
616
|
-
this.show();
|
|
617
|
-
return true;
|
|
618
|
-
}
|
|
619
|
-
this.hide();
|
|
620
|
-
return false;
|
|
621
|
-
}
|
|
622
|
-
show() {
|
|
623
|
-
var _a, _b;
|
|
624
|
-
this.ensureMounted();
|
|
625
|
-
this.enabled = true;
|
|
626
|
-
this.open = true;
|
|
627
|
-
(_a = this.root) == null ? void 0 : _a.setAttribute("data-enabled", "true");
|
|
628
|
-
(_b = this.root) == null ? void 0 : _b.setAttribute("data-open", "true");
|
|
629
|
-
this.loadModels();
|
|
630
|
-
this.focusInput();
|
|
631
|
-
}
|
|
632
|
-
hide() {
|
|
633
|
-
var _a;
|
|
634
|
-
this.open = false;
|
|
635
|
-
(_a = this.root) == null ? void 0 : _a.setAttribute("data-open", "false");
|
|
636
|
-
this.updateStatus("");
|
|
637
|
-
this.clearHighlight();
|
|
638
|
-
this.setWatchMode(false);
|
|
639
|
-
this.setEditMode(false);
|
|
640
|
-
}
|
|
641
|
-
isOpen() {
|
|
642
|
-
return this.open;
|
|
643
|
-
}
|
|
644
|
-
ensureMounted() {
|
|
645
|
-
if (this.mounted) return;
|
|
646
|
-
this.mount();
|
|
647
|
-
}
|
|
648
|
-
injectStyles() {
|
|
649
|
-
if (document.getElementById("hanzo-page-overlay-styles")) return;
|
|
650
|
-
const style = document.createElement("style");
|
|
651
|
-
style.id = "hanzo-page-overlay-styles";
|
|
652
|
-
style.textContent = `
|
|
653
|
-
#hanzo-page-overlay-root {
|
|
654
|
-
position: fixed;
|
|
655
|
-
right: 20px;
|
|
656
|
-
bottom: 20px;
|
|
657
|
-
z-index: 2147483645;
|
|
658
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
659
|
-
pointer-events: none;
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
#hanzo-page-overlay-root * {
|
|
663
|
-
box-sizing: border-box;
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
#hanzo-page-overlay-root[data-enabled="false"] .hanzo-page-launcher {
|
|
667
|
-
opacity: 0;
|
|
668
|
-
transform: translateY(16px);
|
|
669
|
-
pointer-events: none;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
.hanzo-page-launcher {
|
|
673
|
-
width: 54px;
|
|
674
|
-
height: 54px;
|
|
675
|
-
border-radius: 9999px;
|
|
676
|
-
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
677
|
-
background: linear-gradient(135deg, rgba(22, 24, 31, 0.96), rgba(7, 8, 12, 0.96));
|
|
678
|
-
color: #ffffff;
|
|
679
|
-
box-shadow: 0 14px 34px rgba(0, 0, 0, 0.35);
|
|
680
|
-
display: flex;
|
|
681
|
-
align-items: center;
|
|
682
|
-
justify-content: center;
|
|
683
|
-
cursor: pointer;
|
|
684
|
-
pointer-events: auto;
|
|
685
|
-
transition: transform 0.2s ease, opacity 0.2s ease;
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
.hanzo-page-launcher:hover {
|
|
689
|
-
transform: translateY(-2px);
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
.hanzo-page-panel {
|
|
693
|
-
width: min(420px, calc(100vw - 24px));
|
|
694
|
-
max-height: min(620px, calc(100vh - 28px));
|
|
695
|
-
border-radius: 16px;
|
|
696
|
-
border: 1px solid rgba(255, 255, 255, 0.16);
|
|
697
|
-
background: linear-gradient(180deg, rgba(11, 13, 18, 0.97), rgba(7, 8, 12, 0.97));
|
|
698
|
-
color: #eef2ff;
|
|
699
|
-
overflow: hidden;
|
|
700
|
-
box-shadow: 0 22px 48px rgba(0, 0, 0, 0.45);
|
|
701
|
-
transform-origin: bottom right;
|
|
702
|
-
transform: translateY(8px) scale(0.98);
|
|
703
|
-
opacity: 0;
|
|
704
|
-
pointer-events: none;
|
|
705
|
-
display: flex;
|
|
706
|
-
flex-direction: column;
|
|
707
|
-
margin-bottom: 10px;
|
|
708
|
-
transition: transform 0.18s ease, opacity 0.18s ease;
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
#hanzo-page-overlay-root[data-open="true"] .hanzo-page-panel {
|
|
712
|
-
transform: translateY(0) scale(1);
|
|
713
|
-
opacity: 1;
|
|
714
|
-
pointer-events: auto;
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
#hanzo-page-overlay-root[data-open="true"] .hanzo-page-launcher {
|
|
718
|
-
opacity: 0;
|
|
719
|
-
transform: scale(0.9);
|
|
720
|
-
pointer-events: none;
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
.hanzo-page-header {
|
|
724
|
-
display: flex;
|
|
725
|
-
align-items: center;
|
|
726
|
-
justify-content: space-between;
|
|
727
|
-
padding: 12px 14px;
|
|
728
|
-
border-bottom: 1px solid rgba(255, 255, 255, 0.12);
|
|
729
|
-
background: linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent);
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
.hanzo-page-brand {
|
|
733
|
-
font-weight: 700;
|
|
734
|
-
letter-spacing: 0.2px;
|
|
735
|
-
font-size: 13px;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
.hanzo-page-header-actions {
|
|
739
|
-
display: inline-flex;
|
|
740
|
-
align-items: center;
|
|
741
|
-
gap: 6px;
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
.hanzo-chip-btn {
|
|
745
|
-
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
746
|
-
border-radius: 9999px;
|
|
747
|
-
padding: 4px 10px;
|
|
748
|
-
background: rgba(255, 255, 255, 0.02);
|
|
749
|
-
color: #d6deff;
|
|
750
|
-
cursor: pointer;
|
|
751
|
-
font-size: 11px;
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
.hanzo-chip-btn[data-active="true"] {
|
|
755
|
-
border-color: rgba(56, 189, 248, 0.62);
|
|
756
|
-
background: rgba(14, 116, 144, 0.3);
|
|
757
|
-
color: #e0f2fe;
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
.hanzo-icon-btn {
|
|
761
|
-
width: 28px;
|
|
762
|
-
height: 28px;
|
|
763
|
-
border-radius: 8px;
|
|
764
|
-
border: 1px solid rgba(255, 255, 255, 0.18);
|
|
765
|
-
background: transparent;
|
|
766
|
-
color: #e5e7eb;
|
|
767
|
-
cursor: pointer;
|
|
768
|
-
font-size: 16px;
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
.hanzo-page-meta {
|
|
772
|
-
padding: 10px 14px 6px 14px;
|
|
773
|
-
display: grid;
|
|
774
|
-
grid-template-columns: 1fr auto;
|
|
775
|
-
gap: 8px;
|
|
776
|
-
align-items: center;
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
.hanzo-page-context {
|
|
780
|
-
font-size: 11px;
|
|
781
|
-
color: #a5b4fc;
|
|
782
|
-
overflow: hidden;
|
|
783
|
-
text-overflow: ellipsis;
|
|
784
|
-
white-space: nowrap;
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
.hanzo-page-status {
|
|
788
|
-
font-size: 11px;
|
|
789
|
-
color: #93c5fd;
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
.hanzo-model-row {
|
|
793
|
-
padding: 0 14px 8px 14px;
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
.hanzo-model-row select {
|
|
797
|
-
width: 100%;
|
|
798
|
-
border-radius: 8px;
|
|
799
|
-
border: 1px solid rgba(255, 255, 255, 0.16);
|
|
800
|
-
background: rgba(255, 255, 255, 0.03);
|
|
801
|
-
color: #f1f5f9;
|
|
802
|
-
padding: 7px 9px;
|
|
803
|
-
font-size: 12px;
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
.hanzo-page-messages {
|
|
807
|
-
flex: 1;
|
|
808
|
-
min-height: 200px;
|
|
809
|
-
max-height: 370px;
|
|
810
|
-
overflow-y: auto;
|
|
811
|
-
padding: 8px 14px 12px 14px;
|
|
812
|
-
display: flex;
|
|
813
|
-
flex-direction: column;
|
|
814
|
-
gap: 8px;
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
.hanzo-page-msg {
|
|
818
|
-
padding: 9px 10px;
|
|
819
|
-
border-radius: 10px;
|
|
820
|
-
font-size: 12px;
|
|
821
|
-
line-height: 1.45;
|
|
822
|
-
word-break: break-word;
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
.hanzo-page-msg.user {
|
|
826
|
-
align-self: flex-end;
|
|
827
|
-
max-width: 88%;
|
|
828
|
-
background: rgba(59, 130, 246, 0.2);
|
|
829
|
-
border: 1px solid rgba(59, 130, 246, 0.4);
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
.hanzo-page-msg.assistant {
|
|
833
|
-
align-self: flex-start;
|
|
834
|
-
max-width: 92%;
|
|
835
|
-
background: rgba(255, 255, 255, 0.05);
|
|
836
|
-
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
.hanzo-page-composer {
|
|
840
|
-
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
|
841
|
-
padding: 10px 12px;
|
|
842
|
-
display: flex;
|
|
843
|
-
gap: 8px;
|
|
844
|
-
align-items: flex-end;
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
.hanzo-page-composer textarea {
|
|
848
|
-
flex: 1;
|
|
849
|
-
min-height: 38px;
|
|
850
|
-
max-height: 110px;
|
|
851
|
-
resize: none;
|
|
852
|
-
border-radius: 10px;
|
|
853
|
-
border: 1px solid rgba(255, 255, 255, 0.17);
|
|
854
|
-
background: rgba(255, 255, 255, 0.03);
|
|
855
|
-
color: #f8fafc;
|
|
856
|
-
padding: 9px 11px;
|
|
857
|
-
font-size: 12px;
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
.hanzo-page-composer button {
|
|
861
|
-
min-width: 68px;
|
|
862
|
-
height: 38px;
|
|
863
|
-
border-radius: 10px;
|
|
864
|
-
border: 1px solid rgba(37, 99, 235, 0.65);
|
|
865
|
-
background: linear-gradient(180deg, rgba(37, 99, 235, 0.95), rgba(30, 64, 175, 0.95));
|
|
866
|
-
color: #eff6ff;
|
|
867
|
-
font-weight: 600;
|
|
868
|
-
font-size: 12px;
|
|
869
|
-
cursor: pointer;
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
.hanzo-page-composer button:disabled {
|
|
873
|
-
opacity: 0.55;
|
|
874
|
-
cursor: default;
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
.hanzo-page-highlight {
|
|
878
|
-
position: fixed;
|
|
879
|
-
z-index: 2147483644;
|
|
880
|
-
pointer-events: none;
|
|
881
|
-
border: 2px solid rgba(56, 189, 248, 0.95);
|
|
882
|
-
border-radius: 6px;
|
|
883
|
-
box-shadow: 0 0 0 2px rgba(14, 116, 144, 0.2);
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
[data-hanzo-inline-editing="true"] {
|
|
887
|
-
outline: 2px solid rgba(251, 191, 36, 0.92) !important;
|
|
888
|
-
outline-offset: 2px !important;
|
|
889
|
-
}
|
|
890
|
-
`;
|
|
891
|
-
document.head.appendChild(style);
|
|
892
|
-
}
|
|
893
|
-
mount() {
|
|
894
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
895
|
-
if (this.mounted) return;
|
|
896
|
-
this.root = document.createElement("div");
|
|
897
|
-
this.root.id = "hanzo-page-overlay-root";
|
|
898
|
-
this.root.setAttribute("data-open", "false");
|
|
899
|
-
this.root.setAttribute("data-enabled", "false");
|
|
900
|
-
this.root.innerHTML = `
|
|
901
|
-
<div class="hanzo-page-panel" role="dialog" aria-label="Hanzo Page Assistant">
|
|
902
|
-
<div class="hanzo-page-header">
|
|
903
|
-
<div class="hanzo-page-brand">Hanzo Overlay</div>
|
|
904
|
-
<div class="hanzo-page-header-actions">
|
|
905
|
-
<button class="hanzo-chip-btn" data-role="watch" data-active="false" title="Watch elements on hover">Watch</button>
|
|
906
|
-
<button class="hanzo-chip-btn" data-role="edit" data-active="false" title="Click any element to edit text">Edit</button>
|
|
907
|
-
<button class="hanzo-icon-btn" data-role="close" title="Minimize">\xD7</button>
|
|
908
|
-
</div>
|
|
909
|
-
</div>
|
|
910
|
-
<div class="hanzo-page-meta">
|
|
911
|
-
<div class="hanzo-page-context">Use Watch to inspect page elements.</div>
|
|
912
|
-
<span class="hanzo-page-status"></span>
|
|
913
|
-
</div>
|
|
914
|
-
<div class="hanzo-model-row">
|
|
915
|
-
<select data-role="model">
|
|
916
|
-
<option value="claude-sonnet-4-20250514">Claude Sonnet 4</option>
|
|
917
|
-
<option value="claude-opus-4-20250514">Claude Opus 4</option>
|
|
918
|
-
<option value="gpt-4o">GPT-4o</option>
|
|
919
|
-
<option value="zen-coder-flash">Zen Coder Flash</option>
|
|
920
|
-
<option value="zen-max">Zen Max</option>
|
|
921
|
-
</select>
|
|
922
|
-
</div>
|
|
923
|
-
<div class="hanzo-page-messages" data-role="messages">
|
|
924
|
-
<div class="hanzo-page-msg assistant">Ask about this page, inspect any element, or turn on Edit mode to change text in-place.</div>
|
|
925
|
-
</div>
|
|
926
|
-
<div class="hanzo-page-composer">
|
|
927
|
-
<textarea data-role="input" rows="1" placeholder="Ask about this page..."></textarea>
|
|
928
|
-
<button data-role="send" type="button">Ask</button>
|
|
929
|
-
</div>
|
|
930
|
-
</div>
|
|
931
|
-
<button class="hanzo-page-launcher" data-role="launcher" type="button" title="Open Hanzo Overlay">AI</button>
|
|
932
|
-
`;
|
|
933
|
-
this.panel = this.root.querySelector(".hanzo-page-panel");
|
|
934
|
-
this.launcher = this.root.querySelector('[data-role="launcher"]');
|
|
935
|
-
this.messagesEl = this.root.querySelector('[data-role="messages"]');
|
|
936
|
-
this.inputEl = this.root.querySelector('[data-role="input"]');
|
|
937
|
-
this.sendBtn = this.root.querySelector('[data-role="send"]');
|
|
938
|
-
this.modelEl = this.root.querySelector('[data-role="model"]');
|
|
939
|
-
this.contextEl = this.root.querySelector(".hanzo-page-context");
|
|
940
|
-
this.watchBtn = this.root.querySelector('[data-role="watch"]');
|
|
941
|
-
this.editBtn = this.root.querySelector('[data-role="edit"]');
|
|
942
|
-
this.statusEl = this.root.querySelector(".hanzo-page-status");
|
|
943
|
-
(_a = this.launcher) == null ? void 0 : _a.addEventListener("click", () => this.show());
|
|
944
|
-
(_b = this.root.querySelector('[data-role="close"]')) == null ? void 0 : _b.addEventListener("click", () => this.hide());
|
|
945
|
-
(_c = this.watchBtn) == null ? void 0 : _c.addEventListener("click", () => this.setWatchMode(!this.watchMode));
|
|
946
|
-
(_d = this.editBtn) == null ? void 0 : _d.addEventListener("click", () => this.setEditMode(!this.editMode));
|
|
947
|
-
(_e = this.sendBtn) == null ? void 0 : _e.addEventListener("click", () => this.askPageQuestion());
|
|
948
|
-
(_f = this.inputEl) == null ? void 0 : _f.addEventListener("keydown", (event) => {
|
|
949
|
-
if (event.key === "Enter" && !event.shiftKey) {
|
|
950
|
-
event.preventDefault();
|
|
951
|
-
this.askPageQuestion();
|
|
952
|
-
}
|
|
953
|
-
});
|
|
954
|
-
(_g = this.inputEl) == null ? void 0 : _g.addEventListener("input", () => {
|
|
955
|
-
if (!this.inputEl) return;
|
|
956
|
-
this.inputEl.style.height = "auto";
|
|
957
|
-
this.inputEl.style.height = `${Math.min(this.inputEl.scrollHeight, 110)}px`;
|
|
958
|
-
});
|
|
959
|
-
document.documentElement.appendChild(this.root);
|
|
960
|
-
this.mounted = true;
|
|
961
|
-
}
|
|
962
|
-
bindGlobalEvents() {
|
|
963
|
-
document.addEventListener("mousemove", (event) => this.onMouseMove(event), true);
|
|
964
|
-
document.addEventListener("click", (event) => this.onDocumentClick(event), true);
|
|
965
|
-
document.addEventListener("keydown", (event) => this.onKeyDown(event), true);
|
|
966
|
-
}
|
|
967
|
-
onMouseMove(event) {
|
|
968
|
-
if (!this.watchMode) return;
|
|
969
|
-
const target = this.getPageTarget(event.target);
|
|
970
|
-
if (!target) return;
|
|
971
|
-
this.hoveredElement = target;
|
|
972
|
-
this.showHighlight(target);
|
|
973
|
-
if (!this.selectedContext) {
|
|
974
|
-
this.contextEl && (this.contextEl.textContent = this.getElementSummary(target));
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
onDocumentClick(event) {
|
|
978
|
-
if (!this.watchMode && !this.editMode) return;
|
|
979
|
-
const target = this.getPageTarget(event.target);
|
|
980
|
-
if (!target) return;
|
|
981
|
-
event.preventDefault();
|
|
982
|
-
event.stopPropagation();
|
|
983
|
-
event.stopImmediatePropagation();
|
|
984
|
-
if (this.watchMode) {
|
|
985
|
-
this.selectedContext = this.captureElementContext(target);
|
|
986
|
-
this.contextEl && (this.contextEl.textContent = this.getElementSummary(target));
|
|
987
|
-
this.updateStatus("Element selected");
|
|
988
|
-
}
|
|
989
|
-
if (this.editMode) {
|
|
990
|
-
this.enableInlineEdit(target);
|
|
991
|
-
this.updateStatus("Editing element");
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
onKeyDown(event) {
|
|
995
|
-
if (event.key === "Escape") {
|
|
996
|
-
if (this.editingElement) {
|
|
997
|
-
this.disableInlineEdit(this.editingElement, false);
|
|
998
|
-
this.updateStatus("Edit canceled");
|
|
999
|
-
event.preventDefault();
|
|
1000
|
-
return;
|
|
1001
|
-
}
|
|
1002
|
-
if (this.open) {
|
|
1003
|
-
this.hide();
|
|
1004
|
-
event.preventDefault();
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
getPageTarget(target) {
|
|
1009
|
-
var _a;
|
|
1010
|
-
if (!(target instanceof HTMLElement)) return null;
|
|
1011
|
-
if ((_a = this.root) == null ? void 0 : _a.contains(target)) return null;
|
|
1012
|
-
if (!target.isConnected) return null;
|
|
1013
|
-
if (target.tagName.toLowerCase() === "html" || target.tagName.toLowerCase() === "body") return null;
|
|
1014
|
-
return target;
|
|
1015
|
-
}
|
|
1016
|
-
setWatchMode(active) {
|
|
1017
|
-
var _a;
|
|
1018
|
-
this.watchMode = active;
|
|
1019
|
-
if (active) this.setEditMode(false);
|
|
1020
|
-
(_a = this.watchBtn) == null ? void 0 : _a.setAttribute("data-active", active ? "true" : "false");
|
|
1021
|
-
if (!active) {
|
|
1022
|
-
this.hoveredElement = null;
|
|
1023
|
-
this.clearHighlight();
|
|
1024
|
-
if (!this.selectedContext && this.contextEl) {
|
|
1025
|
-
this.contextEl.textContent = "Use Watch to inspect page elements.";
|
|
1026
|
-
}
|
|
1027
|
-
} else {
|
|
1028
|
-
this.updateStatus("Watch mode on");
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
setEditMode(active) {
|
|
1032
|
-
var _a;
|
|
1033
|
-
this.editMode = active;
|
|
1034
|
-
if (active) this.setWatchMode(false);
|
|
1035
|
-
(_a = this.editBtn) == null ? void 0 : _a.setAttribute("data-active", active ? "true" : "false");
|
|
1036
|
-
if (!active && this.editingElement) {
|
|
1037
|
-
this.disableInlineEdit(this.editingElement, true);
|
|
1038
|
-
} else if (active) {
|
|
1039
|
-
this.updateStatus("Edit mode on");
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
enableInlineEdit(element) {
|
|
1043
|
-
if (this.editingElement && this.editingElement !== element) {
|
|
1044
|
-
this.disableInlineEdit(this.editingElement, true);
|
|
1045
|
-
}
|
|
1046
|
-
if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
|
|
1047
|
-
element.focus();
|
|
1048
|
-
this.editingElement = element;
|
|
1049
|
-
return;
|
|
1050
|
-
}
|
|
1051
|
-
if (!element.hasAttribute("data-hanzo-original-html")) {
|
|
1052
|
-
element.setAttribute("data-hanzo-original-html", element.innerHTML);
|
|
1053
|
-
}
|
|
1054
|
-
element.setAttribute("contenteditable", "true");
|
|
1055
|
-
element.setAttribute("spellcheck", "true");
|
|
1056
|
-
element.setAttribute("data-hanzo-inline-editing", "true");
|
|
1057
|
-
element.focus();
|
|
1058
|
-
this.editingElement = element;
|
|
1059
|
-
const keydownHandler = (event) => {
|
|
1060
|
-
if (event.key === "Escape") {
|
|
1061
|
-
this.disableInlineEdit(element, false);
|
|
1062
|
-
this.updateStatus("Edit reverted");
|
|
1063
|
-
}
|
|
1064
|
-
if (event.key === "Enter" && !event.shiftKey) {
|
|
1065
|
-
event.preventDefault();
|
|
1066
|
-
this.disableInlineEdit(element, true);
|
|
1067
|
-
this.updateStatus("Edit applied");
|
|
1068
|
-
}
|
|
1069
|
-
};
|
|
1070
|
-
const blurHandler = () => {
|
|
1071
|
-
this.disableInlineEdit(element, true);
|
|
1072
|
-
this.updateStatus("Edit applied");
|
|
1073
|
-
};
|
|
1074
|
-
element.addEventListener("keydown", keydownHandler, { once: true });
|
|
1075
|
-
element.addEventListener("blur", blurHandler, { once: true });
|
|
1076
|
-
}
|
|
1077
|
-
disableInlineEdit(element, keepChanges) {
|
|
1078
|
-
if (!keepChanges) {
|
|
1079
|
-
const original = element.getAttribute("data-hanzo-original-html");
|
|
1080
|
-
if (original !== null) {
|
|
1081
|
-
element.innerHTML = original;
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
element.removeAttribute("contenteditable");
|
|
1085
|
-
element.removeAttribute("spellcheck");
|
|
1086
|
-
element.removeAttribute("data-hanzo-inline-editing");
|
|
1087
|
-
element.removeAttribute("data-hanzo-original-html");
|
|
1088
|
-
if (this.editingElement === element) {
|
|
1089
|
-
this.editingElement = null;
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
showHighlight(element) {
|
|
1093
|
-
const rect = element.getBoundingClientRect();
|
|
1094
|
-
if (rect.width === 0 && rect.height === 0) {
|
|
1095
|
-
this.clearHighlight();
|
|
1096
|
-
return;
|
|
1097
|
-
}
|
|
1098
|
-
if (!this.highlightBox) {
|
|
1099
|
-
this.highlightBox = document.createElement("div");
|
|
1100
|
-
this.highlightBox.className = "hanzo-page-highlight";
|
|
1101
|
-
document.documentElement.appendChild(this.highlightBox);
|
|
1102
|
-
}
|
|
1103
|
-
this.highlightBox.style.left = `${Math.max(0, rect.left - 3)}px`;
|
|
1104
|
-
this.highlightBox.style.top = `${Math.max(0, rect.top - 3)}px`;
|
|
1105
|
-
this.highlightBox.style.width = `${rect.width + 6}px`;
|
|
1106
|
-
this.highlightBox.style.height = `${rect.height + 6}px`;
|
|
1107
|
-
}
|
|
1108
|
-
clearHighlight() {
|
|
1109
|
-
var _a;
|
|
1110
|
-
(_a = this.highlightBox) == null ? void 0 : _a.remove();
|
|
1111
|
-
this.highlightBox = null;
|
|
1112
|
-
}
|
|
1113
|
-
captureElementContext(element) {
|
|
1114
|
-
const text = this.normalizeText(element.innerText || element.textContent || "");
|
|
1115
|
-
return {
|
|
1116
|
-
selector: this.buildSelector(element),
|
|
1117
|
-
tag: element.tagName.toLowerCase(),
|
|
1118
|
-
text: text.slice(0, 800),
|
|
1119
|
-
html: element.outerHTML.slice(0, 1200)
|
|
1120
|
-
};
|
|
1121
|
-
}
|
|
1122
|
-
buildSelector(element) {
|
|
1123
|
-
if (element.id) return `#${element.id}`;
|
|
1124
|
-
const parts = [];
|
|
1125
|
-
let current = element;
|
|
1126
|
-
let depth = 0;
|
|
1127
|
-
while (current && depth < 6) {
|
|
1128
|
-
let part = current.tagName.toLowerCase();
|
|
1129
|
-
if (current.classList.length > 0) {
|
|
1130
|
-
const className = Array.from(current.classList).slice(0, 2).join(".");
|
|
1131
|
-
if (className) part += `.${className}`;
|
|
1132
|
-
}
|
|
1133
|
-
const parent = current.parentElement;
|
|
1134
|
-
if (parent) {
|
|
1135
|
-
const siblings = Array.from(parent.children).filter((node) => node.tagName === current.tagName);
|
|
1136
|
-
if (siblings.length > 1) {
|
|
1137
|
-
const index = siblings.indexOf(current) + 1;
|
|
1138
|
-
part += `:nth-of-type(${index})`;
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
parts.unshift(part);
|
|
1142
|
-
current = parent;
|
|
1143
|
-
depth += 1;
|
|
1144
|
-
}
|
|
1145
|
-
return parts.join(" > ");
|
|
1146
|
-
}
|
|
1147
|
-
normalizeText(value) {
|
|
1148
|
-
return value.replace(/\s+/g, " ").trim();
|
|
1149
|
-
}
|
|
1150
|
-
getElementSummary(element) {
|
|
1151
|
-
const ctx = this.captureElementContext(element);
|
|
1152
|
-
return `${ctx.tag} \u2022 ${ctx.selector}`;
|
|
1153
|
-
}
|
|
1154
|
-
async loadModels() {
|
|
1155
|
-
if (this.modelsLoaded || !this.modelEl) return;
|
|
1156
|
-
try {
|
|
1157
|
-
const response = await chrome.runtime.sendMessage({ action: "chat.listModels" });
|
|
1158
|
-
if (!(response == null ? void 0 : response.success) || !Array.isArray(response.models) || !response.models.length) {
|
|
1159
|
-
return;
|
|
1160
|
-
}
|
|
1161
|
-
const previous = this.modelEl.value;
|
|
1162
|
-
this.modelEl.innerHTML = "";
|
|
1163
|
-
for (const model of response.models) {
|
|
1164
|
-
if (!(model == null ? void 0 : model.id)) continue;
|
|
1165
|
-
const option = document.createElement("option");
|
|
1166
|
-
option.value = model.id;
|
|
1167
|
-
option.textContent = model.name || model.id;
|
|
1168
|
-
this.modelEl.appendChild(option);
|
|
1169
|
-
}
|
|
1170
|
-
if (previous && Array.from(this.modelEl.options).some((opt) => opt.value === previous)) {
|
|
1171
|
-
this.modelEl.value = previous;
|
|
1172
|
-
}
|
|
1173
|
-
this.modelsLoaded = true;
|
|
1174
|
-
} catch {
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1177
|
-
focusInput() {
|
|
1178
|
-
if (!this.inputEl) return;
|
|
1179
|
-
this.inputEl.focus();
|
|
1180
|
-
}
|
|
1181
|
-
appendMessage(role, content) {
|
|
1182
|
-
if (!this.messagesEl) return;
|
|
1183
|
-
const div = document.createElement("div");
|
|
1184
|
-
div.className = `hanzo-page-msg ${role}`;
|
|
1185
|
-
div.textContent = content;
|
|
1186
|
-
this.messagesEl.appendChild(div);
|
|
1187
|
-
this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
|
|
1188
|
-
}
|
|
1189
|
-
updateStatus(text) {
|
|
1190
|
-
if (!this.statusEl) return;
|
|
1191
|
-
this.statusEl.textContent = text;
|
|
1192
|
-
}
|
|
1193
|
-
buildPageContext() {
|
|
1194
|
-
var _a, _b;
|
|
1195
|
-
const selection = this.normalizeText(((_b = (_a = window.getSelection) == null ? void 0 : _a.call(window)) == null ? void 0 : _b.toString()) || "");
|
|
1196
|
-
const contextLines = [
|
|
1197
|
-
`URL: ${location.href}`,
|
|
1198
|
-
`Title: ${document.title || "Untitled"}`
|
|
1199
|
-
];
|
|
1200
|
-
if (selection) {
|
|
1201
|
-
contextLines.push(`TextSelection: ${selection.slice(0, 600)}`);
|
|
1202
|
-
}
|
|
1203
|
-
const elementContext = this.selectedContext || (this.hoveredElement ? this.captureElementContext(this.hoveredElement) : null);
|
|
1204
|
-
if (elementContext) {
|
|
1205
|
-
contextLines.push(`ElementSelector: ${elementContext.selector}`);
|
|
1206
|
-
if (elementContext.text) contextLines.push(`ElementText: ${elementContext.text.slice(0, 600)}`);
|
|
1207
|
-
contextLines.push(`ElementHTML: ${elementContext.html.slice(0, 800)}`);
|
|
1208
|
-
}
|
|
1209
|
-
return contextLines.join("\n");
|
|
1210
|
-
}
|
|
1211
|
-
async askPageQuestion() {
|
|
1212
|
-
var _a;
|
|
1213
|
-
if (this.sending || !this.inputEl) return;
|
|
1214
|
-
const prompt = this.normalizeText(this.inputEl.value);
|
|
1215
|
-
if (!prompt) return;
|
|
1216
|
-
const tokenResp = await chrome.runtime.sendMessage({ action: "auth.getToken" });
|
|
1217
|
-
if (!(tokenResp == null ? void 0 : tokenResp.success) || !tokenResp.token) {
|
|
1218
|
-
this.appendMessage("assistant", "Please sign in from the Hanzo sidebar/popup before using page chat.");
|
|
1219
|
-
return;
|
|
1220
|
-
}
|
|
1221
|
-
this.sending = true;
|
|
1222
|
-
this.updateStatus("Thinking...");
|
|
1223
|
-
this.sendBtn && (this.sendBtn.disabled = true);
|
|
1224
|
-
this.inputEl.value = "";
|
|
1225
|
-
this.inputEl.style.height = "auto";
|
|
1226
|
-
this.appendMessage("user", prompt);
|
|
1227
|
-
const systemContext = this.buildPageContext();
|
|
1228
|
-
const model = ((_a = this.modelEl) == null ? void 0 : _a.value) || "gpt-4o";
|
|
1229
|
-
const requestMessages = [
|
|
1230
|
-
{
|
|
1231
|
-
role: "system",
|
|
1232
|
-
content: [
|
|
1233
|
-
"You are Hanzo page overlay assistant.",
|
|
1234
|
-
"Use provided page context and selected element context when relevant.",
|
|
1235
|
-
"Be concise and provide concrete UI or DOM edit suggestions when asked.",
|
|
1236
|
-
"",
|
|
1237
|
-
systemContext
|
|
1238
|
-
].join("\n")
|
|
1239
|
-
},
|
|
1240
|
-
...this.messages.slice(-8),
|
|
1241
|
-
{ role: "user", content: prompt }
|
|
1242
|
-
];
|
|
1243
|
-
try {
|
|
1244
|
-
const response = await chrome.runtime.sendMessage({
|
|
1245
|
-
action: "chat.complete",
|
|
1246
|
-
model,
|
|
1247
|
-
messages: requestMessages
|
|
1248
|
-
});
|
|
1249
|
-
if (!(response == null ? void 0 : response.success) || !response.content) {
|
|
1250
|
-
throw new Error((response == null ? void 0 : response.error) || "No response from chat service");
|
|
1251
|
-
}
|
|
1252
|
-
const answer = String(response.content).trim();
|
|
1253
|
-
this.appendMessage("assistant", answer || "No response content.");
|
|
1254
|
-
this.messages.push({ role: "user", content: prompt }, { role: "assistant", content: answer });
|
|
1255
|
-
this.messages = this.messages.slice(-20);
|
|
1256
|
-
this.updateStatus("Ready");
|
|
1257
|
-
} catch (error) {
|
|
1258
|
-
this.appendMessage("assistant", `Error: ${(error == null ? void 0 : error.message) || "Chat request failed"}`);
|
|
1259
|
-
this.updateStatus("Error");
|
|
1260
|
-
} finally {
|
|
1261
|
-
this.sending = false;
|
|
1262
|
-
this.sendBtn && (this.sendBtn.disabled = false);
|
|
1263
|
-
this.focusInput();
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
};
|
|
1267
|
-
var pageOverlay = new HanzoPageOverlay();
|
|
1268
|
-
new HanzoContentScript();
|
|
1269
|
-
})();
|
|
1270
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2NvbnRlbnQtc2NyaXB0LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvLyBIYW56byBCcm93c2VyIEV4dGVuc2lvbiAtIENvbnRlbnQgU2NyaXB0XG4vLyBDb25uZWN0cyBjbGlja2VkIGVsZW1lbnRzIHRvIHNvdXJjZSBjb2RlIHZpYSBzb3VyY2UtbWFwc1xuXG5pbnRlcmZhY2UgU291cmNlTG9jYXRpb24ge1xuICBmaWxlOiBzdHJpbmc7XG4gIGxpbmU6IG51bWJlcjtcbiAgY29sdW1uPzogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgRWxlbWVudFNlbGVjdGVkRXZlbnQge1xuICBldmVudDogJ2VsZW1lbnRTZWxlY3RlZCc7XG4gIGZyYW1ld29yazogc3RyaW5nIHwgbnVsbDtcbiAgZG9tUGF0aDogc3RyaW5nO1xuICBzb3VyY2U/OiBTb3VyY2VMb2NhdGlvbjtcbiAgZmFsbGJhY2tJZD86IHN0cmluZztcbn1cblxuY2xhc3MgSGFuem9Db250ZW50U2NyaXB0IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5zZXR1cENsaWNrSGFuZGxlcigpO1xuICAgIHRoaXMuaW5qZWN0SGVscGVycygpO1xuICAgIHRoaXMuc2V0dXBNZXNzYWdlSGFuZGxlcnMoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBDbGlja0hhbmRsZXIoKSB7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgaWYgKCFlLmFsdEtleSkgcmV0dXJuO1xuXG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICBjb25zdCBlbGVtZW50ID0gZS50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICBjb25zdCBzb3VyY2UgPSB0aGlzLmV4dHJhY3RTb3VyY2VMb2NhdGlvbihlbGVtZW50KTtcbiAgICAgIGNvbnN0IGRvbVBhdGggPSB0aGlzLmdldERPTVBhdGgoZWxlbWVudCk7XG5cbiAgICAgIGNvbnN0IGV2ZW50OiBFbGVtZW50U2VsZWN0ZWRFdmVudCA9IHtcbiAgICAgICAgZXZlbnQ6ICdlbGVtZW50U2VsZWN0ZWQnLFxuICAgICAgICBmcmFtZXdvcms6IHRoaXMuZGV0ZWN0RnJhbWV3b3JrKCksXG4gICAgICAgIGRvbVBhdGgsXG4gICAgICAgIHNvdXJjZSxcbiAgICAgICAgZmFsbGJhY2tJZDogZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaGFuem8taWQnKSB8fCB1bmRlZmluZWQsXG4gICAgICB9O1xuXG4gICAgICAvLyBSb3V0ZSB0aHJvdWdoIGJhY2tncm91bmQgc2NyaXB0ICh3b3JrcyB3aXRoIGJvdGggWkFQIGFuZCBsZWdhY3kgTUNQKVxuICAgICAgY2hyb21lLnJ1bnRpbWUuc2VuZE1lc3NhZ2UoeyBhY3Rpb246ICdlbGVtZW50U2VsZWN0ZWQnLCBkYXRhOiBldmVudCB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBNZXNzYWdlSGFuZGxlcnMoKSB7XG4gICAgY2hyb21lLnJ1bnRpbWUub25NZXNzYWdlLmFkZExpc3RlbmVyKChyZXF1ZXN0LCBfc2VuZGVyLCBzZW5kUmVzcG9uc2UpID0+IHtcbiAgICAgIHN3aXRjaCAocmVxdWVzdC5hY3Rpb24pIHtcbiAgICAgICAgY2FzZSAnYWkuY29udHJvbC5zdGFydCc6XG4gICAgICAgICAgYWlPdmVybGF5LnNob3cocmVxdWVzdC50YXNrIHx8ICdBSSBpcyBjb250cm9sbGluZyB0aGlzIHBhZ2UnKTtcbiAgICAgICAgICBzZW5kUmVzcG9uc2UoeyBzdWNjZXNzOiB0cnVlIH0pO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBjYXNlICdhaS5jb250cm9sLnN0b3AnOlxuICAgICAgICAgIGFpT3ZlcmxheS5oaWRlKCk7XG4gICAgICAgICAgc2VuZFJlc3BvbnNlKHsgc3VjY2VzczogdHJ1ZSB9KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgY2FzZSAnYWkuY29udHJvbC5jdXJzb3InOlxuICAgICAgICAgIGFpT3ZlcmxheS5tb3ZlQ3Vyc29yKHJlcXVlc3QueCwgcmVxdWVzdC55KTtcbiAgICAgICAgICBzZW5kUmVzcG9uc2UoeyBzdWNjZXNzOiB0cnVlIH0pO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBjYXNlICdhaS5jb250cm9sLmhpZ2hsaWdodCc6XG4gICAgICAgICAgYWlPdmVybGF5LmhpZ2hsaWdodChyZXF1ZXN0LnNlbGVjdG9yKTtcbiAgICAgICAgICBzZW5kUmVzcG9uc2UoeyBzdWNjZXNzOiB0cnVlIH0pO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBjYXNlICdhaS5jb250cm9sLnN0YXR1cyc6XG4gICAgICAgICAgYWlPdmVybGF5LnVwZGF0ZVN0YXR1cyhyZXF1ZXN0LnRleHQpO1xuICAgICAgICAgIHNlbmRSZXNwb25zZSh7IHN1Y2Nlc3M6IHRydWUgfSk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIGNhc2UgJ3BhZ2Uub3ZlcmxheS50b2dnbGUnOlxuICAgICAgICAgIHNlbmRSZXNwb25zZSh7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgb3BlbjogcGFnZU92ZXJsYXkudG9nZ2xlKCksXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIGNhc2UgJ3BhZ2Uub3ZlcmxheS5zaG93JzpcbiAgICAgICAgICBwYWdlT3ZlcmxheS5zaG93KCk7XG4gICAgICAgICAgc2VuZFJlc3BvbnNlKHsgc3VjY2VzczogdHJ1ZSwgb3BlbjogdHJ1ZSB9KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgY2FzZSAncGFnZS5vdmVybGF5LmhpZGUnOlxuICAgICAgICAgIHBhZ2VPdmVybGF5LmhpZGUoKTtcbiAgICAgICAgICBzZW5kUmVzcG9uc2UoeyBzdWNjZXNzOiB0cnVlLCBvcGVuOiBmYWxzZSB9KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgY2FzZSAncGFnZS5vdmVybGF5LnN0YXR1cyc6XG4gICAgICAgICAgc2VuZFJlc3BvbnNlKHsgc3VjY2VzczogdHJ1ZSwgb3BlbjogcGFnZU92ZXJsYXkuaXNPcGVuKCkgfSk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIC8vIFRhYiBmaWxlc3lzdGVtIHN1cHBvcnRcbiAgICAgIGlmIChyZXF1ZXN0LmFjdGlvbiA9PT0gJ2dldENvbnRlbnQnKSB7XG4gICAgICAgIHNlbmRSZXNwb25zZSh7IGNvbnRlbnQ6IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudD8ub3V0ZXJIVE1MIHx8ICcnIH0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlcXVlc3QuYWN0aW9uID09PSAnc2V0Q29udGVudCcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXF1ZXN0LmNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgZG9jdW1lbnQub3BlbigpO1xuICAgICAgICAgIGRvY3VtZW50LndyaXRlKHJlcXVlc3QuY29udGVudCk7XG4gICAgICAgICAgZG9jdW1lbnQuY2xvc2UoKTtcbiAgICAgICAgfVxuICAgICAgICBzZW5kUmVzcG9uc2UoeyBzdWNjZXNzOiB0cnVlIH0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0U291cmNlTG9jYXRpb24oZWxlbWVudDogSFRNTEVsZW1lbnQpOiBTb3VyY2VMb2NhdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgZnJhbWV3b3JrID0gdGhpcy5kZXRlY3RGcmFtZXdvcmsoKTtcblxuICAgIHN3aXRjaCAoZnJhbWV3b3JrKSB7XG4gICAgICBjYXNlICdyZWFjdCc6XG4gICAgICAgIHJldHVybiB0aGlzLmV4dHJhY3RSZWFjdFNvdXJjZShlbGVtZW50KTtcbiAgICAgIGNhc2UgJ3Z1ZSc6XG4gICAgICAgIHJldHVybiB0aGlzLmV4dHJhY3RWdWVTb3VyY2UoZWxlbWVudCk7XG4gICAgICBjYXNlICdzdmVsdGUnOlxuICAgICAgICByZXR1cm4gdGhpcy5leHRyYWN0U3ZlbHRlU291cmNlKGVsZW1lbnQpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGV4dHJhY3RSZWFjdFNvdXJjZShlbGVtZW50OiBIVE1MRWxlbWVudCk6IFNvdXJjZUxvY2F0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBob29rID0gKHdpbmRvdyBhcyBhbnkpLl9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXztcbiAgICBpZiAoIWhvb2spIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBmaWJlciA9IHRoaXMuZmluZFJlYWN0RmliZXIoZWxlbWVudCk7XG4gICAgaWYgKCFmaWJlcikgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IHNvdXJjZSA9IGZpYmVyLl9kZWJ1Z1NvdXJjZSB8fCBmaWJlci5wZW5kaW5nUHJvcHM/Ll9fc291cmNlIHx8IGZpYmVyLm1lbW9pemVkUHJvcHM/Ll9fc291cmNlO1xuXG4gICAgaWYgKHNvdXJjZSAmJiBzb3VyY2UuZmlsZU5hbWUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGZpbGU6IHNvdXJjZS5maWxlTmFtZSxcbiAgICAgICAgbGluZTogc291cmNlLmxpbmVOdW1iZXIsXG4gICAgICAgIGNvbHVtbjogc291cmNlLmNvbHVtbk51bWJlcixcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgZmluZFJlYWN0RmliZXIoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBhbnkge1xuICAgIGNvbnN0IGtleSA9IE9iamVjdC5rZXlzKGVsZW1lbnQpLmZpbmQoXG4gICAgICAoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUuc3RhcnRzV2l0aCgnX19yZWFjdEludGVybmFsSW5zdGFuY2UkJykgfHwgY2FuZGlkYXRlLnN0YXJ0c1dpdGgoJ19fcmVhY3RGaWJlciQnKSxcbiAgICApO1xuICAgIHJldHVybiBrZXkgPyAoZWxlbWVudCBhcyBhbnkpW2tleV0gOiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0VnVlU291cmNlKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogU291cmNlTG9jYXRpb24gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGhvb2sgPSAod2luZG93IGFzIGFueSkuX19WVUVfREVWVE9PTFNfR0xPQkFMX0hPT0tfXztcbiAgICBpZiAoIWhvb2spIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBsZXQgaW5zdGFuY2UgPSAoZWxlbWVudCBhcyBhbnkpLl9fdnVlUGFyZW50Q29tcG9uZW50O1xuICAgIGlmICghaW5zdGFuY2UpIHtcbiAgICAgIGluc3RhbmNlID0gKGVsZW1lbnQgYXMgYW55KS5fX3Z1ZV9fO1xuICAgIH1cblxuICAgIGlmIChpbnN0YW5jZT8udHlwZT8uX19maWxlKSB7XG4gICAgICBjb25zdCBsb2NhdGlvbjogU291cmNlTG9jYXRpb24gPSB7XG4gICAgICAgIGZpbGU6IGluc3RhbmNlLnR5cGUuX19maWxlLFxuICAgICAgICBsaW5lOiAxLFxuICAgICAgfTtcblxuICAgICAgaWYgKGluc3RhbmNlLnZub2RlPy5sb2MpIHtcbiAgICAgICAgbG9jYXRpb24ubGluZSA9IGluc3RhbmNlLnZub2RlLmxvYy5zdGFydC5saW5lO1xuICAgICAgICBsb2NhdGlvbi5jb2x1bW4gPSBpbnN0YW5jZS52bm9kZS5sb2Muc3RhcnQuY29sdW1uO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbG9jYXRpb247XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgZXh0cmFjdFN2ZWx0ZVNvdXJjZShlbGVtZW50OiBIVE1MRWxlbWVudCk6IFNvdXJjZUxvY2F0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBjb21wb25lbnQgPSAoZWxlbWVudCBhcyBhbnkpLl9fc3ZlbHRlX2NvbXBvbmVudDtcbiAgICBpZiAoY29tcG9uZW50Py4kJD8uY3R4Py4kJF9sb2NhdGlvbikge1xuICAgICAgcmV0dXJuIGNvbXBvbmVudC4kJC5jdHguJCRfbG9jYXRpb247XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGRldGVjdEZyYW1ld29yaygpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBpZiAoKHdpbmRvdyBhcyBhbnkpLl9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXykgcmV0dXJuICdyZWFjdCc7XG4gICAgaWYgKCh3aW5kb3cgYXMgYW55KS5fX1ZVRV9ERVZUT09MU19HTE9CQUxfSE9PS19fKSByZXR1cm4gJ3Z1ZSc7XG4gICAgaWYgKCh3aW5kb3cgYXMgYW55KS5fX3N2ZWx0ZSkgcmV0dXJuICdzdmVsdGUnO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRET01QYXRoKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXRoOiBzdHJpbmdbXSA9IFtdO1xuICAgIGxldCBjdXJyZW50OiBIVE1MRWxlbWVudCB8IG51bGwgPSBlbGVtZW50O1xuXG4gICAgd2hpbGUgKGN1cnJlbnQgJiYgY3VycmVudCAhPT0gZG9jdW1lbnQuYm9keSkge1xuICAgICAgbGV0IHNlbGVjdG9yID0gY3VycmVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgIGlmIChjdXJyZW50LmlkKSB7XG4gICAgICAgIHNlbGVjdG9yICs9IGAjJHtjdXJyZW50LmlkfWA7XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnQuY2xhc3NOYW1lKSB7XG4gICAgICAgIHNlbGVjdG9yICs9IGAuJHtjdXJyZW50LmNsYXNzTmFtZS5zcGxpdCgnICcpLmpvaW4oJy4nKX1gO1xuICAgICAgfVxuXG4gICAgICBwYXRoLnVuc2hpZnQoc2VsZWN0b3IpO1xuICAgICAgY3VycmVudCA9IGN1cnJlbnQucGFyZW50RWxlbWVudDtcbiAgICB9XG5cbiAgICByZXR1cm4gcGF0aC5qb2luKCcgPiAnKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5qZWN0SGVscGVycygpIHtcbiAgICBjb25zdCBzdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG4gICAgc3R5bGUudGV4dENvbnRlbnQgPSBgXG4gICAgICBbZGF0YS1oYW56by1ob3Zlcl0ge1xuICAgICAgICBvdXRsaW5lOiAycHggZGFzaGVkICNmZjZiNmIgIWltcG9ydGFudDtcbiAgICAgICAgb3V0bGluZS1vZmZzZXQ6IDJweCAhaW1wb3J0YW50O1xuICAgICAgfVxuICAgIGA7XG4gICAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG5cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCAoZSkgPT4ge1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW2RhdGEtaGFuem8taG92ZXJdJykuZm9yRWFjaCgoZWwpID0+IHtcbiAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKCdkYXRhLWhhbnpvLWhvdmVyJyk7XG4gICAgICB9KTtcblxuICAgICAgaWYgKGUuYWx0S2V5ICYmIGUudGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgZS50YXJnZXQuc2V0QXR0cmlidXRlKCdkYXRhLWhhbnpvLWhvdmVyJywgJ3RydWUnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gQUkgQ29udHJvbCBPdmVybGF5IFx1MjAxNCB0YWtlb3ZlciB2aXN1YWwgZmVlZGJhY2sgKyB1c2VyIGludGVyYWN0aW9uIGxvY2tcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmNvbnN0IGFpT3ZlcmxheSA9ICgoKSA9PiB7XG4gIGxldCBvdmVybGF5OiBIVE1MRGl2RWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBsZXQgY3Vyc29yOiBIVE1MRGl2RWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBsZXQgc3RhdHVzRWw6IEhUTUxEaXZFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIGxldCBjYW5jZWxCdG46IEhUTUxCdXR0b25FbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIGxldCBoaWdobGlnaHRFbDogSFRNTERpdkVsZW1lbnQgfCBudWxsID0gbnVsbDtcbiAgbGV0IHRyYWlsTm9kZXM6IEhUTUxEaXZFbGVtZW50W10gPSBbXTtcbiAgbGV0IGludGVyYWN0aW9uQmxvY2tBY3RpdmUgPSBmYWxzZTtcblxuICBjb25zdCBPVkVSTEFZX0lEID0gJ2hhbnpvLWFpLW92ZXJsYXknO1xuICBjb25zdCBTVFlMRVNfSUQgPSAnaGFuem8tYWktb3ZlcmxheS1zdHlsZXMnO1xuICBjb25zdCBCTE9DS0VEX0VWRU5UUyA9IFtcbiAgICAnY2xpY2snLCAnZGJsY2xpY2snLCAnbW91c2Vkb3duJywgJ21vdXNldXAnLCAnY29udGV4dG1lbnUnLFxuICAgICdwb2ludGVyZG93bicsICdwb2ludGVydXAnLCAndG91Y2hzdGFydCcsICd0b3VjaG1vdmUnLCAndG91Y2hlbmQnLCAnd2hlZWwnLFxuICAgICdrZXlkb3duJywgJ2tleXVwJywgJ2tleXByZXNzJyxcbiAgXTtcblxuICBmdW5jdGlvbiBpbmplY3RTdHlsZXMoKSB7XG4gICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFNUWUxFU19JRCkpIHJldHVybjtcblxuICAgIGNvbnN0IHN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICBzdHlsZS5pZCA9IFNUWUxFU19JRDtcbiAgICBzdHlsZS50ZXh0Q29udGVudCA9IGBcbiAgICAgIC8qIC0tLS0gT3ZlcmxheSBiYWNrZHJvcCAtLS0tICovXG4gICAgICAjJHtPVkVSTEFZX0lEfSB7XG4gICAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgICAgaW5zZXQ6IDA7XG4gICAgICAgIHotaW5kZXg6IDIxNDc0ODM2NDY7XG4gICAgICAgIHBvaW50ZXItZXZlbnRzOiBhbGw7XG4gICAgICAgIGJhY2tncm91bmQ6XG4gICAgICAgICAgcmFkaWFsLWdyYWRpZW50KDkwdncgOTB2aCBhdCAxNSUgOCUsIHJnYmEoNTYsIDE4OSwgMjQ4LCAwLjEwKSwgdHJhbnNwYXJlbnQgNTUlKSxcbiAgICAgICAgICByYWRpYWwtZ3JhZGllbnQoNjV2dyA2NXZoIGF0IDg0JSA4MiUsIHJnYmEoOTksIDEwMiwgMjQxLCAwLjEwKSwgdHJhbnNwYXJlbnQgNjAlKSxcbiAgICAgICAgICByZ2JhKDIsIDQsIDEwLCAwLjQyKTtcbiAgICAgICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDEuNXB4KTtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNpdGlvbjogb3BhY2l0eSAzMDBtcyBlYXNlO1xuICAgICAgfVxuICAgICAgIyR7T1ZFUkxBWV9JRH0uaGFuem8tdmlzaWJsZSB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICB9XG5cbiAgICAgIC8qIC0tLS0gUHVsc2luZyBjeWFuIGdsb3cgY3Vyc29yIC0tLS0gKi9cbiAgICAgIC5oYW56by1haS1jdXJzb3Ige1xuICAgICAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgICAgIHdpZHRoOiAyNHB4O1xuICAgICAgICBoZWlnaHQ6IDI0cHg7XG4gICAgICAgIHotaW5kZXg6IDIxNDc0ODM2NDc7XG4gICAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgICAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgICAgIGJvcmRlcjogMnB4IHNvbGlkIHJnYmEoNiwgMTgyLCAyMTIsIDAuOTUpO1xuICAgICAgICBib3gtc2hhZG93OlxuICAgICAgICAgIDAgMCA4cHggMnB4IHJnYmEoNiwgMTgyLCAyMTIsIDAuNDUpLFxuICAgICAgICAgIDAgMCAyNHB4IDZweCByZ2JhKDYsIDE4MiwgMjEyLCAwLjE4KTtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7XG4gICAgICAgIHRyYW5zaXRpb246IGxlZnQgMC4xOHMgZWFzZS1vdXQsIHRvcCAwLjE4cyBlYXNlLW91dDtcbiAgICAgICAgYW5pbWF0aW9uOiBoYW56by1jdXJzb3ItcHVsc2UgMS42cyBlYXNlLWluLW91dCBpbmZpbml0ZTtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgIH1cbiAgICAgIC5oYW56by1haS1jdXJzb3IuaGFuem8tdmlzaWJsZSB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIHRyYW5zaXRpb246IGxlZnQgMC4xOHMgZWFzZS1vdXQsIHRvcCAwLjE4cyBlYXNlLW91dCwgb3BhY2l0eSAzMDBtcyBlYXNlO1xuICAgICAgfVxuICAgICAgQGtleWZyYW1lcyBoYW56by1jdXJzb3ItcHVsc2Uge1xuICAgICAgICAwJSwgMTAwJSB7XG4gICAgICAgICAgYm94LXNoYWRvdzpcbiAgICAgICAgICAgIDAgMCA4cHggMnB4IHJnYmEoNiwgMTgyLCAyMTIsIDAuNDUpLFxuICAgICAgICAgICAgMCAwIDI0cHggNnB4IHJnYmEoNiwgMTgyLCAyMTIsIDAuMTgpO1xuICAgICAgICB9XG4gICAgICAgIDUwJSB7XG4gICAgICAgICAgYm94LXNoYWRvdzpcbiAgICAgICAgICAgIDAgMCAxNHB4IDRweCByZ2JhKDYsIDE4MiwgMjEyLCAwLjY1KSxcbiAgICAgICAgICAgIDAgMCAzNnB4IDEwcHggcmdiYSg2LCAxODIsIDIxMiwgMC4yOCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLyogLS0tLSBDdXJzb3IgdHJhaWwgLS0tLSAqL1xuICAgICAgLmhhbnpvLWN1cnNvci10cmFpbCB7XG4gICAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgICAgd2lkdGg6IDZweDtcbiAgICAgICAgaGVpZ2h0OiA2cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICAgICAgYmFja2dyb3VuZDogcmdiYSg2LCAxODIsIDIxMiwgMC43KTtcbiAgICAgICAgei1pbmRleDogMjE0NzQ4MzY0NjtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpO1xuICAgICAgICBhbmltYXRpb246IGhhbnpvLXRyYWlsLWZhZGUgMC40cyBlYXNlLW91dCBmb3J3YXJkcztcbiAgICAgIH1cbiAgICAgIEBrZXlmcmFtZXMgaGFuem8tdHJhaWwtZmFkZSB7XG4gICAgICAgIGZyb20geyBvcGFjaXR5OiAwLjc7IHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpIHNjYWxlKDEpOyB9XG4gICAgICAgIHRvIHsgb3BhY2l0eTogMDsgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSkgc2NhbGUoMC4xNSk7IH1cbiAgICAgIH1cblxuICAgICAgLyogLS0tLSBTdGF0dXMgYmFubmVyICh0b3AgY2VudGVyIHBpbGwpIC0tLS0gKi9cbiAgICAgIC5oYW56by1haS1zdGF0dXMge1xuICAgICAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgICAgIHRvcDogMTZweDtcbiAgICAgICAgbGVmdDogNTAlO1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTUwJSk7XG4gICAgICAgIHotaW5kZXg6IDIxNDc0ODM2NDc7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgIGdhcDogMTBweDtcbiAgICAgICAgbWF4LXdpZHRoOiA5MHZ3O1xuICAgICAgICBwYWRkaW5nOiAxMHB4IDE0cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDE2cHg7XG4gICAgICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsIHJnYmEoOCwgMTIsIDIwLCAwLjk0KSwgcmdiYSgxMCwgMTYsIDI0LCAwLjk2KSk7XG4gICAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoNTYsIDE4OSwgMjQ4LCAwLjI2KTtcbiAgICAgICAgY29sb3I6ICNmM2Y0ZjY7XG4gICAgICAgIGZvbnQ6IDEzcHgvMS40IC1hcHBsZS1zeXN0ZW0sIEJsaW5rTWFjU3lzdGVtRm9udCwgJ1NlZ29lIFVJJywgc2Fucy1zZXJpZjtcbiAgICAgICAgYm94LXNoYWRvdzpcbiAgICAgICAgICAwIDEwcHggMzZweCByZ2JhKDAsIDAsIDAsIDAuNDYpLFxuICAgICAgICAgIGluc2V0IDAgMXB4IDAgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjA4KTtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNpdGlvbjogb3BhY2l0eSAzMDBtcyBlYXNlO1xuICAgICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgICAgfVxuICAgICAgLmhhbnpvLWFpLXN0YXR1czo6YmVmb3JlIHtcbiAgICAgICAgY29udGVudDogJyc7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgaW5zZXQ6IC0ycHggYXV0byAtMnB4IC0yMCU7XG4gICAgICAgIHdpZHRoOiA0MCU7XG4gICAgICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCg5MGRlZywgdHJhbnNwYXJlbnQsIHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4xNiksIHRyYW5zcGFyZW50KTtcbiAgICAgICAgdHJhbnNmb3JtOiBza2V3WCgtMThkZWcpO1xuICAgICAgICBhbmltYXRpb246IGhhbnpvLXN0YXR1cy1zaGVlbiAzLjZzIGVhc2UtaW4tb3V0IGluZmluaXRlO1xuICAgICAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICAgIH1cbiAgICAgIEBrZXlmcmFtZXMgaGFuem8tc3RhdHVzLXNoZWVuIHtcbiAgICAgICAgMCUsIDY4JSB7IGxlZnQ6IC0zMCU7IG9wYWNpdHk6IDA7IH1cbiAgICAgICAgNzIlIHsgb3BhY2l0eTogMC40OyB9XG4gICAgICAgIDEwMCUgeyBsZWZ0OiAxMzAlOyBvcGFjaXR5OiAwOyB9XG4gICAgICB9XG4gICAgICAuaGFuem8tYWktc3RhdHVzID4gKiB7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgIH1cbiAgICAgIC5oYW56by1haS1zdGF0dXMuaGFuem8tdmlzaWJsZSB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1haS1zdGF0dXMgLmhhbnpvLWJyYW5kLWJ1YmJsZSB7XG4gICAgICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICAgICAgaGVpZ2h0OiAyMHB4O1xuICAgICAgICBtaW4td2lkdGg6IDMwcHg7XG4gICAgICAgIHBhZGRpbmc6IDAgOHB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiA5OTk5cHg7XG4gICAgICAgIGZvbnQtc2l6ZTogMTBweDtcbiAgICAgICAgbGV0dGVyLXNwYWNpbmc6IDAuMjVweDtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICAgICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgICAgICAgY29sb3I6ICNlMGYyZmU7XG4gICAgICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxODBkZWcsIHJnYmEoMTQsIDExNiwgMTQ0LCAwLjk1KSwgcmdiYSgxNSwgMjMsIDQyLCAwLjk1KSk7XG4gICAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoNTYsIDE4OSwgMjQ4LCAwLjM1KTtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLWFpLXN0YXR1cyAuaGFuem8tcHVsc2UtZG90IHtcbiAgICAgICAgd2lkdGg6IDhweDtcbiAgICAgICAgaGVpZ2h0OiA4cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDk5OTlweDtcbiAgICAgICAgYmFja2dyb3VuZDogIzA2YjZkNDtcbiAgICAgICAgYW5pbWF0aW9uOiBoYW56by1kb3QtcHVsc2UgMS40cyBlYXNlLWluLW91dCBpbmZpbml0ZTtcbiAgICAgIH1cbiAgICAgIEBrZXlmcmFtZXMgaGFuem8tZG90LXB1bHNlIHtcbiAgICAgICAgMCUsIDEwMCUgeyBvcGFjaXR5OiAxOyB9XG4gICAgICAgIDUwJSB7IG9wYWNpdHk6IDAuNDsgfVxuICAgICAgfVxuXG4gICAgICAuaGFuem8tYWktc3RhdHVzIC5oYW56by1sYWJlbCB7XG4gICAgICAgIG1heC13aWR0aDogNDZ2dztcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1haS1zdGF0dXMgLmhhbnpvLWRvdHM6OmFmdGVyIHtcbiAgICAgICAgY29udGVudDogJyc7XG4gICAgICAgIGFuaW1hdGlvbjogaGFuem8tYW5pbWF0ZWQtZG90cyAxLjVzIHN0ZXBzKDQpIGluZmluaXRlO1xuICAgICAgfVxuICAgICAgQGtleWZyYW1lcyBoYW56by1hbmltYXRlZC1kb3RzIHtcbiAgICAgICAgMCUgeyBjb250ZW50OiAnJzsgfVxuICAgICAgICAyNSUgeyBjb250ZW50OiAnLic7IH1cbiAgICAgICAgNTAlIHsgY29udGVudDogJy4uJzsgfVxuICAgICAgICA3NSUgeyBjb250ZW50OiAnLi4uJzsgfVxuICAgICAgfVxuXG4gICAgICAuaGFuem8tYWktc3RhdHVzIC5oYW56by1zdG9wLWJ0biB7XG4gICAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4yNCk7XG4gICAgICAgIGJhY2tncm91bmQ6IHJnYmEoMCwgMCwgMCwgMC4xOCk7XG4gICAgICAgIGNvbG9yOiAjZjhmYWZjO1xuICAgICAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICAgICAgICBwYWRkaW5nOiA0cHggMTJweDtcbiAgICAgICAgZm9udC1zaXplOiAxMnB4O1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQgMC4xNXMsIGJvcmRlci1jb2xvciAwLjE1cztcbiAgICAgIH1cbiAgICAgIC5oYW56by1haS1zdGF0dXMgLmhhbnpvLXN0b3AtYnRuOmhvdmVyIHtcbiAgICAgICAgYmFja2dyb3VuZDogcmdiYSgyMjAsIDM4LCAzOCwgMC4yOCk7XG4gICAgICAgIGJvcmRlci1jb2xvcjogcmdiYSgyNDgsIDExMywgMTEzLCAwLjYpO1xuICAgICAgfVxuXG4gICAgICAvKiAtLS0tIFwiVGFrZSBCYWNrIENvbnRyb2xcIiBidXR0b24gKGJvdHRvbS1yaWdodCkgLS0tLSAqL1xuICAgICAgLmhhbnpvLWFpLWNhbmNlbCB7XG4gICAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgICAgYm90dG9tOiAyNHB4O1xuICAgICAgICByaWdodDogMjRweDtcbiAgICAgICAgei1pbmRleDogMjE0NzQ4MzY0NztcbiAgICAgICAgcGFkZGluZzogMTJweCAyNHB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICAgICAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMik7XG4gICAgICAgIGJhY2tncm91bmQ6IHJnYmEoMTUsIDE4LCAyNCwgMC45NSk7XG4gICAgICAgIGNvbG9yOiAjZjNmNGY2O1xuICAgICAgICBmb250OiA2MDAgMTRweC8xLjQgLWFwcGxlLXN5c3RlbSwgQmxpbmtNYWNTeXN0ZW1Gb250LCAnU2Vnb2UgVUknLCBzYW5zLXNlcmlmO1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICAgIGJveC1zaGFkb3c6IDAgOHB4IDI0cHggcmdiYSgwLCAwLCAwLCAwLjQpO1xuICAgICAgICBwb2ludGVyLWV2ZW50czogYXV0bztcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNpdGlvbjogb3BhY2l0eSAzMDBtcyBlYXNlLCBiYWNrZ3JvdW5kIDAuMTVzO1xuICAgICAgfVxuICAgICAgLmhhbnpvLWFpLWNhbmNlbC5oYW56by12aXNpYmxlIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgIH1cbiAgICAgIC5oYW56by1haS1jYW5jZWw6aG92ZXIge1xuICAgICAgICBiYWNrZ3JvdW5kOiByZ2JhKDIyMCwgMzgsIDM4LCAwLjM1KTtcbiAgICAgICAgYm9yZGVyLWNvbG9yOiByZ2JhKDIyMCwgMzgsIDM4LCAwLjUpO1xuICAgICAgfVxuXG4gICAgICAvKiAtLS0tIEVsZW1lbnQgaGlnaGxpZ2h0IC0tLS0gKi9cbiAgICAgIC5oYW56by1haS1oaWdobGlnaHQge1xuICAgICAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgICAgIHotaW5kZXg6IDIxNDc0ODM2NDc7XG4gICAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgICAgICBib3JkZXI6IDJweCBzb2xpZCByZ2JhKDYsIDE4MiwgMjEyLCAwLjg1KTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogNnB4O1xuICAgICAgICBib3gtc2hhZG93OiAwIDAgMCAzcHggcmdiYSg2LCAxODIsIDIxMiwgMC4xNSk7XG4gICAgICAgIHRyYW5zaXRpb246IGxlZnQgMC4xNXMsIHRvcCAwLjE1cywgd2lkdGggMC4xNXMsIGhlaWdodCAwLjE1cztcbiAgICAgIH1cbiAgICBgO1xuICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc3R5bGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNPdmVybGF5RWxlbWVudCh0YXJnZXQ6IEV2ZW50VGFyZ2V0IHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIE5vZGUpKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuICEhKFxuICAgICAgb3ZlcmxheT8uY29udGFpbnModGFyZ2V0KSB8fFxuICAgICAgc3RhdHVzRWw/LmNvbnRhaW5zKHRhcmdldCkgfHxcbiAgICAgIGNhbmNlbEJ0bj8uY29udGFpbnModGFyZ2V0KSB8fFxuICAgICAgY3Vyc29yPy5jb250YWlucyh0YXJnZXQpIHx8XG4gICAgICBoaWdobGlnaHRFbD8uY29udGFpbnModGFyZ2V0KVxuICAgICk7XG4gIH1cblxuICBmdW5jdGlvbiBibG9ja0ludGVyYWN0aW9uKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGlmICghaW50ZXJhY3Rpb25CbG9ja0FjdGl2ZSkgcmV0dXJuO1xuXG4gICAgaWYgKGV2ZW50IGluc3RhbmNlb2YgS2V5Ym9hcmRFdmVudCAmJiBldmVudC5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICBjaHJvbWUucnVudGltZS5zZW5kTWVzc2FnZSh7IGFjdGlvbjogJ2FpLmNvbnRyb2wuY2FuY2VsJyB9KTtcbiAgICAgIGhpZGUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoaXNPdmVybGF5RWxlbWVudChldmVudC50YXJnZXQpKSByZXR1cm47XG5cbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgZnVuY3Rpb24gc2V0SW50ZXJhY3Rpb25CbG9jayhhY3RpdmU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAoaW50ZXJhY3Rpb25CbG9ja0FjdGl2ZSA9PT0gYWN0aXZlKSByZXR1cm47XG5cbiAgICBpbnRlcmFjdGlvbkJsb2NrQWN0aXZlID0gYWN0aXZlO1xuICAgIGZvciAoY29uc3QgZXZlbnROYW1lIG9mIEJMT0NLRURfRVZFTlRTKSB7XG4gICAgICBpZiAoYWN0aXZlKSB7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBibG9ja0ludGVyYWN0aW9uLCB0cnVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBibG9ja0ludGVyYWN0aW9uLCB0cnVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzaG93KHRhc2s6IHN0cmluZykge1xuICAgIGlmIChvdmVybGF5KSBoaWRlKCk7XG5cbiAgICBpbmplY3RTdHlsZXMoKTtcbiAgICBzZXRJbnRlcmFjdGlvbkJsb2NrKHRydWUpO1xuXG4gICAgLy8gQmFja2Ryb3BcbiAgICBvdmVybGF5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgb3ZlcmxheS5pZCA9IE9WRVJMQVlfSUQ7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChvdmVybGF5KTtcblxuICAgIC8vIEN1cnNvclxuICAgIGN1cnNvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGN1cnNvci5jbGFzc05hbWUgPSAnaGFuem8tYWktY3Vyc29yJztcbiAgICBjdXJzb3Iuc3R5bGUubGVmdCA9IGAke3dpbmRvdy5pbm5lcldpZHRoIC8gMn1weGA7XG4gICAgY3Vyc29yLnN0eWxlLnRvcCA9IGAke3dpbmRvdy5pbm5lckhlaWdodCAvIDJ9cHhgO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoY3Vyc29yKTtcblxuICAgIC8vIFN0YXR1cyBiYW5uZXJcbiAgICBzdGF0dXNFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHN0YXR1c0VsLmNsYXNzTmFtZSA9ICdoYW56by1haS1zdGF0dXMnO1xuICAgIHN0YXR1c0VsLmlubmVySFRNTCA9IGBcbiAgICAgIDxzcGFuIGNsYXNzPVwiaGFuem8tYnJhbmQtYnViYmxlXCI+QUk8L3NwYW4+XG4gICAgICA8ZGl2IGNsYXNzPVwiaGFuem8tcHVsc2UtZG90XCI+PC9kaXY+XG4gICAgICA8c3BhbiBjbGFzcz1cImhhbnpvLWxhYmVsXCI+JHtlc2NhcGVIdG1sKHRhc2sgfHwgJ0hhbnpvIEFJIGlzIGNvbnRyb2xsaW5nIHRoaXMgdGFiJyl9PC9zcGFuPjxzcGFuIGNsYXNzPVwiaGFuem8tZG90c1wiPjwvc3Bhbj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJoYW56by1zdG9wLWJ0blwiPlN0b3A8L2J1dHRvbj5cbiAgICBgO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoc3RhdHVzRWwpO1xuXG4gICAgc3RhdHVzRWwucXVlcnlTZWxlY3RvcignLmhhbnpvLXN0b3AtYnRuJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgY2hyb21lLnJ1bnRpbWUuc2VuZE1lc3NhZ2UoeyBhY3Rpb246ICdhaS5jb250cm9sLmNhbmNlbCcgfSk7XG4gICAgICBoaWRlKCk7XG4gICAgfSk7XG5cbiAgICAvLyBcIlRha2UgQmFjayBDb250cm9sXCIgYnV0dG9uXG4gICAgY2FuY2VsQnRuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7XG4gICAgY2FuY2VsQnRuLmNsYXNzTmFtZSA9ICdoYW56by1haS1jYW5jZWwnO1xuICAgIGNhbmNlbEJ0bi50ZXh0Q29udGVudCA9ICdUYWtlIEJhY2sgQ29udHJvbCc7XG4gICAgY2FuY2VsQnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgY2hyb21lLnJ1bnRpbWUuc2VuZE1lc3NhZ2UoeyBhY3Rpb246ICdhaS5jb250cm9sLmNhbmNlbCcgfSk7XG4gICAgICBoaWRlKCk7XG4gICAgfSk7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChjYW5jZWxCdG4pO1xuXG4gICAgLy8gRmFkZSBpbiAobmV4dCBmcmFtZSBzbyB0aGUgdHJhbnNpdGlvbiB0cmlnZ2VycylcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgb3ZlcmxheT8uY2xhc3NMaXN0LmFkZCgnaGFuem8tdmlzaWJsZScpO1xuICAgICAgY3Vyc29yPy5jbGFzc0xpc3QuYWRkKCdoYW56by12aXNpYmxlJyk7XG4gICAgICBzdGF0dXNFbD8uY2xhc3NMaXN0LmFkZCgnaGFuem8tdmlzaWJsZScpO1xuICAgICAgY2FuY2VsQnRuPy5jbGFzc0xpc3QuYWRkKCdoYW56by12aXNpYmxlJyk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBoaWRlKCkge1xuICAgIC8vIEZhZGUgb3V0XG4gICAgb3ZlcmxheT8uY2xhc3NMaXN0LnJlbW92ZSgnaGFuem8tdmlzaWJsZScpO1xuICAgIGN1cnNvcj8uY2xhc3NMaXN0LnJlbW92ZSgnaGFuem8tdmlzaWJsZScpO1xuICAgIHN0YXR1c0VsPy5jbGFzc0xpc3QucmVtb3ZlKCdoYW56by12aXNpYmxlJyk7XG4gICAgY2FuY2VsQnRuPy5jbGFzc0xpc3QucmVtb3ZlKCdoYW56by12aXNpYmxlJyk7XG5cbiAgICAvLyBSZW1vdmUgYWZ0ZXIgdHJhbnNpdGlvblxuICAgIGNvbnN0IHJlZnMgPSB7IG92ZXJsYXksIGN1cnNvciwgc3RhdHVzRWwsIGNhbmNlbEJ0biwgaGlnaGxpZ2h0RWwgfTtcbiAgICBjb25zdCB0cmFpbHMgPSBbLi4udHJhaWxOb2Rlc107XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHJlZnMub3ZlcmxheT8ucmVtb3ZlKCk7XG4gICAgICByZWZzLmN1cnNvcj8ucmVtb3ZlKCk7XG4gICAgICByZWZzLnN0YXR1c0VsPy5yZW1vdmUoKTtcbiAgICAgIHJlZnMuY2FuY2VsQnRuPy5yZW1vdmUoKTtcbiAgICAgIHJlZnMuaGlnaGxpZ2h0RWw/LnJlbW92ZSgpO1xuICAgICAgZm9yIChjb25zdCBub2RlIG9mIHRyYWlscykge1xuICAgICAgICBub2RlLnJlbW92ZSgpO1xuICAgICAgfVxuICAgIH0sIDMyMCk7XG5cbiAgICBzZXRJbnRlcmFjdGlvbkJsb2NrKGZhbHNlKTtcblxuICAgIG92ZXJsYXkgPSBudWxsO1xuICAgIGN1cnNvciA9IG51bGw7XG4gICAgc3RhdHVzRWwgPSBudWxsO1xuICAgIGNhbmNlbEJ0biA9IG51bGw7XG4gICAgaGlnaGxpZ2h0RWwgPSBudWxsO1xuICAgIHRyYWlsTm9kZXMgPSBbXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1vdmVDdXJzb3IoeDogbnVtYmVyLCB5OiBudW1iZXIpIHtcbiAgICBpZiAoIWN1cnNvcikgcmV0dXJuO1xuXG4gICAgY29uc3QgY2xhbXBlZFggPSBNYXRoLm1heCgwLCBNYXRoLm1pbih3aW5kb3cuaW5uZXJXaWR0aCwgTnVtYmVyLmlzRmluaXRlKHgpID8geCA6IDApKTtcbiAgICBjb25zdCBjbGFtcGVkWSA9IE1hdGgubWF4KDAsIE1hdGgubWluKHdpbmRvdy5pbm5lckhlaWdodCwgTnVtYmVyLmlzRmluaXRlKHkpID8geSA6IDApKTtcblxuICAgIC8vIFRyYWlsIGRvdFxuICAgIGNvbnN0IHRyYWlsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdHJhaWwuY2xhc3NOYW1lID0gJ2hhbnpvLWN1cnNvci10cmFpbCc7XG4gICAgdHJhaWwuc3R5bGUubGVmdCA9IGAke2NsYW1wZWRYfXB4YDtcbiAgICB0cmFpbC5zdHlsZS50b3AgPSBgJHtjbGFtcGVkWX1weGA7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0cmFpbCk7XG4gICAgdHJhaWxOb2Rlcy5wdXNoKHRyYWlsKTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdHJhaWwucmVtb3ZlKCk7XG4gICAgICB0cmFpbE5vZGVzID0gdHJhaWxOb2Rlcy5maWx0ZXIoKG5vZGUpID0+IG5vZGUgIT09IHRyYWlsKTtcbiAgICB9LCA0MDApO1xuXG4gICAgd2hpbGUgKHRyYWlsTm9kZXMubGVuZ3RoID4gMTApIHtcbiAgICAgIHRyYWlsTm9kZXMuc2hpZnQoKT8ucmVtb3ZlKCk7XG4gICAgfVxuXG4gICAgY3Vyc29yLnN0eWxlLmxlZnQgPSBgJHtjbGFtcGVkWH1weGA7XG4gICAgY3Vyc29yLnN0eWxlLnRvcCA9IGAke2NsYW1wZWRZfXB4YDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhpZ2hsaWdodChzZWxlY3Rvcjogc3RyaW5nKSB7XG4gICAgaGlnaGxpZ2h0RWw/LnJlbW92ZSgpO1xuICAgIGhpZ2hsaWdodEVsID0gbnVsbDtcblxuICAgIGlmICghc2VsZWN0b3IgfHwgdHlwZW9mIHNlbGVjdG9yICE9PSAnc3RyaW5nJykgcmV0dXJuO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgICAgaWYgKCF0YXJnZXQpIHJldHVybjtcblxuICAgICAgY29uc3QgcmVjdCA9IHRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGlmIChyZWN0LndpZHRoID09PSAwICYmIHJlY3QuaGVpZ2h0ID09PSAwKSByZXR1cm47XG5cbiAgICAgIGhpZ2hsaWdodEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBoaWdobGlnaHRFbC5jbGFzc05hbWUgPSAnaGFuem8tYWktaGlnaGxpZ2h0JztcbiAgICAgIGhpZ2hsaWdodEVsLnN0eWxlLmxlZnQgPSBgJHtNYXRoLm1heCgwLCByZWN0LmxlZnQgLSA0KX1weGA7XG4gICAgICBoaWdobGlnaHRFbC5zdHlsZS50b3AgPSBgJHtNYXRoLm1heCgwLCByZWN0LnRvcCAtIDQpfXB4YDtcbiAgICAgIGhpZ2hsaWdodEVsLnN0eWxlLndpZHRoID0gYCR7cmVjdC53aWR0aCArIDh9cHhgO1xuICAgICAgaGlnaGxpZ2h0RWwuc3R5bGUuaGVpZ2h0ID0gYCR7cmVjdC5oZWlnaHQgKyA4fXB4YDtcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaGlnaGxpZ2h0RWwpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gSWdub3JlIGludmFsaWQgc2VsZWN0b3JzLlxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVN0YXR1cyh0ZXh0OiBzdHJpbmcpIHtcbiAgICBpZiAoIXN0YXR1c0VsKSByZXR1cm47XG5cbiAgICBjb25zdCBsYWJlbCA9IHN0YXR1c0VsLnF1ZXJ5U2VsZWN0b3IoJy5oYW56by1sYWJlbCcpO1xuICAgIGlmIChsYWJlbCkge1xuICAgICAgbGFiZWwudGV4dENvbnRlbnQgPSB0ZXh0IHx8ICdIYW56byBBSSBpcyBjb250cm9sbGluZyB0aGlzIHRhYic7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZXNjYXBlSHRtbCh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi50ZXh0Q29udGVudCA9IHRleHQ7XG4gICAgcmV0dXJuIGRpdi5pbm5lckhUTUw7XG4gIH1cblxuICByZXR1cm4geyBzaG93LCBoaWRlLCBtb3ZlQ3Vyc29yLCBoaWdobGlnaHQsIHVwZGF0ZVN0YXR1cyB9O1xufSkoKTtcblxudHlwZSBPdmVybGF5Q2hhdFJvbGUgPSAndXNlcicgfCAnYXNzaXN0YW50JyB8ICdzeXN0ZW0nO1xuXG5pbnRlcmZhY2UgT3ZlcmxheUNoYXRNZXNzYWdlIHtcbiAgcm9sZTogT3ZlcmxheUNoYXRSb2xlO1xuICBjb250ZW50OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBPdmVybGF5RWxlbWVudENvbnRleHQge1xuICBzZWxlY3Rvcjogc3RyaW5nO1xuICB0YWc6IHN0cmluZztcbiAgdGV4dDogc3RyaW5nO1xuICBodG1sOiBzdHJpbmc7XG59XG5cbmNsYXNzIEhhbnpvUGFnZU92ZXJsYXkge1xuICBwcml2YXRlIG1vdW50ZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBlbmFibGVkID0gZmFsc2U7XG4gIHByaXZhdGUgb3BlbiA9IGZhbHNlO1xuICBwcml2YXRlIHNlbmRpbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSB3YXRjaE1vZGUgPSBmYWxzZTtcbiAgcHJpdmF0ZSBlZGl0TW9kZSA9IGZhbHNlO1xuICBwcml2YXRlIG1vZGVsc0xvYWRlZCA9IGZhbHNlO1xuICBwcml2YXRlIG1lc3NhZ2VzOiBPdmVybGF5Q2hhdE1lc3NhZ2VbXSA9IFtdO1xuICBwcml2YXRlIHNlbGVjdGVkQ29udGV4dDogT3ZlcmxheUVsZW1lbnRDb250ZXh0IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaG92ZXJlZEVsZW1lbnQ6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgZWRpdGluZ0VsZW1lbnQ6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSByb290OiBIVE1MRGl2RWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGxhdW5jaGVyOiBIVE1MQnV0dG9uRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHBhbmVsOiBIVE1MRGl2RWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIG1lc3NhZ2VzRWw6IEhUTUxEaXZFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaW5wdXRFbDogSFRNTFRleHRBcmVhRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHNlbmRCdG46IEhUTUxCdXR0b25FbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgbW9kZWxFbDogSFRNTFNlbGVjdEVsZW1lbnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjb250ZXh0RWw6IEhUTUxEaXZFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgd2F0Y2hCdG46IEhUTUxCdXR0b25FbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgZWRpdEJ0bjogSFRNTEJ1dHRvbkVsZW1lbnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBzdGF0dXNFbDogSFRNTFNwYW5FbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaGlnaGxpZ2h0Qm94OiBIVE1MRGl2RWxlbWVudCB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuaW5qZWN0U3R5bGVzKCk7XG4gICAgdGhpcy5tb3VudCgpO1xuICAgIHRoaXMuYmluZEdsb2JhbEV2ZW50cygpO1xuICB9XG5cbiAgdG9nZ2xlKCk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5lbmFibGVkIHx8ICF0aGlzLm9wZW4pIHtcbiAgICAgIHRoaXMuc2hvdygpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHRoaXMuaGlkZSgpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHNob3coKTogdm9pZCB7XG4gICAgdGhpcy5lbnN1cmVNb3VudGVkKCk7XG4gICAgdGhpcy5lbmFibGVkID0gdHJ1ZTtcbiAgICB0aGlzLm9wZW4gPSB0cnVlO1xuICAgIHRoaXMucm9vdD8uc2V0QXR0cmlidXRlKCdkYXRhLWVuYWJsZWQnLCAndHJ1ZScpO1xuICAgIHRoaXMucm9vdD8uc2V0QXR0cmlidXRlKCdkYXRhLW9wZW4nLCAndHJ1ZScpO1xuICAgIHRoaXMubG9hZE1vZGVscygpO1xuICAgIHRoaXMuZm9jdXNJbnB1dCgpO1xuICB9XG5cbiAgaGlkZSgpOiB2b2lkIHtcbiAgICB0aGlzLm9wZW4gPSBmYWxzZTtcbiAgICB0aGlzLnJvb3Q/LnNldEF0dHJpYnV0ZSgnZGF0YS1vcGVuJywgJ2ZhbHNlJyk7XG4gICAgdGhpcy51cGRhdGVTdGF0dXMoJycpO1xuICAgIHRoaXMuY2xlYXJIaWdobGlnaHQoKTtcbiAgICB0aGlzLnNldFdhdGNoTW9kZShmYWxzZSk7XG4gICAgdGhpcy5zZXRFZGl0TW9kZShmYWxzZSk7XG4gIH1cblxuICBpc09wZW4oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMub3BlbjtcbiAgfVxuXG4gIHByaXZhdGUgZW5zdXJlTW91bnRlZCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tb3VudGVkKSByZXR1cm47XG4gICAgdGhpcy5tb3VudCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbmplY3RTdHlsZXMoKTogdm9pZCB7XG4gICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoYW56by1wYWdlLW92ZXJsYXktc3R5bGVzJykpIHJldHVybjtcblxuICAgIGNvbnN0IHN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICBzdHlsZS5pZCA9ICdoYW56by1wYWdlLW92ZXJsYXktc3R5bGVzJztcbiAgICBzdHlsZS50ZXh0Q29udGVudCA9IGBcbiAgICAgICNoYW56by1wYWdlLW92ZXJsYXktcm9vdCB7XG4gICAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgICAgcmlnaHQ6IDIwcHg7XG4gICAgICAgIGJvdHRvbTogMjBweDtcbiAgICAgICAgei1pbmRleDogMjE0NzQ4MzY0NTtcbiAgICAgICAgZm9udC1mYW1pbHk6IC1hcHBsZS1zeXN0ZW0sIEJsaW5rTWFjU3lzdGVtRm9udCwgJ1NlZ29lIFVJJywgc2Fucy1zZXJpZjtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgICB9XG5cbiAgICAgICNoYW56by1wYWdlLW92ZXJsYXktcm9vdCAqIHtcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgIH1cblxuICAgICAgI2hhbnpvLXBhZ2Utb3ZlcmxheS1yb290W2RhdGEtZW5hYmxlZD1cImZhbHNlXCJdIC5oYW56by1wYWdlLWxhdW5jaGVyIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDE2cHgpO1xuICAgICAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLXBhZ2UtbGF1bmNoZXIge1xuICAgICAgICB3aWR0aDogNTRweDtcbiAgICAgICAgaGVpZ2h0OiA1NHB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiA5OTk5cHg7XG4gICAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4yKTtcbiAgICAgICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgcmdiYSgyMiwgMjQsIDMxLCAwLjk2KSwgcmdiYSg3LCA4LCAxMiwgMC45NikpO1xuICAgICAgICBjb2xvcjogI2ZmZmZmZjtcbiAgICAgICAgYm94LXNoYWRvdzogMCAxNHB4IDM0cHggcmdiYSgwLCAwLCAwLCAwLjM1KTtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IGF1dG87XG4gICAgICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjJzIGVhc2UsIG9wYWNpdHkgMC4ycyBlYXNlO1xuICAgICAgfVxuXG4gICAgICAuaGFuem8tcGFnZS1sYXVuY2hlcjpob3ZlciB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtMnB4KTtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLXBhZ2UtcGFuZWwge1xuICAgICAgICB3aWR0aDogbWluKDQyMHB4LCBjYWxjKDEwMHZ3IC0gMjRweCkpO1xuICAgICAgICBtYXgtaGVpZ2h0OiBtaW4oNjIwcHgsIGNhbGMoMTAwdmggLSAyOHB4KSk7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDE2cHg7XG4gICAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4xNik7XG4gICAgICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxODBkZWcsIHJnYmEoMTEsIDEzLCAxOCwgMC45NyksIHJnYmEoNywgOCwgMTIsIDAuOTcpKTtcbiAgICAgICAgY29sb3I6ICNlZWYyZmY7XG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgIGJveC1zaGFkb3c6IDAgMjJweCA0OHB4IHJnYmEoMCwgMCwgMCwgMC40NSk7XG4gICAgICAgIHRyYW5zZm9ybS1vcmlnaW46IGJvdHRvbSByaWdodDtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDhweCkgc2NhbGUoMC45OCk7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgICBtYXJnaW4tYm90dG9tOiAxMHB4O1xuICAgICAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC4xOHMgZWFzZSwgb3BhY2l0eSAwLjE4cyBlYXNlO1xuICAgICAgfVxuXG4gICAgICAjaGFuem8tcGFnZS1vdmVybGF5LXJvb3RbZGF0YS1vcGVuPVwidHJ1ZVwiXSAuaGFuem8tcGFnZS1wYW5lbCB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgwKSBzY2FsZSgxKTtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IGF1dG87XG4gICAgICB9XG5cbiAgICAgICNoYW56by1wYWdlLW92ZXJsYXktcm9vdFtkYXRhLW9wZW49XCJ0cnVlXCJdIC5oYW56by1wYWdlLWxhdW5jaGVyIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZSgwLjkpO1xuICAgICAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLXBhZ2UtaGVhZGVyIHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgICBwYWRkaW5nOiAxMnB4IDE0cHg7XG4gICAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMTIpO1xuICAgICAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTgwZGVnLCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMDMpLCB0cmFuc3BhcmVudCk7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLWJyYW5kIHtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICAgICAgbGV0dGVyLXNwYWNpbmc6IDAuMnB4O1xuICAgICAgICBmb250LXNpemU6IDEzcHg7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLWhlYWRlci1hY3Rpb25zIHtcbiAgICAgICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgIGdhcDogNnB4O1xuICAgICAgfVxuXG4gICAgICAuaGFuem8tY2hpcC1idG4ge1xuICAgICAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMik7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDk5OTlweDtcbiAgICAgICAgcGFkZGluZzogNHB4IDEwcHg7XG4gICAgICAgIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4wMik7XG4gICAgICAgIGNvbG9yOiAjZDZkZWZmO1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICAgIGZvbnQtc2l6ZTogMTFweDtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLWNoaXAtYnRuW2RhdGEtYWN0aXZlPVwidHJ1ZVwiXSB7XG4gICAgICAgIGJvcmRlci1jb2xvcjogcmdiYSg1NiwgMTg5LCAyNDgsIDAuNjIpO1xuICAgICAgICBiYWNrZ3JvdW5kOiByZ2JhKDE0LCAxMTYsIDE0NCwgMC4zKTtcbiAgICAgICAgY29sb3I6ICNlMGYyZmU7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1pY29uLWJ0biB7XG4gICAgICAgIHdpZHRoOiAyOHB4O1xuICAgICAgICBoZWlnaHQ6IDI4cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjE4KTtcbiAgICAgICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgICAgIGNvbG9yOiAjZTVlN2ViO1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLXBhZ2UtbWV0YSB7XG4gICAgICAgIHBhZGRpbmc6IDEwcHggMTRweCA2cHggMTRweDtcbiAgICAgICAgZGlzcGxheTogZ3JpZDtcbiAgICAgICAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAxZnIgYXV0bztcbiAgICAgICAgZ2FwOiA4cHg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLWNvbnRleHQge1xuICAgICAgICBmb250LXNpemU6IDExcHg7XG4gICAgICAgIGNvbG9yOiAjYTViNGZjO1xuICAgICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgICAgICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLXBhZ2Utc3RhdHVzIHtcbiAgICAgICAgZm9udC1zaXplOiAxMXB4O1xuICAgICAgICBjb2xvcjogIzkzYzVmZDtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLW1vZGVsLXJvdyB7XG4gICAgICAgIHBhZGRpbmc6IDAgMTRweCA4cHggMTRweDtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLW1vZGVsLXJvdyBzZWxlY3Qge1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogOHB4O1xuICAgICAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMTYpO1xuICAgICAgICBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMDMpO1xuICAgICAgICBjb2xvcjogI2YxZjVmOTtcbiAgICAgICAgcGFkZGluZzogN3B4IDlweDtcbiAgICAgICAgZm9udC1zaXplOiAxMnB4O1xuICAgICAgfVxuXG4gICAgICAuaGFuem8tcGFnZS1tZXNzYWdlcyB7XG4gICAgICAgIGZsZXg6IDE7XG4gICAgICAgIG1pbi1oZWlnaHQ6IDIwMHB4O1xuICAgICAgICBtYXgtaGVpZ2h0OiAzNzBweDtcbiAgICAgICAgb3ZlcmZsb3cteTogYXV0bztcbiAgICAgICAgcGFkZGluZzogOHB4IDE0cHggMTJweCAxNHB4O1xuICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgICBnYXA6IDhweDtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLXBhZ2UtbXNnIHtcbiAgICAgICAgcGFkZGluZzogOXB4IDEwcHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDEwcHg7XG4gICAgICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDEuNDU7XG4gICAgICAgIHdvcmQtYnJlYWs6IGJyZWFrLXdvcmQ7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLW1zZy51c2VyIHtcbiAgICAgICAgYWxpZ24tc2VsZjogZmxleC1lbmQ7XG4gICAgICAgIG1heC13aWR0aDogODglO1xuICAgICAgICBiYWNrZ3JvdW5kOiByZ2JhKDU5LCAxMzAsIDI0NiwgMC4yKTtcbiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSg1OSwgMTMwLCAyNDYsIDAuNCk7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLW1zZy5hc3Npc3RhbnQge1xuICAgICAgICBhbGlnbi1zZWxmOiBmbGV4LXN0YXJ0O1xuICAgICAgICBtYXgtd2lkdGg6IDkyJTtcbiAgICAgICAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjA1KTtcbiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjEyKTtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLXBhZ2UtY29tcG9zZXIge1xuICAgICAgICBib3JkZXItdG9wOiAxcHggc29saWQgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjEpO1xuICAgICAgICBwYWRkaW5nOiAxMHB4IDEycHg7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGdhcDogOHB4O1xuICAgICAgICBhbGlnbi1pdGVtczogZmxleC1lbmQ7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLWNvbXBvc2VyIHRleHRhcmVhIHtcbiAgICAgICAgZmxleDogMTtcbiAgICAgICAgbWluLWhlaWdodDogMzhweDtcbiAgICAgICAgbWF4LWhlaWdodDogMTEwcHg7XG4gICAgICAgIHJlc2l6ZTogbm9uZTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMTBweDtcbiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjE3KTtcbiAgICAgICAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjAzKTtcbiAgICAgICAgY29sb3I6ICNmOGZhZmM7XG4gICAgICAgIHBhZGRpbmc6IDlweCAxMXB4O1xuICAgICAgICBmb250LXNpemU6IDEycHg7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLWNvbXBvc2VyIGJ1dHRvbiB7XG4gICAgICAgIG1pbi13aWR0aDogNjhweDtcbiAgICAgICAgaGVpZ2h0OiAzOHB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICAgICAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDM3LCA5OSwgMjM1LCAwLjY1KTtcbiAgICAgICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDE4MGRlZywgcmdiYSgzNywgOTksIDIzNSwgMC45NSksIHJnYmEoMzAsIDY0LCAxNzUsIDAuOTUpKTtcbiAgICAgICAgY29sb3I6ICNlZmY2ZmY7XG4gICAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgfVxuXG4gICAgICAuaGFuem8tcGFnZS1jb21wb3NlciBidXR0b246ZGlzYWJsZWQge1xuICAgICAgICBvcGFjaXR5OiAwLjU1O1xuICAgICAgICBjdXJzb3I6IGRlZmF1bHQ7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLWhpZ2hsaWdodCB7XG4gICAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgICAgei1pbmRleDogMjE0NzQ4MzY0NDtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgICAgIGJvcmRlcjogMnB4IHNvbGlkIHJnYmEoNTYsIDE4OSwgMjQ4LCAwLjk1KTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogNnB4O1xuICAgICAgICBib3gtc2hhZG93OiAwIDAgMCAycHggcmdiYSgxNCwgMTE2LCAxNDQsIDAuMik7XG4gICAgICB9XG5cbiAgICAgIFtkYXRhLWhhbnpvLWlubGluZS1lZGl0aW5nPVwidHJ1ZVwiXSB7XG4gICAgICAgIG91dGxpbmU6IDJweCBzb2xpZCByZ2JhKDI1MSwgMTkxLCAzNiwgMC45MikgIWltcG9ydGFudDtcbiAgICAgICAgb3V0bGluZS1vZmZzZXQ6IDJweCAhaW1wb3J0YW50O1xuICAgICAgfVxuICAgIGA7XG4gICAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG4gIH1cblxuICBwcml2YXRlIG1vdW50KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1vdW50ZWQpIHJldHVybjtcblxuICAgIHRoaXMucm9vdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRoaXMucm9vdC5pZCA9ICdoYW56by1wYWdlLW92ZXJsYXktcm9vdCc7XG4gICAgdGhpcy5yb290LnNldEF0dHJpYnV0ZSgnZGF0YS1vcGVuJywgJ2ZhbHNlJyk7XG4gICAgdGhpcy5yb290LnNldEF0dHJpYnV0ZSgnZGF0YS1lbmFibGVkJywgJ2ZhbHNlJyk7XG4gICAgdGhpcy5yb290LmlubmVySFRNTCA9IGBcbiAgICAgIDxkaXYgY2xhc3M9XCJoYW56by1wYWdlLXBhbmVsXCIgcm9sZT1cImRpYWxvZ1wiIGFyaWEtbGFiZWw9XCJIYW56byBQYWdlIEFzc2lzdGFudFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaGFuem8tcGFnZS1oZWFkZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGFuem8tcGFnZS1icmFuZFwiPkhhbnpvIE92ZXJsYXk8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGFuem8tcGFnZS1oZWFkZXItYWN0aW9uc1wiPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImhhbnpvLWNoaXAtYnRuXCIgZGF0YS1yb2xlPVwid2F0Y2hcIiBkYXRhLWFjdGl2ZT1cImZhbHNlXCIgdGl0bGU9XCJXYXRjaCBlbGVtZW50cyBvbiBob3ZlclwiPldhdGNoPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiaGFuem8tY2hpcC1idG5cIiBkYXRhLXJvbGU9XCJlZGl0XCIgZGF0YS1hY3RpdmU9XCJmYWxzZVwiIHRpdGxlPVwiQ2xpY2sgYW55IGVsZW1lbnQgdG8gZWRpdCB0ZXh0XCI+RWRpdDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImhhbnpvLWljb24tYnRuXCIgZGF0YS1yb2xlPVwiY2xvc2VcIiB0aXRsZT1cIk1pbmltaXplXCI+XHUwMEQ3PC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaGFuem8tcGFnZS1tZXRhXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImhhbnpvLXBhZ2UtY29udGV4dFwiPlVzZSBXYXRjaCB0byBpbnNwZWN0IHBhZ2UgZWxlbWVudHMuPC9kaXY+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJoYW56by1wYWdlLXN0YXR1c1wiPjwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJoYW56by1tb2RlbC1yb3dcIj5cbiAgICAgICAgICA8c2VsZWN0IGRhdGEtcm9sZT1cIm1vZGVsXCI+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiY2xhdWRlLXNvbm5ldC00LTIwMjUwNTE0XCI+Q2xhdWRlIFNvbm5ldCA0PC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiY2xhdWRlLW9wdXMtNC0yMDI1MDUxNFwiPkNsYXVkZSBPcHVzIDQ8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJncHQtNG9cIj5HUFQtNG88L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJ6ZW4tY29kZXItZmxhc2hcIj5aZW4gQ29kZXIgRmxhc2g8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJ6ZW4tbWF4XCI+WmVuIE1heDwvb3B0aW9uPlxuICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImhhbnpvLXBhZ2UtbWVzc2FnZXNcIiBkYXRhLXJvbGU9XCJtZXNzYWdlc1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJoYW56by1wYWdlLW1zZyBhc3Npc3RhbnRcIj5Bc2sgYWJvdXQgdGhpcyBwYWdlLCBpbnNwZWN0IGFueSBlbGVtZW50LCBvciB0dXJuIG9uIEVkaXQgbW9kZSB0byBjaGFuZ2UgdGV4dCBpbi1wbGFjZS48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJoYW56by1wYWdlLWNvbXBvc2VyXCI+XG4gICAgICAgICAgPHRleHRhcmVhIGRhdGEtcm9sZT1cImlucHV0XCIgcm93cz1cIjFcIiBwbGFjZWhvbGRlcj1cIkFzayBhYm91dCB0aGlzIHBhZ2UuLi5cIj48L3RleHRhcmVhPlxuICAgICAgICAgIDxidXR0b24gZGF0YS1yb2xlPVwic2VuZFwiIHR5cGU9XCJidXR0b25cIj5Bc2s8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJoYW56by1wYWdlLWxhdW5jaGVyXCIgZGF0YS1yb2xlPVwibGF1bmNoZXJcIiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCJPcGVuIEhhbnpvIE92ZXJsYXlcIj5BSTwvYnV0dG9uPlxuICAgIGA7XG5cbiAgICB0aGlzLnBhbmVsID0gdGhpcy5yb290LnF1ZXJ5U2VsZWN0b3IoJy5oYW56by1wYWdlLXBhbmVsJyk7XG4gICAgdGhpcy5sYXVuY2hlciA9IHRoaXMucm9vdC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1yb2xlPVwibGF1bmNoZXJcIl0nKTtcbiAgICB0aGlzLm1lc3NhZ2VzRWwgPSB0aGlzLnJvb3QucXVlcnlTZWxlY3RvcignW2RhdGEtcm9sZT1cIm1lc3NhZ2VzXCJdJyk7XG4gICAgdGhpcy5pbnB1dEVsID0gdGhpcy5yb290LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXJvbGU9XCJpbnB1dFwiXScpO1xuICAgIHRoaXMuc2VuZEJ0biA9IHRoaXMucm9vdC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1yb2xlPVwic2VuZFwiXScpO1xuICAgIHRoaXMubW9kZWxFbCA9IHRoaXMucm9vdC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1yb2xlPVwibW9kZWxcIl0nKTtcbiAgICB0aGlzLmNvbnRleHRFbCA9IHRoaXMucm9vdC5xdWVyeVNlbGVjdG9yKCcuaGFuem8tcGFnZS1jb250ZXh0Jyk7XG4gICAgdGhpcy53YXRjaEJ0biA9IHRoaXMucm9vdC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1yb2xlPVwid2F0Y2hcIl0nKTtcbiAgICB0aGlzLmVkaXRCdG4gPSB0aGlzLnJvb3QucXVlcnlTZWxlY3RvcignW2RhdGEtcm9sZT1cImVkaXRcIl0nKTtcbiAgICB0aGlzLnN0YXR1c0VsID0gdGhpcy5yb290LnF1ZXJ5U2VsZWN0b3IoJy5oYW56by1wYWdlLXN0YXR1cycpO1xuXG4gICAgdGhpcy5sYXVuY2hlcj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB0aGlzLnNob3coKSk7XG4gICAgdGhpcy5yb290LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXJvbGU9XCJjbG9zZVwiXScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHRoaXMuaGlkZSgpKTtcbiAgICB0aGlzLndhdGNoQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHRoaXMuc2V0V2F0Y2hNb2RlKCF0aGlzLndhdGNoTW9kZSkpO1xuICAgIHRoaXMuZWRpdEJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB0aGlzLnNldEVkaXRNb2RlKCF0aGlzLmVkaXRNb2RlKSk7XG4gICAgdGhpcy5zZW5kQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHRoaXMuYXNrUGFnZVF1ZXN0aW9uKCkpO1xuICAgIHRoaXMuaW5wdXRFbD8uYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIChldmVudCkgPT4ge1xuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VudGVyJyAmJiAhZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5hc2tQYWdlUXVlc3Rpb24oKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLmlucHV0RWw/LmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLmlucHV0RWwpIHJldHVybjtcbiAgICAgIHRoaXMuaW5wdXRFbC5zdHlsZS5oZWlnaHQgPSAnYXV0byc7XG4gICAgICB0aGlzLmlucHV0RWwuc3R5bGUuaGVpZ2h0ID0gYCR7TWF0aC5taW4odGhpcy5pbnB1dEVsLnNjcm9sbEhlaWdodCwgMTEwKX1weGA7XG4gICAgfSk7XG5cbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5yb290KTtcbiAgICB0aGlzLm1vdW50ZWQgPSB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBiaW5kR2xvYmFsRXZlbnRzKCk6IHZvaWQge1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIChldmVudCkgPT4gdGhpcy5vbk1vdXNlTW92ZShldmVudCksIHRydWUpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB0aGlzLm9uRG9jdW1lbnRDbGljayhldmVudCksIHRydWUpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCAoZXZlbnQpID0+IHRoaXMub25LZXlEb3duKGV2ZW50KSwgdHJ1ZSk7XG4gIH1cblxuICBwcml2YXRlIG9uTW91c2VNb3ZlKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLndhdGNoTW9kZSkgcmV0dXJuO1xuICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuZ2V0UGFnZVRhcmdldChldmVudC50YXJnZXQpO1xuICAgIGlmICghdGFyZ2V0KSByZXR1cm47XG4gICAgdGhpcy5ob3ZlcmVkRWxlbWVudCA9IHRhcmdldDtcbiAgICB0aGlzLnNob3dIaWdobGlnaHQodGFyZ2V0KTtcbiAgICBpZiAoIXRoaXMuc2VsZWN0ZWRDb250ZXh0KSB7XG4gICAgICB0aGlzLmNvbnRleHRFbCAmJiAodGhpcy5jb250ZXh0RWwudGV4dENvbnRlbnQgPSB0aGlzLmdldEVsZW1lbnRTdW1tYXJ5KHRhcmdldCkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25Eb2N1bWVudENsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLndhdGNoTW9kZSAmJiAhdGhpcy5lZGl0TW9kZSkgcmV0dXJuO1xuICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuZ2V0UGFnZVRhcmdldChldmVudC50YXJnZXQpO1xuICAgIGlmICghdGFyZ2V0KSByZXR1cm47XG5cbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXG4gICAgaWYgKHRoaXMud2F0Y2hNb2RlKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkQ29udGV4dCA9IHRoaXMuY2FwdHVyZUVsZW1lbnRDb250ZXh0KHRhcmdldCk7XG4gICAgICB0aGlzLmNvbnRleHRFbCAmJiAodGhpcy5jb250ZXh0RWwudGV4dENvbnRlbnQgPSB0aGlzLmdldEVsZW1lbnRTdW1tYXJ5KHRhcmdldCkpO1xuICAgICAgdGhpcy51cGRhdGVTdGF0dXMoJ0VsZW1lbnQgc2VsZWN0ZWQnKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5lZGl0TW9kZSkge1xuICAgICAgdGhpcy5lbmFibGVJbmxpbmVFZGl0KHRhcmdldCk7XG4gICAgICB0aGlzLnVwZGF0ZVN0YXR1cygnRWRpdGluZyBlbGVtZW50Jyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvbktleURvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnRXNjYXBlJykge1xuICAgICAgaWYgKHRoaXMuZWRpdGluZ0VsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5kaXNhYmxlSW5saW5lRWRpdCh0aGlzLmVkaXRpbmdFbGVtZW50LCBmYWxzZSk7XG4gICAgICAgIHRoaXMudXBkYXRlU3RhdHVzKCdFZGl0IGNhbmNlbGVkJyk7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm9wZW4pIHtcbiAgICAgICAgdGhpcy5oaWRlKCk7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRQYWdlVGFyZ2V0KHRhcmdldDogRXZlbnRUYXJnZXQgfCBudWxsKTogSFRNTEVsZW1lbnQgfCBudWxsIHtcbiAgICBpZiAoISh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHJldHVybiBudWxsO1xuICAgIGlmICh0aGlzLnJvb3Q/LmNvbnRhaW5zKHRhcmdldCkpIHJldHVybiBudWxsO1xuICAgIGlmICghdGFyZ2V0LmlzQ29ubmVjdGVkKSByZXR1cm4gbnVsbDtcbiAgICBpZiAodGFyZ2V0LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2h0bWwnIHx8IHRhcmdldC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdib2R5JykgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfVxuXG4gIHByaXZhdGUgc2V0V2F0Y2hNb2RlKGFjdGl2ZTogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMud2F0Y2hNb2RlID0gYWN0aXZlO1xuICAgIGlmIChhY3RpdmUpIHRoaXMuc2V0RWRpdE1vZGUoZmFsc2UpO1xuICAgIHRoaXMud2F0Y2hCdG4/LnNldEF0dHJpYnV0ZSgnZGF0YS1hY3RpdmUnLCBhY3RpdmUgPyAndHJ1ZScgOiAnZmFsc2UnKTtcbiAgICBpZiAoIWFjdGl2ZSkge1xuICAgICAgdGhpcy5ob3ZlcmVkRWxlbWVudCA9IG51bGw7XG4gICAgICB0aGlzLmNsZWFySGlnaGxpZ2h0KCk7XG4gICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRDb250ZXh0ICYmIHRoaXMuY29udGV4dEVsKSB7XG4gICAgICAgIHRoaXMuY29udGV4dEVsLnRleHRDb250ZW50ID0gJ1VzZSBXYXRjaCB0byBpbnNwZWN0IHBhZ2UgZWxlbWVudHMuJztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51cGRhdGVTdGF0dXMoJ1dhdGNoIG1vZGUgb24nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldEVkaXRNb2RlKGFjdGl2ZTogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuZWRpdE1vZGUgPSBhY3RpdmU7XG4gICAgaWYgKGFjdGl2ZSkgdGhpcy5zZXRXYXRjaE1vZGUoZmFsc2UpO1xuICAgIHRoaXMuZWRpdEJ0bj8uc2V0QXR0cmlidXRlKCdkYXRhLWFjdGl2ZScsIGFjdGl2ZSA/ICd0cnVlJyA6ICdmYWxzZScpO1xuICAgIGlmICghYWN0aXZlICYmIHRoaXMuZWRpdGluZ0VsZW1lbnQpIHtcbiAgICAgIHRoaXMuZGlzYWJsZUlubGluZUVkaXQodGhpcy5lZGl0aW5nRWxlbWVudCwgdHJ1ZSk7XG4gICAgfSBlbHNlIGlmIChhY3RpdmUpIHtcbiAgICAgIHRoaXMudXBkYXRlU3RhdHVzKCdFZGl0IG1vZGUgb24nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGVuYWJsZUlubGluZUVkaXQoZWxlbWVudDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lZGl0aW5nRWxlbWVudCAmJiB0aGlzLmVkaXRpbmdFbGVtZW50ICE9PSBlbGVtZW50KSB7XG4gICAgICB0aGlzLmRpc2FibGVJbmxpbmVFZGl0KHRoaXMuZWRpdGluZ0VsZW1lbnQsIHRydWUpO1xuICAgIH1cblxuICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCB8fCBlbGVtZW50IGluc3RhbmNlb2YgSFRNTFRleHRBcmVhRWxlbWVudCkge1xuICAgICAgZWxlbWVudC5mb2N1cygpO1xuICAgICAgdGhpcy5lZGl0aW5nRWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFlbGVtZW50Lmhhc0F0dHJpYnV0ZSgnZGF0YS1oYW56by1vcmlnaW5hbC1odG1sJykpIHtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLWhhbnpvLW9yaWdpbmFsLWh0bWwnLCBlbGVtZW50LmlubmVySFRNTCk7XG4gICAgfVxuICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnLCAndHJ1ZScpO1xuICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdzcGVsbGNoZWNrJywgJ3RydWUnKTtcbiAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1oYW56by1pbmxpbmUtZWRpdGluZycsICd0cnVlJyk7XG4gICAgZWxlbWVudC5mb2N1cygpO1xuICAgIHRoaXMuZWRpdGluZ0VsZW1lbnQgPSBlbGVtZW50O1xuXG4gICAgY29uc3Qga2V5ZG93bkhhbmRsZXIgPSAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICAgIGlmIChldmVudC5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICAgIHRoaXMuZGlzYWJsZUlubGluZUVkaXQoZWxlbWVudCwgZmFsc2UpO1xuICAgICAgICB0aGlzLnVwZGF0ZVN0YXR1cygnRWRpdCByZXZlcnRlZCcpO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VudGVyJyAmJiAhZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5kaXNhYmxlSW5saW5lRWRpdChlbGVtZW50LCB0cnVlKTtcbiAgICAgICAgdGhpcy51cGRhdGVTdGF0dXMoJ0VkaXQgYXBwbGllZCcpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBibHVySGFuZGxlciA9ICgpID0+IHtcbiAgICAgIHRoaXMuZGlzYWJsZUlubGluZUVkaXQoZWxlbWVudCwgdHJ1ZSk7XG4gICAgICB0aGlzLnVwZGF0ZVN0YXR1cygnRWRpdCBhcHBsaWVkJyk7XG4gICAgfTtcblxuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGtleWRvd25IYW5kbGVyLCB7IG9uY2U6IHRydWUgfSk7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdibHVyJywgYmx1ckhhbmRsZXIsIHsgb25jZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZGlzYWJsZUlubGluZUVkaXQoZWxlbWVudDogSFRNTEVsZW1lbnQsIGtlZXBDaGFuZ2VzOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKCFrZWVwQ2hhbmdlcykge1xuICAgICAgY29uc3Qgb3JpZ2luYWwgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1oYW56by1vcmlnaW5hbC1odG1sJyk7XG4gICAgICBpZiAob3JpZ2luYWwgIT09IG51bGwpIHtcbiAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBvcmlnaW5hbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJyk7XG4gICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ3NwZWxsY2hlY2snKTtcbiAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgnZGF0YS1oYW56by1pbmxpbmUtZWRpdGluZycpO1xuICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdkYXRhLWhhbnpvLW9yaWdpbmFsLWh0bWwnKTtcblxuICAgIGlmICh0aGlzLmVkaXRpbmdFbGVtZW50ID09PSBlbGVtZW50KSB7XG4gICAgICB0aGlzLmVkaXRpbmdFbGVtZW50ID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNob3dIaWdobGlnaHQoZWxlbWVudDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcbiAgICBjb25zdCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBpZiAocmVjdC53aWR0aCA9PT0gMCAmJiByZWN0LmhlaWdodCA9PT0gMCkge1xuICAgICAgdGhpcy5jbGVhckhpZ2hsaWdodCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5oaWdobGlnaHRCb3gpIHtcbiAgICAgIHRoaXMuaGlnaGxpZ2h0Qm94ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICB0aGlzLmhpZ2hsaWdodEJveC5jbGFzc05hbWUgPSAnaGFuem8tcGFnZS1oaWdobGlnaHQnO1xuICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuaGlnaGxpZ2h0Qm94KTtcbiAgICB9XG5cbiAgICB0aGlzLmhpZ2hsaWdodEJveC5zdHlsZS5sZWZ0ID0gYCR7TWF0aC5tYXgoMCwgcmVjdC5sZWZ0IC0gMyl9cHhgO1xuICAgIHRoaXMuaGlnaGxpZ2h0Qm94LnN0eWxlLnRvcCA9IGAke01hdGgubWF4KDAsIHJlY3QudG9wIC0gMyl9cHhgO1xuICAgIHRoaXMuaGlnaGxpZ2h0Qm94LnN0eWxlLndpZHRoID0gYCR7cmVjdC53aWR0aCArIDZ9cHhgO1xuICAgIHRoaXMuaGlnaGxpZ2h0Qm94LnN0eWxlLmhlaWdodCA9IGAke3JlY3QuaGVpZ2h0ICsgNn1weGA7XG4gIH1cblxuICBwcml2YXRlIGNsZWFySGlnaGxpZ2h0KCk6IHZvaWQge1xuICAgIHRoaXMuaGlnaGxpZ2h0Qm94Py5yZW1vdmUoKTtcbiAgICB0aGlzLmhpZ2hsaWdodEJveCA9IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGNhcHR1cmVFbGVtZW50Q29udGV4dChlbGVtZW50OiBIVE1MRWxlbWVudCk6IE92ZXJsYXlFbGVtZW50Q29udGV4dCB7XG4gICAgY29uc3QgdGV4dCA9IHRoaXMubm9ybWFsaXplVGV4dChlbGVtZW50LmlubmVyVGV4dCB8fCBlbGVtZW50LnRleHRDb250ZW50IHx8ICcnKTtcbiAgICByZXR1cm4ge1xuICAgICAgc2VsZWN0b3I6IHRoaXMuYnVpbGRTZWxlY3RvcihlbGVtZW50KSxcbiAgICAgIHRhZzogZWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCksXG4gICAgICB0ZXh0OiB0ZXh0LnNsaWNlKDAsIDgwMCksXG4gICAgICBodG1sOiBlbGVtZW50Lm91dGVySFRNTC5zbGljZSgwLCAxMjAwKSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFNlbGVjdG9yKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogc3RyaW5nIHtcbiAgICBpZiAoZWxlbWVudC5pZCkgcmV0dXJuIGAjJHtlbGVtZW50LmlkfWA7XG5cbiAgICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgY3VycmVudDogSFRNTEVsZW1lbnQgfCBudWxsID0gZWxlbWVudDtcbiAgICBsZXQgZGVwdGggPSAwO1xuXG4gICAgd2hpbGUgKGN1cnJlbnQgJiYgZGVwdGggPCA2KSB7XG4gICAgICBsZXQgcGFydCA9IGN1cnJlbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKGN1cnJlbnQuY2xhc3NMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgY2xhc3NOYW1lID0gQXJyYXkuZnJvbShjdXJyZW50LmNsYXNzTGlzdCkuc2xpY2UoMCwgMikuam9pbignLicpO1xuICAgICAgICBpZiAoY2xhc3NOYW1lKSBwYXJ0ICs9IGAuJHtjbGFzc05hbWV9YDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBhcmVudCA9IGN1cnJlbnQucGFyZW50RWxlbWVudDtcbiAgICAgIGlmIChwYXJlbnQpIHtcbiAgICAgICAgY29uc3Qgc2libGluZ3MgPSBBcnJheS5mcm9tKHBhcmVudC5jaGlsZHJlbikuZmlsdGVyKChub2RlKSA9PiBub2RlLnRhZ05hbWUgPT09IGN1cnJlbnQhLnRhZ05hbWUpO1xuICAgICAgICBpZiAoc2libGluZ3MubGVuZ3RoID4gMSkge1xuICAgICAgICAgIGNvbnN0IGluZGV4ID0gc2libGluZ3MuaW5kZXhPZihjdXJyZW50KSArIDE7XG4gICAgICAgICAgcGFydCArPSBgOm50aC1vZi10eXBlKCR7aW5kZXh9KWA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHBhcnRzLnVuc2hpZnQocGFydCk7XG4gICAgICBjdXJyZW50ID0gcGFyZW50O1xuICAgICAgZGVwdGggKz0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFydHMuam9pbignID4gJyk7XG4gIH1cblxuICBwcml2YXRlIG5vcm1hbGl6ZVRleHQodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL1xccysvZywgJyAnKS50cmltKCk7XG4gIH1cblxuICBwcml2YXRlIGdldEVsZW1lbnRTdW1tYXJ5KGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogc3RyaW5nIHtcbiAgICBjb25zdCBjdHggPSB0aGlzLmNhcHR1cmVFbGVtZW50Q29udGV4dChlbGVtZW50KTtcbiAgICByZXR1cm4gYCR7Y3R4LnRhZ30gXHUyMDIyICR7Y3R4LnNlbGVjdG9yfWA7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvYWRNb2RlbHMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMubW9kZWxzTG9hZGVkIHx8ICF0aGlzLm1vZGVsRWwpIHJldHVybjtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNocm9tZS5ydW50aW1lLnNlbmRNZXNzYWdlKHsgYWN0aW9uOiAnY2hhdC5saXN0TW9kZWxzJyB9KTtcbiAgICAgIGlmICghcmVzcG9uc2U/LnN1Y2Nlc3MgfHwgIUFycmF5LmlzQXJyYXkocmVzcG9uc2UubW9kZWxzKSB8fCAhcmVzcG9uc2UubW9kZWxzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHByZXZpb3VzID0gdGhpcy5tb2RlbEVsLnZhbHVlO1xuICAgICAgdGhpcy5tb2RlbEVsLmlubmVySFRNTCA9ICcnO1xuICAgICAgZm9yIChjb25zdCBtb2RlbCBvZiByZXNwb25zZS5tb2RlbHMpIHtcbiAgICAgICAgaWYgKCFtb2RlbD8uaWQpIGNvbnRpbnVlO1xuICAgICAgICBjb25zdCBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvcHRpb24nKTtcbiAgICAgICAgb3B0aW9uLnZhbHVlID0gbW9kZWwuaWQ7XG4gICAgICAgIG9wdGlvbi50ZXh0Q29udGVudCA9IG1vZGVsLm5hbWUgfHwgbW9kZWwuaWQ7XG4gICAgICAgIHRoaXMubW9kZWxFbC5hcHBlbmRDaGlsZChvcHRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKHByZXZpb3VzICYmIEFycmF5LmZyb20odGhpcy5tb2RlbEVsLm9wdGlvbnMpLnNvbWUoKG9wdCkgPT4gb3B0LnZhbHVlID09PSBwcmV2aW91cykpIHtcbiAgICAgICAgdGhpcy5tb2RlbEVsLnZhbHVlID0gcHJldmlvdXM7XG4gICAgICB9XG4gICAgICB0aGlzLm1vZGVsc0xvYWRlZCA9IHRydWU7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBLZWVwIGxvY2FsIGRlZmF1bHRzIGlmIG1vZGVsIGZldGNoIGZhaWxzLlxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZm9jdXNJbnB1dCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaW5wdXRFbCkgcmV0dXJuO1xuICAgIHRoaXMuaW5wdXRFbC5mb2N1cygpO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBlbmRNZXNzYWdlKHJvbGU6ICd1c2VyJyB8ICdhc3Npc3RhbnQnLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMubWVzc2FnZXNFbCkgcmV0dXJuO1xuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi5jbGFzc05hbWUgPSBgaGFuem8tcGFnZS1tc2cgJHtyb2xlfWA7XG4gICAgZGl2LnRleHRDb250ZW50ID0gY29udGVudDtcbiAgICB0aGlzLm1lc3NhZ2VzRWwuYXBwZW5kQ2hpbGQoZGl2KTtcbiAgICB0aGlzLm1lc3NhZ2VzRWwuc2Nyb2xsVG9wID0gdGhpcy5tZXNzYWdlc0VsLnNjcm9sbEhlaWdodDtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlU3RhdHVzKHRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zdGF0dXNFbCkgcmV0dXJuO1xuICAgIHRoaXMuc3RhdHVzRWwudGV4dENvbnRlbnQgPSB0ZXh0O1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFBhZ2VDb250ZXh0KCk6IHN0cmluZyB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gdGhpcy5ub3JtYWxpemVUZXh0KHdpbmRvdy5nZXRTZWxlY3Rpb24/LigpPy50b1N0cmluZygpIHx8ICcnKTtcbiAgICBjb25zdCBjb250ZXh0TGluZXMgPSBbXG4gICAgICBgVVJMOiAke2xvY2F0aW9uLmhyZWZ9YCxcbiAgICAgIGBUaXRsZTogJHtkb2N1bWVudC50aXRsZSB8fCAnVW50aXRsZWQnfWAsXG4gICAgXTtcblxuICAgIGlmIChzZWxlY3Rpb24pIHtcbiAgICAgIGNvbnRleHRMaW5lcy5wdXNoKGBUZXh0U2VsZWN0aW9uOiAke3NlbGVjdGlvbi5zbGljZSgwLCA2MDApfWApO1xuICAgIH1cblxuICAgIGNvbnN0IGVsZW1lbnRDb250ZXh0ID0gdGhpcy5zZWxlY3RlZENvbnRleHQgfHwgKHRoaXMuaG92ZXJlZEVsZW1lbnQgPyB0aGlzLmNhcHR1cmVFbGVtZW50Q29udGV4dCh0aGlzLmhvdmVyZWRFbGVtZW50KSA6IG51bGwpO1xuICAgIGlmIChlbGVtZW50Q29udGV4dCkge1xuICAgICAgY29udGV4dExpbmVzLnB1c2goYEVsZW1lbnRTZWxlY3RvcjogJHtlbGVtZW50Q29udGV4dC5zZWxlY3Rvcn1gKTtcbiAgICAgIGlmIChlbGVtZW50Q29udGV4dC50ZXh0KSBjb250ZXh0TGluZXMucHVzaChgRWxlbWVudFRleHQ6ICR7ZWxlbWVudENvbnRleHQudGV4dC5zbGljZSgwLCA2MDApfWApO1xuICAgICAgY29udGV4dExpbmVzLnB1c2goYEVsZW1lbnRIVE1MOiAke2VsZW1lbnRDb250ZXh0Lmh0bWwuc2xpY2UoMCwgODAwKX1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29udGV4dExpbmVzLmpvaW4oJ1xcbicpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBhc2tQYWdlUXVlc3Rpb24oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuc2VuZGluZyB8fCAhdGhpcy5pbnB1dEVsKSByZXR1cm47XG5cbiAgICBjb25zdCBwcm9tcHQgPSB0aGlzLm5vcm1hbGl6ZVRleHQodGhpcy5pbnB1dEVsLnZhbHVlKTtcbiAgICBpZiAoIXByb21wdCkgcmV0dXJuO1xuXG4gICAgY29uc3QgdG9rZW5SZXNwID0gYXdhaXQgY2hyb21lLnJ1bnRpbWUuc2VuZE1lc3NhZ2UoeyBhY3Rpb246ICdhdXRoLmdldFRva2VuJyB9KTtcbiAgICBpZiAoIXRva2VuUmVzcD8uc3VjY2VzcyB8fCAhdG9rZW5SZXNwLnRva2VuKSB7XG4gICAgICB0aGlzLmFwcGVuZE1lc3NhZ2UoJ2Fzc2lzdGFudCcsICdQbGVhc2Ugc2lnbiBpbiBmcm9tIHRoZSBIYW56byBzaWRlYmFyL3BvcHVwIGJlZm9yZSB1c2luZyBwYWdlIGNoYXQuJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZW5kaW5nID0gdHJ1ZTtcbiAgICB0aGlzLnVwZGF0ZVN0YXR1cygnVGhpbmtpbmcuLi4nKTtcbiAgICB0aGlzLnNlbmRCdG4gJiYgKHRoaXMuc2VuZEJ0bi5kaXNhYmxlZCA9IHRydWUpO1xuXG4gICAgdGhpcy5pbnB1dEVsLnZhbHVlID0gJyc7XG4gICAgdGhpcy5pbnB1dEVsLnN0eWxlLmhlaWdodCA9ICdhdXRvJztcbiAgICB0aGlzLmFwcGVuZE1lc3NhZ2UoJ3VzZXInLCBwcm9tcHQpO1xuXG4gICAgY29uc3Qgc3lzdGVtQ29udGV4dCA9IHRoaXMuYnVpbGRQYWdlQ29udGV4dCgpO1xuICAgIGNvbnN0IG1vZGVsID0gdGhpcy5tb2RlbEVsPy52YWx1ZSB8fCAnZ3B0LTRvJztcbiAgICBjb25zdCByZXF1ZXN0TWVzc2FnZXM6IE92ZXJsYXlDaGF0TWVzc2FnZVtdID0gW1xuICAgICAge1xuICAgICAgICByb2xlOiAnc3lzdGVtJyxcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICdZb3UgYXJlIEhhbnpvIHBhZ2Ugb3ZlcmxheSBhc3Npc3RhbnQuJyxcbiAgICAgICAgICAnVXNlIHByb3ZpZGVkIHBhZ2UgY29udGV4dCBhbmQgc2VsZWN0ZWQgZWxlbWVudCBjb250ZXh0IHdoZW4gcmVsZXZhbnQuJyxcbiAgICAgICAgICAnQmUgY29uY2lzZSBhbmQgcHJvdmlkZSBjb25jcmV0ZSBVSSBvciBET00gZWRpdCBzdWdnZXN0aW9ucyB3aGVuIGFza2VkLicsXG4gICAgICAgICAgJycsXG4gICAgICAgICAgc3lzdGVtQ29udGV4dCxcbiAgICAgICAgXS5qb2luKCdcXG4nKSxcbiAgICAgIH0sXG4gICAgICAuLi50aGlzLm1lc3NhZ2VzLnNsaWNlKC04KSxcbiAgICAgIHsgcm9sZTogJ3VzZXInLCBjb250ZW50OiBwcm9tcHQgfSxcbiAgICBdO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2hyb21lLnJ1bnRpbWUuc2VuZE1lc3NhZ2Uoe1xuICAgICAgICBhY3Rpb246ICdjaGF0LmNvbXBsZXRlJyxcbiAgICAgICAgbW9kZWwsXG4gICAgICAgIG1lc3NhZ2VzOiByZXF1ZXN0TWVzc2FnZXMsXG4gICAgICB9KTtcblxuICAgICAgaWYgKCFyZXNwb25zZT8uc3VjY2VzcyB8fCAhcmVzcG9uc2UuY29udGVudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IocmVzcG9uc2U/LmVycm9yIHx8ICdObyByZXNwb25zZSBmcm9tIGNoYXQgc2VydmljZScpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBhbnN3ZXIgPSBTdHJpbmcocmVzcG9uc2UuY29udGVudCkudHJpbSgpO1xuICAgICAgdGhpcy5hcHBlbmRNZXNzYWdlKCdhc3Npc3RhbnQnLCBhbnN3ZXIgfHwgJ05vIHJlc3BvbnNlIGNvbnRlbnQuJyk7XG4gICAgICB0aGlzLm1lc3NhZ2VzLnB1c2goeyByb2xlOiAndXNlcicsIGNvbnRlbnQ6IHByb21wdCB9LCB7IHJvbGU6ICdhc3Npc3RhbnQnLCBjb250ZW50OiBhbnN3ZXIgfSk7XG4gICAgICB0aGlzLm1lc3NhZ2VzID0gdGhpcy5tZXNzYWdlcy5zbGljZSgtMjApO1xuICAgICAgdGhpcy51cGRhdGVTdGF0dXMoJ1JlYWR5Jyk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgdGhpcy5hcHBlbmRNZXNzYWdlKCdhc3Npc3RhbnQnLCBgRXJyb3I6ICR7ZXJyb3I/Lm1lc3NhZ2UgfHwgJ0NoYXQgcmVxdWVzdCBmYWlsZWQnfWApO1xuICAgICAgdGhpcy51cGRhdGVTdGF0dXMoJ0Vycm9yJyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuc2VuZGluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5zZW5kQnRuICYmICh0aGlzLnNlbmRCdG4uZGlzYWJsZWQgPSBmYWxzZSk7XG4gICAgICB0aGlzLmZvY3VzSW5wdXQoKTtcbiAgICB9XG4gIH1cbn1cblxuY29uc3QgcGFnZU92ZXJsYXkgPSBuZXcgSGFuem9QYWdlT3ZlcmxheSgpO1xuXG4vLyBJbml0aWFsaXplXG5uZXcgSGFuem9Db250ZW50U2NyaXB0KCk7XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7QUFpQkEsTUFBTSxxQkFBTixNQUF5QjtBQUFBLElBQ3ZCLGNBQWM7QUFDWixXQUFLLGtCQUFrQjtBQUN2QixXQUFLLGNBQWM7QUFDbkIsV0FBSyxxQkFBcUI7QUFBQSxJQUM1QjtBQUFBLElBRVEsb0JBQW9CO0FBQzFCLGVBQVMsaUJBQWlCLFNBQVMsQ0FBQyxNQUFNO0FBQ3hDLFlBQUksQ0FBQyxFQUFFLE9BQVE7QUFFZixVQUFFLGVBQWU7QUFDakIsVUFBRSxnQkFBZ0I7QUFFbEIsY0FBTSxVQUFVLEVBQUU7QUFDbEIsY0FBTSxTQUFTLEtBQUssc0JBQXNCLE9BQU87QUFDakQsY0FBTSxVQUFVLEtBQUssV0FBVyxPQUFPO0FBRXZDLGNBQU0sUUFBOEI7QUFBQSxVQUNsQyxPQUFPO0FBQUEsVUFDUCxXQUFXLEtBQUssZ0JBQWdCO0FBQUEsVUFDaEM7QUFBQSxVQUNBO0FBQUEsVUFDQSxZQUFZLFFBQVEsYUFBYSxlQUFlLEtBQUs7QUFBQSxRQUN2RDtBQUdBLGVBQU8sUUFBUSxZQUFZLEVBQUUsUUFBUSxtQkFBbUIsTUFBTSxNQUFNLENBQUM7QUFBQSxNQUN2RSxDQUFDO0FBQUEsSUFDSDtBQUFBLElBRVEsdUJBQXVCO0FBQzdCLGFBQU8sUUFBUSxVQUFVLFlBQVksQ0FBQyxTQUFTLFNBQVMsaUJBQWlCO0FBakQ3RTtBQWtETSxnQkFBUSxRQUFRLFFBQVE7QUFBQSxVQUN0QixLQUFLO0FBQ0gsc0JBQVUsS0FBSyxRQUFRLFFBQVEsNkJBQTZCO0FBQzVELHlCQUFhLEVBQUUsU0FBUyxLQUFLLENBQUM7QUFDOUIsbUJBQU87QUFBQSxVQUNULEtBQUs7QUFDSCxzQkFBVSxLQUFLO0FBQ2YseUJBQWEsRUFBRSxTQUFTLEtBQUssQ0FBQztBQUM5QixtQkFBTztBQUFBLFVBQ1QsS0FBSztBQUNILHNCQUFVLFdBQVcsUUFBUSxHQUFHLFFBQVEsQ0FBQztBQUN6Qyx5QkFBYSxFQUFFLFNBQVMsS0FBSyxDQUFDO0FBQzlCLG1CQUFPO0FBQUEsVUFDVCxLQUFLO0FBQ0gsc0JBQVUsVUFBVSxRQUFRLFFBQVE7QUFDcEMseUJBQWEsRUFBRSxTQUFTLEtBQUssQ0FBQztBQUM5QixtQkFBTztBQUFBLFVBQ1QsS0FBSztBQUNILHNCQUFVLGFBQWEsUUFBUSxJQUFJO0FBQ25DLHlCQUFhLEVBQUUsU0FBUyxLQUFLLENBQUM7QUFDOUIsbUJBQU87QUFBQSxVQUNULEtBQUs7QUFDSCx5QkFBYTtBQUFBLGNBQ1gsU0FBUztBQUFBLGNBQ1QsTUFBTSxZQUFZLE9BQU87QUFBQSxZQUMzQixDQUFDO0FBQ0QsbUJBQU87QUFBQSxVQUNULEtBQUs7QUFDSCx3QkFBWSxLQUFLO0FBQ2pCLHlCQUFhLEVBQUUsU0FBUyxNQUFNLE1BQU0sS0FBSyxDQUFDO0FBQzFDLG1CQUFPO0FBQUEsVUFDVCxLQUFLO0FBQ0gsd0JBQVksS0FBSztBQUNqQix5QkFBYSxFQUFFLFNBQVMsTUFBTSxNQUFNLE1BQU0sQ0FBQztBQUMzQyxtQkFBTztBQUFBLFVBQ1QsS0FBSztBQUNILHlCQUFhLEVBQUUsU0FBUyxNQUFNLE1BQU0sWUFBWSxPQUFPLEVBQUUsQ0FBQztBQUMxRCxtQkFBTztBQUFBLFFBQ1g7QUFHQSxZQUFJLFFBQVEsV0FBVyxjQUFjO0FBQ25DLHVCQUFhLEVBQUUsV0FBUyxjQUFTLG9CQUFULG1CQUEwQixjQUFhLEdBQUcsQ0FBQztBQUNuRSxpQkFBTztBQUFBLFFBQ1Q7QUFFQSxZQUFJLFFBQVEsV0FBVyxjQUFjO0FBQ25DLGNBQUksT0FBTyxRQUFRLFlBQVksVUFBVTtBQUN2QyxxQkFBUyxLQUFLO0FBQ2QscUJBQVMsTUFBTSxRQUFRLE9BQU87QUFDOUIscUJBQVMsTUFBTTtBQUFBLFVBQ2pCO0FBQ0EsdUJBQWEsRUFBRSxTQUFTLEtBQUssQ0FBQztBQUM5QixpQkFBTztBQUFBLFFBQ1Q7QUFFQSxlQUFPO0FBQUEsTUFDVCxDQUFDO0FBQUEsSUFDSDtBQUFBLElBRVEsc0JBQXNCLFNBQWtEO0FBQzlFLFlBQU0sWUFBWSxLQUFLLGdCQUFnQjtBQUV2QyxjQUFRLFdBQVc7QUFBQSxRQUNqQixLQUFLO0FBQ0gsaUJBQU8sS0FBSyxtQkFBbUIsT0FBTztBQUFBLFFBQ3hDLEtBQUs7QUFDSCxpQkFBTyxLQUFLLGlCQUFpQixPQUFPO0FBQUEsUUFDdEMsS0FBSztBQUNILGlCQUFPLEtBQUssb0JBQW9CLE9BQU87QUFBQSxRQUN6QztBQUNFLGlCQUFPO0FBQUEsTUFDWDtBQUFBLElBQ0Y7QUFBQSxJQUVRLG1CQUFtQixTQUFrRDtBQTdIL0U7QUE4SEksWUFBTSxPQUFRLE9BQWU7QUFDN0IsVUFBSSxDQUFDLEtBQU0sUUFBTztBQUVsQixZQUFNLFFBQVEsS0FBSyxlQUFlLE9BQU87QUFDekMsVUFBSSxDQUFDLE1BQU8sUUFBTztBQUVuQixZQUFNLFNBQVMsTUFBTSxrQkFBZ0IsV0FBTSxpQkFBTixtQkFBb0IsZUFBWSxXQUFNLGtCQUFOLG1CQUFxQjtBQUUxRixVQUFJLFVBQVUsT0FBTyxVQUFVO0FBQzdCLGVBQU87QUFBQSxVQUNMLE1BQU0sT0FBTztBQUFBLFVBQ2IsTUFBTSxPQUFPO0FBQUEsVUFDYixRQUFRLE9BQU87QUFBQSxRQUNqQjtBQUFBLE1BQ0Y7QUFFQSxhQUFPO0FBQUEsSUFDVDtBQUFBLElBRVEsZUFBZSxTQUEyQjtBQUNoRCxZQUFNLE1BQU0sT0FBTyxLQUFLLE9BQU8sRUFBRTtBQUFBLFFBQy9CLENBQUMsY0FBYyxVQUFVLFdBQVcsMEJBQTBCLEtBQUssVUFBVSxXQUFXLGVBQWU7QUFBQSxNQUN6RztBQUNBLGFBQU8sTUFBTyxRQUFnQixHQUFHLElBQUk7QUFBQSxJQUN2QztBQUFBLElBRVEsaUJBQWlCLFNBQWtEO0FBeEo3RTtBQXlKSSxZQUFNLE9BQVEsT0FBZTtBQUM3QixVQUFJLENBQUMsS0FBTSxRQUFPO0FBRWxCLFVBQUksV0FBWSxRQUFnQjtBQUNoQyxVQUFJLENBQUMsVUFBVTtBQUNiLG1CQUFZLFFBQWdCO0FBQUEsTUFDOUI7QUFFQSxXQUFJLDBDQUFVLFNBQVYsbUJBQWdCLFFBQVE7QUFDMUIsY0FBTUEsWUFBMkI7QUFBQSxVQUMvQixNQUFNLFNBQVMsS0FBSztBQUFBLFVBQ3BCLE1BQU07QUFBQSxRQUNSO0FBRUEsYUFBSSxjQUFTLFVBQVQsbUJBQWdCLEtBQUs7QUFDdkIsVUFBQUEsVUFBUyxPQUFPLFNBQVMsTUFBTSxJQUFJLE1BQU07QUFDekMsVUFBQUEsVUFBUyxTQUFTLFNBQVMsTUFBTSxJQUFJLE1BQU07QUFBQSxRQUM3QztBQUVBLGVBQU9BO0FBQUEsTUFDVDtBQUVBLGFBQU87QUFBQSxJQUNUO0FBQUEsSUFFUSxvQkFBb0IsU0FBa0Q7QUFsTGhGO0FBbUxJLFlBQU0sWUFBYSxRQUFnQjtBQUNuQyxXQUFJLGtEQUFXLE9BQVgsbUJBQWUsUUFBZixtQkFBb0IsYUFBYTtBQUNuQyxlQUFPLFVBQVUsR0FBRyxJQUFJO0FBQUEsTUFDMUI7QUFDQSxhQUFPO0FBQUEsSUFDVDtBQUFBLElBRVEsa0JBQWlDO0FBQ3ZDLFVBQUssT0FBZSwrQkFBZ0MsUUFBTztBQUMzRCxVQUFLLE9BQWUsNkJBQThCLFFBQU87QUFDekQsVUFBSyxPQUFlLFNBQVUsUUFBTztBQUNyQyxhQUFPO0FBQUEsSUFDVDtBQUFBLElBRVEsV0FBVyxTQUE4QjtBQUMvQyxZQUFNLE9BQWlCLENBQUM7QUFDeEIsVUFBSSxVQUE4QjtBQUVsQyxhQUFPLFdBQVcsWUFBWSxTQUFTLE1BQU07QUFDM0MsWUFBSSxXQUFXLFFBQVEsUUFBUSxZQUFZO0FBRTNDLFlBQUksUUFBUSxJQUFJO0FBQ2Qsc0JBQVksSUFBSSxRQUFRLEVBQUU7QUFBQSxRQUM1QixXQUFXLFFBQVEsV0FBVztBQUM1QixzQkFBWSxJQUFJLFFBQVEsVUFBVSxNQUFNLEdBQUcsRUFBRSxLQUFLLEdBQUcsQ0FBQztBQUFBLFFBQ3hEO0FBRUEsYUFBSyxRQUFRLFFBQVE7QUFDckIsa0JBQVUsUUFBUTtBQUFBLE1BQ3BCO0FBRUEsYUFBTyxLQUFLLEtBQUssS0FBSztBQUFBLElBQ3hCO0FBQUEsSUFFUSxnQkFBZ0I7QUFDdEIsWUFBTSxRQUFRLFNBQVMsY0FBYyxPQUFPO0FBQzVDLFlBQU0sY0FBYztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFNcEIsZUFBUyxLQUFLLFlBQVksS0FBSztBQUUvQixlQUFTLGlCQUFpQixhQUFhLENBQUMsTUFBTTtBQUM1QyxpQkFBUyxpQkFBaUIsb0JBQW9CLEVBQUUsUUFBUSxDQUFDLE9BQU87QUFDOUQsYUFBRyxnQkFBZ0Isa0JBQWtCO0FBQUEsUUFDdkMsQ0FBQztBQUVELFlBQUksRUFBRSxVQUFVLEVBQUUsa0JBQWtCLGFBQWE7QUFDL0MsWUFBRSxPQUFPLGFBQWEsb0JBQW9CLE1BQU07QUFBQSxRQUNsRDtBQUFBLE1BQ0YsQ0FBQztBQUFBLElBQ0g7QUFBQSxFQUNGO0FBTUEsTUFBTSxZQUFhLHVCQUFNO0FBQ3ZCLFFBQUksVUFBaUM7QUFDckMsUUFBSSxTQUFnQztBQUNwQyxRQUFJLFdBQWtDO0FBQ3RDLFFBQUksWUFBc0M7QUFDMUMsUUFBSSxjQUFxQztBQUN6QyxRQUFJLGFBQStCLENBQUM7QUFDcEMsUUFBSSx5QkFBeUI7QUFFN0IsVUFBTSxhQUFhO0FBQ25CLFVBQU0sWUFBWTtBQUNsQixVQUFNLGlCQUFpQjtBQUFBLE1BQ3JCO0FBQUEsTUFBUztBQUFBLE1BQVk7QUFBQSxNQUFhO0FBQUEsTUFBVztBQUFBLE1BQzdDO0FBQUEsTUFBZTtBQUFBLE1BQWE7QUFBQSxNQUFjO0FBQUEsTUFBYTtBQUFBLE1BQVk7QUFBQSxNQUNuRTtBQUFBLE1BQVc7QUFBQSxNQUFTO0FBQUEsSUFDdEI7QUFFQSxhQUFTLGVBQWU7QUFDdEIsVUFBSSxTQUFTLGVBQWUsU0FBUyxFQUFHO0FBRXhDLFlBQU0sUUFBUSxTQUFTLGNBQWMsT0FBTztBQUM1QyxZQUFNLEtBQUs7QUFDWCxZQUFNLGNBQWM7QUFBQTtBQUFBLFNBRWYsVUFBVTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLFNBYVYsVUFBVTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7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QUFBLElBRVEsZ0JBQXNCO0FBQzVCLFVBQUksS0FBSyxRQUFTO0FBQ2xCLFdBQUssTUFBTTtBQUFBLElBQ2I7QUFBQSxJQUVRLGVBQXFCO0FBQzNCLFVBQUksU0FBUyxlQUFlLDJCQUEyQixFQUFHO0FBRTFELFlBQU0sUUFBUSxTQUFTLGNBQWMsT0FBTztBQUM1QyxZQUFNLEtBQUs7QUFDWCxZQUFNLGNBQWM7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtB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
|