698 lines
90 KiB
JavaScript
698 lines
90 KiB
JavaScript
/*
|
|
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
if you want to view the source, please visit the github repository of this plugin
|
|
*/
|
|
|
|
var __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __export = (target, all) => {
|
|
for (var name in all)
|
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames(from))
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
|
|
// main.ts
|
|
var main_exports = {};
|
|
__export(main_exports, {
|
|
default: () => LLMAgentPlugin
|
|
});
|
|
module.exports = __toCommonJS(main_exports);
|
|
var import_obsidian3 = require("obsidian");
|
|
|
|
// src/utils/EventBus.ts
|
|
var EventBus = class {
|
|
constructor() {
|
|
this.events = {};
|
|
}
|
|
on(eventName, callback) {
|
|
if (!this.events[eventName]) {
|
|
this.events[eventName] = [];
|
|
}
|
|
this.events[eventName].push(callback);
|
|
}
|
|
off(eventName, callback) {
|
|
if (this.events[eventName]) {
|
|
this.events[eventName] = this.events[eventName].filter((cb) => cb !== callback);
|
|
}
|
|
}
|
|
emit(eventName, data) {
|
|
if (this.events[eventName]) {
|
|
this.events[eventName].forEach((callback) => callback(data));
|
|
}
|
|
}
|
|
};
|
|
|
|
// src/views/GraphView.ts
|
|
var import_obsidian = require("obsidian");
|
|
|
|
// src/components/GraphPanel.ts
|
|
var GraphPanel = class {
|
|
constructor(container, props) {
|
|
this.container = container;
|
|
this.props = props;
|
|
this.nodes = [];
|
|
this.edges = [];
|
|
this.init();
|
|
}
|
|
init() {
|
|
this.container.innerHTML = `
|
|
<div class="llm-agent-graph-panel">
|
|
<div id="reactflow-container" style="width: 100%; height: 100%;"></div>
|
|
</div>
|
|
`;
|
|
this.initReactFlow();
|
|
}
|
|
async initReactFlow() {
|
|
try {
|
|
this.createSimpleGraph();
|
|
} catch (error) {
|
|
console.error("\u041E\u0448\u0438\u0431\u043A\u0430 \u0438\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0438 React Flow:", error);
|
|
this.createFallbackGraph();
|
|
}
|
|
}
|
|
createSimpleGraph() {
|
|
const container = this.container.querySelector("#reactflow-container");
|
|
container.innerHTML = `
|
|
<div class="simple-graph">
|
|
<div class="graph-nodes" id="graph-nodes"></div>
|
|
<svg class="graph-edges" id="graph-edges"></svg>
|
|
</div>
|
|
`;
|
|
this.renderNodes();
|
|
this.renderEdges();
|
|
}
|
|
renderNodes() {
|
|
const nodesContainer = this.container.querySelector("#graph-nodes");
|
|
nodesContainer.innerHTML = "";
|
|
this.nodes.forEach((node, index) => {
|
|
var _a;
|
|
const nodeEl = document.createElement("div");
|
|
nodeEl.className = `graph-node node-${node.type || "default"}`;
|
|
nodeEl.style.cssText = `
|
|
position: absolute;
|
|
left: ${50 + index * 150}px;
|
|
top: ${50 + Math.floor(index / 5) * 80}px;
|
|
padding: 8px 12px;
|
|
border: 2px solid #333;
|
|
border-radius: 4px;
|
|
background: #fff;
|
|
cursor: pointer;
|
|
max-width: 120px;
|
|
word-wrap: break-word;
|
|
`;
|
|
nodeEl.textContent = ((_a = node.data) == null ? void 0 : _a.label) || `Node ${node.id}`;
|
|
nodeEl.dataset.nodeId = node.id;
|
|
nodeEl.addEventListener("click", () => {
|
|
this.handleNodeClick(node.id);
|
|
});
|
|
nodesContainer.appendChild(nodeEl);
|
|
});
|
|
}
|
|
renderEdges() {
|
|
const edgesContainer = this.container.querySelector("#graph-edges");
|
|
edgesContainer.innerHTML = "";
|
|
}
|
|
createFallbackGraph() {
|
|
const container = this.container.querySelector("#reactflow-container");
|
|
container.innerHTML = `
|
|
<div class="fallback-graph">
|
|
<p>\u0423\u043F\u0440\u043E\u0449\u0435\u043D\u043D\u043E\u0435 \u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u0433\u0440\u0430\u0444\u0430</p>
|
|
<div id="nodes-list"></div>
|
|
</div>
|
|
`;
|
|
this.renderFallbackNodes();
|
|
}
|
|
renderFallbackNodes() {
|
|
const nodesList = this.container.querySelector("#nodes-list");
|
|
nodesList.innerHTML = "";
|
|
this.nodes.forEach((node) => {
|
|
var _a;
|
|
const nodeEl = document.createElement("div");
|
|
nodeEl.className = "fallback-node";
|
|
nodeEl.textContent = `${node.id}: ${((_a = node.data) == null ? void 0 : _a.label) || "No label"}`;
|
|
nodeEl.addEventListener("click", () => this.handleNodeClick(node.id));
|
|
nodesList.appendChild(nodeEl);
|
|
});
|
|
}
|
|
updateData(graphData) {
|
|
this.nodes = graphData.nodes || [];
|
|
this.edges = graphData.edges || [];
|
|
this.renderNodes();
|
|
this.renderEdges();
|
|
}
|
|
handleNodeClick(nodeId) {
|
|
if (this.props.onNodeClick) {
|
|
this.props.onNodeClick(nodeId);
|
|
}
|
|
}
|
|
destroy() {
|
|
this.container.innerHTML = "";
|
|
}
|
|
};
|
|
|
|
// src/views/GraphView.ts
|
|
var GRAPH_VIEW_TYPE = "llm-agent-graph-view";
|
|
var GraphView = class extends import_obsidian.ItemView {
|
|
constructor(leaf, plugin) {
|
|
super(leaf);
|
|
this.plugin = plugin;
|
|
this.graphData = { nodes: [], edges: [] };
|
|
this.currentNode = null;
|
|
this.graphPanel = null;
|
|
}
|
|
getViewType() {
|
|
return GRAPH_VIEW_TYPE;
|
|
}
|
|
getDisplayText() {
|
|
return "LLM Agent Graph";
|
|
}
|
|
getIcon() {
|
|
return "brain-circuit";
|
|
}
|
|
async onOpen() {
|
|
const container = this.containerEl.children[1];
|
|
container.empty();
|
|
this.reactContainer = container.createDiv();
|
|
this.reactContainer.addClass("llm-agent-graph-container");
|
|
this.graphPanel = new GraphPanel(this.reactContainer, {
|
|
graphData: this.graphData,
|
|
onNodeClick: this.handleNodeClick.bind(this)
|
|
});
|
|
this.plugin.eventBus.on("graph-updated", this.handleGraphUpdate.bind(this));
|
|
this.plugin.eventBus.on("new-chat", this.handleNewChat.bind(this));
|
|
}
|
|
async onClose() {
|
|
if (this.graphPanel) {
|
|
this.graphPanel.destroy();
|
|
this.graphPanel = null;
|
|
}
|
|
this.plugin.eventBus.off("graph-updated", this.handleGraphUpdate);
|
|
this.plugin.eventBus.off("new-chat", this.handleNewChat);
|
|
}
|
|
// ----------------------------------------------- Event Handlers ---------------------------------------------------------------
|
|
handleNodeClick(nodeId) {
|
|
this.currentNode = nodeId;
|
|
this.plugin.eventBus.emit("node-selected", { nodeId });
|
|
}
|
|
handleGraphUpdate(data) {
|
|
this.graphData = data.graphData;
|
|
this.currentNode = data.currentNode;
|
|
if (this.graphPanel) {
|
|
this.graphPanel.updateData(this.graphData);
|
|
}
|
|
}
|
|
handleNewChat() {
|
|
this.graphData = { nodes: [], edges: [] };
|
|
this.currentNode = null;
|
|
if (this.graphPanel) {
|
|
this.graphPanel.updateData(this.graphData);
|
|
}
|
|
}
|
|
};
|
|
|
|
// src/views/ChatView.ts
|
|
var import_obsidian2 = require("obsidian");
|
|
|
|
// src/components/ChatPanel.ts
|
|
var ChatPanel = class {
|
|
constructor(container, props) {
|
|
this.container = container;
|
|
this.props = props;
|
|
this.chatHistory = props.chatHistory || [];
|
|
this.init();
|
|
}
|
|
init() {
|
|
this.container.innerHTML = `
|
|
<div class="llm-agent-chat-panel">
|
|
<div class="chat-history" id="chat-history"></div>
|
|
<div class="chat-input-form">
|
|
<div class="command-input">
|
|
<input type="text" id="message-input" placeholder="\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u0438\u043B\u0438 \u043A\u043E\u043C\u0430\u043D\u0434\u0443 (/)..." />
|
|
<div class="suggestions" id="suggestions" style="display: none;"></div>
|
|
</div>
|
|
<button type="button" id="send-button">\u041E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C</button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
this.messageInput = this.container.querySelector("#message-input");
|
|
this.sendButton = this.container.querySelector("#send-button");
|
|
this.suggestionsContainer = this.container.querySelector("#suggestions");
|
|
this.setupEventListeners();
|
|
this.renderHistory();
|
|
}
|
|
setupEventListeners() {
|
|
this.sendButton.addEventListener("click", () => this.handleSend());
|
|
this.messageInput.addEventListener("keydown", (e) => {
|
|
if (e.key === "Enter") {
|
|
if (this.suggestionsContainer.style.display === "block") {
|
|
const firstSuggestion = this.suggestionsContainer.querySelector(".suggestion-item");
|
|
if (firstSuggestion) {
|
|
this.messageInput.value = firstSuggestion.textContent || "";
|
|
this.hideSuggestions();
|
|
e.preventDefault();
|
|
return;
|
|
}
|
|
}
|
|
this.handleSend();
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
this.messageInput.addEventListener("input", (e) => {
|
|
this.handleInput(e.target.value);
|
|
});
|
|
}
|
|
handleInput(value) {
|
|
const commands = ["/help", "/imagine", "/analyze", "/subtitles_meet", "/subtitles_teams", "/summarize", "/chat"];
|
|
if (value.startsWith("/")) {
|
|
const filteredCommands = commands.filter((cmd) => cmd.startsWith(value.toLowerCase()));
|
|
this.showSuggestions(filteredCommands);
|
|
} else {
|
|
this.hideSuggestions();
|
|
}
|
|
}
|
|
showSuggestions(suggestions) {
|
|
if (suggestions.length === 0) {
|
|
this.hideSuggestions();
|
|
return;
|
|
}
|
|
this.suggestionsContainer.innerHTML = suggestions.map((suggestion) => `<div class="suggestion-item">${suggestion}</div>`).join("");
|
|
this.suggestionsContainer.style.display = "block";
|
|
this.suggestionsContainer.querySelectorAll(".suggestion-item").forEach((item) => {
|
|
item.addEventListener("click", () => {
|
|
this.messageInput.value = item.textContent || "";
|
|
this.hideSuggestions();
|
|
this.messageInput.focus();
|
|
});
|
|
});
|
|
}
|
|
hideSuggestions() {
|
|
this.suggestionsContainer.style.display = "none";
|
|
}
|
|
handleSend() {
|
|
const message = this.messageInput.value.trim();
|
|
if (message && this.props.onSendMessage) {
|
|
this.props.onSendMessage(message);
|
|
this.messageInput.value = "";
|
|
this.hideSuggestions();
|
|
}
|
|
}
|
|
renderHistory() {
|
|
const historyContainer = this.container.querySelector("#chat-history");
|
|
historyContainer.innerHTML = this.chatHistory.map(
|
|
(msg) => `
|
|
<div class="message ${msg.role}">
|
|
<div class="message-content">${this.processMessageContent(msg.content)}</div>
|
|
</div>
|
|
`
|
|
).join("");
|
|
historyContainer.scrollTop = historyContainer.scrollHeight;
|
|
}
|
|
processMessageContent(content) {
|
|
return content.replace(/<img([^>]*?)>/g, '<img$1 style="max-width: 100%; height: auto;">').replace(/\n/g, "<br>");
|
|
}
|
|
updateHistory(newHistory) {
|
|
this.chatHistory = newHistory;
|
|
this.renderHistory();
|
|
}
|
|
destroy() {
|
|
this.container.innerHTML = "";
|
|
}
|
|
};
|
|
|
|
// src/components/HistoryPanel.ts
|
|
var HistoryPanel = class {
|
|
constructor(container, props) {
|
|
this.container = container;
|
|
this.props = props;
|
|
this.graphs = props.graphs || [];
|
|
this.init();
|
|
}
|
|
init() {
|
|
this.container.innerHTML = `
|
|
<div class="llm-agent-history-panel">
|
|
<div class="history-header">
|
|
<h3>\u0418\u0441\u0442\u043E\u0440\u0438\u044F \u0434\u0438\u0430\u043B\u043E\u0433\u043E\u0432</h3>
|
|
<button id="new-chat-button" class="new-chat-button">+ \u041D\u043E\u0432\u044B\u0439 \u0447\u0430\u0442</button>
|
|
</div>
|
|
<div class="chat-list" id="chat-list"></div>
|
|
<div class="context-menu" id="context-menu" style="display: none;">
|
|
<button id="delete-graph-button">\u0423\u0434\u0430\u043B\u0438\u0442\u044C</button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
this.newChatButton = this.container.querySelector("#new-chat-button");
|
|
this.chatList = this.container.querySelector("#chat-list");
|
|
this.contextMenu = this.container.querySelector("#context-menu");
|
|
this.deleteButton = this.container.querySelector("#delete-graph-button");
|
|
this.setupEventListeners();
|
|
this.renderGraphs();
|
|
}
|
|
setupEventListeners() {
|
|
this.newChatButton.addEventListener("click", () => {
|
|
if (this.props.onNewChat) {
|
|
this.props.onNewChat();
|
|
}
|
|
});
|
|
this.deleteButton.addEventListener("click", () => {
|
|
if (this.contextMenuGraphId) {
|
|
this.handleDeleteGraph(this.contextMenuGraphId);
|
|
}
|
|
});
|
|
document.addEventListener("click", (e) => {
|
|
if (!this.contextMenu.contains(e.target)) {
|
|
this.contextMenu.style.display = "none";
|
|
}
|
|
});
|
|
}
|
|
renderGraphs() {
|
|
this.chatList.innerHTML = this.graphs.map(
|
|
(graph) => `
|
|
<div class="chat-list-item" data-graph-id="${graph.id}">
|
|
<div class="chat-item-content">
|
|
<div class="chat-item-text">
|
|
<span class="truncate">
|
|
${graph.first_message || `\u0413\u0440\u0430\u0444 ${graph.id}`}
|
|
</span>
|
|
</div>
|
|
<div class="chat-item-actions">
|
|
<button class="chat-item-options-button" data-graph-id="${graph.id}">
|
|
\u22EE
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`
|
|
).join("");
|
|
this.chatList.querySelectorAll(".chat-list-item").forEach((item) => {
|
|
item.addEventListener("click", (e) => {
|
|
if (!e.target.classList.contains("chat-item-options-button")) {
|
|
const graphId = item.dataset.graphId;
|
|
if (graphId && this.props.onGraphSelect) {
|
|
this.props.onGraphSelect(graphId);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
this.chatList.querySelectorAll(".chat-item-options-button").forEach((button) => {
|
|
button.addEventListener("click", (e) => {
|
|
e.stopPropagation();
|
|
this.showContextMenu(e, button.dataset.graphId || "");
|
|
});
|
|
});
|
|
}
|
|
showContextMenu(event, graphId) {
|
|
this.contextMenuGraphId = graphId;
|
|
this.contextMenu.style.display = "block";
|
|
this.contextMenu.style.left = `${event.clientX}px`;
|
|
this.contextMenu.style.top = `${event.clientY}px`;
|
|
}
|
|
async handleDeleteGraph(graphId) {
|
|
try {
|
|
const response = await fetch(`http://localhost:5000/api/graphs/${graphId}`, {
|
|
method: "DELETE"
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP \u043E\u0448\u0438\u0431\u043A\u0430! \u0441\u0442\u0430\u0442\u0443\u0441: ${response.status}`);
|
|
}
|
|
this.graphs = this.graphs.filter((graph) => graph.id !== graphId);
|
|
this.renderGraphs();
|
|
this.contextMenu.style.display = "none";
|
|
} catch (error) {
|
|
console.error("\u041E\u0448\u0438\u0431\u043A\u0430 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u0433\u0440\u0430\u0444\u0430:", error);
|
|
}
|
|
}
|
|
updateGraphs(newGraphs) {
|
|
this.graphs = newGraphs;
|
|
this.renderGraphs();
|
|
}
|
|
destroy() {
|
|
this.container.innerHTML = "";
|
|
}
|
|
};
|
|
|
|
// src/views/ChatView.ts
|
|
var CHAT_VIEW_TYPE = "llm-agent-chat-view";
|
|
var ChatView = class extends import_obsidian2.ItemView {
|
|
constructor(leaf, plugin) {
|
|
super(leaf);
|
|
this.plugin = plugin;
|
|
this.chatHistory = [];
|
|
this.graphsList = [];
|
|
this.selectedGraphId = null;
|
|
this.currentNode = null;
|
|
this.chatPanel = null;
|
|
this.historyPanel = null;
|
|
}
|
|
getViewType() {
|
|
return CHAT_VIEW_TYPE;
|
|
}
|
|
getDisplayText() {
|
|
return "LLM Agent Chat";
|
|
}
|
|
getIcon() {
|
|
return "message-circle";
|
|
}
|
|
async onOpen() {
|
|
const container = this.containerEl.children[1];
|
|
container.empty();
|
|
this.chatContainer = container.createDiv();
|
|
this.chatContainer.addClass("llm-agent-chat-container");
|
|
this.historyContainer = container.createDiv();
|
|
this.historyContainer.addClass("llm-agent-history-container");
|
|
this.chatPanel = new ChatPanel(this.chatContainer, {
|
|
chatHistory: this.chatHistory,
|
|
onSendMessage: this.handleSendMessage.bind(this)
|
|
});
|
|
this.historyPanel = new HistoryPanel(this.historyContainer, {
|
|
graphs: this.graphsList,
|
|
onGraphSelect: this.handleGraphSelect.bind(this),
|
|
onNewChat: this.handleNewChat.bind(this)
|
|
});
|
|
this.plugin.eventBus.on("node-selected", this.handleNodeSelected.bind(this));
|
|
this.plugin.eventBus.on("new-chat", this.handleNewChat.bind(this));
|
|
this.fetchGraphsList();
|
|
}
|
|
async onClose() {
|
|
if (this.chatPanel) {
|
|
this.chatPanel.destroy();
|
|
this.chatPanel = null;
|
|
}
|
|
if (this.historyPanel) {
|
|
this.historyPanel.destroy();
|
|
this.historyPanel = null;
|
|
}
|
|
this.plugin.eventBus.off("node-selected", this.handleNodeSelected);
|
|
this.plugin.eventBus.off("new-chat", this.handleNewChat);
|
|
}
|
|
// ----------------------------------------------- API Methods ---------------------------------------------------------------
|
|
async fetchGraphsList() {
|
|
try {
|
|
const response = await fetch(`${this.plugin.settings.apiBaseUrl}/graphs`);
|
|
const data = await response.json();
|
|
this.graphsList = data;
|
|
if (this.historyPanel) {
|
|
this.historyPanel.updateGraphs(this.graphsList);
|
|
}
|
|
} catch (error) {
|
|
console.error("\u041E\u0448\u0438\u0431\u043A\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438 \u0441\u043F\u0438\u0441\u043A\u0430 \u0433\u0440\u0430\u0444\u043E\u0432:", error);
|
|
}
|
|
}
|
|
async fetchGraphData(graphId) {
|
|
try {
|
|
const response = await fetch(`${this.plugin.settings.apiBaseUrl}/graphs/${graphId}`);
|
|
if (!response.ok) {
|
|
if (response.status === 404) {
|
|
console.error(`\u0413\u0440\u0430\u0444 \u0441 ID ${graphId} \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D.`);
|
|
}
|
|
throw new Error(`HTTP \u043E\u0448\u0438\u0431\u043A\u0430! \u0441\u0442\u0430\u0442\u0443\u0441: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
this.plugin.eventBus.emit("graph-updated", {
|
|
graphData: {
|
|
nodes: data.graph_nodes || [],
|
|
edges: data.graph_edges || []
|
|
},
|
|
currentNode: data.current_node_id
|
|
});
|
|
this.chatHistory = data.messages || [];
|
|
if (this.chatPanel) {
|
|
this.chatPanel.updateHistory(this.chatHistory);
|
|
}
|
|
} catch (error) {
|
|
console.error("\u041E\u0448\u0438\u0431\u043A\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438 \u0434\u0430\u043D\u043D\u044B\u0445 \u0433\u0440\u0430\u0444\u0430:", error);
|
|
}
|
|
}
|
|
async fetchMessagesFromRootToNode(nodeId) {
|
|
try {
|
|
const response = await fetch(`${this.plugin.settings.apiBaseUrl}/messages/${this.selectedGraphId}/${nodeId}`);
|
|
const data = await response.json();
|
|
this.chatHistory = data;
|
|
if (this.chatPanel) {
|
|
this.chatPanel.updateHistory(this.chatHistory);
|
|
}
|
|
} catch (error) {
|
|
console.error("\u041E\u0448\u0438\u0431\u043A\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439:", error);
|
|
}
|
|
}
|
|
// ----------------------------------------------- Event Handlers ---------------------------------------------------------------
|
|
async handleSendMessage(message) {
|
|
try {
|
|
const response = await fetch(`${this.plugin.settings.apiBaseUrl}/chat`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
},
|
|
body: JSON.stringify({
|
|
message,
|
|
graph_id: this.selectedGraphId,
|
|
parent_node_id: this.currentNode
|
|
})
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP \u043E\u0448\u0438\u0431\u043A\u0430! \u0441\u0442\u0430\u0442\u0443\u0441: ${response.status}`);
|
|
}
|
|
const result = await response.json();
|
|
this.selectedGraphId = result.graph_id;
|
|
const newCurrentNodeId = result.graph_visualization_data.current_node_id;
|
|
this.currentNode = newCurrentNodeId;
|
|
this.plugin.eventBus.emit("graph-updated", {
|
|
graphData: {
|
|
nodes: result.graph_visualization_data.nodes || [],
|
|
edges: result.graph_visualization_data.edges || []
|
|
},
|
|
currentNode: newCurrentNodeId
|
|
});
|
|
if (newCurrentNodeId) {
|
|
await this.fetchMessagesFromRootToNode(newCurrentNodeId);
|
|
} else {
|
|
this.chatHistory = result.messages || [];
|
|
if (this.chatPanel) {
|
|
this.chatPanel.updateHistory(this.chatHistory);
|
|
}
|
|
}
|
|
this.fetchGraphsList();
|
|
} catch (error) {
|
|
console.error("\u041E\u0448\u0438\u0431\u043A\u0430 \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0438 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F:", error);
|
|
}
|
|
}
|
|
handleNodeSelected(data) {
|
|
this.currentNode = data.nodeId;
|
|
if (this.selectedGraphId) {
|
|
this.fetchMessagesFromRootToNode(data.nodeId);
|
|
}
|
|
}
|
|
handleGraphSelect(graphId) {
|
|
this.selectedGraphId = graphId;
|
|
this.fetchGraphData(graphId);
|
|
}
|
|
handleNewChat() {
|
|
this.chatHistory = [];
|
|
this.currentNode = null;
|
|
this.selectedGraphId = null;
|
|
if (this.chatPanel) {
|
|
this.chatPanel.updateHistory(this.chatHistory);
|
|
}
|
|
}
|
|
};
|
|
|
|
// main.ts
|
|
var DEFAULT_SETTINGS = {
|
|
apiBaseUrl: "http://localhost:5000/api"
|
|
};
|
|
var LLMAgentPlugin = class extends import_obsidian3.Plugin {
|
|
async onload() {
|
|
await this.loadSettings();
|
|
this.eventBus = new EventBus();
|
|
this.registerView(GRAPH_VIEW_TYPE, (leaf) => new GraphView(leaf, this));
|
|
this.registerView(CHAT_VIEW_TYPE, (leaf) => new ChatView(leaf, this));
|
|
this.addCommand({
|
|
id: "open-llm-agent-graph",
|
|
name: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0433\u0440\u0430\u0444 \u0434\u0438\u0430\u043B\u043E\u0433\u043E\u0432 LLM Agent",
|
|
callback: () => this.activateGraphView()
|
|
});
|
|
this.addCommand({
|
|
id: "open-llm-agent-chat",
|
|
name: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0447\u0430\u0442 LLM Agent",
|
|
callback: () => this.activateChatView()
|
|
});
|
|
this.addCommand({
|
|
id: "new-llm-agent-chat",
|
|
name: "\u041D\u043E\u0432\u044B\u0439 \u0447\u0430\u0442 LLM Agent",
|
|
callback: () => this.handleNewChat()
|
|
});
|
|
this.addRibbonIcon("brain-circuit", "LLM Agent", () => {
|
|
this.activateGraphView();
|
|
this.activateChatView();
|
|
});
|
|
console.log("LLM Agent plugin \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D");
|
|
this.addSettingTab(new SampleSettingTab(this.app, this));
|
|
}
|
|
onunload() {
|
|
console.log("LLM Agent plugin \u0432\u044B\u0433\u0440\u0443\u0436\u0435\u043D");
|
|
}
|
|
// ----------------------------------------------- Settings Management ---------------------------------------------------------------
|
|
async loadSettings() {
|
|
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
|
}
|
|
async saveSettings() {
|
|
await this.saveData(this.settings);
|
|
}
|
|
// ----------------------------------------------- View Management ---------------------------------------------------------------
|
|
async activateGraphView() {
|
|
const existingLeaf = this.app.workspace.getLeavesOfType(GRAPH_VIEW_TYPE)[0];
|
|
if (existingLeaf) {
|
|
this.app.workspace.revealLeaf(existingLeaf);
|
|
} else {
|
|
await this.app.workspace.getLeaf("tab").setViewState({
|
|
type: GRAPH_VIEW_TYPE,
|
|
active: true
|
|
});
|
|
}
|
|
}
|
|
async activateChatView() {
|
|
const existingLeaf = this.app.workspace.getLeavesOfType(CHAT_VIEW_TYPE)[0];
|
|
if (existingLeaf) {
|
|
this.app.workspace.revealLeaf(existingLeaf);
|
|
} else {
|
|
const rightLeaf = this.app.workspace.getRightLeaf(false);
|
|
if (rightLeaf) {
|
|
await rightLeaf.setViewState({
|
|
type: CHAT_VIEW_TYPE,
|
|
active: true
|
|
});
|
|
}
|
|
}
|
|
}
|
|
// ----------------------------------------------- Event Handlers ---------------------------------------------------------------
|
|
handleNewChat() {
|
|
this.eventBus.emit("new-chat");
|
|
}
|
|
};
|
|
var SampleSettingTab = class extends import_obsidian3.PluginSettingTab {
|
|
constructor(app, plugin) {
|
|
super(app, plugin);
|
|
this.plugin = plugin;
|
|
}
|
|
display() {
|
|
const { containerEl } = this;
|
|
containerEl.empty();
|
|
new import_obsidian3.Setting(containerEl).setName("API Base URL").setDesc("\u0411\u0430\u0437\u043E\u0432\u044B\u0439 URL \u0434\u043B\u044F API LLM Agent").addText(
|
|
(text) => text.setPlaceholder("\u0412\u0432\u0435\u0434\u0438\u0442\u0435 URL").setValue(this.plugin.settings.apiBaseUrl).onChange(async (value) => {
|
|
this.plugin.settings.apiBaseUrl = value;
|
|
await this.plugin.saveSettings();
|
|
})
|
|
);
|
|
}
|
|
};
|
|
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibWFpbi50cyIsICJzcmMvdXRpbHMvRXZlbnRCdXMudHMiLCAic3JjL3ZpZXdzL0dyYXBoVmlldy50cyIsICJzcmMvY29tcG9uZW50cy9HcmFwaFBhbmVsLnRzIiwgInNyYy92aWV3cy9DaGF0Vmlldy50cyIsICJzcmMvY29tcG9uZW50cy9DaGF0UGFuZWwudHMiLCAic3JjL2NvbXBvbmVudHMvSGlzdG9yeVBhbmVsLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBBcHAsIEVkaXRvciwgTWFya2Rvd25WaWV3LCBNb2RhbCwgTm90aWNlLCBQbHVnaW4sIFBsdWdpblNldHRpbmdUYWIsIFNldHRpbmcsIEl0ZW1WaWV3LCBXb3Jrc3BhY2VMZWFmIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBFdmVudEJ1cyB9IGZyb20gJy4vc3JjL3V0aWxzL0V2ZW50QnVzJztcclxuaW1wb3J0IHsgR3JhcGhWaWV3LCBHUkFQSF9WSUVXX1RZUEUgfSBmcm9tICcuL3NyYy92aWV3cy9HcmFwaFZpZXcnO1xyXG5pbXBvcnQgeyBDaGF0VmlldywgQ0hBVF9WSUVXX1RZUEUgfSBmcm9tICcuL3NyYy92aWV3cy9DaGF0Vmlldyc7XHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBTZXR0aW5ncyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbmludGVyZmFjZSBMTE1BZ2VudFNldHRpbmdzIHtcclxuXHRhcGlCYXNlVXJsOiBzdHJpbmc7XHJcbn1cclxuXHJcbmNvbnN0IERFRkFVTFRfU0VUVElOR1M6IExMTUFnZW50U2V0dGluZ3MgPSB7XHJcblx0YXBpQmFzZVVybDogJ2h0dHA6Ly9sb2NhbGhvc3Q6NTAwMC9hcGknXHJcbn07XHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNYWluIFBsdWdpbiBDbGFzcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExMTUFnZW50UGx1Z2luIGV4dGVuZHMgUGx1Z2luIHtcclxuXHRzZXR0aW5nczogTExNQWdlbnRTZXR0aW5ncztcclxuXHRldmVudEJ1czogRXZlbnRCdXM7XHJcblxyXG5cdGFzeW5jIG9ubG9hZCgpIHtcclxuXHRcdGF3YWl0IHRoaXMubG9hZFNldHRpbmdzKCk7XHJcblxyXG5cdFx0dGhpcy5ldmVudEJ1cyA9IG5ldyBFdmVudEJ1cygpO1xyXG5cclxuXHRcdC8vIFx1MDQyMFx1MDQzNVx1MDQzM1x1MDQzOFx1MDQ0MVx1MDQ0Mlx1MDQ0MFx1MDQzOFx1MDQ0MFx1MDQ0M1x1MDQzNVx1MDQzQyBcdTA0M0FcdTA0MzBcdTA0NDFcdTA0NDJcdTA0M0VcdTA0M0NcdTA0M0RcdTA0NEJcdTA0MzUgdmlld3NcclxuXHRcdHRoaXMucmVnaXN0ZXJWaWV3KEdSQVBIX1ZJRVdfVFlQRSwgKGxlYWYpID0+IG5ldyBHcmFwaFZpZXcobGVhZiwgdGhpcykpO1xyXG5cdFx0dGhpcy5yZWdpc3RlclZpZXcoQ0hBVF9WSUVXX1RZUEUsIChsZWFmKSA9PiBuZXcgQ2hhdFZpZXcobGVhZiwgdGhpcykpO1xyXG5cclxuXHRcdC8vIFx1MDQxNFx1MDQzRVx1MDQzMVx1MDQzMFx1MDQzMlx1MDQzQlx1MDQ0Rlx1MDQzNVx1MDQzQyBcdTA0M0FcdTA0M0VcdTA0M0NcdTA0MzBcdTA0M0RcdTA0MzRcdTA0NEJcclxuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XHJcblx0XHRcdGlkOiAnb3Blbi1sbG0tYWdlbnQtZ3JhcGgnLFxyXG5cdFx0XHRuYW1lOiAnXHUwNDFFXHUwNDQyXHUwNDNBXHUwNDQwXHUwNDRCXHUwNDQyXHUwNDRDIFx1MDQzM1x1MDQ0MFx1MDQzMFx1MDQ0NCBcdTA0MzRcdTA0MzhcdTA0MzBcdTA0M0JcdTA0M0VcdTA0MzNcdTA0M0VcdTA0MzIgTExNIEFnZW50JyxcclxuXHRcdFx0Y2FsbGJhY2s6ICgpID0+IHRoaXMuYWN0aXZhdGVHcmFwaFZpZXcoKVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5hZGRDb21tYW5kKHtcclxuXHRcdFx0aWQ6ICdvcGVuLWxsbS1hZ2VudC1jaGF0JyxcclxuXHRcdFx0bmFtZTogJ1x1MDQxRVx1MDQ0Mlx1MDQzQVx1MDQ0MFx1MDQ0Qlx1MDQ0Mlx1MDQ0QyBcdTA0NDdcdTA0MzBcdTA0NDIgTExNIEFnZW50JyxcclxuXHRcdFx0Y2FsbGJhY2s6ICgpID0+IHRoaXMuYWN0aXZhdGVDaGF0VmlldygpXHJcblx0XHR9KTtcclxuXHJcblx0XHR0aGlzLmFkZENvbW1hbmQoe1xyXG5cdFx0XHRpZDogJ25ldy1sbG0tYWdlbnQtY2hhdCcsXHJcblx0XHRcdG5hbWU6ICdcdTA0MURcdTA0M0VcdTA0MzJcdTA0NEJcdTA0MzkgXHUwNDQ3XHUwNDMwXHUwNDQyIExMTSBBZ2VudCcsXHJcblx0XHRcdGNhbGxiYWNrOiAoKSA9PiB0aGlzLmhhbmRsZU5ld0NoYXQoKVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gXHUwNDE0XHUwNDNFXHUwNDMxXHUwNDMwXHUwNDMyXHUwNDNCXHUwNDRGXHUwNDM1XHUwNDNDIFx1MDQzOFx1MDQzQVx1MDQzRVx1MDQzRFx1MDQzQVx1MDQ0MyBcdTA0MzIgcmliYm9uXHJcblx0XHR0aGlzLmFkZFJpYmJvbkljb24oJ2JyYWluLWNpcmN1aXQnLCAnTExNIEFnZW50JywgKCkgPT4ge1xyXG5cdFx0XHR0aGlzLmFjdGl2YXRlR3JhcGhWaWV3KCk7XHJcblx0XHRcdHRoaXMuYWN0aXZhdGVDaGF0VmlldygpO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Y29uc29sZS5sb2coJ0xMTSBBZ2VudCBwbHVnaW4gXHUwNDM3XHUwNDMwXHUwNDMzXHUwNDQwXHUwNDQzXHUwNDM2XHUwNDM1XHUwNDNEJyk7XHJcblxyXG5cdFx0Ly8gVGhpcyBhZGRzIGEgc2V0dGluZ3MgdGFiIHNvIHRoZSB1c2VyIGNhbiBjb25maWd1cmUgdmFyaW91cyBhc3BlY3RzIG9mIHRoZSBwbHVnaW5cclxuXHRcdHRoaXMuYWRkU2V0dGluZ1RhYihuZXcgU2FtcGxlU2V0dGluZ1RhYih0aGlzLmFwcCwgdGhpcykpO1xyXG5cdH1cclxuXHJcblx0b251bmxvYWQoKSB7XHJcblx0XHRjb25zb2xlLmxvZygnTExNIEFnZW50IHBsdWdpbiBcdTA0MzJcdTA0NEJcdTA0MzNcdTA0NDBcdTA0NDNcdTA0MzZcdTA0MzVcdTA0M0QnKTtcclxuXHR9XHJcblxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFNldHRpbmdzIE1hbmFnZW1lbnQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG5cdGFzeW5jIGxvYWRTZXR0aW5ncygpIHtcclxuXHRcdHRoaXMuc2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX1NFVFRJTkdTLCBhd2FpdCB0aGlzLmxvYWREYXRhKCkpO1xyXG5cdH1cclxuXHJcblx0YXN5bmMgc2F2ZVNldHRpbmdzKCkge1xyXG5cdFx0YXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcclxuXHR9XHJcblxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFZpZXcgTWFuYWdlbWVudCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcblx0YXN5bmMgYWN0aXZhdGVHcmFwaFZpZXcoKSB7XHJcblx0XHRjb25zdCBleGlzdGluZ0xlYWYgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhdmVzT2ZUeXBlKEdSQVBIX1ZJRVdfVFlQRSlbMF07XHJcblx0XHRpZiAoZXhpc3RpbmdMZWFmKSB7XHJcblx0XHRcdHRoaXMuYXBwLndvcmtzcGFjZS5yZXZlYWxMZWFmKGV4aXN0aW5nTGVhZik7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRhd2FpdCB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhZigndGFiJykuc2V0Vmlld1N0YXRlKHtcclxuXHRcdFx0XHR0eXBlOiBHUkFQSF9WSUVXX1RZUEUsXHJcblx0XHRcdFx0YWN0aXZlOiB0cnVlXHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0YXN5bmMgYWN0aXZhdGVDaGF0VmlldygpIHtcclxuXHRcdGNvbnN0IGV4aXN0aW5nTGVhZiA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRMZWF2ZXNPZlR5cGUoQ0hBVF9WSUVXX1RZUEUpWzBdO1xyXG5cdFx0aWYgKGV4aXN0aW5nTGVhZikge1xyXG5cdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2UucmV2ZWFsTGVhZihleGlzdGluZ0xlYWYpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0Y29uc3QgcmlnaHRMZWFmID0gdGhpcy5hcHAud29ya3NwYWNlLmdldFJpZ2h0TGVhZihmYWxzZSk7XHJcblx0XHRcdGlmIChyaWdodExlYWYpIHtcclxuXHRcdFx0XHRhd2FpdCByaWdodExlYWYuc2V0Vmlld1N0YXRlKHtcclxuXHRcdFx0XHRcdHR5cGU6IENIQVRfVklFV19UWVBFLFxyXG5cdFx0XHRcdFx0YWN0aXZlOiB0cnVlXHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV2ZW50IEhhbmRsZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuXHRoYW5kbGVOZXdDaGF0KCkge1xyXG5cdFx0dGhpcy5ldmVudEJ1cy5lbWl0KCduZXctY2hhdCcpO1xyXG5cdH1cclxufVxyXG5cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gU2FtcGxlIFNldHRpbmcgVGFiIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuY2xhc3MgU2FtcGxlU2V0dGluZ1RhYiBleHRlbmRzIFBsdWdpblNldHRpbmdUYWIge1xyXG5cdHBsdWdpbjogTExNQWdlbnRQbHVnaW47XHJcblxyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IExMTUFnZW50UGx1Z2luKSB7XHJcblx0XHRzdXBlcihhcHAsIHBsdWdpbik7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHR9XHJcblxyXG5cdGRpc3BsYXkoKTogdm9pZCB7XHJcblx0XHRjb25zdCB7IGNvbnRhaW5lckVsIH0gPSB0aGlzO1xyXG5cclxuXHRcdGNvbnRhaW5lckVsLmVtcHR5KCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdBUEkgQmFzZSBVUkwnKVxyXG5cdFx0XHQuc2V0RGVzYygnXHUwNDExXHUwNDMwXHUwNDM3XHUwNDNFXHUwNDMyXHUwNDRCXHUwNDM5IFVSTCBcdTA0MzRcdTA0M0JcdTA0NEYgQVBJIExMTSBBZ2VudCcpXHJcblx0XHRcdC5hZGRUZXh0KCh0ZXh0KSA9PlxyXG5cdFx0XHRcdHRleHRcclxuXHRcdFx0XHRcdC5zZXRQbGFjZWhvbGRlcignXHUwNDEyXHUwNDMyXHUwNDM1XHUwNDM0XHUwNDM4XHUwNDQyXHUwNDM1IFVSTCcpXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuYXBpQmFzZVVybClcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuYXBpQmFzZVVybCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblx0fVxyXG59XHJcbiIsICIvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFdmVudCBCdXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG5leHBvcnQgY2xhc3MgRXZlbnRCdXMge1xyXG5cdHByaXZhdGUgZXZlbnRzOiB7IFtrZXk6IHN0cmluZ106ICgoZGF0YT86IGFueSkgPT4gdm9pZClbXSB9ID0ge307XHJcblxyXG5cdG9uKGV2ZW50TmFtZTogc3RyaW5nLCBjYWxsYmFjazogKGRhdGE/OiBhbnkpID0+IHZvaWQpOiB2b2lkIHtcclxuXHRcdGlmICghdGhpcy5ldmVudHNbZXZlbnROYW1lXSkge1xyXG5cdFx0XHR0aGlzLmV2ZW50c1tldmVudE5hbWVdID0gW107XHJcblx0XHR9XHJcblx0XHR0aGlzLmV2ZW50c1tldmVudE5hbWVdLnB1c2goY2FsbGJhY2spO1xyXG5cdH1cclxuXHJcblx0b2ZmKGV2ZW50TmFtZTogc3RyaW5nLCBjYWxsYmFjazogKGRhdGE/OiBhbnkpID0+IHZvaWQpOiB2b2lkIHtcclxuXHRcdGlmICh0aGlzLmV2ZW50c1tldmVudE5hbWVdKSB7XHJcblx0XHRcdHRoaXMuZXZlbnRzW2V2ZW50TmFtZV0gPSB0aGlzLmV2ZW50c1tldmVudE5hbWVdLmZpbHRlcigoY2IpID0+IGNiICE9PSBjYWxsYmFjayk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRlbWl0KGV2ZW50TmFtZTogc3RyaW5nLCBkYXRhPzogYW55KTogdm9pZCB7XHJcblx0XHRpZiAodGhpcy5ldmVudHNbZXZlbnROYW1lXSkge1xyXG5cdFx0XHR0aGlzLmV2ZW50c1tldmVudE5hbWVdLmZvckVhY2goKGNhbGxiYWNrKSA9PiBjYWxsYmFjayhkYXRhKSk7XHJcblx0XHR9XHJcblx0fVxyXG59XHJcbiIsICJpbXBvcnQgeyBJdGVtVmlldywgV29ya3NwYWNlTGVhZiB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IHsgR3JhcGhQYW5lbCB9IGZyb20gJy4uL2NvbXBvbmVudHMvR3JhcGhQYW5lbCc7XHJcbmltcG9ydCBMTE1BZ2VudFBsdWdpbiBmcm9tICdtYWluJztcclxuXHJcbmV4cG9ydCBjb25zdCBHUkFQSF9WSUVXX1RZUEUgPSAnbGxtLWFnZW50LWdyYXBoLXZpZXcnO1xyXG5cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gR3JhcGggVmlldyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbmV4cG9ydCBjbGFzcyBHcmFwaFZpZXcgZXh0ZW5kcyBJdGVtVmlldyB7XHJcblx0cGx1Z2luOiBMTE1BZ2VudFBsdWdpbjtcclxuXHRncmFwaERhdGE6IHsgbm9kZXM6IGFueVtdOyBlZGdlczogYW55W10gfTtcclxuXHRjdXJyZW50Tm9kZTogc3RyaW5nIHwgbnVsbDtcclxuXHRncmFwaFBhbmVsOiBHcmFwaFBhbmVsIHwgbnVsbDtcclxuXHRyZWFjdENvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQ7XHJcblxyXG5cdGNvbnN0cnVjdG9yKGxlYWY6IFdvcmtzcGFjZUxlYWYsIHBsdWdpbjogTExNQWdlbnRQbHVnaW4pIHtcclxuXHRcdHN1cGVyKGxlYWYpO1xyXG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XHJcblx0XHR0aGlzLmdyYXBoRGF0YSA9IHsgbm9kZXM6IFtdLCBlZGdlczogW10gfTtcclxuXHRcdHRoaXMuY3VycmVudE5vZGUgPSBudWxsO1xyXG5cdFx0dGhpcy5ncmFwaFBhbmVsID0gbnVsbDtcclxuXHR9XHJcblxyXG5cdGdldFZpZXdUeXBlKCk6IHN0cmluZyB7XHJcblx0XHRyZXR1cm4gR1JBUEhfVklFV19UWVBFO1xyXG5cdH1cclxuXHJcblx0Z2V0RGlzcGxheVRleHQoKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiAnTExNIEFnZW50IEdyYXBoJztcclxuXHR9XHJcblxyXG5cdGdldEljb24oKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiAnYnJhaW4tY2lyY3VpdCc7XHJcblx0fVxyXG5cclxuXHRhc3luYyBvbk9wZW4oKTogUHJvbWlzZTx2b2lkPiB7XHJcblx0XHRjb25zdCBjb250YWluZXIgPSB0aGlzLmNvbnRhaW5lckVsLmNoaWxkcmVuWzFdIGFzIEhUTUxFbGVtZW50O1xyXG5cdFx0Y29udGFpbmVyLmVtcHR5KCk7XHJcblxyXG5cdFx0Ly8gXHUwNDIxXHUwNDNFXHUwNDM3XHUwNDM0XHUwNDMwXHUwNDM1XHUwNDNDIFx1MDQzQVx1MDQzRVx1MDQzRFx1MDQ0Mlx1MDQzNVx1MDQzOVx1MDQzRFx1MDQzNVx1MDQ0MCBcdTA0MzRcdTA0M0JcdTA0NEYgUmVhY3QgXHUwNDNBXHUwNDNFXHUwNDNDXHUwNDNGXHUwNDNFXHUwNDNEXHUwNDM1XHUwNDNEXHUwNDQyXHUwNDMwXHJcblx0XHR0aGlzLnJlYWN0Q29udGFpbmVyID0gY29udGFpbmVyLmNyZWF0ZURpdigpIGFzIEhUTUxEaXZFbGVtZW50O1xyXG5cdFx0dGhpcy5yZWFjdENvbnRhaW5lci5hZGRDbGFzcygnbGxtLWFnZW50LWdyYXBoLWNvbnRhaW5lcicpO1xyXG5cclxuXHRcdC8vIFx1MDQxOFx1MDQzRFx1MDQzOFx1MDQ0Nlx1MDQzOFx1MDQzMFx1MDQzQlx1MDQzOFx1MDQzN1x1MDQzOFx1MDQ0MFx1MDQ0M1x1MDQzNVx1MDQzQyBSZWFjdCBcdTA0M0FcdTA0M0VcdTA0M0NcdTA0M0ZcdTA0M0VcdTA0M0RcdTA0MzVcdTA0M0RcdTA0NDJcclxuXHRcdHRoaXMuZ3JhcGhQYW5lbCA9IG5ldyBHcmFwaFBhbmVsKHRoaXMucmVhY3RDb250YWluZXIsIHtcclxuXHRcdFx0Z3JhcGhEYXRhOiB0aGlzLmdyYXBoRGF0YSxcclxuXHRcdFx0b25Ob2RlQ2xpY2s6IHRoaXMuaGFuZGxlTm9kZUNsaWNrLmJpbmQodGhpcylcclxuXHRcdH0pO1xyXG5cclxuXHRcdC8vIFx1MDQxRlx1MDQzRVx1MDQzNFx1MDQzRlx1MDQzOFx1MDQ0MVx1MDQ0Qlx1MDQzMlx1MDQzMFx1MDQzNVx1MDQzQ1x1MDQ0MVx1MDQ0RiBcdTA0M0RcdTA0MzAgXHUwNDQxXHUwNDNFXHUwNDMxXHUwNDRCXHUwNDQyXHUwNDM4XHUwNDRGXHJcblx0XHR0aGlzLnBsdWdpbi5ldmVudEJ1cy5vbignZ3JhcGgtdXBkYXRlZCcsIHRoaXMuaGFuZGxlR3JhcGhVcGRhdGUuYmluZCh0aGlzKSk7XHJcblx0XHR0aGlzLnBsdWdpbi5ldmVudEJ1cy5vbignbmV3LWNoYXQnLCB0aGlzLmhhbmRsZU5ld0NoYXQuYmluZCh0aGlzKSk7XHJcblx0fVxyXG5cclxuXHRhc3luYyBvbkNsb3NlKCk6IFByb21pc2U8dm9pZD4ge1xyXG5cdFx0aWYgKHRoaXMuZ3JhcGhQYW5lbCkge1xyXG5cdFx0XHR0aGlzLmdyYXBoUGFuZWwuZGVzdHJveSgpO1xyXG5cdFx0XHR0aGlzLmdyYXBoUGFuZWwgPSBudWxsO1xyXG5cdFx0fVxyXG5cdFx0dGhpcy5wbHVnaW4uZXZlbnRCdXMub2ZmKCdncmFwaC11cGRhdGVkJywgdGhpcy5oYW5kbGVHcmFwaFVwZGF0ZSk7XHJcblx0XHR0aGlzLnBsdWdpbi5ldmVudEJ1cy5vZmYoJ25ldy1jaGF0JywgdGhpcy5oYW5kbGVOZXdDaGF0KTtcclxuXHR9XHJcblxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV2ZW50IEhhbmRsZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuXHRoYW5kbGVOb2RlQ2xpY2sobm9kZUlkOiBzdHJpbmcpOiB2b2lkIHtcclxuXHRcdHRoaXMuY3VycmVudE5vZGUgPSBub2RlSWQ7XHJcblx0XHR0aGlzLnBsdWdpbi5ldmVudEJ1cy5lbWl0KCdub2RlLXNlbGVjdGVkJywgeyBub2RlSWQgfSk7XHJcblx0fVxyXG5cclxuXHRoYW5kbGVHcmFwaFVwZGF0ZShkYXRhOiB7IGdyYXBoRGF0YTogeyBub2RlczogYW55W107IGVkZ2VzOiBhbnlbXSB9OyBjdXJyZW50Tm9kZTogc3RyaW5nIHwgbnVsbCB9KTogdm9pZCB7XHJcblx0XHR0aGlzLmdyYXBoRGF0YSA9IGRhdGEuZ3JhcGhEYXRhO1xyXG5cdFx0dGhpcy5jdXJyZW50Tm9kZSA9IGRhdGEuY3VycmVudE5vZGU7XHJcblx0XHRpZiAodGhpcy5ncmFwaFBhbmVsKSB7XHJcblx0XHRcdHRoaXMuZ3JhcGhQYW5lbC51cGRhdGVEYXRhKHRoaXMuZ3JhcGhEYXRhKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGhhbmRsZU5ld0NoYXQoKTogdm9pZCB7XHJcblx0XHR0aGlzLmdyYXBoRGF0YSA9IHsgbm9kZXM6IFtdLCBlZGdlczogW10gfTtcclxuXHRcdHRoaXMuY3VycmVudE5vZGUgPSBudWxsO1xyXG5cdFx0aWYgKHRoaXMuZ3JhcGhQYW5lbCkge1xyXG5cdFx0XHR0aGlzLmdyYXBoUGFuZWwudXBkYXRlRGF0YSh0aGlzLmdyYXBoRGF0YSk7XHJcblx0XHR9XHJcblx0fVxyXG59XHJcbiIsICJleHBvcnQgY2xhc3MgR3JhcGhQYW5lbCB7XHJcblx0Y29udGFpbmVyOiBIVE1MRWxlbWVudDtcclxuXHRwcm9wczoge1xyXG5cdFx0Z3JhcGhEYXRhOiB7IG5vZGVzOiBhbnlbXTsgZWRnZXM6IGFueVtdIH07XHJcblx0XHRvbk5vZGVDbGljazogKG5vZGVJZDogc3RyaW5nKSA9PiB2b2lkO1xyXG5cdH07XHJcblx0bm9kZXM6IGFueVtdO1xyXG5cdGVkZ2VzOiBhbnlbXTtcclxuXHJcblx0Y29uc3RydWN0b3IoXHJcblx0XHRjb250YWluZXI6IEhUTUxFbGVtZW50LFxyXG5cdFx0cHJvcHM6IHtcclxuXHRcdFx0Z3JhcGhEYXRhOiB7IG5vZGVzOiBhbnlbXTsgZWRnZXM6IGFueVtdIH07XHJcblx0XHRcdG9uTm9kZUNsaWNrOiAobm9kZUlkOiBzdHJpbmcpID0+IHZvaWQ7XHJcblx0XHR9XHJcblx0KSB7XHJcblx0XHR0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcclxuXHRcdHRoaXMucHJvcHMgPSBwcm9wcztcclxuXHRcdHRoaXMubm9kZXMgPSBbXTtcclxuXHRcdHRoaXMuZWRnZXMgPSBbXTtcclxuXHJcblx0XHR0aGlzLmluaXQoKTtcclxuXHR9XHJcblxyXG5cdGluaXQoKTogdm9pZCB7XHJcblx0XHQvLyBcdTA0MjFcdTA0M0VcdTA0MzdcdTA0MzRcdTA0MzBcdTA0MzVcdTA0M0MgXHUwNDQxXHUwNDQyXHUwNDQwXHUwNDQzXHUwNDNBXHUwNDQyXHUwNDQzXHUwNDQwXHUwNDQzIFx1MDQzNFx1MDQzQlx1MDQ0RiBSZWFjdCBGbG93XHJcblx0XHR0aGlzLmNvbnRhaW5lci5pbm5lckhUTUwgPSBgXHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsbG0tYWdlbnQtZ3JhcGgtcGFuZWxcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgaWQ9XCJyZWFjdGZsb3ctY29udGFpbmVyXCIgc3R5bGU9XCJ3aWR0aDogMTAwJTsgaGVpZ2h0OiAxMDAlO1wiPjwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICBgO1xyXG5cclxuXHRcdC8vIFx1MDQxN1x1MDQzMFx1MDQzM1x1MDQ0MFx1MDQ0M1x1MDQzNlx1MDQzMFx1MDQzNVx1MDQzQyBSZWFjdCBGbG93IFx1MDQzNFx1MDQzOFx1MDQzRFx1MDQzMFx1MDQzQ1x1MDQzOFx1MDQ0N1x1MDQzNVx1MDQ0MVx1MDQzQVx1MDQzOCAoXHUwNDM1XHUwNDQxXHUwNDNCXHUwNDM4IFx1MDQzNFx1MDQzRVx1MDQ0MVx1MDQ0Mlx1MDQ0M1x1MDQzRlx1MDQzNVx1MDQzRClcclxuXHRcdHRoaXMuaW5pdFJlYWN0RmxvdygpO1xyXG5cdH1cclxuXHJcblx0YXN5bmMgaW5pdFJlYWN0RmxvdygpOiBQcm9taXNlPHZvaWQ+IHtcclxuXHRcdHRyeSB7XHJcblx0XHRcdC8vIFx1MDQxMiBcdTA0NDFcdTA0NDBcdTA0MzVcdTA0MzRcdTA0MzUgT2JzaWRpYW4gXHUwNDNEXHUwNDQzXHUwNDM2XHUwNDNEXHUwNDNFIFx1MDQzMVx1MDQ0M1x1MDQzNFx1MDQzNVx1MDQ0MiBcdTA0M0ZcdTA0M0VcdTA0MzRcdTA0M0FcdTA0M0JcdTA0NEVcdTA0NDdcdTA0MzhcdTA0NDJcdTA0NEMgUmVhY3QgRmxvdyBcdTA0NDdcdTA0MzVcdTA0NDBcdTA0MzVcdTA0MzcgQ0ROIFx1MDQzOFx1MDQzQlx1MDQzOCBidW5kbGVyXHJcblx0XHRcdC8vIFx1MDQxNFx1MDQzQlx1MDQ0RiBcdTA0MzRcdTA0MzVcdTA0M0NcdTA0M0VcdTA0M0RcdTA0NDFcdTA0NDJcdTA0NDBcdTA0MzBcdTA0NDZcdTA0MzhcdTA0MzggXHUwNDQxXHUwNDNFXHUwNDM3XHUwNDM0XHUwNDMwXHUwNDM1XHUwNDNDIFx1MDQ0M1x1MDQzRlx1MDQ0MFx1MDQzRVx1MDQ0OVx1MDQzNVx1MDQzRFx1MDQzRFx1MDQ0M1x1MDQ0RSBcdTA0MzJcdTA0MzhcdTA0MzdcdTA0NDNcdTA0MzBcdTA0M0JcdTA0MzhcdTA0MzdcdTA0MzBcdTA0NDZcdTA0MzhcdTA0NEVcclxuXHRcdFx0dGhpcy5jcmVhdGVTaW1wbGVHcmFwaCgpO1xyXG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcclxuXHRcdFx0Y29uc29sZS5lcnJvcignXHUwNDFFXHUwNDQ4XHUwNDM4XHUwNDMxXHUwNDNBXHUwNDMwIFx1MDQzOFx1MDQzRFx1MDQzOFx1MDQ0Nlx1MDQzOFx1MDQzMFx1MDQzQlx1MDQzOFx1MDQzN1x1MDQzMFx1MDQ0Nlx1MDQzOFx1MDQzOCBSZWFjdCBGbG93OicsIGVycm9yKTtcclxuXHRcdFx0dGhpcy5jcmVhdGVGYWxsYmFja0dyYXBoKCk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRjcmVhdGVTaW1wbGVHcmFwaCgpOiB2b2lkIHtcclxuXHRcdGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJyNyZWFjdGZsb3ctY29udGFpbmVyJykgYXMgSFRNTEVsZW1lbnQ7XHJcblx0XHRjb250YWluZXIuaW5uZXJIVE1MID0gYFxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2ltcGxlLWdyYXBoXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ3JhcGgtbm9kZXNcIiBpZD1cImdyYXBoLW5vZGVzXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8c3ZnIGNsYXNzPVwiZ3JhcGgtZWRnZXNcIiBpZD1cImdyYXBoLWVkZ2VzXCI+PC9zdmc+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIGA7XHJcblxyXG5cdFx0dGhpcy5yZW5kZXJOb2RlcygpO1xyXG5cdFx0dGhpcy5yZW5kZXJFZGdlcygpO1xyXG5cdH1cclxuXHJcblx0cmVuZGVyTm9kZXMoKTogdm9pZCB7XHJcblx0XHRjb25zdCBub2Rlc0NvbnRhaW5lciA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJyNncmFwaC1ub2RlcycpIGFzIEhUTUxFbGVtZW50O1xyXG5cdFx0bm9kZXNDb250YWluZXIuaW5uZXJIVE1MID0gJyc7XHJcblxyXG5cdFx0dGhpcy5ub2Rlcy5mb3JFYWNoKChub2RlLCBpbmRleCkgPT4ge1xyXG5cdFx0XHRjb25zdCBub2RlRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuXHRcdFx0bm9kZUVsLmNsYXNzTmFtZSA9IGBncmFwaC1ub2RlIG5vZGUtJHtub2RlLnR5cGUgfHwgJ2RlZmF1bHQnfWA7XHJcblx0XHRcdG5vZGVFbC5zdHlsZS5jc3NUZXh0ID0gYFxyXG4gICAgICAgICAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgICAgICAgICAgICAgbGVmdDogJHs1MCArIGluZGV4ICogMTUwfXB4O1xyXG4gICAgICAgICAgICAgICAgdG9wOiAkezUwICsgTWF0aC5mbG9vcihpbmRleCAvIDUpICogODB9cHg7XHJcbiAgICAgICAgICAgICAgICBwYWRkaW5nOiA4cHggMTJweDtcclxuICAgICAgICAgICAgICAgIGJvcmRlcjogMnB4IHNvbGlkICMzMzM7XHJcbiAgICAgICAgICAgICAgICBib3JkZXItcmFkaXVzOiA0cHg7XHJcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiAjZmZmO1xyXG4gICAgICAgICAgICAgICAgY3Vyc29yOiBwb2ludGVyO1xyXG4gICAgICAgICAgICAgICAgbWF4LXdpZHRoOiAxMjBweDtcclxuICAgICAgICAgICAgICAgIHdvcmQtd3JhcDogYnJlYWstd29yZDtcclxuICAgICAgICAgICAgYDtcclxuXHRcdFx0bm9kZUVsLnRleHRDb250ZW50ID0gbm9kZS5kYXRhPy5sYWJlbCB8fCBgTm9kZSAke25vZGUuaWR9YDtcclxuXHRcdFx0bm9kZUVsLmRhdGFzZXQubm9kZUlkID0gbm9kZS5pZDtcclxuXHJcblx0XHRcdG5vZGVFbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcclxuXHRcdFx0XHR0aGlzLmhhbmRsZU5vZGVDbGljayhub2RlLmlkKTtcclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHRub2Rlc0NvbnRhaW5lci5hcHBlbmRDaGlsZChub2RlRWwpO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRyZW5kZXJFZGdlcygpOiB2b2lkIHtcclxuXHRcdGNvbnN0IGVkZ2VzQ29udGFpbmVyID0gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvcignI2dyYXBoLWVkZ2VzJykgYXMgSFRNTEVsZW1lbnQ7XHJcblx0XHRlZGdlc0NvbnRhaW5lci5pbm5lckhUTUwgPSAnJztcclxuXHRcdC8vIFx1MDQyM1x1MDQzRlx1MDQ0MFx1MDQzRVx1MDQ0OVx1MDQzNVx1MDQzRFx1MDQzRFx1MDQzMFx1MDQ0RiBcdTA0M0VcdTA0NDJcdTA0NDBcdTA0MzhcdTA0NDFcdTA0M0VcdTA0MzJcdTA0M0FcdTA0MzAgXHUwNDQxXHUwNDMyXHUwNDRGXHUwNDM3XHUwNDM1XHUwNDM5IC0gXHUwNDMyIFx1MDQ0MFx1MDQzNVx1MDQzMFx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQzRVx1MDQzOSBcdTA0NDBcdTA0MzVcdTA0MzBcdTA0M0JcdTA0MzhcdTA0MzdcdTA0MzBcdTA0NDZcdTA0MzhcdTA0MzggXHUwNDNEXHUwNDQzXHUwNDM2XHUwNDNEXHUwNDNFIFx1MDQzMVx1MDQ0M1x1MDQzNFx1MDQzNVx1MDQ0MiBcdTA0MzJcdTA0NEJcdTA0NDdcdTA0MzhcdTA0NDFcdTA0M0JcdTA0NEZcdTA0NDJcdTA0NEMgXHUwNDNGXHUwNDNFXHUwNDM3XHUwNDM4XHUwNDQ2XHUwNDM4XHUwNDM4XHJcblx0fVxyXG5cclxuXHRjcmVhdGVGYWxsYmFja0dyYXBoKCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgY29udGFpbmVyID0gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvcignI3JlYWN0Zmxvdy1jb250YWluZXInKSBhcyBIVE1MRWxlbWVudDtcclxuXHRcdGNvbnRhaW5lci5pbm5lckhUTUwgPSBgXHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmYWxsYmFjay1ncmFwaFwiPlxyXG4gICAgICAgICAgICAgICAgPHA+XHUwNDIzXHUwNDNGXHUwNDQwXHUwNDNFXHUwNDQ5XHUwNDM1XHUwNDNEXHUwNDNEXHUwNDNFXHUwNDM1IFx1MDQzRlx1MDQ0MFx1MDQzNVx1MDQzNFx1MDQ0MVx1MDQ0Mlx1MDQzMFx1MDQzMlx1MDQzQlx1MDQzNVx1MDQzRFx1MDQzOFx1MDQzNSBcdTA0MzNcdTA0NDBcdTA0MzBcdTA0NDRcdTA0MzA8L3A+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGlkPVwibm9kZXMtbGlzdFwiPjwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICBgO1xyXG5cdFx0dGhpcy5yZW5kZXJGYWxsYmFja05vZGVzKCk7XHJcblx0fVxyXG5cclxuXHRyZW5kZXJGYWxsYmFja05vZGVzKCk6IHZvaWQge1xyXG5cdFx0Y29uc3Qgbm9kZXNMaXN0ID0gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvcignI25vZGVzLWxpc3QnKSBhcyBIVE1MRWxlbWVudDtcclxuXHRcdG5vZGVzTGlzdC5pbm5lckhUTUwgPSAnJztcclxuXHJcblx0XHR0aGlzLm5vZGVzLmZvckVhY2goKG5vZGUpID0+IHtcclxuXHRcdFx0Y29uc3Qgbm9kZUVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcblx0XHRcdG5vZGVFbC5jbGFzc05hbWUgPSAnZmFsbGJhY2stbm9kZSc7XHJcblx0XHRcdG5vZGVFbC50ZXh0Q29udGVudCA9IGAke25vZGUuaWR9OiAke25vZGUuZGF0YT8ubGFiZWwgfHwgJ05vIGxhYmVsJ31gO1xyXG5cdFx0XHRub2RlRWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB0aGlzLmhhbmRsZU5vZGVDbGljayhub2RlLmlkKSk7XHJcblx0XHRcdG5vZGVzTGlzdC5hcHBlbmRDaGlsZChub2RlRWwpO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHR1cGRhdGVEYXRhKGdyYXBoRGF0YTogeyBub2RlczogYW55W107IGVkZ2VzOiBhbnlbXSB9KTogdm9pZCB7XHJcblx0XHR0aGlzLm5vZGVzID0gZ3JhcGhEYXRhLm5vZGVzIHx8IFtdO1xyXG5cdFx0dGhpcy5lZGdlcyA9IGdyYXBoRGF0YS5lZGdlcyB8fCBbXTtcclxuXHRcdHRoaXMucmVuZGVyTm9kZXMoKTtcclxuXHRcdHRoaXMucmVuZGVyRWRnZXMoKTtcclxuXHR9XHJcblxyXG5cdGhhbmRsZU5vZGVDbGljayhub2RlSWQ6IHN0cmluZyk6IHZvaWQge1xyXG5cdFx0aWYgKHRoaXMucHJvcHMub25Ob2RlQ2xpY2spIHtcclxuXHRcdFx0dGhpcy5wcm9wcy5vbk5vZGVDbGljayhub2RlSWQpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0ZGVzdHJveSgpOiB2b2lkIHtcclxuXHRcdC8vIFx1MDQxRVx1MDQ0N1x1MDQzOFx1MDQ0MVx1MDQ0Mlx1MDQzQVx1MDQzMCBcdTA0NDBcdTA0MzVcdTA0NDFcdTA0NDNcdTA0NDBcdTA0NDFcdTA0M0VcdTA0MzJcclxuXHRcdHRoaXMuY29udGFpbmVyLmlubmVySFRNTCA9ICcnO1xyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IHsgSXRlbVZpZXcsIFdvcmtzcGFjZUxlYWYgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IENoYXRQYW5lbCB9IGZyb20gJy4uL2NvbXBvbmVudHMvQ2hhdFBhbmVsJztcclxuaW1wb3J0IHsgSGlzdG9yeVBhbmVsIH0gZnJvbSAnLi4vY29tcG9uZW50cy9IaXN0b3J5UGFuZWwnO1xyXG5pbXBvcnQgTExNQWdlbnRQbHVnaW4gZnJvbSAnbWFpbic7XHJcblxyXG5leHBvcnQgY29uc3QgQ0hBVF9WSUVXX1RZUEUgPSAnbGxtLWFnZW50LWNoYXQtdmlldyc7XHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDaGF0IFZpZXcgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG5leHBvcnQgY2xhc3MgQ2hhdFZpZXcgZXh0ZW5kcyBJdGVtVmlldyB7XHJcblx0cGx1Z2luOiBMTE1BZ2VudFBsdWdpbjtcclxuXHRjaGF0SGlzdG9yeTogYW55W107XHJcblx0Z3JhcGhzTGlzdDogYW55W107XHJcblx0c2VsZWN0ZWRHcmFwaElkOiBzdHJpbmcgfCBudWxsO1xyXG5cdGN1cnJlbnROb2RlOiBzdHJpbmcgfCBudWxsO1xyXG5cdGNoYXRDb250YWluZXI6IEhUTUxEaXZFbGVtZW50O1xyXG5cdGhpc3RvcnlDb250YWluZXI6IEhUTUxEaXZFbGVtZW50O1xyXG5cdGNoYXRQYW5lbDogQ2hhdFBhbmVsIHwgbnVsbDtcclxuXHRoaXN0b3J5UGFuZWw6IEhpc3RvcnlQYW5lbCB8IG51bGw7XHJcblxyXG5cdGNvbnN0cnVjdG9yKGxlYWY6IFdvcmtzcGFjZUxlYWYsIHBsdWdpbjogTExNQWdlbnRQbHVnaW4pIHtcclxuXHRcdHN1cGVyKGxlYWYpO1xyXG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XHJcblx0XHR0aGlzLmNoYXRIaXN0b3J5ID0gW107XHJcblx0XHR0aGlzLmdyYXBoc0xpc3QgPSBbXTtcclxuXHRcdHRoaXMuc2VsZWN0ZWRHcmFwaElkID0gbnVsbDtcclxuXHRcdHRoaXMuY3VycmVudE5vZGUgPSBudWxsO1xyXG5cdFx0dGhpcy5jaGF0UGFuZWwgPSBudWxsO1xyXG5cdFx0dGhpcy5oaXN0b3J5UGFuZWwgPSBudWxsO1xyXG5cdH1cclxuXHJcblx0Z2V0Vmlld1R5cGUoKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiBDSEFUX1ZJRVdfVFlQRTtcclxuXHR9XHJcblxyXG5cdGdldERpc3BsYXlUZXh0KCk6IHN0cmluZyB7XHJcblx0XHRyZXR1cm4gJ0xMTSBBZ2VudCBDaGF0JztcclxuXHR9XHJcblxyXG5cdGdldEljb24oKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiAnbWVzc2FnZS1jaXJjbGUnO1xyXG5cdH1cclxuXHJcblx0YXN5bmMgb25PcGVuKCk6IFByb21pc2U8dm9pZD4ge1xyXG5cdFx0Y29uc3QgY29udGFpbmVyID0gdGhpcy5jb250YWluZXJFbC5jaGlsZHJlblsxXSBhcyBIVE1MRWxlbWVudDtcclxuXHRcdGNvbnRhaW5lci5lbXB0eSgpO1xyXG5cclxuXHRcdC8vIFx1MDQyMVx1MDQzRVx1MDQzN1x1MDQzNFx1MDQzMFx1MDQzNVx1MDQzQyBcdTA0M0FcdTA0M0VcdTA0M0RcdTA0NDJcdTA0MzVcdTA0MzlcdTA0M0RcdTA0MzVcdTA0NDBcdTA0NEIgXHUwNDM0XHUwNDNCXHUwNDRGIFJlYWN0IFx1MDQzQVx1MDQzRVx1MDQzQ1x1MDQzRlx1MDQzRVx1MDQzRFx1MDQzNVx1MDQzRFx1MDQ0Mlx1MDQzRVx1MDQzMlxyXG5cdFx0dGhpcy5jaGF0Q29udGFpbmVyID0gY29udGFpbmVyLmNyZWF0ZURpdigpIGFzIEhUTUxEaXZFbGVtZW50O1xyXG5cdFx0dGhpcy5jaGF0Q29udGFpbmVyLmFkZENsYXNzKCdsbG0tYWdlbnQtY2hhdC1jb250YWluZXInKTtcclxuXHJcblx0XHR0aGlzLmhpc3RvcnlDb250YWluZXIgPSBjb250YWluZXIuY3JlYXRlRGl2KCkgYXMgSFRNTERpdkVsZW1lbnQ7XHJcblx0XHR0aGlzLmhpc3RvcnlDb250YWluZXIuYWRkQ2xhc3MoJ2xsbS1hZ2VudC1oaXN0b3J5LWNvbnRhaW5lcicpO1xyXG5cclxuXHRcdC8vIFx1MDQxOFx1MDQzRFx1MDQzOFx1MDQ0Nlx1MDQzOFx1MDQzMFx1MDQzQlx1MDQzOFx1MDQzN1x1MDQzOFx1MDQ0MFx1MDQ0M1x1MDQzNVx1MDQzQyBSZWFjdCBcdTA0M0FcdTA0M0VcdTA0M0NcdTA0M0ZcdTA0M0VcdTA0M0RcdTA0MzVcdTA0M0RcdTA0NDJcdTA0NEJcclxuXHRcdHRoaXMuY2hhdFBhbmVsID0gbmV3IENoYXRQYW5lbCh0aGlzLmNoYXRDb250YWluZXIsIHtcclxuXHRcdFx0Y2hhdEhpc3Rvcnk6IHRoaXMuY2hhdEhpc3RvcnksXHJcblx0XHRcdG9uU2VuZE1lc3NhZ2U6IHRoaXMuaGFuZGxlU2VuZE1lc3NhZ2UuYmluZCh0aGlzKVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5oaXN0b3J5UGFuZWwgPSBuZXcgSGlzdG9yeVBhbmVsKHRoaXMuaGlzdG9yeUNvbnRhaW5lciwge1xyXG5cdFx0XHRncmFwaHM6IHRoaXMuZ3JhcGhzTGlzdCxcclxuXHRcdFx0b25HcmFwaFNlbGVjdDogdGhpcy5oYW5kbGVHcmFwaFNlbGVjdC5iaW5kKHRoaXMpLFxyXG5cdFx0XHRvbk5ld0NoYXQ6IHRoaXMuaGFuZGxlTmV3Q2hhdC5iaW5kKHRoaXMpXHJcblx0XHR9KTtcclxuXHJcblx0XHQvLyBcdTA0MUZcdTA0M0VcdTA0MzRcdTA0M0ZcdTA0MzhcdTA0NDFcdTA0NEJcdTA0MzJcdTA0MzBcdTA0MzVcdTA0M0NcdTA0NDFcdTA0NEYgXHUwNDNEXHUwNDMwIFx1MDQ0MVx1MDQzRVx1MDQzMVx1MDQ0Qlx1MDQ0Mlx1MDQzOFx1MDQ0RlxyXG5cdFx0dGhpcy5wbHVnaW4uZXZlbnRCdXMub24oJ25vZGUtc2VsZWN0ZWQnLCB0aGlzLmhhbmRsZU5vZGVTZWxlY3RlZC5iaW5kKHRoaXMpKTtcclxuXHRcdHRoaXMucGx1Z2luLmV2ZW50QnVzLm9uKCduZXctY2hhdCcsIHRoaXMuaGFuZGxlTmV3Q2hhdC5iaW5kKHRoaXMpKTtcclxuXHJcblx0XHQvLyBcdTA0MTdcdTA0MzBcdTA0MzNcdTA0NDBcdTA0NDNcdTA0MzZcdTA0MzBcdTA0MzVcdTA0M0MgXHUwNDQxXHUwNDNGXHUwNDM4XHUwNDQxXHUwNDNFXHUwNDNBIFx1MDQzM1x1MDQ0MFx1MDQzMFx1MDQ0NFx1MDQzRVx1MDQzMlxyXG5cdFx0dGhpcy5mZXRjaEdyYXBoc0xpc3QoKTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIG9uQ2xvc2UoKTogUHJvbWlzZTx2b2lkPiB7XHJcblx0XHRpZiAodGhpcy5jaGF0UGFuZWwpIHtcclxuXHRcdFx0dGhpcy5jaGF0UGFuZWwuZGVzdHJveSgpO1xyXG5cdFx0XHR0aGlzLmNoYXRQYW5lbCA9IG51bGw7XHJcblx0XHR9XHJcblx0XHRpZiAodGhpcy5oaXN0b3J5UGFuZWwpIHtcclxuXHRcdFx0dGhpcy5oaXN0b3J5UGFuZWwuZGVzdHJveSgpO1xyXG5cdFx0XHR0aGlzLmhpc3RvcnlQYW5lbCA9IG51bGw7XHJcblx0XHR9XHJcblx0XHR0aGlzLnBsdWdpbi5ldmVudEJ1cy5vZmYoJ25vZGUtc2VsZWN0ZWQnLCB0aGlzLmhhbmRsZU5vZGVTZWxlY3RlZCk7XHJcblx0XHR0aGlzLnBsdWdpbi5ldmVudEJ1cy5vZmYoJ25ldy1jaGF0JywgdGhpcy5oYW5kbGVOZXdDaGF0KTtcclxuXHR9XHJcblxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEFQSSBNZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuXHRhc3luYyBmZXRjaEdyYXBoc0xpc3QoKTogUHJvbWlzZTx2b2lkPiB7XHJcblx0XHR0cnkge1xyXG5cdFx0XHRjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke3RoaXMucGx1Z2luLnNldHRpbmdzLmFwaUJhc2VVcmx9L2dyYXBoc2ApO1xyXG5cdFx0XHRjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xyXG5cdFx0XHR0aGlzLmdyYXBoc0xpc3QgPSBkYXRhO1xyXG5cdFx0XHRpZiAodGhpcy5oaXN0b3J5UGFuZWwpIHtcclxuXHRcdFx0XHR0aGlzLmhpc3RvcnlQYW5lbC51cGRhdGVHcmFwaHModGhpcy5ncmFwaHNMaXN0KTtcclxuXHRcdFx0fVxyXG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcclxuXHRcdFx0Y29uc29sZS5lcnJvcignXHUwNDFFXHUwNDQ4XHUwNDM4XHUwNDMxXHUwNDNBXHUwNDMwIFx1MDQzN1x1MDQzMFx1MDQzM1x1MDQ0MFx1MDQ0M1x1MDQzN1x1MDQzQVx1MDQzOCBcdTA0NDFcdTA0M0ZcdTA0MzhcdTA0NDFcdTA0M0FcdTA0MzAgXHUwNDMzXHUwNDQwXHUwNDMwXHUwNDQ0XHUwNDNFXHUwNDMyOicsIGVycm9yKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGFzeW5jIGZldGNoR3JhcGhEYXRhKGdyYXBoSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xyXG5cdFx0dHJ5IHtcclxuXHRcdFx0Y29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChgJHt0aGlzLnBsdWdpbi5zZXR0aW5ncy5hcGlCYXNlVXJsfS9ncmFwaHMvJHtncmFwaElkfWApO1xyXG5cdFx0XHRpZiAoIXJlc3BvbnNlLm9rKSB7XHJcblx0XHRcdFx0aWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gNDA0KSB7XHJcblx0XHRcdFx0XHRjb25zb2xlLmVycm9yKGBcdTA0MTNcdTA0NDBcdTA0MzBcdTA0NDQgXHUwNDQxIElEICR7Z3JhcGhJZH0gXHUwNDNEXHUwNDM1IFx1MDQzRFx1MDQzMFx1MDQzOVx1MDQzNFx1MDQzNVx1MDQzRC5gKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKGBIVFRQIFx1MDQzRVx1MDQ0OFx1MDQzOFx1MDQzMVx1MDQzQVx1MDQzMCEgXHUwNDQxXHUwNDQyXHUwNDMwXHUwNDQyXHUwNDQzXHUwNDQxOiAke3Jlc3BvbnNlLnN0YXR1c31gKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xyXG5cclxuXHRcdFx0Ly8gXHUwNDFFXHUwNDMxXHUwNDNEXHUwNDNFXHUwNDMyXHUwNDNCXHUwNDRGXHUwNDM1XHUwNDNDIFx1MDQzM1x1MDQ0MFx1MDQzMFx1MDQ0NFxyXG5cdFx0XHR0aGlzLnBsdWdpbi5ldmVudEJ1cy5lbWl0KCdncmFwaC11cGRhdGVkJywge1xyXG5cdFx0XHRcdGdyYXBoRGF0YToge1xyXG5cdFx0XHRcdFx0bm9kZXM6IGRhdGEuZ3JhcGhfbm9kZXMgfHwgW10sXHJcblx0XHRcdFx0XHRlZGdlczogZGF0YS5ncmFwaF9lZGdlcyB8fCBbXVxyXG5cdFx0XHRcdH0sXHJcblx0XHRcdFx0Y3VycmVudE5vZGU6IGRhdGEuY3VycmVudF9ub2RlX2lkXHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0Ly8gXHUwNDFFXHUwNDMxXHUwNDNEXHUwNDNFXHUwNDMyXHUwNDNCXHUwNDRGXHUwNDM1XHUwNDNDIFx1MDQzOFx1MDQ0MVx1MDQ0Mlx1MDQzRVx1MDQ0MFx1MDQzOFx1MDQ0RSBcdTA0NDdcdTA0MzBcdTA0NDJcdTA0MzBcclxuXHRcdFx0dGhpcy5jaGF0SGlzdG9yeSA9IGRhdGEubWVzc2FnZXMgfHwgW107XHJcblx0XHRcdGlmICh0aGlzLmNoYXRQYW5lbCkge1xyXG5cdFx0XHRcdHRoaXMuY2hhdFBhbmVsLnVwZGF0ZUhpc3RvcnkodGhpcy5jaGF0SGlzdG9yeSk7XHJcblx0XHRcdH1cclxuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XHJcblx0XHRcdGNvbnNvbGUuZXJyb3IoJ1x1MDQxRVx1MDQ0OFx1MDQzOFx1MDQzMVx1MDQzQVx1MDQzMCBcdTA0MzdcdTA0MzBcdTA0MzNcdTA0NDBcdTA0NDNcdTA0MzdcdTA0M0FcdTA0MzggXHUwNDM0XHUwNDMwXHUwNDNEXHUwNDNEXHUwNDRCXHUwNDQ1IFx1MDQzM1x1MDQ0MFx1MDQzMFx1MDQ0NFx1MDQzMDonLCBlcnJvcik7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRhc3luYyBmZXRjaE1lc3NhZ2VzRnJvbVJvb3RUb05vZGUobm9kZUlkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuXHRcdHRyeSB7XHJcblx0XHRcdGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYCR7dGhpcy5wbHVnaW4uc2V0dGluZ3MuYXBpQmFzZVVybH0vbWVzc2FnZXMvJHt0aGlzLnNlbGVjdGVkR3JhcGhJZH0vJHtub2RlSWR9YCk7XHJcblx0XHRcdGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XHJcblx0XHRcdHRoaXMuY2hhdEhpc3RvcnkgPSBkYXRhO1xyXG5cdFx0XHRpZiAodGhpcy5jaGF0UGFuZWwpIHtcclxuXHRcdFx0XHR0aGlzLmNoYXRQYW5lbC51cGRhdGVIaXN0b3J5KHRoaXMuY2hhdEhpc3RvcnkpO1xyXG5cdFx0XHR9XHJcblx0XHR9IGNhdGNoIChlcnJvcikge1xyXG5cdFx0XHRjb25zb2xlLmVycm9yKCdcdTA0MUVcdTA0NDhcdTA0MzhcdTA0MzFcdTA0M0FcdTA0MzAgXHUwNDM3XHUwNDMwXHUwNDMzXHUwNDQwXHUwNDQzXHUwNDM3XHUwNDNBXHUwNDM4IFx1MDQ0MVx1MDQzRVx1MDQzRVx1MDQzMVx1MDQ0OVx1MDQzNVx1MDQzRFx1MDQzOFx1MDQzOTonLCBlcnJvcik7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFdmVudCBIYW5kbGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcblx0YXN5bmMgaGFuZGxlU2VuZE1lc3NhZ2UobWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcblx0XHR0cnkge1xyXG5cdFx0XHRjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke3RoaXMucGx1Z2luLnNldHRpbmdzLmFwaUJhc2VVcmx9L2NoYXRgLCB7XHJcblx0XHRcdFx0bWV0aG9kOiAnUE9TVCcsXHJcblx0XHRcdFx0aGVhZGVyczoge1xyXG5cdFx0XHRcdFx0J0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xyXG5cdFx0XHRcdH0sXHJcblx0XHRcdFx0Ym9keTogSlNPTi5zdHJpbmdpZnkoe1xyXG5cdFx0XHRcdFx0bWVzc2FnZTogbWVzc2FnZSxcclxuXHRcdFx0XHRcdGdyYXBoX2lkOiB0aGlzLnNlbGVjdGVkR3JhcGhJZCxcclxuXHRcdFx0XHRcdHBhcmVudF9ub2RlX2lkOiB0aGlzLmN1cnJlbnROb2RlXHJcblx0XHRcdFx0fSlcclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHRpZiAoIXJlc3BvbnNlLm9rKSB7XHJcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKGBIVFRQIFx1MDQzRVx1MDQ0OFx1MDQzOFx1MDQzMVx1MDQzQVx1MDQzMCEgXHUwNDQxXHUwNDQyXHUwNDMwXHUwNDQyXHUwNDQzXHUwNDQxOiAke3Jlc3BvbnNlLnN0YXR1c31gKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xyXG5cclxuXHRcdFx0Ly8gXHUwNDFFXHUwNDMxXHUwNDNEXHUwNDNFXHUwNDMyXHUwNDNCXHUwNDRGXHUwNDM1XHUwNDNDIFx1MDQzMlx1MDQ0Qlx1MDQzMVx1MDQ0MFx1MDQzMFx1MDQzRFx1MDQzRFx1MDQ0Qlx1MDQzOSBJRCBcdTA0MzNcdTA0NDBcdTA0MzBcdTA0NDRcdTA0MzBcclxuXHRcdFx0dGhpcy5zZWxlY3RlZEdyYXBoSWQgPSByZXN1bHQuZ3JhcGhfaWQ7XHJcblxyXG5cdFx0XHQvLyBcdTA0MjNcdTA0NDFcdTA0NDJcdTA0MzBcdTA0M0RcdTA0MzBcdTA0MzJcdTA0M0JcdTA0MzhcdTA0MzJcdTA0MzBcdTA0MzVcdTA0M0MgXHUwNDQyXHUwNDM1XHUwNDNBXHUwNDQzXHUwNDQ5XHUwNDM4XHUwNDM5IFx1MDQ0M1x1MDQzN1x1MDQzNVx1MDQzQlxyXG5cdFx0XHRjb25zdCBuZXdDdXJyZW50Tm9kZUlkID0gcmVzdWx0LmdyYXBoX3Zpc3VhbGl6YXRpb25fZGF0YS5jdXJyZW50X25vZGVfaWQ7XHJcblx0XHRcdHRoaXMuY3VycmVudE5vZGUgPSBuZXdDdXJyZW50Tm9kZUlkO1xyXG5cclxuXHRcdFx0Ly8gXHUwNDFFXHUwNDMxXHUwNDNEXHUwNDNFXHUwNDMyXHUwNDNCXHUwNDRGXHUwNDM1XHUwNDNDIFx1MDQzM1x1MDQ0MFx1MDQzMFx1MDQ0NFxyXG5cdFx0XHR0aGlzLnBsdWdpbi5ldmVudEJ1cy5lbWl0KCdncmFwaC11cGRhdGVkJywge1xyXG5cdFx0XHRcdGdyYXBoRGF0YToge1xyXG5cdFx0XHRcdFx0bm9kZXM6IHJlc3VsdC5ncmFwaF92aXN1YWxpemF0aW9uX2RhdGEubm9kZXMgfHwgW10sXHJcblx0XHRcdFx0XHRlZGdlczogcmVzdWx0LmdyYXBoX3Zpc3VhbGl6YXRpb25fZGF0YS5lZGdlcyB8fCBbXVxyXG5cdFx0XHRcdH0sXHJcblx0XHRcdFx0Y3VycmVudE5vZGU6IG5ld0N1cnJlbnROb2RlSWRcclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHQvLyBcdTA0MTdcdTA0MzBcdTA0MzNcdTA0NDBcdTA0NDNcdTA0MzZcdTA0MzBcdTA0MzVcdTA0M0MgXHUwNDQxXHUwNDNFXHUwNDNFXHUwNDMxXHUwNDQ5XHUwNDM1XHUwNDNEXHUwNDM4XHUwNDRGIFx1MDQzRVx1MDQ0MiBcdTA0M0FcdTA0M0VcdTA0NDBcdTA0M0RcdTA0NEYgXHUwNDM0XHUwNDNFIFx1MDQzRFx1MDQzRVx1MDQzMlx1MDQzRVx1MDQzM1x1MDQzRSBcdTA0NDJcdTA0MzVcdTA0M0FcdTA0NDNcdTA0NDlcdTA0MzVcdTA0MzNcdTA0M0UgXHUwNDQzXHUwNDM3XHUwNDNCXHUwNDMwXHJcblx0XHRcdGlmIChuZXdDdXJyZW50Tm9kZUlkKSB7XHJcblx0XHRcdFx0YXdhaXQgdGhpcy5mZXRjaE1lc3NhZ2VzRnJvbVJvb3RUb05vZGUobmV3Q3VycmVudE5vZGVJZCk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0dGhpcy5jaGF0SGlzdG9yeSA9IHJlc3VsdC5tZXNzYWdlcyB8fCBbXTtcclxuXHRcdFx0XHRpZiAodGhpcy5jaGF0UGFuZWwpIHtcclxuXHRcdFx0XHRcdHRoaXMuY2hhdFBhbmVsLnVwZGF0ZUhpc3RvcnkodGhpcy5jaGF0SGlzdG9yeSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBcdTA0MUVcdTA0MzFcdTA0M0RcdTA0M0VcdTA0MzJcdTA0M0JcdTA0NEZcdTA0MzVcdTA0M0MgXHUwNDQxXHUwNDNGXHUwNDM4XHUwNDQxXHUwNDNFXHUwNDNBIFx1MDQzM1x1MDQ0MFx1MDQzMFx1MDQ0NFx1MDQzRVx1MDQzMlxyXG5cdFx0XHR0aGlzLmZldGNoR3JhcGhzTGlzdCgpO1xyXG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcclxuXHRcdFx0Y29uc29sZS5lcnJvcignXHUwNDFFXHUwNDQ4XHUwNDM4XHUwNDMxXHUwNDNBXHUwNDMwIFx1MDQzRVx1MDQ0Mlx1MDQzRlx1MDQ0MFx1MDQzMFx1MDQzMlx1MDQzQVx1MDQzOCBcdTA0NDFcdTA0M0VcdTA0M0VcdTA0MzFcdTA0NDlcdTA0MzVcdTA0M0RcdTA0MzhcdTA0NEY6JywgZXJyb3IpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0aGFuZGxlTm9kZVNlbGVjdGVkKGRhdGE6IHsgbm9kZUlkOiBzdHJpbmcgfSk6IHZvaWQge1xyXG5cdFx0dGhpcy5jdXJyZW50Tm9kZSA9IGRhdGEubm9kZUlkO1xyXG5cdFx0aWYgKHRoaXMuc2VsZWN0ZWRHcmFwaElkKSB7XHJcblx0XHRcdHRoaXMuZmV0Y2hNZXNzYWdlc0Zyb21Sb290VG9Ob2RlKGRhdGEubm9kZUlkKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGhhbmRsZUdyYXBoU2VsZWN0KGdyYXBoSWQ6IHN0cmluZyk6IHZvaWQge1xyXG5cdFx0dGhpcy5zZWxlY3RlZEdyYXBoSWQgPSBncmFwaElkO1xyXG5cdFx0dGhpcy5mZXRjaEdyYXBoRGF0YShncmFwaElkKTtcclxuXHR9XHJcblxyXG5cdGhhbmRsZU5ld0NoYXQoKTogdm9pZCB7XHJcblx0XHR0aGlzLmNoYXRIaXN0b3J5ID0gW107XHJcblx0XHR0aGlzLmN1cnJlbnROb2RlID0gbnVsbDtcclxuXHRcdHRoaXMuc2VsZWN0ZWRHcmFwaElkID0gbnVsbDtcclxuXHRcdGlmICh0aGlzLmNoYXRQYW5lbCkge1xyXG5cdFx0XHR0aGlzLmNoYXRQYW5lbC51cGRhdGVIaXN0b3J5KHRoaXMuY2hhdEhpc3RvcnkpO1xyXG5cdFx0fVxyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IHsgQ2hhdEhpc3RvcnlJdGVtIH0gZnJvbSAnLi9tb2RlbHMvQ2hhdEhpc3RvcnlJdGVtJztcclxuXHJcbmV4cG9ydCBjbGFzcyBDaGF0UGFuZWwge1xyXG5cdGNvbnRhaW5lcjogSFRNTEVsZW1lbnQ7XHJcblx0cHJvcHM6IHtcclxuXHRcdGNoYXRIaXN0b3J5OiBDaGF0SGlzdG9yeUl0ZW1bXTtcclxuXHRcdG9uU2VuZE1lc3NhZ2U6IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQ7XHJcblx0fTtcclxuXHRjaGF0SGlzdG9yeTogQ2hhdEhpc3RvcnlJdGVtW107XHJcblx0bWVzc2FnZUlucHV0OiBIVE1MSW5wdXRFbGVtZW50O1xyXG5cdHNlbmRCdXR0b246IEhUTUxCdXR0b25FbGVtZW50O1xyXG5cdHN1Z2dlc3Rpb25zQ29udGFpbmVyOiBIVE1MRGl2RWxlbWVudDtcclxuXHJcblx0Y29uc3RydWN0b3IoXHJcblx0XHRjb250YWluZXI6IEhUTUxFbGVtZW50LFxyXG5cdFx0cHJvcHM6IHtcclxuXHRcdFx0Y2hhdEhpc3Rvcnk6IENoYXRIaXN0b3J5SXRlbVtdO1xyXG5cdFx0XHRvblNlbmRNZXNzYWdlOiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkO1xyXG5cdFx0fVxyXG5cdCkge1xyXG5cdFx0dGhpcy5jb250YWluZXIgPSBjb250YWluZXI7XHJcblx0XHR0aGlzLnByb3BzID0gcHJvcHM7XHJcblx0XHR0aGlzLmNoYXRIaXN0b3J5ID0gcHJvcHMuY2hhdEhpc3RvcnkgfHwgW107XHJcblxyXG5cdFx0dGhpcy5pbml0KCk7XHJcblx0fVxyXG5cclxuXHRpbml0KCk6IHZvaWQge1xyXG5cdFx0dGhpcy5jb250YWluZXIuaW5uZXJIVE1MID0gYFxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGxtLWFnZW50LWNoYXQtcGFuZWxcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjaGF0LWhpc3RvcnlcIiBpZD1cImNoYXQtaGlzdG9yeVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNoYXQtaW5wdXQtZm9ybVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21tYW5kLWlucHV0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwibWVzc2FnZS1pbnB1dFwiIHBsYWNlaG9sZGVyPVwiXHUwNDEyXHUwNDMyXHUwNDM1XHUwNDM0XHUwNDM4XHUwNDQyXHUwNDM1IFx1MDQ0MVx1MDQzRVx1MDQzRVx1MDQzMVx1MDQ0OVx1MDQzNVx1MDQzRFx1MDQzOFx1MDQzNSBcdTA0MzhcdTA0M0JcdTA0MzggXHUwNDNBXHUwNDNFXHUwNDNDXHUwNDMwXHUwNDNEXHUwNDM0XHUwNDQzICgvKS4uLlwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdWdnZXN0aW9uc1wiIGlkPVwic3VnZ2VzdGlvbnNcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgaWQ9XCJzZW5kLWJ1dHRvblwiPlx1MDQxRVx1MDQ0Mlx1MDQzRlx1MDQ0MFx1MDQzMFx1MDQzMlx1MDQzOFx1MDQ0Mlx1MDQ0QzwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIGA7XHJcblxyXG5cdFx0dGhpcy5tZXNzYWdlSW5wdXQgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcjbWVzc2FnZS1pbnB1dCcpIGFzIEhUTUxJbnB1dEVsZW1lbnQ7XHJcblx0XHR0aGlzLnNlbmRCdXR0b24gPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcjc2VuZC1idXR0b24nKSBhcyBIVE1MQnV0dG9uRWxlbWVudDtcclxuXHRcdHRoaXMuc3VnZ2VzdGlvbnNDb250YWluZXIgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcjc3VnZ2VzdGlvbnMnKSBhcyBIVE1MRGl2RWxlbWVudDtcclxuXHJcblx0XHR0aGlzLnNldHVwRXZlbnRMaXN0ZW5lcnMoKTtcclxuXHRcdHRoaXMucmVuZGVySGlzdG9yeSgpO1xyXG5cdH1cclxuXHJcblx0c2V0dXBFdmVudExpc3RlbmVycygpOiB2b2lkIHtcclxuXHRcdHRoaXMuc2VuZEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHRoaXMuaGFuZGxlU2VuZCgpKTtcclxuXHJcblx0XHR0aGlzLm1lc3NhZ2VJbnB1dC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgKGUpID0+IHtcclxuXHRcdFx0aWYgKGUua2V5ID09PSAnRW50ZXInKSB7XHJcblx0XHRcdFx0aWYgKHRoaXMuc3VnZ2VzdGlvbnNDb250YWluZXIuc3R5bGUuZGlzcGxheSA9PT0gJ2Jsb2NrJykge1xyXG5cdFx0XHRcdFx0Y29uc3QgZmlyc3RTdWdnZXN0aW9uID0gdGhpcy5zdWdnZXN0aW9uc0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcuc3VnZ2VzdGlvbi1pdGVtJyk7XHJcblx0XHRcdFx0XHRpZiAoZmlyc3RTdWdnZXN0aW9uKSB7XHJcblx0XHRcdFx0XHRcdHRoaXMubWVzc2FnZUlucHV0LnZhbHVlID0gZmlyc3RTdWdnZXN0aW9uLnRleHRDb250ZW50IHx8ICcnO1xyXG5cdFx0XHRcdFx0XHR0aGlzLmhpZGVTdWdnZXN0aW9ucygpO1xyXG5cdFx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRcdFx0XHRcdHJldHVybjtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0dGhpcy5oYW5kbGVTZW5kKCk7XHJcblx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHR0aGlzLm1lc3NhZ2VJbnB1dC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIChlKSA9PiB7XHJcblx0XHRcdHRoaXMuaGFuZGxlSW5wdXQoKGUudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpLnZhbHVlKTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0aGFuZGxlSW5wdXQodmFsdWU6IHN0cmluZyk6IHZvaWQge1xyXG5cdFx0Y29uc3QgY29tbWFuZHMgPSBbJy9oZWxwJywgJy9pbWFnaW5lJywgJy9hbmFseXplJywgJy9zdWJ0aXRsZXNfbWVldCcsICcvc3VidGl0bGVzX3RlYW1zJywgJy9zdW1tYXJpemUnLCAnL2NoYXQnXTtcclxuXHJcblx0XHRpZiAodmFsdWUuc3RhcnRzV2l0aCgnLycpKSB7XHJcblx0XHRcdGNvbnN0IGZpbHRlcmVkQ29tbWFuZHMgPSBjb21tYW5kcy5maWx0ZXIoKGNtZCkgPT4gY21kLnN0YXJ0c1dpdGgodmFsdWUudG9Mb3dlckNhc2UoKSkpO1xyXG5cdFx0XHR0aGlzLnNob3dTdWdnZXN0aW9ucyhmaWx0ZXJlZENvbW1hbmRzKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHRoaXMuaGlkZVN1Z2dlc3Rpb25zKCk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRzaG93U3VnZ2VzdGlvbnMoc3VnZ2VzdGlvbnM6IHN0cmluZ1tdKTogdm9pZCB7XHJcblx0XHRpZiAoc3VnZ2VzdGlvbnMubGVuZ3RoID09PSAwKSB7XHJcblx0XHRcdHRoaXMuaGlkZVN1Z2dlc3Rpb25zKCk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLnN1Z2dlc3Rpb25zQ29udGFpbmVyLmlubmVySFRNTCA9IHN1Z2dlc3Rpb25zLm1hcCgoc3VnZ2VzdGlvbikgPT4gYDxkaXYgY2xhc3M9XCJzdWdnZXN0aW9uLWl0ZW1cIj4ke3N1Z2dlc3Rpb259PC9kaXY+YCkuam9pbignJyk7XHJcblxyXG5cdFx0dGhpcy5zdWdnZXN0aW9uc0NvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuXHJcblx0XHQvLyBcdTA0MTRcdTA0M0VcdTA0MzFcdTA0MzBcdTA0MzJcdTA0M0JcdTA0NEZcdTA0MzVcdTA0M0MgXHUwNDNFXHUwNDMxXHUwNDQwXHUwNDMwXHUwNDMxXHUwNDNFXHUwNDQyXHUwNDQ3XHUwNDM4XHUwNDNBXHUwNDM4IFx1MDQzQVx1MDQzQlx1MDQzOFx1MDQzQVx1MDQzRVx1MDQzMiBcdTA0M0RcdTA0MzAgXHUwNDNGXHUwNDQwXHUwNDM1XHUwNDM0XHUwNDNCXHUwNDNFXHUwNDM2XHUwNDM1XHUwNDNEXHUwNDM4XHUwNDRGXHJcblx0XHR0aGlzLnN1Z2dlc3Rpb25zQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5zdWdnZXN0aW9uLWl0ZW0nKS5mb3JFYWNoKChpdGVtKSA9PiB7XHJcblx0XHRcdGl0ZW0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XHJcblx0XHRcdFx0dGhpcy5tZXNzYWdlSW5wdXQudmFsdWUgPSBpdGVtLnRleHRDb250ZW50IHx8ICcnO1xyXG5cdFx0XHRcdHRoaXMuaGlkZVN1Z2dlc3Rpb25zKCk7XHJcblx0XHRcdFx0dGhpcy5tZXNzYWdlSW5wdXQuZm9jdXMoKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdGhpZGVTdWdnZXN0aW9ucygpOiB2b2lkIHtcclxuXHRcdHRoaXMuc3VnZ2VzdGlvbnNDb250YWluZXIuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuXHR9XHJcblxyXG5cdGhhbmRsZVNlbmQoKTogdm9pZCB7XHJcblx0XHRjb25zdCBtZXNzYWdlID0gdGhpcy5tZXNzYWdlSW5wdXQudmFsdWUudHJpbSgpO1xyXG5cdFx0aWYgKG1lc3NhZ2UgJiYgdGhpcy5wcm9wcy5vblNlbmRNZXNzYWdlKSB7XHJcblx0XHRcdHRoaXMucHJvcHMub25TZW5kTWVzc2FnZShtZXNzYWdlKTtcclxuXHRcdFx0dGhpcy5tZXNzYWdlSW5wdXQudmFsdWUgPSAnJztcclxuXHRcdFx0dGhpcy5oaWRlU3VnZ2VzdGlvbnMoKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJlbmRlckhpc3RvcnkoKTogdm9pZCB7XHJcblx0XHRjb25zdCBoaXN0b3J5Q29udGFpbmVyID0gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvcignI2NoYXQtaGlzdG9yeScpIGFzIEhUTUxFbGVtZW50O1xyXG5cdFx0aGlzdG9yeUNvbnRhaW5lci5pbm5lckhUTUwgPSB0aGlzLmNoYXRIaXN0b3J5XHJcblx0XHRcdC5tYXAoXHJcblx0XHRcdFx0KG1zZykgPT4gYFxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lc3NhZ2UgJHttc2cucm9sZX1cIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVzc2FnZS1jb250ZW50XCI+JHt0aGlzLnByb2Nlc3NNZXNzYWdlQ29udGVudChtc2cuY29udGVudCl9PC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgYFxyXG5cdFx0XHQpXHJcblx0XHRcdC5qb2luKCcnKTtcclxuXHJcblx0XHQvLyBcdTA0MUZcdTA0NDBcdTA0M0VcdTA0M0FcdTA0NDBcdTA0NDNcdTA0NDdcdTA0MzhcdTA0MzJcdTA0MzBcdTA0MzVcdTA0M0MgXHUwNDNBIFx1MDQzQVx1MDQzRVx1MDQzRFx1MDQ0Nlx1MDQ0M1xyXG5cdFx0aGlzdG9yeUNvbnRhaW5lci5zY3JvbGxUb3AgPSBoaXN0b3J5Q29udGFpbmVyLnNjcm9sbEhlaWdodDtcclxuXHR9XHJcblxyXG5cdHByb2Nlc3NNZXNzYWdlQ29udGVudChjb250ZW50OiBzdHJpbmcpOiBzdHJpbmcge1xyXG5cdFx0Ly8gXHUwNDFGXHUwNDQwXHUwNDNFXHUwNDQxXHUwNDQyXHUwNDM1XHUwNDM5XHUwNDQ4XHUwNDMwXHUwNDRGIFx1MDQzRVx1MDQzMVx1MDQ0MFx1MDQzMFx1MDQzMVx1MDQzRVx1MDQ0Mlx1MDQzQVx1MDQzMCBNYXJrZG93biBcdTA0MzRcdTA0M0JcdTA0NEYgXHUwNDM4XHUwNDM3XHUwNDNFXHUwNDMxXHUwNDQwXHUwNDMwXHUwNDM2XHUwNDM1XHUwNDNEXHUwNDM4XHUwNDM5XHJcblx0XHRyZXR1cm4gY29udGVudC5yZXBsYWNlKC88aW1nKFtePl0qPyk+L2csICc8aW1nJDEgc3R5bGU9XCJtYXgtd2lkdGg6IDEwMCU7IGhlaWdodDogYXV0bztcIj4nKS5yZXBsYWNlKC9cXG4vZywgJzxicj4nKTtcclxuXHR9XHJcblxyXG5cdHVwZGF0ZUhpc3RvcnkobmV3SGlzdG9yeTogQ2hhdEhpc3RvcnlJdGVtW10pOiB2b2lkIHtcclxuXHRcdHRoaXMuY2hhdEhpc3RvcnkgPSBuZXdIaXN0b3J5O1xyXG5cdFx0dGhpcy5yZW5kZXJIaXN0b3J5KCk7XHJcblx0fVxyXG5cclxuXHRkZXN0cm95KCk6IHZvaWQge1xyXG5cdFx0dGhpcy5jb250YWluZXIuaW5uZXJIVE1MID0gJyc7XHJcblx0fVxyXG59XHJcbiIsICJleHBvcnQgY2xhc3MgSGlzdG9yeVBhbmVsIHtcclxuXHRjb250YWluZXI6IEhUTUxFbGVtZW50O1xyXG5cdHByb3BzOiB7XHJcblx0XHRncmFwaHM6IGFueVtdO1xyXG5cdFx0b25HcmFwaFNlbGVjdDogKGdyYXBoSWQ6IHN0cmluZykgPT4gdm9pZDtcclxuXHRcdG9uTmV3Q2hhdDogKCkgPT4gdm9pZDtcclxuXHR9O1xyXG5cdGdyYXBoczogYW55W107XHJcblx0bmV3Q2hhdEJ1dHRvbjogSFRNTEJ1dHRvbkVsZW1lbnQ7XHJcblx0Y2hhdExpc3Q6IEhUTUxFbGVtZW50O1xyXG5cdGNvbnRleHRNZW51OiBIVE1MRWxlbWVudDtcclxuXHRkZWxldGVCdXR0b246IEhUTUxCdXR0b25FbGVtZW50O1xyXG5cdGNvbnRleHRNZW51R3JhcGhJZDogc3RyaW5nIHwgbnVsbDtcclxuXHJcblx0Y29uc3RydWN0b3IoXHJcblx0XHRjb250YWluZXI6IEhUTUxFbGVtZW50LFxyXG5cdFx0cHJvcHM6IHtcclxuXHRcdFx0Z3JhcGhzOiBhbnlbXTtcclxuXHRcdFx0b25HcmFwaFNlbGVjdDogKGdyYXBoSWQ6IHN0cmluZykgPT4gdm9pZDtcclxuXHRcdFx0b25OZXdDaGF0OiAoKSA9PiB2b2lkO1xyXG5cdFx0fVxyXG5cdCkge1xyXG5cdFx0dGhpcy5jb250YWluZXIgPSBjb250YWluZXI7XHJcblx0XHR0aGlzLnByb3BzID0gcHJvcHM7XHJcblx0XHR0aGlzLmdyYXBocyA9IHByb3BzLmdyYXBocyB8fCBbXTtcclxuXHJcblx0XHR0aGlzLmluaXQoKTtcclxuXHR9XHJcblxyXG5cdGluaXQoKTogdm9pZCB7XHJcblx0XHR0aGlzLmNvbnRhaW5lci5pbm5lckhUTUwgPSBgXHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsbG0tYWdlbnQtaGlzdG9yeS1wYW5lbFwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhpc3RvcnktaGVhZGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGgzPlx1MDQxOFx1MDQ0MVx1MDQ0Mlx1MDQzRVx1MDQ0MFx1MDQzOFx1MDQ0RiBcdTA0MzRcdTA0MzhcdTA0MzBcdTA0M0JcdTA0M0VcdTA0MzNcdTA0M0VcdTA0MzI8L2gzPlxyXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gaWQ9XCJuZXctY2hhdC1idXR0b25cIiBjbGFzcz1cIm5ldy1jaGF0LWJ1dHRvblwiPisgXHUwNDFEXHUwNDNFXHUwNDMyXHUwNDRCXHUwNDM5IFx1MDQ0N1x1MDQzMFx1MDQ0MjwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2hhdC1saXN0XCIgaWQ9XCJjaGF0LWxpc3RcIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb250ZXh0LW1lbnVcIiBpZD1cImNvbnRleHQtbWVudVwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cclxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGlkPVwiZGVsZXRlLWdyYXBoLWJ1dHRvblwiPlx1MDQyM1x1MDQzNFx1MDQzMFx1MDQzQlx1MDQzOFx1MDQ0Mlx1MDQ0QzwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIGA7XHJcblxyXG5cdFx0dGhpcy5uZXdDaGF0QnV0dG9uID0gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvcignI25ldy1jaGF0LWJ1dHRvbicpIGFzIEhUTUxCdXR0b25FbGVtZW50O1xyXG5cdFx0dGhpcy5jaGF0TGlzdCA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJyNjaGF0LWxpc3QnKSBhcyBIVE1MRWxlbWVudDtcclxuXHRcdHRoaXMuY29udGV4dE1lbnUgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcjY29udGV4dC1tZW51JykgYXMgSFRNTEVsZW1lbnQ7XHJcblx0XHR0aGlzLmRlbGV0ZUJ1dHRvbiA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJyNkZWxldGUtZ3JhcGgtYnV0dG9uJykgYXMgSFRNTEJ1dHRvbkVsZW1lbnQ7XHJcblxyXG5cdFx0dGhpcy5zZXR1cEV2ZW50TGlzdGVuZXJzKCk7XHJcblx0XHR0aGlzLnJlbmRlckdyYXBocygpO1xyXG5cdH1cclxuXHJcblx0c2V0dXBFdmVudExpc3RlbmVycygpOiB2b2lkIHtcclxuXHRcdHRoaXMubmV3Q2hhdEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcclxuXHRcdFx0aWYgKHRoaXMucHJvcHMub25OZXdDaGF0KSB7XHJcblx0XHRcdFx0dGhpcy5wcm9wcy5vbk5ld0NoYXQoKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5kZWxldGVCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XHJcblx0XHRcdGlmICh0aGlzLmNvbnRleHRNZW51R3JhcGhJZCkge1xyXG5cdFx0XHRcdHRoaXMuaGFuZGxlRGVsZXRlR3JhcGgodGhpcy5jb250ZXh0TWVudUdyYXBoSWQpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHQvLyBcdTA0MTdcdTA0MzBcdTA0M0FcdTA0NDBcdTA0NEJcdTA0NDJcdTA0MzhcdTA0MzUgXHUwNDNBXHUwNDNFXHUwNDNEXHUwNDQyXHUwNDM1XHUwNDNBXHUwNDQxXHUwNDQyXHUwNDNEXHUwNDNFXHUwNDMzXHUwNDNFIFx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQ0RSBcdTA0M0ZcdTA0NDBcdTA0MzggXHUwNDNBXHUwNDNCXHUwNDM4XHUwNDNBXHUwNDM1IFx1MDQzMlx1MDQzRFx1MDQzNSBcdTA0MzVcdTA0MzNcdTA0M0VcclxuXHRcdGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGUpID0+IHtcclxuXHRcdFx0aWYgKCF0aGlzLmNvbnRleHRNZW51LmNvbnRhaW5zKGUudGFyZ2V0IGFzIE5vZGUpKSB7XHJcblx0XHRcdFx0dGhpcy5jb250ZXh0TWVudS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdHJlbmRlckdyYXBocygpOiB2b2lkIHtcclxuXHRcdHRoaXMuY2hhdExpc3QuaW5uZXJIVE1MID0gdGhpcy5ncmFwaHNcclxuXHRcdFx0Lm1hcChcclxuXHRcdFx0XHQoZ3JhcGgpID0+IGBcclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjaGF0LWxpc3QtaXRlbVwiIGRhdGEtZ3JhcGgtaWQ9XCIke2dyYXBoLmlkfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjaGF0LWl0ZW0tY29udGVudFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2hhdC1pdGVtLXRleHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidHJ1bmNhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2dyYXBoLmZpcnN0X21lc3NhZ2UgfHwgYFx1MDQxM1x1MDQ0MFx1MDQzMFx1MDQ0NCAke2dyYXBoLmlkfWB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2hhdC1pdGVtLWFjdGlvbnNcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJjaGF0LWl0ZW0tb3B0aW9ucy1idXR0b25cIiBkYXRhLWdyYXBoLWlkPVwiJHtncmFwaC5pZH1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcdTIyRUVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICBgXHJcblx0XHRcdClcclxuXHRcdFx0LmpvaW4oJycpO1xyXG5cclxuXHRcdC8vIFx1MDQxNFx1MDQzRVx1MDQzMVx1MDQzMFx1MDQzMlx1MDQzQlx1MDQ0Rlx1MDQzNVx1MDQzQyBcdTA0M0VcdTA0MzFcdTA0NDBcdTA0MzBcdTA0MzFcdTA0M0VcdTA0NDJcdTA0NDdcdTA0MzhcdTA0M0FcdTA0MzggXHUwNDQxXHUwNDNFXHUwNDMxXHUwNDRCXHUwNDQyXHUwNDM4XHUwNDM5XHJcblx0XHR0aGlzLmNoYXRMaXN0LnF1ZXJ5U2VsZWN0b3JBbGwoJy5jaGF0LWxpc3QtaXRlbScpLmZvckVhY2goKGl0ZW0pID0+IHtcclxuXHRcdFx0aXRlbS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChlKSA9PiB7XHJcblx0XHRcdFx0aWYgKCEoZS50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLmNsYXNzTGlzdC5jb250YWlucygnY2hhdC1pdGVtLW9wdGlvbnMtYnV0dG9uJykpIHtcclxuXHRcdFx0XHRcdGNvbnN0IGdyYXBoSWQgPSAoaXRlbSBhcyBIVE1MRWxlbWVudCkuZGF0YXNldC5ncmFwaElkO1xyXG5cdFx0XHRcdFx0aWYgKGdyYXBoSWQgJiYgdGhpcy5wcm9wcy5vbkdyYXBoU2VsZWN0KSB7XHJcblx0XHRcdFx0XHRcdHRoaXMucHJvcHMub25HcmFwaFNlbGVjdChncmFwaElkKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5jaGF0TGlzdC5xdWVyeVNlbGVjdG9yQWxsKCcuY2hhdC1pdGVtLW9wdGlvbnMtYnV0dG9uJykuZm9yRWFjaCgoYnV0dG9uKSA9PiB7XHJcblx0XHRcdGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChlKSA9PiB7XHJcblx0XHRcdFx0ZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHRcdFx0XHR0aGlzLnNob3dDb250ZXh0TWVudShlLCAoYnV0dG9uIGFzIEhUTUxFbGVtZW50KS5kYXRhc2V0LmdyYXBoSWQgfHwgJycpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0c2hvd0NvbnRleHRNZW51KGV2ZW50OiBFdmVudCwgZ3JhcGhJZDogc3RyaW5nKTogdm9pZCB7XHJcblx0XHR0aGlzLmNvbnRleHRNZW51R3JhcGhJZCA9IGdyYXBoSWQ7XHJcblx0XHR0aGlzLmNvbnRleHRNZW51LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG5cdFx0dGhpcy5jb250ZXh0TWVudS5zdHlsZS5sZWZ0ID0gYCR7KGV2ZW50IGFzIE1vdXNlRXZlbnQpLmNsaWVudFh9cHhgO1xyXG5cdFx0dGhpcy5jb250ZXh0TWVudS5zdHlsZS50b3AgPSBgJHsoZXZlbnQgYXMgTW91c2VFdmVudCkuY2xpZW50WX1weGA7XHJcblx0fVxyXG5cclxuXHRhc3luYyBoYW5kbGVEZWxldGVHcmFwaChncmFwaElkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuXHRcdHRyeSB7XHJcblx0XHRcdGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYGh0dHA6Ly9sb2NhbGhvc3Q6NTAwMC9hcGkvZ3JhcGhzLyR7Z3JhcGhJZH1gLCB7XHJcblx0XHRcdFx0bWV0aG9kOiAnREVMRVRFJ1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdGlmICghcmVzcG9uc2Uub2spIHtcclxuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoYEhUVFAgXHUwNDNFXHUwNDQ4XHUwNDM4XHUwNDMxXHUwNDNBXHUwNDMwISBcdTA0NDFcdTA0NDJcdTA0MzBcdTA0NDJcdTA0NDNcdTA0NDE6ICR7cmVzcG9uc2Uuc3RhdHVzfWApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBcdTA0MUVcdTA0MzFcdTA0M0RcdTA0M0VcdTA0MzJcdTA0M0JcdTA0NEZcdTA0MzVcdTA0M0MgXHUwNDQxXHUwNDNGXHUwNDM4XHUwNDQxXHUwNDNFXHUwNDNBIFx1MDQzM1x1MDQ0MFx1MDQzMFx1MDQ0NFx1MDQzRVx1MDQzMlxyXG5cdFx0XHR0aGlzLmdyYXBocyA9IHRoaXMuZ3JhcGhzLmZpbHRlcigoZ3JhcGgpID0+IGdyYXBoLmlkICE9PSBncmFwaElkKTtcclxuXHRcdFx0dGhpcy5yZW5kZXJHcmFwaHMoKTtcclxuXHRcdFx0dGhpcy5jb250ZXh0TWVudS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcclxuXHRcdFx0Y29uc29sZS5lcnJvcignXHUwNDFFXHUwNDQ4XHUwNDM4XHUwNDMxXHUwNDNBXHUwNDMwIFx1MDQ0M1x1MDQzNFx1MDQzMFx1MDQzQlx1MDQzNVx1MDQzRFx1MDQzOFx1MDQ0RiBcdTA0MzNcdTA0NDBcdTA0MzBcdTA0NDRcdTA0MzA6JywgZXJyb3IpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0dXBkYXRlR3JhcGhzKG5ld0dyYXBoczogYW55W10pOiB2b2lkIHtcclxuXHRcdHRoaXMuZ3JhcGhzID0gbmV3R3JhcGhzO1xyXG5cdFx0dGhpcy5yZW5kZXJHcmFwaHMoKTtcclxuXHR9XHJcblxyXG5cdGRlc3Ryb3koKTogdm9pZCB7XHJcblx0XHR0aGlzLmNvbnRhaW5lci5pbm5lckhUTUwgPSAnJztcclxuXHR9XHJcbn1cclxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLElBQUFBLG1CQUFxSDs7O0FDRTlHLElBQU0sV0FBTixNQUFlO0FBQUEsRUFBZjtBQUNOLFNBQVEsU0FBc0QsQ0FBQztBQUFBO0FBQUEsRUFFL0QsR0FBRyxXQUFtQixVQUFzQztBQUMzRCxRQUFJLENBQUMsS0FBSyxPQUFPLFNBQVMsR0FBRztBQUM1QixXQUFLLE9BQU8sU0FBUyxJQUFJLENBQUM7QUFBQSxJQUMzQjtBQUNBLFNBQUssT0FBTyxTQUFTLEVBQUUsS0FBSyxRQUFRO0FBQUEsRUFDckM7QUFBQSxFQUVBLElBQUksV0FBbUIsVUFBc0M7QUFDNUQsUUFBSSxLQUFLLE9BQU8sU0FBUyxHQUFHO0FBQzNCLFdBQUssT0FBTyxTQUFTLElBQUksS0FBSyxPQUFPLFNBQVMsRUFBRSxPQUFPLENBQUMsT0FBTyxPQUFP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QSxFQUN4RDtBQUFBLEVBRUEsV0FBVztBQUNWLFlBQVEsSUFBSSxtRUFBMkI7QUFBQSxFQUN4QztBQUFBO0FBQUEsRUFJQSxNQUFNLGVBQWU7QUFDcEIsU0FBSyxXQUFXLE9BQU8sT0FBTyxDQUFDLEdBQUcsa0JBQWtCLE1BQU0sS0FBSyxTQUFTLENBQUM7QUFBQSxFQUMxRTtBQUFBLEVBRUEsTUFBTSxlQUFlO0FBQ3BCLFVBQU0sS0FBSyxTQUFTLEtBQUssUUFBUTtBQUFBLEVBQ2xDO0FBQUE7QUFBQSxFQUlBLE1BQU0sb0JBQW9CO0FBQ3pCLFVBQU0sZUFBZSxLQUFLLElBQUksVUFBVSxnQkFBZ0IsZUFBZSxFQUFFLENBQUM7QUFDMUUsUUFBSSxjQUFjO0FBQ2pCLFdBQUssSUFBSSxVQUFVLFdBQVcsWUFBWTtBQUFBLElBQzNDLE9BQU87QUFDTixZQUFNLEtBQUssSUFBSSxVQUFVLFFBQVEsS0FBSyxFQUFFLGFBQWE7QUFBQSxRQUNwRCxNQUFNO0FBQUEsUUFDTixRQUFRO0FBQUEsTUFDVCxDQUFDO0FBQUEsSUFDRjtBQUFBLEVBQ0Q7QUFBQSxFQUVBLE1BQU0sbUJBQW1CO0FBQ3hCLFVBQU0sZUFBZSxLQUFLLElBQUksVUFBVSxnQkFBZ0IsY0FBYyxFQUFFLENBQUM7QUFDekUsUUFBSSxjQUFjO0FBQ2pCLFdBQUssSUFBSSxVQUFVLFdBQVcsWUFBWTtBQUFBLElBQzNDLE9BQU87QUFDTixZQUFNLFlBQVksS0FBSyxJQUFJLFVBQVUsYUFBYSxLQUFLO0FBQ3ZELFVBQUksV0FBVztBQUNkLGNBQU0sVUFBVSxhQUFhO0FBQUEsVUFDNUIsTUFBTTtBQUFBLFVBQ04sUUFBUTtBQUFBLFFBQ1QsQ0FBQztBQUFBLE1BQ0Y7QUFBQSxJQUNEO0FBQUEsRUFDRDtBQUFBO0FBQUEsRUFJQSxnQkFBZ0I7QUFDZixTQUFLLFNBQVMsS0FBSyxVQUFVO0FBQUEsRUFDOUI7QUFDRDtBQUlBLElBQU0sbUJBQU4sY0FBK0Isa0NBQWlCO0FBQUEsRUFHL0MsWUFBWSxLQUFVLFFBQXdCO0FBQzdDLFVBQU0sS0FBSyxNQUFNO0FBQ2pCLFNBQUssU0FBUztBQUFBLEVBQ2Y7QUFBQSxFQUVBLFVBQWdCO0FBQ2YsVUFBTSxFQUFFLFlBQVksSUFBSTtBQUV4QixnQkFBWSxNQUFNO0FBRWxCLFFBQUkseUJBQVEsV0FBVyxFQUNyQixRQUFRLGNBQWMsRUFDdEIsUUFBUSxpRkFBK0IsRUFDdkM7QUFBQSxNQUFRLENBQUMsU0FDVCxLQUNFLGVBQWUsZ0RBQWEsRUFDNUIsU0FBUyxLQUFLLE9BQU8sU0FBUyxVQUFVLEVBQ3hDLFNBQVMsT0FBTyxVQUFVO0FBQzFCLGFBQUssT0FBTyxTQUFTLGFBQWE7QUFDbEMsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNIO0FBQUEsRUFDRjtBQUNEOyIsCiAgIm5hbWVzIjogWyJpbXBvcnRfb2JzaWRpYW4iLCAiaW1wb3J0X29ic2lkaWFuIl0KfQo=
|