Skip to content

Instantly share code, notes, and snippets.

@DickHorner
Last active January 8, 2026 11:31
Show Gist options
  • Select an option

  • Save DickHorner/ff38c29cb345674bffa1332deb938ec2 to your computer and use it in GitHub Desktop.

Select an option

Save DickHorner/ff38c29cb345674bffa1332deb938ec2 to your computer and use it in GitHub Desktop.
Lightweight userscript to sort ChatGPT Chats in Folders

ChatGPT Sidebar Folders (Userscript)

Adds a folder system to the ChatGPT sidebar: create folders (incl. nesting), drag & drop chats, optional auto-suggest/auto-sort, and lightweight diagnostics.

Install (recommended)

  1. Install Tampermonkey (Chrome/Edge) or Violentmonkey (Firefox).
  2. Open cgptfolderize.user.min.js in this Gist.
  3. Click Raw → your userscript manager should prompt to install.
  4. Refresh ChatGPT.

Recommended file: cgptfolderize.user.min.js (small, release build)

Files

  • cgptfolderize.user.min.js
    Minified release build (smallest, best for daily use). No sourcemaps.

  • cgptfolderize.user.js
    Unminified build (human-readable). Good for review.

  • cgptfolderize.user.min.debug.js
    Minified build with inline sourcemap. Best when debugging issues that reproduce only in “release-like” builds.

  • cgptfolderize.user.js.map
    External sourcemap for cgptfolderize.user.js (optional).

Debugging / Diagnostics

Enable debug mode by opening ChatGPT with:

  • ?cgptdebug=1

In debug mode the panel shows counters/timings (scans, renders, last durations) and logs to the console.

Notes / Limitations

  • ChatGPT loads sidebar history lazily; the script can only index chats that appear in the sidebar DOM.
  • ChatGPT UI changes may require selector updates.

Build (optional, for development)

Source is modularized and bundled into a single userscript.

Typical commands:

  • npm i
  • npm run build → unminified + sourcemap
  • npm run build:min → minified + minified-debug (inline sourcemap)
  • npm run watch → rebuild on changes

License

MIT License © 2026 Jasper Luetkens

// ==UserScript==
// @name ChatGPT Sidebar Folders v9.4 (Modular)
// @namespace https://chatgpt.com
// @version 9.4
// @description Folder system for the ChatGPT sidebar (modular source, bundled build, debug counters)
// @author https://gist.github.com/DickHorner
// @match https://chat.openai.com/*
// @match https://chatgpt.com/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @run-at document-idle
// ==/UserScript==
(() => {
// src/core/events.js
function createEventBus() {
const listeners = /* @__PURE__ */ Object.create(null);
function on(evt, fn) {
(listeners[evt] = listeners[evt] || []).push(fn);
}
function off(evt, fn) {
const arr = listeners[evt] || [];
const i = arr.indexOf(fn);
if (i >= 0) arr.splice(i, 1);
}
function emit(evt, payload) {
(listeners[evt] || []).forEach((fn) => {
try {
fn(payload);
} catch (e) {
console.error("[CGPT] Listener error:", e);
}
});
}
return { on, off, emit };
}
// src/core/log.js
function initLogging(CGPT) {
CGPT.debug = false;
CGPT.log = (...args) => {
if (CGPT.debug) console.log("[CGPT]", ...args);
};
}
// src/core/storage.js
function createGMStore() {
function safeParse(raw) {
if (raw === void 0 || raw === null) return raw;
if (typeof raw !== "string") return raw;
try {
return JSON.parse(raw);
} catch {
return raw;
}
}
function safeStringify(value) {
if (typeof value === "string") return value;
return JSON.stringify(value);
}
return {
get(key, fallback) {
try {
const raw = GM_getValue(key);
const parsed = safeParse(raw);
return parsed === void 0 || parsed === null ? fallback : parsed;
} catch (e) {
console.warn("[CGPT] Storage get error:", e);
return fallback;
}
},
set(key, value) {
try {
GM_setValue(key, safeStringify(value));
} catch (e) {
console.warn("[CGPT] Storage set error:", e);
}
},
del(key) {
try {
GM_deleteValue(key);
} catch (e) {
console.warn("[CGPT] Storage delete error:", e);
}
}
};
}
// src/core/i18n.js
function initI18n(CGPT) {
const supported = ["de", "en"];
const rawLang = (navigator.language || "en").toLowerCase();
const short = rawLang.slice(0, 2);
const lang = supported.includes(short) ? short : "en";
CGPT.locale = lang;
const L = {
de: {
unsorted: "Unsortiert",
newFolder: "Neuer Ordner",
search: "Suchen\u2026",
rename: "Umbenennen",
delete: "L\xF6schen",
export: "Exportieren",
import: "Importieren",
confirmDelete: (name) => `Ordner "${name}" l\xF6schen?`,
icon: "Symbol",
suggestion: "Vorschlag:",
autosort: "Automatisch einsortieren",
autosuggest: "Vorschl\xE4ge anzeigen",
pinned: "Angeheftet",
reindex: "Alle Chats neu kategorisieren",
cloudTitles: "Titel in Cloud-Sync einschlie\xDFen",
settings: "Einstellungen",
color: "Farbe"
},
en: {
unsorted: "Unsorted",
newFolder: "New Folder",
search: "Search\u2026",
rename: "Rename",
delete: "Delete",
export: "Export",
import: "Import",
confirmDelete: (name) => `Delete folder "${name}"?`,
icon: "Icon",
suggestion: "Suggestion:",
autosort: "Auto-sort",
autosuggest: "Show suggestions",
pinned: "Pinned",
reindex: "Re-categorize all chats",
cloudTitles: "Include titles in Cloud Sync",
settings: "Settings",
color: "Color"
}
};
CGPT.L = L[CGPT.locale] || L.en;
}
// src/core/theme.js
function initTheme(CGPT) {
const mq = window.matchMedia ? window.matchMedia("(prefers-color-scheme: dark)") : { matches: true, addEventListener: null, addListener: null };
const computeTheme = () => {
const isDark = !!mq.matches;
return {
dark: isDark,
FG: isDark ? "#ececec" : "#222",
FG_MUTED: isDark ? "#999" : "#555",
BG: isDark ? "#2a2b32" : "#eaeaea",
BG_HOVER: isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.08)",
BTN_BG: isDark ? "#3b3b3b" : "#fff"
};
};
CGPT.theme = computeTheme();
const onChange = () => {
CGPT.theme = computeTheme();
CGPT.emit("theme-changed", CGPT.theme);
};
if (mq && mq.addEventListener) mq.addEventListener("change", onChange);
else if (mq && mq.addListener) mq.addListener(onChange);
}
// src/dom/sidebar.js
function getSidebar() {
return document.querySelector("nav") || document.querySelector('[class*="sidebar"]');
}
function onSidebarReady(cb) {
const tryIt = () => {
const el = getSidebar();
if (el) cb(el);
else setTimeout(tryIt, 200);
};
tryIt();
}
// src/state/state.js
function initState(CGPT) {
CGPT.state = {
FOLDERS_KEY: "cgpt_folders_v9",
ASSIGN_KEY: "cgpt_assign_v9",
SETTINGS_KEY: "cgpt_settings_v9",
DISMISSED_KEY: "cgpt_dismissed_v9",
folders: {},
assign: {},
dismissed: {},
settings: {
autosuggest: true,
autosort: false,
theme: "auto",
lang: CGPT.locale,
cloudTitles: true
}
};
CGPT.state.folders = CGPT.store.get(CGPT.state.FOLDERS_KEY, {
uncategorized: {
id: "uncategorized",
name: CGPT.L.unsorted,
icon: "",
color: "#888",
expanded: true,
order: 0,
pinned: false,
parentId: null
}
});
CGPT.state.assign = CGPT.store.get(CGPT.state.ASSIGN_KEY, {});
CGPT.state.settings = CGPT.store.get(CGPT.state.SETTINGS_KEY, CGPT.state.settings);
CGPT.state.dismissed = CGPT.store.get(CGPT.state.DISMISSED_KEY, {});
CGPT.saveFolders = () => CGPT.store.set(CGPT.state.FOLDERS_KEY, CGPT.state.folders);
CGPT.saveAssign = () => CGPT.store.set(CGPT.state.ASSIGN_KEY, CGPT.state.assign);
CGPT.saveSettings = () => CGPT.store.set(CGPT.state.SETTINGS_KEY, CGPT.state.settings);
CGPT.saveDismissed = () => CGPT.store.set(CGPT.state.DISMISSED_KEY, CGPT.state.dismissed);
CGPT.diag = {
scans: 0,
renders: 0,
lastScanAt: 0,
lastRenderAt: 0,
lastScanDurationMs: 0,
lastRenderDurationMs: 0,
chatsFoundLastScan: 0
};
}
// src/folders/folders.js
function initFolders(CGPT) {
CGPT.folders = {};
const F = () => CGPT.state.folders;
const uid = () => crypto.randomUUID ? crypto.randomUUID() : "id_" + Math.random().toString(36).slice(2);
const compareFolder = (a, b) => b.pinned - a.pinned || a.order - b.order;
CGPT.folders.create = (name, parentId = null, icon = "") => {
const id = uid();
F()[id] = {
id,
name,
icon,
color: "#66aaff",
parentId,
pinned: false,
expanded: true,
order: Date.now()
};
CGPT.saveFolders();
CGPT.emit("folders-updated", F());
return id;
};
CGPT.folders.delete = (folderId) => {
const f = F()[folderId];
if (!f || folderId === "uncategorized") return;
Object.values(F()).forEach((x) => {
if (x.parentId === folderId) x.parentId = f.parentId ?? null;
});
Object.keys(CGPT.state.assign).forEach((cid) => {
if (CGPT.state.assign[cid] === folderId) CGPT.state.assign[cid] = "uncategorized";
});
delete F()[folderId];
CGPT.saveFolders();
CGPT.saveAssign();
CGPT.emit("folders-updated", F());
CGPT.emit("assign-updated", CGPT.state.assign);
};
CGPT.folders.rename = (folderId, newName) => {
if (F()[folderId]) {
F()[folderId].name = newName;
CGPT.saveFolders();
CGPT.emit("folders-updated", F());
}
};
CGPT.folders.setIcon = (folderId, icon) => {
if (F()[folderId]) {
F()[folderId].icon = icon;
CGPT.saveFolders();
CGPT.emit("folders-updated", F());
}
};
CGPT.folders.setColor = (folderId, color) => {
if (F()[folderId]) {
F()[folderId].color = color;
CGPT.saveFolders();
CGPT.emit("folders-updated", F());
}
};
CGPT.folders.togglePin = (folderId) => {
if (F()[folderId]) {
F()[folderId].pinned = !F()[folderId].pinned;
CGPT.saveFolders();
CGPT.emit("folders-updated", F());
}
};
CGPT.folders.setParent = (folderId, parentId) => {
const node = F()[folderId];
if (!node || folderId === "uncategorized") return;
let p = parentId;
while (p) {
if (p === folderId) return;
p = (F()[p] || {}).parentId;
}
node.parentId = parentId ?? null;
CGPT.saveFolders();
CGPT.emit("folders-updated", F());
};
CGPT.folders.move = (folderId, direction) => {
const node = F()[folderId];
if (!node) return;
const siblings = Object.values(F()).filter((x) => (x.parentId ?? null) === (node.parentId ?? null)).sort((a, b) => a.order - b.order);
const idx = siblings.findIndex((x) => x.id === folderId);
if (idx < 0) return;
const swapIdx = direction === "up" ? idx - 1 : idx + 1;
if (swapIdx < 0 || swapIdx >= siblings.length) return;
const other = siblings[swapIdx];
const t = node.order;
node.order = other.order;
other.order = t;
CGPT.saveFolders();
CGPT.emit("folders-updated", F());
};
CGPT.folders.getTree = () => {
const all = Object.values(F());
const byParent = /* @__PURE__ */ new Map();
all.forEach((f) => {
const k = f.parentId ?? "root";
const arr = byParent.get(k);
if (arr) arr.push(f);
else byParent.set(k, [f]);
});
const build = (parentId, level) => (byParent.get(parentId ?? "root") || []).sort(compareFolder).map((f) => ({ folder: f, level, children: build(f.id, level + 1) }));
return build(null, 0);
};
CGPT.folders.assignChat = (chatId, folderId) => {
CGPT.state.assign[chatId] = folderId;
CGPT.saveAssign();
CGPT.emit("assign-updated", CGPT.state.assign);
};
CGPT._folders = { F };
}
// src/chats/scan.js
function initChats(CGPT) {
CGPT.chats = { map: {}, _lastScan: 0 };
CGPT.scanChats = () => {
const start = performance.now();
const sidebar = getSidebar();
if (!sidebar) return;
const nodes = sidebar.querySelectorAll("a[href*='/c/']");
const map = {};
nodes.forEach((a) => {
if (a.closest('[data-cgpt-injected="true"]')) return;
const href = a.getAttribute("href") || "";
const m = href.match(/\/c\/([\w-]+)/);
const id = m ? m[1] : href;
const title = (a.textContent || "").trim() || href;
map[id] = { id, title, href, el: a };
});
CGPT.chats.map = map;
CGPT.chats._lastScan = Date.now();
CGPT.diag.scans += 1;
CGPT.diag.lastScanAt = Date.now();
CGPT.diag.lastScanDurationMs = Math.round(performance.now() - start);
CGPT.diag.chatsFoundLastScan = Object.keys(map).length;
CGPT.emit("chats-updated", map);
};
}
// src/core/debounce.js
function debounce(fn, ms) {
let t;
return (...args) => {
if (t) clearTimeout(t);
t = setTimeout(() => fn(...args), ms);
};
}
// src/ui/panel.js
function initUI(CGPT) {
CGPT.ui = {};
CGPT.ui.panelId = "cgpt-folder-panel-v9";
CGPT.ui.lastSearch = "";
const ICON = {
arrowDown: "\u25BC",
arrowRight: "\u25B6",
pin: "\u{1F4CC}",
folder: "\u{1F4C1}",
del: "\u{1F5D1}\uFE0F",
settings: "\u2699\uFE0F"
};
let currentMenu = null;
CGPT.ui.closeContextMenu = () => {
if (currentMenu) {
currentMenu.remove();
currentMenu = null;
}
};
document.addEventListener("click", (e) => {
if (currentMenu && !currentMenu.contains(e.target)) CGPT.ui.closeContextMenu();
});
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") CGPT.ui.closeContextMenu();
});
CGPT.ui.ensurePanel = () => {
const sidebar = getSidebar();
if (!sidebar) return null;
let container = document.getElementById(CGPT.ui.panelId + "-container");
let panel = document.getElementById(CGPT.ui.panelId);
if (!container) {
container = document.createElement("div");
container.id = CGPT.ui.panelId + "-container";
container.setAttribute("data-cgpt-injected", "true");
Object.assign(container.style, {
margin: "8px",
borderRadius: "8px",
background: CGPT.theme.BG,
border: `1px solid ${CGPT.theme.FG_MUTED}`,
boxSizing: "border-box",
width: "calc(100% - 16px)",
minHeight: "200px",
height: "200px",
display: "flex",
flexDirection: "column",
alignItems: "stretch",
overflow: "hidden",
flexShrink: "0"
});
panel = document.createElement("div");
panel.id = CGPT.ui.panelId;
Object.assign(panel.style, {
padding: "12px 8px 8px 8px",
boxSizing: "border-box",
overflow: "auto",
flex: "1 1 auto",
minHeight: "0",
width: "100%"
});
const resizeHandle = document.createElement("div");
resizeHandle.setAttribute("data-resize-handle", "true");
Object.assign(resizeHandle.style, {
height: "8px",
flex: "0 0 8px",
cursor: "ns-resize",
background: `linear-gradient(to bottom, transparent, ${CGPT.theme.FG_MUTED}44)`,
borderRadius: "0 0 8px 8px",
alignSelf: "stretch"
});
resizeHandle.addEventListener("mousedown", (e) => {
e.preventDefault();
const containerEl = document.getElementById(CGPT.ui.panelId + "-container");
if (!containerEl) return;
let startY = e.clientY;
let startHeight = containerEl.offsetHeight;
resizeHandle.style.background = `linear-gradient(to bottom, transparent, ${CGPT.theme.FG_MUTED}88)`;
const onMove = (ev) => {
const delta = ev.clientY - startY;
const newHeight = Math.max(150, Math.min(startHeight + delta, window.innerHeight - 80));
containerEl.style.height = newHeight + "px";
};
const onUp = () => {
document.removeEventListener("mousemove", onMove);
document.removeEventListener("mouseup", onUp);
resizeHandle.style.background = `linear-gradient(to bottom, transparent, ${CGPT.theme.FG_MUTED}44)`;
};
document.addEventListener("mousemove", onMove);
document.addEventListener("mouseup", onUp);
});
container.appendChild(panel);
container.appendChild(resizeHandle);
if (sidebar.firstChild) sidebar.insertBefore(container, sidebar.firstChild);
else sidebar.appendChild(container);
} else {
container.setAttribute("data-cgpt-injected", "true");
if (!panel) {
panel = document.createElement("div");
panel.id = CGPT.ui.panelId;
Object.assign(panel.style, {
padding: "12px 8px 8px 8px",
boxSizing: "border-box",
overflow: "auto",
flex: "1 1 auto",
minHeight: "0",
width: "100%"
});
container.insertBefore(panel, container.firstChild || null);
}
}
return document.getElementById(CGPT.ui.panelId);
};
function debugLine() {
if (!CGPT.debug) return null;
const now = Date.now();
const sinceScan = CGPT.diag.lastScanAt ? now - CGPT.diag.lastScanAt : null;
const sinceRender = CGPT.diag.lastRenderAt ? now - CGPT.diag.lastRenderAt : null;
const line = document.createElement("div");
line.textContent = `DBG scans:${CGPT.diag.scans} (last ${CGPT.diag.lastScanDurationMs}ms, chats ${CGPT.diag.chatsFoundLastScan}${sinceScan !== null ? ", " + sinceScan + "ms ago" : ""}) renders:${CGPT.diag.renders} (last ${CGPT.diag.lastRenderDurationMs}ms${sinceRender !== null ? ", " + sinceRender + "ms ago" : ""})`;
Object.assign(line.style, {
marginTop: "6px",
fontSize: "11px",
color: CGPT.theme.FG_MUTED,
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis"
});
return line;
}
CGPT.ui.render = () => {
const start = performance.now();
const panel = CGPT.ui.ensurePanel();
if (!panel) return;
panel.innerHTML = "";
const topBar = document.createElement("div");
Object.assign(topBar.style, { display: "flex", gap: "6px", marginBottom: "8px", alignItems: "center" });
const search = document.createElement("input");
search.placeholder = CGPT.L.search;
search.value = CGPT.ui.lastSearch || "";
Object.assign(search.style, {
flex: "1",
padding: "6px 8px",
border: `1px solid ${CGPT.theme.FG_MUTED}`,
borderRadius: "6px",
background: CGPT.theme.dark ? "#333" : "#fff",
color: CGPT.theme.FG,
boxSizing: "border-box",
minWidth: "0"
});
const applySearch = debounce(() => {
CGPT.ui.lastSearch = search.value;
CGPT.ui.render();
}, 200);
search.addEventListener("input", applySearch);
const settingsBtn = document.createElement("button");
settingsBtn.textContent = ICON.settings;
settingsBtn.title = CGPT.L.settings;
Object.assign(settingsBtn.style, {
padding: "6px 10px",
background: CGPT.theme.BTN_BG,
border: `1px solid ${CGPT.theme.FG_MUTED}`,
borderRadius: "6px",
cursor: "pointer",
color: CGPT.theme.FG,
flexShrink: "0",
minWidth: "40px"
});
settingsBtn.addEventListener("click", (e) => {
e.preventDefault();
e.stopPropagation();
CGPT.ui.showSettings();
});
topBar.appendChild(search);
topBar.appendChild(settingsBtn);
panel.appendChild(topBar);
const dbg = debugLine();
if (dbg) panel.appendChild(dbg);
const query = (search.value || "").toLowerCase().trim();
const tree = CGPT.folders.getTree();
tree.forEach((node) => CGPT.ui.renderFolderNode(panel, node, query));
const addBtn = document.createElement("button");
addBtn.textContent = `\uFF0B ${CGPT.L.newFolder}`;
Object.assign(addBtn.style, {
width: "100%",
marginTop: "12px",
padding: "8px",
background: CGPT.theme.BTN_BG,
border: `1px solid ${CGPT.theme.FG_MUTED}`,
borderRadius: "6px",
cursor: "pointer",
color: CGPT.theme.FG,
fontWeight: "500"
});
addBtn.addEventListener("click", () => {
const name = prompt(CGPT.L.newFolder) || "";
if (!name.trim()) return;
CGPT.folders.create(name.trim());
});
panel.appendChild(addBtn);
CGPT.diag.renders += 1;
CGPT.diag.lastRenderAt = Date.now();
CGPT.diag.lastRenderDurationMs = Math.round(performance.now() - start);
};
CGPT.ui.renderFolderNode = (panel, node, query) => {
const { folder, level, children } = node;
const container = document.createElement("div");
Object.assign(container.style, { paddingLeft: `${level * 14}px`, marginBottom: "4px", maxWidth: "100%", boxSizing: "border-box" });
const head = document.createElement("div");
Object.assign(head.style, {
display: "flex",
alignItems: "center",
gap: "6px",
cursor: "pointer",
padding: "6px 8px",
borderRadius: "6px",
background: folder.color ? `${folder.color}22` : "rgba(255,255,255,0.05)",
maxWidth: "100%",
overflow: "hidden"
});
head.addEventListener("mouseover", () => {
head.style.background = folder.color ? `${folder.color}44` : "rgba(255,255,255,0.1)";
});
head.addEventListener("mouseout", () => {
head.style.background = folder.color ? `${folder.color}22` : "rgba(255,255,255,0.05)";
});
const arrow = document.createElement("span");
arrow.textContent = folder.expanded ? ICON.arrowDown : ICON.arrowRight;
Object.assign(arrow.style, { width: "16px", color: CGPT.theme.FG_MUTED, fontSize: "10px" });
const icon = document.createElement("span");
icon.textContent = folder.icon || ICON.folder;
icon.style.fontSize = "16px";
if (folder.pinned) {
const pinIcon = document.createElement("span");
pinIcon.textContent = ICON.pin;
Object.assign(pinIcon.style, { fontSize: "10px", color: "#f59e0b" });
head.appendChild(pinIcon);
}
const title = document.createElement("span");
title.textContent = folder.name;
Object.assign(title.style, {
flex: "1",
color: CGPT.theme.FG,
fontSize: "14px",
fontWeight: "500",
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
minWidth: "0"
});
head.addEventListener("click", () => {
folder.expanded = !folder.expanded;
CGPT.saveFolders();
CGPT.ui.render();
});
head.addEventListener("contextmenu", (e) => {
e.preventDefault();
CGPT.ui.openFolderContextMenu(e.pageX, e.pageY, folder);
});
head.appendChild(arrow);
head.appendChild(icon);
head.appendChild(title);
container.appendChild(head);
if (folder.expanded) {
const chats = Object.values(CGPT.chats.map).filter(
(c) => (CGPT.state.assign[c.id] || "uncategorized") === folder.id
);
chats.forEach((c) => {
if (query && !c.title.toLowerCase().includes(query)) return;
container.appendChild(CGPT.ui.renderChatItem(c, level));
});
children.forEach((child) => CGPT.ui.renderFolderNode(panel, child, query));
}
panel.appendChild(container);
};
CGPT.ui.renderChatItem = (chat, level) => {
const wrapper = document.createElement("div");
Object.assign(wrapper.style, { paddingLeft: `${(level + 1) * 14}px`, maxWidth: "100%", boxSizing: "border-box" });
const row = document.createElement("div");
Object.assign(row.style, { padding: "4px 8px", borderRadius: "4px", cursor: "pointer", overflow: "hidden", boxSizing: "border-box" });
row.addEventListener("mouseover", () => row.style.background = CGPT.theme.BG_HOVER);
row.addEventListener("mouseout", () => row.style.background = "");
const link = document.createElement("a");
link.textContent = chat.title;
link.href = chat.href;
Object.assign(link.style, {
color: CGPT.theme.FG,
textDecoration: "none",
fontSize: "13px",
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
display: "block",
maxWidth: "100%"
});
row.appendChild(link);
wrapper.appendChild(row);
return wrapper;
};
CGPT.ui.openFolderContextMenu = (x, y, folder) => {
CGPT.ui.closeContextMenu();
const menu = document.createElement("div");
currentMenu = menu;
Object.assign(menu.style, {
position: "fixed",
left: x + "px",
top: y + "px",
background: CGPT.theme.BG,
color: CGPT.theme.FG,
border: `1px solid ${CGPT.theme.FG_MUTED}`,
borderRadius: "8px",
padding: "6px",
zIndex: 9999,
minWidth: "200px",
boxShadow: "0 4px 12px rgba(0,0,0,0.5)"
});
const addItem = (label, handler) => {
const b = document.createElement("button");
b.textContent = label;
Object.assign(b.style, {
width: "100%",
display: "block",
padding: "8px 12px",
background: CGPT.theme.BTN_BG,
border: "none",
borderRadius: "4px",
color: CGPT.theme.FG,
cursor: "pointer",
margin: "4px 0",
textAlign: "left"
});
b.addEventListener("mouseover", () => b.style.background = CGPT.theme.BG_HOVER);
b.addEventListener("mouseout", () => b.style.background = CGPT.theme.BTN_BG);
b.addEventListener("click", () => {
handler();
CGPT.ui.closeContextMenu();
});
menu.appendChild(b);
};
addItem(CGPT.L.rename, () => {
const name = prompt(CGPT.L.rename, folder.name);
if (name && name.trim()) CGPT.folders.rename(folder.id, name.trim());
});
if (folder.id !== "uncategorized") {
addItem(CGPT.L.delete, () => {
if (!confirm(CGPT.L.confirmDelete(folder.name))) return;
CGPT.folders.delete(folder.id);
});
}
addItem(CGPT.L.pinned, () => CGPT.folders.togglePin(folder.id));
addItem(CGPT.L.icon, () => {
const ic = prompt(CGPT.L.icon, folder.icon || "");
if (ic !== null) CGPT.folders.setIcon(folder.id, ic);
});
addItem(CGPT.L.color, () => CGPT.ui.showColorPicker(folder.id, folder.color || "#66aaff"));
document.body.appendChild(menu);
};
CGPT.ui.showColorPicker = (folderId, currentColor) => {
const picked = prompt("Color (hex)", currentColor || "#66aaff");
if (!picked) return;
CGPT.folders.setColor(folderId, picked.trim());
};
CGPT.ui.showSettings = () => {
const autosuggest = confirm(`${CGPT.L.autosuggest}
OK = ON, Cancel = OFF`);
CGPT.state.settings.autosuggest = autosuggest;
const autosort = confirm(`${CGPT.L.autosort}
OK = ON, Cancel = OFF`);
CGPT.state.settings.autosort = autosort;
const cloudTitles = confirm(`${CGPT.L.cloudTitles}
OK = ON, Cancel = OFF`);
CGPT.state.settings.cloudTitles = cloudTitles;
CGPT.saveSettings();
CGPT.ui.render();
};
const debouncedRender = debounce(() => CGPT.ui.render(), 100);
CGPT.on("chats-updated", debouncedRender);
CGPT.on("folders-updated", debouncedRender);
CGPT.on("assign-updated", debouncedRender);
CGPT.on("theme-changed", debouncedRender);
}
// src/suggest/suggest.js
function initSuggest(CGPT) {
const SUGGESTION_RULES = [
{ folder: "\u{1F4BB} Code", words: ["code", "javascript", "python", "regex", "bug", "debug", "error", "function", "api"] },
{ folder: "\u2709\uFE0F Writing", words: ["email", "letter", "text", "write", "draft", "essay", "article"] },
{ folder: "\u{1F3EB} Education", words: ["school", "class", "study", "learn", "homework", "exam", "university"] },
{ folder: "\u{1F4C1} Work", words: ["project", "meeting", "plan", "research", "report", "business", "task"] },
{ folder: "\u2764\uFE0F Personal", words: ["family", "health", "advice", "help", "personal", "life"] }
];
CGPT.suggest = (title) => {
const t = (title || "").toLowerCase();
for (const rule of SUGGESTION_RULES) {
for (const w of rule.words) {
if (t.includes(w)) return rule.folder;
}
}
return null;
};
const stripLeadingSymbols = (s) => {
try {
return s.replace(/^[^\p{L}\p{N}]+/gu, "");
} catch {
return s.replace(/^[^A-Za-z0-9]+/, "");
}
};
const normName = (s) => stripLeadingSymbols((s ?? "").normalize("NFKC")).trim().replace(/\s+/g, " ").toLowerCase();
function findFolderByName(name) {
const n = normName(name);
const F = CGPT._folders.F;
return Object.values(F()).find((f) => normName(f.name) === n) || null;
}
function ensureFolder(name) {
const clean = (name || "").trim();
const existing = findFolderByName(clean);
if (existing) return existing.id;
return CGPT.folders.create(clean);
}
function autoSortChat(chatId, chatTitle) {
if (CGPT.state.dismissed[chatId]) return;
const suggestion = CGPT.suggest(chatTitle);
if (!suggestion) return;
const folderId = ensureFolder(suggestion);
CGPT.folders.assignChat(chatId, folderId);
}
function confirmSuggestChat(chatId, chatTitle) {
if (CGPT.state.dismissed[chatId]) return;
const suggestion = CGPT.suggest(chatTitle);
if (!suggestion) return;
const clean = suggestion.trim();
const text = `Chat: "${chatTitle}"
${CGPT.L.suggestion} ${clean}
Assign to this folder?`;
if (!confirm(text)) {
CGPT.state.dismissed[chatId] = Date.now();
CGPT.saveDismissed();
return;
}
const folderId = ensureFolder(clean);
CGPT.folders.assignChat(chatId, folderId);
}
let bootstrapped = false;
const seenChatIds = new Set(Object.keys(CGPT.state.assign || {}));
CGPT.on("chats-updated", () => {
const autosort = !!CGPT.state.settings.autosort;
const autosuggest = !!CGPT.state.settings.autosuggest;
const chats = Object.values(CGPT.chats.map);
if (!bootstrapped) {
chats.forEach((c) => seenChatIds.add(c.id));
bootstrapped = true;
return;
}
chats.forEach((c) => {
if (seenChatIds.has(c.id)) return;
seenChatIds.add(c.id);
if (CGPT.state.assign[c.id]) return;
if (autosort) autoSortChat(c.id, c.title);
else if (autosuggest) confirmSuggestChat(c.id, c.title);
});
CGPT.saveAssign();
CGPT.emit("assign-updated", CGPT.state.assign);
});
CGPT.suggest.reindexAll = (mode = "confirm") => {
Object.values(CGPT.chats.map).forEach((c) => {
if (mode === "auto") autoSortChat(c.id, c.title);
else confirmSuggestChat(c.id, c.title);
});
CGPT.saveAssign();
CGPT.emit("assign-updated", CGPT.state.assign);
};
}
// src/sync/sync.js
function initSync(CGPT) {
CGPT.sync = {};
CGPT.sync.export = () => ({
timestamp: Date.now(),
version: "9.4",
locale: CGPT.locale,
data: {
folders: CGPT.state.folders,
assign: CGPT.state.assign,
settings: CGPT.state.settings,
dismissed: CGPT.state.dismissed
}
});
CGPT.sync.import = (payload) => {
try {
if (!payload || !payload.data) return false;
if (payload.data.folders) CGPT.state.folders = payload.data.folders;
if (payload.data.assign) CGPT.state.assign = payload.data.assign;
if (payload.data.settings) CGPT.state.settings = payload.data.settings;
if (payload.data.dismissed) CGPT.state.dismissed = payload.data.dismissed;
CGPT.saveFolders();
CGPT.saveAssign();
CGPT.saveSettings();
CGPT.saveDismissed();
CGPT.emit("folders-updated", CGPT.state.folders);
CGPT.emit("assign-updated", CGPT.state.assign);
CGPT.emit("theme-changed", CGPT.theme);
return true;
} catch (e) {
console.warn("[CGPT] import failed", e);
return false;
}
};
}
// src/main/start.js
function initStart(CGPT) {
CGPT.start = () => {
const params = new URLSearchParams(window.location.search);
CGPT.debug = params.get("cgptdebug") === "1";
CGPT.log("starting", { version: "9.4", debug: CGPT.debug });
CGPT.scanChats();
CGPT.ui.render();
const sidebar = getSidebar();
if (!sidebar) return;
const debouncedScan = debounce(() => CGPT.scanChats(), 200);
const chatObserver = new MutationObserver((muts) => {
const injected = document.querySelector('[data-cgpt-injected="true"]');
const relevant = muts.some((m) => !(injected && injected.contains(m.target)));
if (relevant) debouncedScan();
});
chatObserver.observe(sidebar, {
childList: true,
subtree: true,
characterData: true,
attributes: true,
attributeFilter: ["href", "aria-label", "title"]
});
const containerObserver = new MutationObserver(() => {
const container = document.getElementById(CGPT.ui.panelId + "-container");
const currentSidebar = getSidebar();
if (!container && currentSidebar) {
CGPT.log("panel missing -> recreating");
setTimeout(() => CGPT.ui.render(), 100);
}
});
containerObserver.observe(sidebar, { childList: true, subtree: false });
setInterval(() => {
const container = document.getElementById(CGPT.ui.panelId + "-container");
const currentSidebar = getSidebar();
if (!container && currentSidebar) {
CGPT.log("panel missing (interval) -> recreating");
CGPT.ui.render();
}
}, 2500);
CGPT.log("started");
};
}
// src/index.js
(function() {
"use strict";
const CGPT = window.CGPT = window.CGPT || {};
const bus = createEventBus();
CGPT.on = bus.on;
CGPT.off = bus.off;
CGPT.emit = bus.emit;
initLogging(CGPT);
CGPT.store = createGMStore();
initI18n(CGPT);
initState(CGPT);
initTheme(CGPT);
initFolders(CGPT);
initChats(CGPT);
initUI(CGPT);
initSuggest(CGPT);
initSync(CGPT);
initStart(CGPT);
onSidebarReady(() => {
CGPT.start();
});
})();
})();
//# sourceMappingURL=_bundle.tmp.js.map
{
"version": 3,
"sources": ["../src/core/events.js", "../src/core/log.js", "../src/core/storage.js", "../src/core/i18n.js", "../src/core/theme.js", "../src/dom/sidebar.js", "../src/state/state.js", "../src/folders/folders.js", "../src/chats/scan.js", "../src/core/debounce.js", "../src/ui/panel.js", "../src/suggest/suggest.js", "../src/sync/sync.js", "../src/main/start.js", "../src/index.js"],
"sourcesContent": ["export function createEventBus() {\n const listeners = Object.create(null);\n\n function on(evt, fn) {\n (listeners[evt] = listeners[evt] || []).push(fn);\n }\n\n function off(evt, fn) {\n const arr = listeners[evt] || [];\n const i = arr.indexOf(fn);\n if (i >= 0) arr.splice(i, 1);\n }\n\n function emit(evt, payload) {\n (listeners[evt] || []).forEach((fn) => {\n try {\n fn(payload);\n } catch (e) {\n console.error(\"[CGPT] Listener error:\", e);\n }\n });\n }\n\n return { on, off, emit };\n}\n", "export function initLogging(CGPT) {\n CGPT.debug = false;\n CGPT.log = (...args) => {\n if (CGPT.debug) console.log(\"[CGPT]\", ...args);\n };\n}\n", "export function createGMStore() {\n function safeParse(raw) {\n if (raw === undefined || raw === null) return raw;\n if (typeof raw !== \"string\") return raw;\n try {\n return JSON.parse(raw);\n } catch {\n // Some GM engines may store plain strings; keep as-is.\n return raw;\n }\n }\n\n function safeStringify(value) {\n if (typeof value === \"string\") return value;\n return JSON.stringify(value);\n }\n\n return {\n get(key, fallback) {\n try {\n const raw = GM_getValue(key);\n const parsed = safeParse(raw);\n return parsed === undefined || parsed === null ? fallback : parsed;\n } catch (e) {\n console.warn(\"[CGPT] Storage get error:\", e);\n return fallback;\n }\n },\n set(key, value) {\n try {\n GM_setValue(key, safeStringify(value));\n } catch (e) {\n console.warn(\"[CGPT] Storage set error:\", e);\n }\n },\n del(key) {\n try {\n GM_deleteValue(key);\n } catch (e) {\n console.warn(\"[CGPT] Storage delete error:\", e);\n }\n }\n };\n}\n", "export function initI18n(CGPT) {\n const supported = [\"de\", \"en\"];\n const rawLang = (navigator.language || \"en\").toLowerCase();\n const short = rawLang.slice(0, 2);\n const lang = supported.includes(short) ? short : \"en\";\n CGPT.locale = lang;\n\n const L = {\n de: {\n unsorted: \"Unsortiert\",\n newFolder: \"Neuer Ordner\",\n search: \"Suchen\u2026\",\n rename: \"Umbenennen\",\n delete: \"L\u00F6schen\",\n export: \"Exportieren\",\n import: \"Importieren\",\n confirmDelete: (name) => `Ordner \"${name}\" l\u00F6schen?`,\n icon: \"Symbol\",\n suggestion: \"Vorschlag:\",\n autosort: \"Automatisch einsortieren\",\n autosuggest: \"Vorschl\u00E4ge anzeigen\",\n pinned: \"Angeheftet\",\n reindex: \"Alle Chats neu kategorisieren\",\n cloudTitles: \"Titel in Cloud-Sync einschlie\u00DFen\",\n settings: \"Einstellungen\",\n color: \"Farbe\"\n },\n en: {\n unsorted: \"Unsorted\",\n newFolder: \"New Folder\",\n search: \"Search\u2026\",\n rename: \"Rename\",\n delete: \"Delete\",\n export: \"Export\",\n import: \"Import\",\n confirmDelete: (name) => `Delete folder \"${name}\"?`,\n icon: \"Icon\",\n suggestion: \"Suggestion:\",\n autosort: \"Auto-sort\",\n autosuggest: \"Show suggestions\",\n pinned: \"Pinned\",\n reindex: \"Re-categorize all chats\",\n cloudTitles: \"Include titles in Cloud Sync\",\n settings: \"Settings\",\n color: \"Color\"\n }\n };\n\n CGPT.L = L[CGPT.locale] || L.en;\n}\n", "export function initTheme(CGPT) {\n const mq = window.matchMedia\n ? window.matchMedia(\"(prefers-color-scheme: dark)\")\n : { matches: true, addEventListener: null, addListener: null };\n\n const computeTheme = () => {\n const isDark = !!mq.matches;\n return {\n dark: isDark,\n FG: isDark ? \"#ececec\" : \"#222\",\n FG_MUTED: isDark ? \"#999\" : \"#555\",\n BG: isDark ? \"#2a2b32\" : \"#eaeaea\",\n BG_HOVER: isDark ? \"rgba(255,255,255,0.1)\" : \"rgba(0,0,0,0.08)\",\n BTN_BG: isDark ? \"#3b3b3b\" : \"#fff\"\n };\n };\n\n CGPT.theme = computeTheme();\n\n const onChange = () => {\n CGPT.theme = computeTheme();\n CGPT.emit(\"theme-changed\", CGPT.theme);\n };\n\n if (mq && mq.addEventListener) mq.addEventListener(\"change\", onChange);\n else if (mq && mq.addListener) mq.addListener(onChange);\n}\n", "export function getSidebar() {\n return document.querySelector(\"nav\") || document.querySelector('[class*=\"sidebar\"]');\n}\n\nexport function onSidebarReady(cb) {\n const tryIt = () => {\n const el = getSidebar();\n if (el) cb(el);\n else setTimeout(tryIt, 200);\n };\n tryIt();\n}\n", "export function initState(CGPT) {\n CGPT.state = {\n FOLDERS_KEY: \"cgpt_folders_v9\",\n ASSIGN_KEY: \"cgpt_assign_v9\",\n SETTINGS_KEY: \"cgpt_settings_v9\",\n DISMISSED_KEY: \"cgpt_dismissed_v9\",\n folders: {},\n assign: {},\n dismissed: {},\n settings: {\n autosuggest: true,\n autosort: false,\n theme: \"auto\",\n lang: CGPT.locale,\n cloudTitles: true\n }\n };\n\n CGPT.state.folders = CGPT.store.get(CGPT.state.FOLDERS_KEY, {\n uncategorized: {\n id: \"uncategorized\",\n name: CGPT.L.unsorted,\n icon: \"\",\n color: \"#888\",\n expanded: true,\n order: 0,\n pinned: false,\n parentId: null\n }\n });\n\n CGPT.state.assign = CGPT.store.get(CGPT.state.ASSIGN_KEY, {});\n CGPT.state.settings = CGPT.store.get(CGPT.state.SETTINGS_KEY, CGPT.state.settings);\n CGPT.state.dismissed = CGPT.store.get(CGPT.state.DISMISSED_KEY, {});\n\n CGPT.saveFolders = () => CGPT.store.set(CGPT.state.FOLDERS_KEY, CGPT.state.folders);\n CGPT.saveAssign = () => CGPT.store.set(CGPT.state.ASSIGN_KEY, CGPT.state.assign);\n CGPT.saveSettings = () => CGPT.store.set(CGPT.state.SETTINGS_KEY, CGPT.state.settings);\n CGPT.saveDismissed = () => CGPT.store.set(CGPT.state.DISMISSED_KEY, CGPT.state.dismissed);\n\n CGPT.diag = {\n scans: 0,\n renders: 0,\n lastScanAt: 0,\n lastRenderAt: 0,\n lastScanDurationMs: 0,\n lastRenderDurationMs: 0,\n chatsFoundLastScan: 0\n };\n}\n", "export function initFolders(CGPT) {\n CGPT.folders = {};\n const F = () => CGPT.state.folders;\n\n const uid = () =>\n crypto.randomUUID ? crypto.randomUUID() : \"id_\" + Math.random().toString(36).slice(2);\n\n const compareFolder = (a, b) => (b.pinned - a.pinned) || (a.order - b.order);\n\n CGPT.folders.create = (name, parentId = null, icon = \"\") => {\n const id = uid();\n F()[id] = {\n id,\n name,\n icon,\n color: \"#66aaff\",\n parentId,\n pinned: false,\n expanded: true,\n order: Date.now()\n };\n CGPT.saveFolders();\n CGPT.emit(\"folders-updated\", F());\n return id;\n };\n\n CGPT.folders.delete = (folderId) => {\n const f = F()[folderId];\n if (!f || folderId === \"uncategorized\") return;\n\n // Re-parent children\n Object.values(F()).forEach((x) => {\n if (x.parentId === folderId) x.parentId = f.parentId ?? null;\n });\n\n // Move assigned chats to uncategorized\n Object.keys(CGPT.state.assign).forEach((cid) => {\n if (CGPT.state.assign[cid] === folderId) CGPT.state.assign[cid] = \"uncategorized\";\n });\n\n delete F()[folderId];\n CGPT.saveFolders();\n CGPT.saveAssign();\n CGPT.emit(\"folders-updated\", F());\n CGPT.emit(\"assign-updated\", CGPT.state.assign);\n };\n\n CGPT.folders.rename = (folderId, newName) => {\n if (F()[folderId]) {\n F()[folderId].name = newName;\n CGPT.saveFolders();\n CGPT.emit(\"folders-updated\", F());\n }\n };\n\n CGPT.folders.setIcon = (folderId, icon) => {\n if (F()[folderId]) {\n F()[folderId].icon = icon;\n CGPT.saveFolders();\n CGPT.emit(\"folders-updated\", F());\n }\n };\n\n CGPT.folders.setColor = (folderId, color) => {\n if (F()[folderId]) {\n F()[folderId].color = color;\n CGPT.saveFolders();\n CGPT.emit(\"folders-updated\", F());\n }\n };\n\n CGPT.folders.togglePin = (folderId) => {\n if (F()[folderId]) {\n F()[folderId].pinned = !F()[folderId].pinned;\n CGPT.saveFolders();\n CGPT.emit(\"folders-updated\", F());\n }\n };\n\n CGPT.folders.setParent = (folderId, parentId) => {\n const node = F()[folderId];\n if (!node || folderId === \"uncategorized\") return;\n\n // Prevent cycles\n let p = parentId;\n while (p) {\n if (p === folderId) return;\n p = (F()[p] || {}).parentId;\n }\n\n node.parentId = parentId ?? null;\n CGPT.saveFolders();\n CGPT.emit(\"folders-updated\", F());\n };\n\n CGPT.folders.move = (folderId, direction) => {\n const node = F()[folderId];\n if (!node) return;\n\n const siblings = Object.values(F())\n .filter((x) => (x.parentId ?? null) === (node.parentId ?? null))\n .sort((a, b) => a.order - b.order);\n\n const idx = siblings.findIndex((x) => x.id === folderId);\n if (idx < 0) return;\n\n const swapIdx = direction === \"up\" ? idx - 1 : idx + 1;\n if (swapIdx < 0 || swapIdx >= siblings.length) return;\n\n const other = siblings[swapIdx];\n const t = node.order;\n node.order = other.order;\n other.order = t;\n\n CGPT.saveFolders();\n CGPT.emit(\"folders-updated\", F());\n };\n\n CGPT.folders.getTree = () => {\n const all = Object.values(F());\n const byParent = new Map();\n all.forEach((f) => {\n const k = f.parentId ?? \"root\";\n const arr = byParent.get(k);\n if (arr) arr.push(f);\n else byParent.set(k, [f]);\n });\n\n const build = (parentId, level) =>\n (byParent.get(parentId ?? \"root\") || [])\n .sort(compareFolder)\n .map((f) => ({ folder: f, level, children: build(f.id, level + 1) }));\n\n return build(null, 0);\n };\n\n CGPT.folders.assignChat = (chatId, folderId) => {\n CGPT.state.assign[chatId] = folderId;\n CGPT.saveAssign();\n CGPT.emit(\"assign-updated\", CGPT.state.assign);\n };\n\n // Expose helper for internal modules\n CGPT._folders = { F };\n}\n", "import { getSidebar } from \"../dom/sidebar.js\";\n\nexport function initChats(CGPT) {\n CGPT.chats = { map: {}, _lastScan: 0 };\n\n CGPT.scanChats = () => {\n const start = performance.now();\n const sidebar = getSidebar();\n if (!sidebar) return;\n\n // Fast scan: only anchors that look like chats.\n const nodes = sidebar.querySelectorAll(\"a[href*='/c/']\");\n const map = {};\n\n nodes.forEach((a) => {\n // Ignore our injected UI (prevents self-trigger feedback loops)\n if (a.closest('[data-cgpt-injected=\"true\"]')) return;\n\n const href = a.getAttribute(\"href\") || \"\";\n const m = href.match(/\\/c\\/([\\w-]+)/);\n const id = m ? m[1] : href;\n const title = (a.textContent || \"\").trim() || href;\n map[id] = { id, title, href, el: a };\n });\n\n CGPT.chats.map = map;\n CGPT.chats._lastScan = Date.now();\n\n // Diag counters\n CGPT.diag.scans += 1;\n CGPT.diag.lastScanAt = Date.now();\n CGPT.diag.lastScanDurationMs = Math.round(performance.now() - start);\n CGPT.diag.chatsFoundLastScan = Object.keys(map).length;\n\n CGPT.emit(\"chats-updated\", map);\n };\n}\n", "export function debounce(fn, ms) {\n let t;\n return (...args) => {\n if (t) clearTimeout(t);\n t = setTimeout(() => fn(...args), ms);\n };\n}\n", "import { debounce } from \"../core/debounce.js\";\nimport { getSidebar } from \"../dom/sidebar.js\";\n\nexport function initUI(CGPT) {\n CGPT.ui = {};\n CGPT.ui.panelId = \"cgpt-folder-panel-v9\";\n CGPT.ui.lastSearch = \"\";\n\n const ICON = {\n arrowDown: \"\u25BC\",\n arrowRight: \"\u25B6\",\n pin: \"\uD83D\uDCCC\",\n folder: \"\uD83D\uDCC1\",\n del: \"\uD83D\uDDD1\uFE0F\",\n settings: \"\u2699\uFE0F\"\n };\n\n let currentMenu = null;\n\n CGPT.ui.closeContextMenu = () => {\n if (currentMenu) {\n currentMenu.remove();\n currentMenu = null;\n }\n };\n\n document.addEventListener(\"click\", (e) => {\n if (currentMenu && !currentMenu.contains(e.target)) CGPT.ui.closeContextMenu();\n });\n document.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Escape\") CGPT.ui.closeContextMenu();\n });\n\n CGPT.ui.ensurePanel = () => {\n const sidebar = getSidebar();\n if (!sidebar) return null;\n\n let container = document.getElementById(CGPT.ui.panelId + \"-container\");\n let panel = document.getElementById(CGPT.ui.panelId);\n\n if (!container) {\n container = document.createElement(\"div\");\n container.id = CGPT.ui.panelId + \"-container\";\n container.setAttribute(\"data-cgpt-injected\", \"true\");\n Object.assign(container.style, {\n margin: \"8px\",\n borderRadius: \"8px\",\n background: CGPT.theme.BG,\n border: `1px solid ${CGPT.theme.FG_MUTED}`,\n boxSizing: \"border-box\",\n width: \"calc(100% - 16px)\",\n minHeight: \"200px\",\n height: \"200px\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n overflow: \"hidden\",\n flexShrink: \"0\"\n });\n\n panel = document.createElement(\"div\");\n panel.id = CGPT.ui.panelId;\n Object.assign(panel.style, {\n padding: \"12px 8px 8px 8px\",\n boxSizing: \"border-box\",\n overflow: \"auto\",\n flex: \"1 1 auto\",\n minHeight: \"0\",\n width: \"100%\"\n });\n\n const resizeHandle = document.createElement(\"div\");\n resizeHandle.setAttribute(\"data-resize-handle\", \"true\");\n Object.assign(resizeHandle.style, {\n height: \"8px\",\n flex: \"0 0 8px\",\n cursor: \"ns-resize\",\n background: `linear-gradient(to bottom, transparent, ${CGPT.theme.FG_MUTED}44)`,\n borderRadius: \"0 0 8px 8px\",\n alignSelf: \"stretch\"\n });\n\n resizeHandle.addEventListener(\"mousedown\", (e) => {\n e.preventDefault();\n const containerEl = document.getElementById(CGPT.ui.panelId + \"-container\");\n if (!containerEl) return;\n\n let startY = e.clientY;\n let startHeight = containerEl.offsetHeight;\n resizeHandle.style.background = `linear-gradient(to bottom, transparent, ${CGPT.theme.FG_MUTED}88)`;\n\n const onMove = (ev) => {\n const delta = ev.clientY - startY;\n const newHeight = Math.max(150, Math.min(startHeight + delta, window.innerHeight - 80));\n containerEl.style.height = newHeight + \"px\";\n };\n const onUp = () => {\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n resizeHandle.style.background = `linear-gradient(to bottom, transparent, ${CGPT.theme.FG_MUTED}44)`;\n };\n\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n });\n\n container.appendChild(panel);\n container.appendChild(resizeHandle);\n\n if (sidebar.firstChild) sidebar.insertBefore(container, sidebar.firstChild);\n else sidebar.appendChild(container);\n } else {\n container.setAttribute(\"data-cgpt-injected\", \"true\");\n if (!panel) {\n panel = document.createElement(\"div\");\n panel.id = CGPT.ui.panelId;\n Object.assign(panel.style, {\n padding: \"12px 8px 8px 8px\",\n boxSizing: \"border-box\",\n overflow: \"auto\",\n flex: \"1 1 auto\",\n minHeight: \"0\",\n width: \"100%\"\n });\n container.insertBefore(panel, container.firstChild || null);\n }\n }\n\n return document.getElementById(CGPT.ui.panelId);\n };\n\n function debugLine() {\n if (!CGPT.debug) return null;\n\n const now = Date.now();\n const sinceScan = CGPT.diag.lastScanAt ? (now - CGPT.diag.lastScanAt) : null;\n const sinceRender = CGPT.diag.lastRenderAt ? (now - CGPT.diag.lastRenderAt) : null;\n\n const line = document.createElement(\"div\");\n line.textContent =\n `DBG scans:${CGPT.diag.scans} (last ${CGPT.diag.lastScanDurationMs}ms, chats ${CGPT.diag.chatsFoundLastScan}${sinceScan !== null ? \", \" + sinceScan + \"ms ago\" : \"\"}) ` +\n `renders:${CGPT.diag.renders} (last ${CGPT.diag.lastRenderDurationMs}ms${sinceRender !== null ? \", \" + sinceRender + \"ms ago\" : \"\"})`;\n Object.assign(line.style, {\n marginTop: \"6px\",\n fontSize: \"11px\",\n color: CGPT.theme.FG_MUTED,\n whiteSpace: \"nowrap\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\"\n });\n return line;\n }\n\n CGPT.ui.render = () => {\n const start = performance.now();\n const panel = CGPT.ui.ensurePanel();\n if (!panel) return;\n\n panel.innerHTML = \"\";\n\n // Topbar\n const topBar = document.createElement(\"div\");\n Object.assign(topBar.style, { display: \"flex\", gap: \"6px\", marginBottom: \"8px\", alignItems: \"center\" });\n\n const search = document.createElement(\"input\");\n search.placeholder = CGPT.L.search;\n search.value = CGPT.ui.lastSearch || \"\";\n Object.assign(search.style, {\n flex: \"1\",\n padding: \"6px 8px\",\n border: `1px solid ${CGPT.theme.FG_MUTED}`,\n borderRadius: \"6px\",\n background: CGPT.theme.dark ? \"#333\" : \"#fff\",\n color: CGPT.theme.FG,\n boxSizing: \"border-box\",\n minWidth: \"0\"\n });\n\n const applySearch = debounce(() => {\n CGPT.ui.lastSearch = search.value;\n CGPT.ui.render();\n }, 200);\n\n search.addEventListener(\"input\", applySearch);\n\n const settingsBtn = document.createElement(\"button\");\n settingsBtn.textContent = ICON.settings;\n settingsBtn.title = CGPT.L.settings;\n Object.assign(settingsBtn.style, {\n padding: \"6px 10px\",\n background: CGPT.theme.BTN_BG,\n border: `1px solid ${CGPT.theme.FG_MUTED}`,\n borderRadius: \"6px\",\n cursor: \"pointer\",\n color: CGPT.theme.FG,\n flexShrink: \"0\",\n minWidth: \"40px\"\n });\n settingsBtn.addEventListener(\"click\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n CGPT.ui.showSettings();\n });\n\n topBar.appendChild(search);\n topBar.appendChild(settingsBtn);\n panel.appendChild(topBar);\n\n const dbg = debugLine();\n if (dbg) panel.appendChild(dbg);\n\n const query = (search.value || \"\").toLowerCase().trim();\n const tree = CGPT.folders.getTree();\n tree.forEach((node) => CGPT.ui.renderFolderNode(panel, node, query));\n\n const addBtn = document.createElement(\"button\");\n addBtn.textContent = `\uFF0B ${CGPT.L.newFolder}`;\n Object.assign(addBtn.style, {\n width: \"100%\",\n marginTop: \"12px\",\n padding: \"8px\",\n background: CGPT.theme.BTN_BG,\n border: `1px solid ${CGPT.theme.FG_MUTED}`,\n borderRadius: \"6px\",\n cursor: \"pointer\",\n color: CGPT.theme.FG,\n fontWeight: \"500\"\n });\n addBtn.addEventListener(\"click\", () => {\n const name = prompt(CGPT.L.newFolder) || \"\";\n if (!name.trim()) return;\n CGPT.folders.create(name.trim());\n });\n\n panel.appendChild(addBtn);\n\n // Diag\n CGPT.diag.renders += 1;\n CGPT.diag.lastRenderAt = Date.now();\n CGPT.diag.lastRenderDurationMs = Math.round(performance.now() - start);\n };\n\n CGPT.ui.renderFolderNode = (panel, node, query) => {\n const { folder, level, children } = node;\n\n const container = document.createElement(\"div\");\n Object.assign(container.style, { paddingLeft: `${level * 14}px`, marginBottom: \"4px\", maxWidth: \"100%\", boxSizing: \"border-box\" });\n\n const head = document.createElement(\"div\");\n Object.assign(head.style, {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n cursor: \"pointer\",\n padding: \"6px 8px\",\n borderRadius: \"6px\",\n background: folder.color ? `${folder.color}22` : \"rgba(255,255,255,0.05)\",\n maxWidth: \"100%\",\n overflow: \"hidden\"\n });\n\n head.addEventListener(\"mouseover\", () => { head.style.background = folder.color ? `${folder.color}44` : \"rgba(255,255,255,0.1)\"; });\n head.addEventListener(\"mouseout\", () => { head.style.background = folder.color ? `${folder.color}22` : \"rgba(255,255,255,0.05)\"; });\n\n const arrow = document.createElement(\"span\");\n arrow.textContent = folder.expanded ? ICON.arrowDown : ICON.arrowRight;\n Object.assign(arrow.style, { width: \"16px\", color: CGPT.theme.FG_MUTED, fontSize: \"10px\" });\n\n const icon = document.createElement(\"span\");\n icon.textContent = folder.icon || ICON.folder;\n icon.style.fontSize = \"16px\";\n\n if (folder.pinned) {\n const pinIcon = document.createElement(\"span\");\n pinIcon.textContent = ICON.pin;\n Object.assign(pinIcon.style, { fontSize: \"10px\", color: \"#f59e0b\" });\n head.appendChild(pinIcon);\n }\n\n const title = document.createElement(\"span\");\n title.textContent = folder.name;\n Object.assign(title.style, {\n flex: \"1\",\n color: CGPT.theme.FG,\n fontSize: \"14px\",\n fontWeight: \"500\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n minWidth: \"0\"\n });\n\n head.addEventListener(\"click\", () => {\n folder.expanded = !folder.expanded;\n CGPT.saveFolders();\n CGPT.ui.render();\n });\n\n head.addEventListener(\"contextmenu\", (e) => {\n e.preventDefault();\n CGPT.ui.openFolderContextMenu(e.pageX, e.pageY, folder);\n });\n\n head.appendChild(arrow);\n head.appendChild(icon);\n head.appendChild(title);\n\n container.appendChild(head);\n\n if (folder.expanded) {\n const chats = Object.values(CGPT.chats.map).filter(\n (c) => (CGPT.state.assign[c.id] || \"uncategorized\") === folder.id\n );\n\n chats.forEach((c) => {\n if (query && !c.title.toLowerCase().includes(query)) return;\n container.appendChild(CGPT.ui.renderChatItem(c, level));\n });\n\n children.forEach((child) => CGPT.ui.renderFolderNode(panel, child, query));\n }\n\n panel.appendChild(container);\n };\n\n CGPT.ui.renderChatItem = (chat, level) => {\n const wrapper = document.createElement(\"div\");\n Object.assign(wrapper.style, { paddingLeft: `${(level + 1) * 14}px`, maxWidth: \"100%\", boxSizing: \"border-box\" });\n\n const row = document.createElement(\"div\");\n Object.assign(row.style, { padding: \"4px 8px\", borderRadius: \"4px\", cursor: \"pointer\", overflow: \"hidden\", boxSizing: \"border-box\" });\n row.addEventListener(\"mouseover\", () => row.style.background = CGPT.theme.BG_HOVER);\n row.addEventListener(\"mouseout\", () => row.style.background = \"\");\n\n const link = document.createElement(\"a\");\n link.textContent = chat.title;\n link.href = chat.href;\n Object.assign(link.style, {\n color: CGPT.theme.FG,\n textDecoration: \"none\",\n fontSize: \"13px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n display: \"block\",\n maxWidth: \"100%\"\n });\n\n row.appendChild(link);\n wrapper.appendChild(row);\n return wrapper;\n };\n\n CGPT.ui.openFolderContextMenu = (x, y, folder) => {\n CGPT.ui.closeContextMenu();\n const menu = document.createElement(\"div\");\n currentMenu = menu;\n\n Object.assign(menu.style, {\n position: \"fixed\",\n left: x + \"px\",\n top: y + \"px\",\n background: CGPT.theme.BG,\n color: CGPT.theme.FG,\n border: `1px solid ${CGPT.theme.FG_MUTED}`,\n borderRadius: \"8px\",\n padding: \"6px\",\n zIndex: 9999,\n minWidth: \"200px\",\n boxShadow: \"0 4px 12px rgba(0,0,0,0.5)\"\n });\n\n const addItem = (label, handler) => {\n const b = document.createElement(\"button\");\n b.textContent = label;\n Object.assign(b.style, {\n width: \"100%\",\n display: \"block\",\n padding: \"8px 12px\",\n background: CGPT.theme.BTN_BG,\n border: \"none\",\n borderRadius: \"4px\",\n color: CGPT.theme.FG,\n cursor: \"pointer\",\n margin: \"4px 0\",\n textAlign: \"left\"\n });\n b.addEventListener(\"mouseover\", () => b.style.background = CGPT.theme.BG_HOVER);\n b.addEventListener(\"mouseout\", () => b.style.background = CGPT.theme.BTN_BG);\n b.addEventListener(\"click\", () => { handler(); CGPT.ui.closeContextMenu(); });\n menu.appendChild(b);\n };\n\n addItem(CGPT.L.rename, () => {\n const name = prompt(CGPT.L.rename, folder.name);\n if (name && name.trim()) CGPT.folders.rename(folder.id, name.trim());\n });\n\n if (folder.id !== \"uncategorized\") {\n addItem(CGPT.L.delete, () => {\n if (!confirm(CGPT.L.confirmDelete(folder.name))) return;\n CGPT.folders.delete(folder.id);\n });\n }\n\n addItem(CGPT.L.pinned, () => CGPT.folders.togglePin(folder.id));\n addItem(CGPT.L.icon, () => {\n const ic = prompt(CGPT.L.icon, folder.icon || \"\");\n if (ic !== null) CGPT.folders.setIcon(folder.id, ic);\n });\n\n addItem(CGPT.L.color, () => CGPT.ui.showColorPicker(folder.id, folder.color || \"#66aaff\"));\n\n document.body.appendChild(menu);\n };\n\n CGPT.ui.showColorPicker = (folderId, currentColor) => {\n const picked = prompt(\"Color (hex)\", currentColor || \"#66aaff\");\n if (!picked) return;\n CGPT.folders.setColor(folderId, picked.trim());\n };\n\n CGPT.ui.showSettings = () => {\n const autosuggest = confirm(`${CGPT.L.autosuggest}\\n\\nOK = ON, Cancel = OFF`);\n CGPT.state.settings.autosuggest = autosuggest;\n\n const autosort = confirm(`${CGPT.L.autosort}\\n\\nOK = ON, Cancel = OFF`);\n CGPT.state.settings.autosort = autosort;\n\n const cloudTitles = confirm(`${CGPT.L.cloudTitles}\\n\\nOK = ON, Cancel = OFF`);\n CGPT.state.settings.cloudTitles = cloudTitles;\n\n CGPT.saveSettings();\n CGPT.ui.render();\n };\n\n // Auto-render on changes (debounced)\n const debouncedRender = debounce(() => CGPT.ui.render(), 100);\n CGPT.on(\"chats-updated\", debouncedRender);\n CGPT.on(\"folders-updated\", debouncedRender);\n CGPT.on(\"assign-updated\", debouncedRender);\n CGPT.on(\"theme-changed\", debouncedRender);\n}\n", "export function initSuggest(CGPT) {\n const SUGGESTION_RULES = [\n { folder: \"\uD83D\uDCBB Code\", words: [\"code\", \"javascript\", \"python\", \"regex\", \"bug\", \"debug\", \"error\", \"function\", \"api\"] },\n { folder: \"\u2709\uFE0F Writing\", words: [\"email\", \"letter\", \"text\", \"write\", \"draft\", \"essay\", \"article\"] },\n { folder: \"\uD83C\uDFEB Education\", words: [\"school\", \"class\", \"study\", \"learn\", \"homework\", \"exam\", \"university\"] },\n { folder: \"\uD83D\uDCC1 Work\", words: [\"project\", \"meeting\", \"plan\", \"research\", \"report\", \"business\", \"task\"] },\n { folder: \"\u2764\uFE0F Personal\", words: [\"family\", \"health\", \"advice\", \"help\", \"personal\", \"life\"] }\n ];\n\n CGPT.suggest = (title) => {\n const t = (title || \"\").toLowerCase();\n for (const rule of SUGGESTION_RULES) {\n for (const w of rule.words) {\n if (t.includes(w)) return rule.folder;\n }\n }\n return null;\n };\n\n const stripLeadingSymbols = (s) => {\n try {\n return s.replace(/^[^\\p{L}\\p{N}]+/gu, \"\");\n } catch {\n return s.replace(/^[^A-Za-z0-9]+/, \"\");\n }\n };\n\n const normName = (s) =>\n stripLeadingSymbols((s ?? \"\").normalize(\"NFKC\"))\n .trim()\n .replace(/\\s+/g, \" \")\n .toLowerCase();\n\n function findFolderByName(name) {\n const n = normName(name);\n const F = CGPT._folders.F;\n return Object.values(F()).find((f) => normName(f.name) === n) || null;\n }\n\n function ensureFolder(name) {\n const clean = (name || \"\").trim();\n const existing = findFolderByName(clean);\n if (existing) return existing.id;\n return CGPT.folders.create(clean);\n }\n\n function autoSortChat(chatId, chatTitle) {\n if (CGPT.state.dismissed[chatId]) return;\n const suggestion = CGPT.suggest(chatTitle);\n if (!suggestion) return;\n const folderId = ensureFolder(suggestion);\n CGPT.folders.assignChat(chatId, folderId);\n }\n\n function confirmSuggestChat(chatId, chatTitle) {\n if (CGPT.state.dismissed[chatId]) return;\n const suggestion = CGPT.suggest(chatTitle);\n if (!suggestion) return;\n\n const clean = suggestion.trim();\n const text = `Chat: \"${chatTitle}\"\\n\\n${CGPT.L.suggestion} ${clean}\\n\\nAssign to this folder?`;\n\n if (!confirm(text)) {\n CGPT.state.dismissed[chatId] = Date.now();\n CGPT.saveDismissed();\n return;\n }\n\n const folderId = ensureFolder(clean);\n CGPT.folders.assignChat(chatId, folderId);\n }\n\n // Only touch *new* chats after initial bootstrap, to avoid \u201Cprompt storm\u201D.\n let bootstrapped = false;\n const seenChatIds = new Set(Object.keys(CGPT.state.assign || {}));\n\n CGPT.on(\"chats-updated\", () => {\n const autosort = !!CGPT.state.settings.autosort;\n const autosuggest = !!CGPT.state.settings.autosuggest;\n const chats = Object.values(CGPT.chats.map);\n\n if (!bootstrapped) {\n chats.forEach((c) => seenChatIds.add(c.id));\n bootstrapped = true;\n return;\n }\n\n chats.forEach((c) => {\n if (seenChatIds.has(c.id)) return;\n seenChatIds.add(c.id);\n\n if (CGPT.state.assign[c.id]) return;\n\n if (autosort) autoSortChat(c.id, c.title);\n else if (autosuggest) confirmSuggestChat(c.id, c.title);\n });\n\n CGPT.saveAssign();\n CGPT.emit(\"assign-updated\", CGPT.state.assign);\n });\n\n CGPT.suggest.reindexAll = (mode = \"confirm\") => {\n Object.values(CGPT.chats.map).forEach((c) => {\n if (mode === \"auto\") autoSortChat(c.id, c.title);\n else confirmSuggestChat(c.id, c.title);\n });\n CGPT.saveAssign();\n CGPT.emit(\"assign-updated\", CGPT.state.assign);\n };\n}\n", "export function initSync(CGPT) {\n CGPT.sync = {};\n\n CGPT.sync.export = () => ({\n timestamp: Date.now(),\n version: __CGPT_VERSION__,\n locale: CGPT.locale,\n data: {\n folders: CGPT.state.folders,\n assign: CGPT.state.assign,\n settings: CGPT.state.settings,\n dismissed: CGPT.state.dismissed\n }\n });\n\n CGPT.sync.import = (payload) => {\n try {\n if (!payload || !payload.data) return false;\n\n if (payload.data.folders) CGPT.state.folders = payload.data.folders;\n if (payload.data.assign) CGPT.state.assign = payload.data.assign;\n if (payload.data.settings) CGPT.state.settings = payload.data.settings;\n if (payload.data.dismissed) CGPT.state.dismissed = payload.data.dismissed;\n\n CGPT.saveFolders();\n CGPT.saveAssign();\n CGPT.saveSettings();\n CGPT.saveDismissed();\n\n CGPT.emit(\"folders-updated\", CGPT.state.folders);\n CGPT.emit(\"assign-updated\", CGPT.state.assign);\n CGPT.emit(\"theme-changed\", CGPT.theme);\n return true;\n } catch (e) {\n console.warn(\"[CGPT] import failed\", e);\n return false;\n }\n };\n}\n", "import { getSidebar } from \"../dom/sidebar.js\";\nimport { debounce } from \"../core/debounce.js\";\n\nexport function initStart(CGPT) {\n CGPT.start = () => {\n const params = new URLSearchParams(window.location.search);\n CGPT.debug = params.get(\"cgptdebug\") === \"1\";\n\n CGPT.log(\"starting\", { version: __CGPT_VERSION__, debug: CGPT.debug });\n\n // Initial scan + render\n CGPT.scanChats();\n CGPT.ui.render();\n\n const sidebar = getSidebar();\n if (!sidebar) return;\n\n const debouncedScan = debounce(() => CGPT.scanChats(), 200);\n\n const chatObserver = new MutationObserver((muts) => {\n const injected = document.querySelector('[data-cgpt-injected=\"true\"]');\n const relevant = muts.some((m) => !(injected && injected.contains(m.target)));\n if (relevant) debouncedScan();\n });\n\n chatObserver.observe(sidebar, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: true,\n attributeFilter: [\"href\", \"aria-label\", \"title\"]\n });\n\n // Re-create panel if ChatGPT nukes sidebar children\n const containerObserver = new MutationObserver(() => {\n const container = document.getElementById(CGPT.ui.panelId + \"-container\");\n const currentSidebar = getSidebar();\n if (!container && currentSidebar) {\n CGPT.log(\"panel missing -> recreating\");\n setTimeout(() => CGPT.ui.render(), 100);\n }\n });\n containerObserver.observe(sidebar, { childList: true, subtree: false });\n\n setInterval(() => {\n const container = document.getElementById(CGPT.ui.panelId + \"-container\");\n const currentSidebar = getSidebar();\n if (!container && currentSidebar) {\n CGPT.log(\"panel missing (interval) -> recreating\");\n CGPT.ui.render();\n }\n }, 2500);\n\n CGPT.log(\"started\");\n };\n}\n", "import { createEventBus } from \"./core/events.js\";\nimport { initLogging } from \"./core/log.js\";\nimport { createGMStore } from \"./core/storage.js\";\nimport { initI18n } from \"./core/i18n.js\";\nimport { initTheme } from \"./core/theme.js\";\nimport { onSidebarReady } from \"./dom/sidebar.js\";\nimport { initState } from \"./state/state.js\";\nimport { initFolders } from \"./folders/folders.js\";\nimport { initChats } from \"./chats/scan.js\";\nimport { initUI } from \"./ui/panel.js\";\nimport { initSuggest } from \"./suggest/suggest.js\";\nimport { initSync } from \"./sync/sync.js\";\nimport { initStart } from \"./main/start.js\";\n\n(function () {\n \"use strict\";\n\n const CGPT = (window.CGPT = window.CGPT || {});\n\n // Event bus first\n const bus = createEventBus();\n CGPT.on = bus.on;\n CGPT.off = bus.off;\n CGPT.emit = bus.emit;\n\n initLogging(CGPT);\n CGPT.store = createGMStore();\n initI18n(CGPT);\n initState(CGPT);\n initTheme(CGPT);\n initFolders(CGPT);\n initChats(CGPT);\n initUI(CGPT);\n initSuggest(CGPT);\n initSync(CGPT);\n initStart(CGPT);\n\n onSidebarReady(() => {\n CGPT.start();\n });\n})();\n"],
"mappings": "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",
"names": []
}
// ==UserScript==
// @name ChatGPT Sidebar Folders v9.4.1 (Modular)
// @namespace https://chatgpt.com
// @version 9.4.1
// @description Folder system for the ChatGPT sidebar (modular source, bundled build, debug counters)
// @author https://gist.github.com/DickHorner
// @match https://chat.openai.com/*
// @match https://chatgpt.com/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @run-at document-idle
// ==/UserScript==
(()=>{function v(){let e=Object.create(null);function n(o,r){(e[o]=e[o]||[]).push(r)}function a(o,r){let s=e[o]||[],t=s.indexOf(r);t>=0&&s.splice(t,1)}function p(o,r){(e[o]||[]).forEach(s=>{try{s(r)}catch(t){console.error("[CGPT] Listener error:",t)}})}return{on:n,off:a,emit:p}}function E(e){e.debug=!1,e.log=(...n)=>{e.debug&&console.log("[CGPT]",...n)}}function w(){function e(a){if(a==null||typeof a!="string")return a;try{return JSON.parse(a)}catch{return a}}function n(a){return typeof a=="string"?a:JSON.stringify(a)}return{get(a,p){try{let o=GM_getValue(a),r=e(o);return r??p}catch(o){return console.warn("[CGPT] Storage get error:",o),p}},set(a,p){try{GM_setValue(a,n(p))}catch(o){console.warn("[CGPT] Storage set error:",o)}},del(a){try{GM_deleteValue(a)}catch(p){console.warn("[CGPT] Storage delete error:",p)}}}}function y(e){let n=["de","en"],p=(navigator.language||"en").toLowerCase().slice(0,2),o=n.includes(p)?p:"en";e.locale=o;let r={de:{unsorted:"Unsortiert",newFolder:"Neuer Ordner",search:"Suchen\u2026",rename:"Umbenennen",delete:"L\xF6schen",export:"Exportieren",import:"Importieren",confirmDelete:s=>`Ordner "${s}" l\xF6schen?`,icon:"Symbol",suggestion:"Vorschlag:",autosort:"Automatisch einsortieren",autosuggest:"Vorschl\xE4ge anzeigen",pinned:"Angeheftet",reindex:"Alle Chats neu kategorisieren",cloudTitles:"Titel in Cloud-Sync einschlie\xDFen",settings:"Einstellungen",color:"Farbe"},en:{unsorted:"Unsorted",newFolder:"New Folder",search:"Search\u2026",rename:"Rename",delete:"Delete",export:"Export",import:"Import",confirmDelete:s=>`Delete folder "${s}"?`,icon:"Icon",suggestion:"Suggestion:",autosort:"Auto-sort",autosuggest:"Show suggestions",pinned:"Pinned",reindex:"Re-categorize all chats",cloudTitles:"Include titles in Cloud Sync",settings:"Settings",color:"Color"}};e.L=r[e.locale]||r.en}function L(e){let n=window.matchMedia?window.matchMedia("(prefers-color-scheme: dark)"):{matches:!0,addEventListener:null,addListener:null},a=()=>{let o=!!n.matches;return{dark:o,FG:o?"#ececec":"#222",FG_MUTED:o?"#999":"#555",BG:o?"#2a2b32":"#eaeaea",BG_HOVER:o?"rgba(255,255,255,0.1)":"rgba(0,0,0,0.08)",BTN_BG:o?"#3b3b3b":"#fff"}};e.theme=a();let p=()=>{e.theme=a(),e.emit("theme-changed",e.theme)};n&&n.addEventListener?n.addEventListener("change",p):n&&n.addListener&&n.addListener(p)}function x(){return document.querySelector("nav")||document.querySelector('[class*="sidebar"]')}function F(e){let n=()=>{let a=x();a?e(a):setTimeout(n,200)};n()}function O(e){e.state={FOLDERS_KEY:"cgpt_folders_v9",ASSIGN_KEY:"cgpt_assign_v9",SETTINGS_KEY:"cgpt_settings_v9",DISMISSED_KEY:"cgpt_dismissed_v9",folders:{},assign:{},dismissed:{},settings:{autosuggest:!0,autosort:!1,theme:"auto",lang:e.locale,cloudTitles:!0}},e.state.folders=e.store.get(e.state.FOLDERS_KEY,{uncategorized:{id:"uncategorized",name:e.L.unsorted,icon:"",color:"#888",expanded:!0,order:0,pinned:!1,parentId:null}}),e.state.assign=e.store.get(e.state.ASSIGN_KEY,{}),e.state.settings=e.store.get(e.state.SETTINGS_KEY,e.state.settings),e.state.dismissed=e.store.get(e.state.DISMISSED_KEY,{}),e.saveFolders=()=>e.store.set(e.state.FOLDERS_KEY,e.state.folders),e.saveAssign=()=>e.store.set(e.state.ASSIGN_KEY,e.state.assign),e.saveSettings=()=>e.store.set(e.state.SETTINGS_KEY,e.state.settings),e.saveDismissed=()=>e.store.set(e.state.DISMISSED_KEY,e.state.dismissed),e.diag={scans:0,renders:0,lastScanAt:0,lastRenderAt:0,lastScanDurationMs:0,lastRenderDurationMs:0,chatsFoundLastScan:0}}function _(e){e.folders={};let n=()=>e.state.folders,a=()=>crypto.randomUUID?crypto.randomUUID():"id_"+Math.random().toString(36).slice(2),p=(o,r)=>r.pinned-o.pinned||o.order-r.order;e.folders.create=(o,r=null,s="")=>{let t=a();return n()[t]={id:t,name:o,icon:s,color:"#66aaff",parentId:r,pinned:!1,expanded:!0,order:Date.now()},e.saveFolders(),e.emit("folders-updated",n()),t},e.folders.delete=o=>{let r=n()[o];!r||o==="uncategorized"||(Object.values(n()).forEach(s=>{s.parentId===o&&(s.parentId=r.parentId??null)}),Object.keys(e.state.assign).forEach(s=>{e.state.assign[s]===o&&(e.state.assign[s]="uncategorized")}),delete n()[o],e.saveFolders(),e.saveAssign(),e.emit("folders-updated",n()),e.emit("assign-updated",e.state.assign))},e.folders.rename=(o,r)=>{n()[o]&&(n()[o].name=r,e.saveFolders(),e.emit("folders-updated",n()))},e.folders.setIcon=(o,r)=>{n()[o]&&(n()[o].icon=r,e.saveFolders(),e.emit("folders-updated",n()))},e.folders.setColor=(o,r)=>{n()[o]&&(n()[o].color=r,e.saveFolders(),e.emit("folders-updated",n()))},e.folders.togglePin=o=>{n()[o]&&(n()[o].pinned=!n()[o].pinned,e.saveFolders(),e.emit("folders-updated",n()))},e.folders.setParent=(o,r)=>{let s=n()[o];if(!s||o==="uncategorized")return;let t=r;for(;t;){if(t===o)return;t=(n()[t]||{}).parentId}s.parentId=r??null,e.saveFolders(),e.emit("folders-updated",n())},e.folders.move=(o,r)=>{let s=n()[o];if(!s)return;let t=Object.values(n()).filter(d=>(d.parentId??null)===(s.parentId??null)).sort((d,g)=>d.order-g.order),i=t.findIndex(d=>d.id===o);if(i<0)return;let l=r==="up"?i-1:i+1;if(l<0||l>=t.length)return;let c=t[l],u=s.order;s.order=c.order,c.order=u,e.saveFolders(),e.emit("folders-updated",n())},e.folders.getTree=()=>{let o=Object.values(n()),r=new Map;o.forEach(t=>{let i=t.parentId??"root",l=r.get(i);l?l.push(t):r.set(i,[t])});let s=(t,i)=>(r.get(t??"root")||[]).sort(p).map(l=>({folder:l,level:i,children:s(l.id,i+1)}));return s(null,0)},e.folders.assignChat=(o,r)=>{e.state.assign[o]=r,e.saveAssign(),e.emit("assign-updated",e.state.assign)},e._folders={F:n}}function D(e){e.chats={map:{},_lastScan:0},e.scanChats=()=>{let n=performance.now(),a=x();if(!a)return;let p=a.querySelectorAll("a[href*='/c/']"),o={};p.forEach(r=>{if(r.closest('[data-cgpt-injected="true"]'))return;let s=r.getAttribute("href")||"",t=s.match(/\/c\/([\w-]+)/),i=t?t[1]:s,l=(r.textContent||"").trim()||s;o[i]={id:i,title:l,href:s,el:r}}),e.chats.map=o,e.chats._lastScan=Date.now(),e.diag.scans+=1,e.diag.lastScanAt=Date.now(),e.diag.lastScanDurationMs=Math.round(performance.now()-n),e.diag.chatsFoundLastScan=Object.keys(o).length,e.emit("chats-updated",o)}}function S(e,n){let a;return(...p)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...p),n)}}function I(e){e.ui={},e.ui.panelId="cgpt-folder-panel-v9",e.ui.lastSearch="";let n={arrowDown:"\u25BC",arrowRight:"\u25B6",pin:"\u{1F4CC}",folder:"\u{1F4C1}",del:"\u{1F5D1}\uFE0F",settings:"\u2699\uFE0F"},a=null;e.ui.closeContextMenu=()=>{a&&(a.remove(),a=null)},document.addEventListener("click",r=>{a&&!a.contains(r.target)&&e.ui.closeContextMenu()}),document.addEventListener("keydown",r=>{r.key==="Escape"&&e.ui.closeContextMenu()}),e.ui.ensurePanel=()=>{let r=x();if(!r)return null;let s=document.getElementById(e.ui.panelId+"-container"),t=document.getElementById(e.ui.panelId);if(s)s.setAttribute("data-cgpt-injected","true"),t||(t=document.createElement("div"),t.id=e.ui.panelId,Object.assign(t.style,{padding:"12px 8px 8px 8px",boxSizing:"border-box",overflow:"auto",flex:"1 1 auto",minHeight:"0",width:"100%"}),s.insertBefore(t,s.firstChild||null));else{s=document.createElement("div"),s.id=e.ui.panelId+"-container",s.setAttribute("data-cgpt-injected","true"),Object.assign(s.style,{margin:"8px",borderRadius:"8px",background:e.theme.BG,border:`1px solid ${e.theme.FG_MUTED}`,boxSizing:"border-box",width:"calc(100% - 16px)",minHeight:"200px",height:"200px",display:"flex",flexDirection:"column",alignItems:"stretch",overflow:"hidden",flexShrink:"0"}),t=document.createElement("div"),t.id=e.ui.panelId,Object.assign(t.style,{padding:"12px 8px 8px 8px",boxSizing:"border-box",overflow:"auto",flex:"1 1 auto",minHeight:"0",width:"100%"});let i=document.createElement("div");i.setAttribute("data-resize-handle","true"),Object.assign(i.style,{height:"8px",flex:"0 0 8px",cursor:"ns-resize",background:`linear-gradient(to bottom, transparent, ${e.theme.FG_MUTED}44)`,borderRadius:"0 0 8px 8px",alignSelf:"stretch"}),i.addEventListener("mousedown",l=>{l.preventDefault();let c=document.getElementById(e.ui.panelId+"-container");if(!c)return;let u=l.clientY,d=c.offsetHeight;i.style.background=`linear-gradient(to bottom, transparent, ${e.theme.FG_MUTED}88)`;let g=m=>{let h=m.clientY-u,b=Math.max(150,Math.min(d+h,window.innerHeight-80));c.style.height=b+"px"},f=()=>{document.removeEventListener("mousemove",g),document.removeEventListener("mouseup",f),i.style.background=`linear-gradient(to bottom, transparent, ${e.theme.FG_MUTED}44)`};document.addEventListener("mousemove",g),document.addEventListener("mouseup",f)}),s.appendChild(t),s.appendChild(i),r.firstChild?r.insertBefore(s,r.firstChild):r.appendChild(s)}return document.getElementById(e.ui.panelId)};function p(){if(!e.debug)return null;let r=Date.now(),s=e.diag.lastScanAt?r-e.diag.lastScanAt:null,t=e.diag.lastRenderAt?r-e.diag.lastRenderAt:null,i=document.createElement("div");return i.textContent=`DBG scans:${e.diag.scans} (last ${e.diag.lastScanDurationMs}ms, chats ${e.diag.chatsFoundLastScan}${s!==null?", "+s+"ms ago":""}) renders:${e.diag.renders} (last ${e.diag.lastRenderDurationMs}ms${t!==null?", "+t+"ms ago":""})`,Object.assign(i.style,{marginTop:"6px",fontSize:"11px",color:e.theme.FG_MUTED,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}),i}e.ui.render=()=>{let r=performance.now(),s=e.ui.ensurePanel();if(!s)return;s.innerHTML="";let t=document.createElement("div");Object.assign(t.style,{display:"flex",gap:"6px",marginBottom:"8px",alignItems:"center"});let i=document.createElement("input");i.placeholder=e.L.search,i.value=e.ui.lastSearch||"",Object.assign(i.style,{flex:"1",padding:"6px 8px",border:`1px solid ${e.theme.FG_MUTED}`,borderRadius:"6px",background:e.theme.dark?"#333":"#fff",color:e.theme.FG,boxSizing:"border-box",minWidth:"0"});let l=S(()=>{e.ui.lastSearch=i.value,e.ui.render()},200);i.addEventListener("input",l);let c=document.createElement("button");c.textContent=n.settings,c.title=e.L.settings,Object.assign(c.style,{padding:"6px 10px",background:e.theme.BTN_BG,border:`1px solid ${e.theme.FG_MUTED}`,borderRadius:"6px",cursor:"pointer",color:e.theme.FG,flexShrink:"0",minWidth:"40px"}),c.addEventListener("click",m=>{m.preventDefault(),m.stopPropagation(),e.ui.showSettings()}),t.appendChild(i),t.appendChild(c),s.appendChild(t);let u=p();u&&s.appendChild(u);let d=(i.value||"").toLowerCase().trim();e.folders.getTree().forEach(m=>e.ui.renderFolderNode(s,m,d));let f=document.createElement("button");f.textContent=`\uFF0B ${e.L.newFolder}`,Object.assign(f.style,{width:"100%",marginTop:"12px",padding:"8px",background:e.theme.BTN_BG,border:`1px solid ${e.theme.FG_MUTED}`,borderRadius:"6px",cursor:"pointer",color:e.theme.FG,fontWeight:"500"}),f.addEventListener("click",()=>{let m=prompt(e.L.newFolder)||"";m.trim()&&e.folders.create(m.trim())}),s.appendChild(f),e.diag.renders+=1,e.diag.lastRenderAt=Date.now(),e.diag.lastRenderDurationMs=Math.round(performance.now()-r)},e.ui.renderFolderNode=(r,s,t)=>{let{folder:i,level:l,children:c}=s,u=document.createElement("div");Object.assign(u.style,{paddingLeft:`${l*14}px`,marginBottom:"4px",maxWidth:"100%",boxSizing:"border-box"});let d=document.createElement("div");Object.assign(d.style,{display:"flex",alignItems:"center",gap:"6px",cursor:"pointer",padding:"6px 8px",borderRadius:"6px",background:i.color?`${i.color}22`:"rgba(255,255,255,0.05)",maxWidth:"100%",overflow:"hidden"}),d.addEventListener("mouseover",()=>{d.style.background=i.color?`${i.color}44`:"rgba(255,255,255,0.1)"}),d.addEventListener("mouseout",()=>{d.style.background=i.color?`${i.color}22`:"rgba(255,255,255,0.05)"});let g=document.createElement("span");g.textContent=i.expanded?n.arrowDown:n.arrowRight,Object.assign(g.style,{width:"16px",color:e.theme.FG_MUTED,fontSize:"10px"});let f=document.createElement("span");if(f.textContent=i.icon||n.folder,f.style.fontSize="16px",i.pinned){let h=document.createElement("span");h.textContent=n.pin,Object.assign(h.style,{fontSize:"10px",color:"#f59e0b"}),d.appendChild(h)}let m=document.createElement("span");m.textContent=i.name,Object.assign(m.style,{flex:"1",color:e.theme.FG,fontSize:"14px",fontWeight:"500",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:"0"}),d.addEventListener("click",()=>{i.expanded=!i.expanded,e.saveFolders(),e.ui.render()}),d.addEventListener("contextmenu",h=>{h.preventDefault(),e.ui.openFolderContextMenu(h.pageX,h.pageY,i)}),d.appendChild(g),d.appendChild(f),d.appendChild(m),u.appendChild(d),i.expanded&&(Object.values(e.chats.map).filter(b=>(e.state.assign[b.id]||"uncategorized")===i.id).forEach(b=>{t&&!b.title.toLowerCase().includes(t)||u.appendChild(e.ui.renderChatItem(b,l))}),c.forEach(b=>e.ui.renderFolderNode(r,b,t))),r.appendChild(u)},e.ui.renderChatItem=(r,s)=>{let t=document.createElement("div");Object.assign(t.style,{paddingLeft:`${(s+1)*14}px`,maxWidth:"100%",boxSizing:"border-box"});let i=document.createElement("div");Object.assign(i.style,{padding:"4px 8px",borderRadius:"4px",cursor:"pointer",overflow:"hidden",boxSizing:"border-box"}),i.addEventListener("mouseover",()=>i.style.background=e.theme.BG_HOVER),i.addEventListener("mouseout",()=>i.style.background="");let l=document.createElement("a");return l.textContent=r.title,l.href=r.href,Object.assign(l.style,{color:e.theme.FG,textDecoration:"none",fontSize:"13px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"block",maxWidth:"100%"}),i.appendChild(l),t.appendChild(i),t},e.ui.openFolderContextMenu=(r,s,t)=>{e.ui.closeContextMenu();let i=document.createElement("div");a=i,Object.assign(i.style,{position:"fixed",left:r+"px",top:s+"px",background:e.theme.BG,color:e.theme.FG,border:`1px solid ${e.theme.FG_MUTED}`,borderRadius:"8px",padding:"6px",zIndex:9999,minWidth:"200px",boxShadow:"0 4px 12px rgba(0,0,0,0.5)"});let l=(c,u)=>{let d=document.createElement("button");d.textContent=c,Object.assign(d.style,{width:"100%",display:"block",padding:"8px 12px",background:e.theme.BTN_BG,border:"none",borderRadius:"4px",color:e.theme.FG,cursor:"pointer",margin:"4px 0",textAlign:"left"}),d.addEventListener("mouseover",()=>d.style.background=e.theme.BG_HOVER),d.addEventListener("mouseout",()=>d.style.background=e.theme.BTN_BG),d.addEventListener("click",()=>{u(),e.ui.closeContextMenu()}),i.appendChild(d)};l(e.L.rename,()=>{let c=prompt(e.L.rename,t.name);c&&c.trim()&&e.folders.rename(t.id,c.trim())}),t.id!=="uncategorized"&&l(e.L.delete,()=>{confirm(e.L.confirmDelete(t.name))&&e.folders.delete(t.id)}),l(e.L.pinned,()=>e.folders.togglePin(t.id)),l(e.L.icon,()=>{let c=prompt(e.L.icon,t.icon||"");c!==null&&e.folders.setIcon(t.id,c)}),l(e.L.color,()=>e.ui.showColorPicker(t.id,t.color||"#66aaff")),document.body.appendChild(i)},e.ui.showColorPicker=(r,s)=>{let t=prompt("Color (hex)",s||"#66aaff");t&&e.folders.setColor(r,t.trim())},e.ui.showSettings=()=>{let r=confirm(`${e.L.autosuggest}
OK = ON, Cancel = OFF`);e.state.settings.autosuggest=r;let s=confirm(`${e.L.autosort}
OK = ON, Cancel = OFF`);e.state.settings.autosort=s;let t=confirm(`${e.L.cloudTitles}
OK = ON, Cancel = OFF`);e.state.settings.cloudTitles=t,e.saveSettings(),e.ui.render()};let o=S(()=>e.ui.render(),100);e.on("chats-updated",o),e.on("folders-updated",o),e.on("assign-updated",o),e.on("theme-changed",o)}function M(e){let n=[{folder:"\u{1F4BB} Code",words:["code","javascript","python","regex","bug","debug","error","function","api"]},{folder:"\u2709\uFE0F Writing",words:["email","letter","text","write","draft","essay","article"]},{folder:"\u{1F3EB} Education",words:["school","class","study","learn","homework","exam","university"]},{folder:"\u{1F4C1} Work",words:["project","meeting","plan","research","report","business","task"]},{folder:"\u2764\uFE0F Personal",words:["family","health","advice","help","personal","life"]}];e.suggest=c=>{let u=(c||"").toLowerCase();for(let d of n)for(let g of d.words)if(u.includes(g))return d.folder;return null};let a=c=>{try{return c.replace(/^[^\p{L}\p{N}]+/gu,"")}catch{return c.replace(/^[^A-Za-z0-9]+/,"")}},p=c=>a((c??"").normalize("NFKC")).trim().replace(/\s+/g," ").toLowerCase();function o(c){let u=p(c),d=e._folders.F;return Object.values(d()).find(g=>p(g.name)===u)||null}function r(c){let u=(c||"").trim(),d=o(u);return d?d.id:e.folders.create(u)}function s(c,u){if(e.state.dismissed[c])return;let d=e.suggest(u);if(!d)return;let g=r(d);e.folders.assignChat(c,g)}function t(c,u){if(e.state.dismissed[c])return;let d=e.suggest(u);if(!d)return;let g=d.trim(),f=`Chat: "${u}"
${e.L.suggestion} ${g}
Assign to this folder?`;if(!confirm(f)){e.state.dismissed[c]=Date.now(),e.saveDismissed();return}let m=r(g);e.folders.assignChat(c,m)}let i=!1,l=new Set(Object.keys(e.state.assign||{}));e.on("chats-updated",()=>{let c=!!e.state.settings.autosort,u=!!e.state.settings.autosuggest,d=Object.values(e.chats.map);if(!i){d.forEach(g=>l.add(g.id)),i=!0;return}d.forEach(g=>{l.has(g.id)||(l.add(g.id),!e.state.assign[g.id]&&(c?s(g.id,g.title):u&&t(g.id,g.title)))}),e.saveAssign(),e.emit("assign-updated",e.state.assign)}),e.suggest.reindexAll=(c="confirm")=>{Object.values(e.chats.map).forEach(u=>{c==="auto"?s(u.id,u.title):t(u.id,u.title)}),e.saveAssign(),e.emit("assign-updated",e.state.assign)}}function k(e){e.sync={},e.sync.export=()=>({timestamp:Date.now(),version:"9.4.1",locale:e.locale,data:{folders:e.state.folders,assign:e.state.assign,settings:e.state.settings,dismissed:e.state.dismissed}}),e.sync.import=n=>{try{return!n||!n.data?!1:(n.data.folders&&(e.state.folders=n.data.folders),n.data.assign&&(e.state.assign=n.data.assign),n.data.settings&&(e.state.settings=n.data.settings),n.data.dismissed&&(e.state.dismissed=n.data.dismissed),e.saveFolders(),e.saveAssign(),e.saveSettings(),e.saveDismissed(),e.emit("folders-updated",e.state.folders),e.emit("assign-updated",e.state.assign),e.emit("theme-changed",e.theme),!0)}catch(a){return console.warn("[CGPT] import failed",a),!1}}}function j(e){e.start=()=>{let n=new URLSearchParams(window.location.search);e.debug=n.get("cgptdebug")==="1",e.log("starting",{version:"9.4.1",debug:e.debug}),e.scanChats(),e.ui.render();let a=x();if(!a)return;let p=S(()=>e.scanChats(),200);new MutationObserver(s=>{let t=document.querySelector('[data-cgpt-injected="true"]');s.some(l=>!(t&&t.contains(l.target)))&&p()}).observe(a,{childList:!0,subtree:!0,characterData:!0,attributes:!0,attributeFilter:["href","aria-label","title"]}),new MutationObserver(()=>{let s=document.getElementById(e.ui.panelId+"-container"),t=x();!s&&t&&(e.log("panel missing -> recreating"),setTimeout(()=>e.ui.render(),100))}).observe(a,{childList:!0,subtree:!1}),setInterval(()=>{let s=document.getElementById(e.ui.panelId+"-container"),t=x();!s&&t&&(e.log("panel missing (interval) -> recreating"),e.ui.render())},2500),e.log("started")}}(function(){"use strict";let e=window.CGPT=window.CGPT||{},n=v();e.on=n.on,e.off=n.off,e.emit=n.emit,E(e),e.store=w(),y(e),O(e),L(e),_(e),D(e),I(e),M(e),k(e),j(e),F(()=>{e.start()})})();})();
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2NvcmUvZXZlbnRzLmpzIiwgIi4uL3NyYy9jb3JlL2xvZy5qcyIsICIuLi9zcmMvY29yZS9zdG9yYWdlLmpzIiwgIi4uL3NyYy9jb3JlL2kxOG4uanMiLCAiLi4vc3JjL2NvcmUvdGhlbWUuanMiLCAiLi4vc3JjL2RvbS9zaWRlYmFyLmpzIiwgIi4uL3NyYy9zdGF0ZS9zdGF0ZS5qcyIsICIuLi9zcmMvZm9sZGVycy9mb2xkZXJzLmpzIiwgIi4uL3NyYy9jaGF0cy9zY2FuLmpzIiwgIi4uL3NyYy9jb3JlL2RlYm91bmNlLmpzIiwgIi4uL3NyYy91aS9wYW5lbC5qcyIsICIuLi9zcmMvc3VnZ2VzdC9zdWdnZXN0LmpzIiwgIi4uL3NyYy9zeW5jL3N5bmMuanMiLCAiLi4vc3JjL21haW4vc3RhcnQuanMiLCAiLi4vc3JjL2luZGV4LmpzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJleHBvcnQgZnVuY3Rpb24gY3JlYXRlRXZlbnRCdXMoKSB7XG4gIGNvbnN0IGxpc3RlbmVycyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgZnVuY3Rpb24gb24oZXZ0LCBmbikge1xuICAgIChsaXN0ZW5lcnNbZXZ0XSA9IGxpc3RlbmVyc1tldnRdIHx8IFtdKS5wdXNoKGZuKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9mZihldnQsIGZuKSB7XG4gICAgY29uc3QgYXJyID0gbGlzdGVuZXJzW2V2dF0gfHwgW107XG4gICAgY29uc3QgaSA9IGFyci5pbmRleE9mKGZuKTtcbiAgICBpZiAoaSA+PSAwKSBhcnIuc3BsaWNlKGksIDEpO1xuICB9XG5cbiAgZnVuY3Rpb24gZW1pdChldnQsIHBheWxvYWQpIHtcbiAgICAobGlzdGVuZXJzW2V2dF0gfHwgW10pLmZvckVhY2goKGZuKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBmbihwYXlsb2FkKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcIltDR1BUXSBMaXN0ZW5lciBlcnJvcjpcIiwgZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4geyBvbiwgb2ZmLCBlbWl0IH07XG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGluaXRMb2dnaW5nKENHUFQpIHtcbiAgQ0dQVC5kZWJ1ZyA9IGZhbHNlO1xuICBDR1BULmxvZyA9ICguLi5hcmdzKSA9PiB7XG4gICAgaWYgKENHUFQuZGVidWcpIGNvbnNvbGUubG9nKFwiW0NHUFRdXCIsIC4uLmFyZ3MpO1xuICB9O1xufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBjcmVhdGVHTVN0b3JlKCkge1xuICBmdW5jdGlvbiBzYWZlUGFyc2UocmF3KSB7XG4gICAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gbnVsbCkgcmV0dXJuIHJhdztcbiAgICBpZiAodHlwZW9mIHJhdyAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIHJhdztcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UocmF3KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIFNvbWUgR00gZW5naW5lcyBtYXkgc3RvcmUgcGxhaW4gc3RyaW5nczsga2VlcCBhcy1pcy5cbiAgICAgIHJldHVybiByYXc7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc2FmZVN0cmluZ2lmeSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHJldHVybiB2YWx1ZTtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBnZXQoa2V5LCBmYWxsYmFjaykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmF3ID0gR01fZ2V0VmFsdWUoa2V5KTtcbiAgICAgICAgY29uc3QgcGFyc2VkID0gc2FmZVBhcnNlKHJhdyk7XG4gICAgICAgIHJldHVybiBwYXJzZWQgPT09IHVuZGVmaW5lZCB8fCBwYXJzZWQgPT09IG51bGwgPyBmYWxsYmFjayA6IHBhcnNlZDtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFwiW0NHUFRdIFN0b3JhZ2UgZ2V0IGVycm9yOlwiLCBlKTtcbiAgICAgICAgcmV0dXJuIGZhbGxiYWNrO1xuICAgICAgfVxuICAgIH0sXG4gICAgc2V0KGtleSwgdmFsdWUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIEdNX3NldFZhbHVlKGtleSwgc2FmZVN0cmluZ2lmeSh2YWx1ZSkpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLndhcm4oXCJbQ0dQVF0gU3RvcmFnZSBzZXQgZXJyb3I6XCIsIGUpO1xuICAgICAgfVxuICAgIH0sXG4gICAgZGVsKGtleSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgR01fZGVsZXRlVmFsdWUoa2V5KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFwiW0NHUFRdIFN0b3JhZ2UgZGVsZXRlIGVycm9yOlwiLCBlKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGluaXRJMThuKENHUFQpIHtcbiAgY29uc3Qgc3VwcG9ydGVkID0gW1wiZGVcIiwgXCJlblwiXTtcbiAgY29uc3QgcmF3TGFuZyA9IChuYXZpZ2F0b3IubGFuZ3VhZ2UgfHwgXCJlblwiKS50b0xvd2VyQ2FzZSgpO1xuICBjb25zdCBzaG9ydCA9IHJhd0xhbmcuc2xpY2UoMCwgMik7XG4gIGNvbnN0IGxhbmcgPSBzdXBwb3J0ZWQuaW5jbHVkZXMoc2hvcnQpID8gc2hvcnQgOiBcImVuXCI7XG4gIENHUFQubG9jYWxlID0gbGFuZztcblxuICBjb25zdCBMID0ge1xuICAgIGRlOiB7XG4gICAgICB1bnNvcnRlZDogXCJVbnNvcnRpZXJ0XCIsXG4gICAgICBuZXdGb2xkZXI6IFwiTmV1ZXIgT3JkbmVyXCIsXG4gICAgICBzZWFyY2g6IFwiU3VjaGVuXHUyMDI2XCIsXG4gICAgICByZW5hbWU6IFwiVW1iZW5lbm5lblwiLFxuICAgICAgZGVsZXRlOiBcIkxcdTAwRjZzY2hlblwiLFxuICAgICAgZXhwb3J0OiBcIkV4cG9ydGllcmVuXCIsXG4gICAgICBpbXBvcnQ6IFwiSW1wb3J0aWVyZW5cIixcbiAgICAgIGNvbmZpcm1EZWxldGU6IChuYW1lKSA9PiBgT3JkbmVyIFwiJHtuYW1lfVwiIGxcdTAwRjZzY2hlbj9gLFxuICAgICAgaWNvbjogXCJTeW1ib2xcIixcbiAgICAgIHN1Z2dlc3Rpb246IFwiVm9yc2NobGFnOlwiLFxuICAgICAgYXV0b3NvcnQ6IFwiQXV0b21hdGlzY2ggZWluc29ydGllcmVuXCIsXG4gICAgICBhdXRvc3VnZ2VzdDogXCJWb3JzY2hsXHUwMEU0Z2UgYW56ZWlnZW5cIixcbiAgICAgIHBpbm5lZDogXCJBbmdlaGVmdGV0XCIsXG4gICAgICByZWluZGV4OiBcIkFsbGUgQ2hhdHMgbmV1IGthdGVnb3Jpc2llcmVuXCIsXG4gICAgICBjbG91ZFRpdGxlczogXCJUaXRlbCBpbiBDbG91ZC1TeW5jIGVpbnNjaGxpZVx1MDBERmVuXCIsXG4gICAgICBzZXR0aW5nczogXCJFaW5zdGVsbHVuZ2VuXCIsXG4gICAgICBjb2xvcjogXCJGYXJiZVwiXG4gICAgfSxcbiAgICBlbjoge1xuICAgICAgdW5zb3J0ZWQ6IFwiVW5zb3J0ZWRcIixcbiAgICAgIG5ld0ZvbGRlcjogXCJOZXcgRm9sZGVyXCIsXG4gICAgICBzZWFyY2g6IFwiU2VhcmNoXHUyMDI2XCIsXG4gICAgICByZW5hbWU6IFwiUmVuYW1lXCIsXG4gICAgICBkZWxldGU6IFwiRGVsZXRlXCIsXG4gICAgICBleHBvcnQ6IFwiRXhwb3J0XCIsXG4gICAgICBpbXBvcnQ6IFwiSW1wb3J0XCIsXG4gICAgICBjb25maXJtRGVsZXRlOiAobmFtZSkgPT4gYERlbGV0ZSBmb2xkZXIgXCIke25hbWV9XCI/YCxcbiAgICAgIGljb246IFwiSWNvblwiLFxuICAgICAgc3VnZ2VzdGlvbjogXCJTdWdnZXN0aW9uOlwiLFxuICAgICAgYXV0b3NvcnQ6IFwiQXV0by1zb3J0XCIsXG4gICAgICBhdXRvc3VnZ2VzdDogXCJTaG93IHN1Z2dlc3Rpb25zXCIsXG4gICAgICBwaW5uZWQ6IFwiUGlubmVkXCIsXG4gICAgICByZWluZGV4OiBcIlJlLWNhdGVnb3JpemUgYWxsIGNoYXRzXCIsXG4gICAgICBjbG91ZFRpdGxlczogXCJJbmNsdWRlIHRpdGxlcyBpbiBDbG91ZCBTeW5jXCIsXG4gICAgICBzZXR0aW5nczogXCJTZXR0aW5nc1wiLFxuICAgICAgY29sb3I6IFwiQ29sb3JcIlxuICAgIH1cbiAgfTtcblxuICBDR1BULkwgPSBMW0NHUFQubG9jYWxlXSB8fCBMLmVuO1xufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBpbml0VGhlbWUoQ0dQVCkge1xuICBjb25zdCBtcSA9IHdpbmRvdy5tYXRjaE1lZGlhXG4gICAgPyB3aW5kb3cubWF0Y2hNZWRpYShcIihwcmVmZXJzLWNvbG9yLXNjaGVtZTogZGFyaylcIilcbiAgICA6IHsgbWF0Y2hlczogdHJ1ZSwgYWRkRXZlbnRMaXN0ZW5lcjogbnVsbCwgYWRkTGlzdGVuZXI6IG51bGwgfTtcblxuICBjb25zdCBjb21wdXRlVGhlbWUgPSAoKSA9PiB7XG4gICAgY29uc3QgaXNEYXJrID0gISFtcS5tYXRjaGVzO1xuICAgIHJldHVybiB7XG4gICAgICBkYXJrOiBpc0RhcmssXG4gICAgICBGRzogaXNEYXJrID8gXCIjZWNlY2VjXCIgOiBcIiMyMjJcIixcbiAgICAgIEZHX01VVEVEOiBpc0RhcmsgPyBcIiM5OTlcIiA6IFwiIzU1NVwiLFxuICAgICAgQkc6IGlzRGFyayA/IFwiIzJhMmIzMlwiIDogXCIjZWFlYWVhXCIsXG4gICAgICBCR19IT1ZFUjogaXNEYXJrID8gXCJyZ2JhKDI1NSwyNTUsMjU1LDAuMSlcIiA6IFwicmdiYSgwLDAsMCwwLjA4KVwiLFxuICAgICAgQlROX0JHOiBpc0RhcmsgPyBcIiMzYjNiM2JcIiA6IFwiI2ZmZlwiXG4gICAgfTtcbiAgfTtcblxuICBDR1BULnRoZW1lID0gY29tcHV0ZVRoZW1lKCk7XG5cbiAgY29uc3Qgb25DaGFuZ2UgPSAoKSA9PiB7XG4gICAgQ0dQVC50aGVtZSA9IGNvbXB1dGVUaGVtZSgpO1xuICAgIENHUFQuZW1pdChcInRoZW1lLWNoYW5nZWRcIiwgQ0dQVC50aGVtZSk7XG4gIH07XG5cbiAgaWYgKG1xICYmIG1xLmFkZEV2ZW50TGlzdGVuZXIpIG1xLmFkZEV2ZW50TGlzdGVuZXIoXCJjaGFuZ2VcIiwgb25DaGFuZ2UpO1xuICBlbHNlIGlmIChtcSAmJiBtcS5hZGRMaXN0ZW5lcikgbXEuYWRkTGlzdGVuZXIob25DaGFuZ2UpO1xufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBnZXRTaWRlYmFyKCkge1xuICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIm5hdlwiKSB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbY2xhc3MqPVwic2lkZWJhclwiXScpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gb25TaWRlYmFyUmVhZHkoY2IpIHtcbiAgY29uc3QgdHJ5SXQgPSAoKSA9PiB7XG4gICAgY29uc3QgZWwgPSBnZXRTaWRlYmFyKCk7XG4gICAgaWYgKGVsKSBjYihlbCk7XG4gICAgZWxzZSBzZXRUaW1lb3V0KHRyeUl0LCAyMDApO1xuICB9O1xuICB0cnlJdCgpO1xufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBpbml0U3RhdGUoQ0dQVCkge1xuICBDR1BULnN0YXRlID0ge1xuICAgIEZPTERFUlNfS0VZOiBcImNncHRfZm9sZGVyc192OVwiLFxuICAgIEFTU0lHTl9LRVk6IFwiY2dwdF9hc3NpZ25fdjlcIixcbiAgICBTRVRUSU5HU19LRVk6IFwiY2dwdF9zZXR0aW5nc192OVwiLFxuICAgIERJU01JU1NFRF9LRVk6IFwiY2dwdF9kaXNtaXNzZWRfdjlcIixcbiAgICBmb2xkZXJzOiB7fSxcbiAgICBhc3NpZ246IHt9LFxuICAgIGRpc21pc3NlZDoge30sXG4gICAgc2V0dGluZ3M6IHtcbiAgICAgIGF1dG9zdWdnZXN0OiB0cnVlLFxuICAgICAgYXV0b3NvcnQ6IGZhbHNlLFxuICAgICAgdGhlbWU6IFwiYXV0b1wiLFxuICAgICAgbGFuZzogQ0dQVC5sb2NhbGUsXG4gICAgICBjbG91ZFRpdGxlczogdHJ1ZVxuICAgIH1cbiAgfTtcblxuICBDR1BULnN0YXRlLmZvbGRlcnMgPSBDR1BULnN0b3JlLmdldChDR1BULnN0YXRlLkZPTERFUlNfS0VZLCB7XG4gICAgdW5jYXRlZ29yaXplZDoge1xuICAgICAgaWQ6IFwidW5jYXRlZ29yaXplZFwiLFxuICAgICAgbmFtZTogQ0dQVC5MLnVuc29ydGVkLFxuICAgICAgaWNvbjogXCJcIixcbiAgICAgIGNvbG9yOiBcIiM4ODhcIixcbiAgICAgIGV4cGFuZGVkOiB0cnVlLFxuICAgICAgb3JkZXI6IDAsXG4gICAgICBwaW5uZWQ6IGZhbHNlLFxuICAgICAgcGFyZW50SWQ6IG51bGxcbiAgICB9XG4gIH0pO1xuXG4gIENHUFQuc3RhdGUuYXNzaWduID0gQ0dQVC5zdG9yZS5nZXQoQ0dQVC5zdGF0ZS5BU1NJR05fS0VZLCB7fSk7XG4gIENHUFQuc3RhdGUuc2V0dGluZ3MgPSBDR1BULnN0b3JlLmdldChDR1BULnN0YXRlLlNFVFRJTkdTX0tFWSwgQ0dQVC5zdGF0ZS5zZXR0aW5ncyk7XG4gIENHUFQuc3RhdGUuZGlzbWlzc2VkID0gQ0dQVC5zdG9yZS5nZXQoQ0dQVC5zdGF0ZS5ESVNNSVNTRURfS0VZLCB7fSk7XG5cbiAgQ0dQVC5zYXZlRm9sZGVycyA9ICgpID0+IENHUFQuc3RvcmUuc2V0KENHUFQuc3RhdGUuRk9MREVSU19LRVksIENHUFQuc3RhdGUuZm9sZGVycyk7XG4gIENHUFQuc2F2ZUFzc2lnbiA9ICgpID0+IENHUFQuc3RvcmUuc2V0KENHUFQuc3RhdGUuQVNTSUdOX0tFWSwgQ0dQVC5zdGF0ZS5hc3NpZ24pO1xuICBDR1BULnNhdmVTZXR0aW5ncyA9ICgpID0+IENHUFQuc3RvcmUuc2V0KENHUFQuc3RhdGUuU0VUVElOR1NfS0VZLCBDR1BULnN0YXRlLnNldHRpbmdzKTtcbiAgQ0dQVC5zYXZlRGlzbWlzc2VkID0gKCkgPT4gQ0dQVC5zdG9yZS5zZXQoQ0dQVC5zdGF0ZS5ESVNNSVNTRURfS0VZLCBDR1BULnN0YXRlLmRpc21pc3NlZCk7XG5cbiAgQ0dQVC5kaWFnID0ge1xuICAgIHNjYW5zOiAwLFxuICAgIHJlbmRlcnM6IDAsXG4gICAgbGFzdFNjYW5BdDogMCxcbiAgICBsYXN0UmVuZGVyQXQ6IDAsXG4gICAgbGFzdFNjYW5EdXJhdGlvbk1zOiAwLFxuICAgIGxhc3RSZW5kZXJEdXJhdGlvbk1zOiAwLFxuICAgIGNoYXRzRm91bmRMYXN0U2NhbjogMFxuICB9O1xufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBpbml0Rm9sZGVycyhDR1BUKSB7XG4gIENHUFQuZm9sZGVycyA9IHt9O1xuICBjb25zdCBGID0gKCkgPT4gQ0dQVC5zdGF0ZS5mb2xkZXJzO1xuXG4gIGNvbnN0IHVpZCA9ICgpID0+XG4gICAgY3J5cHRvLnJhbmRvbVVVSUQgPyBjcnlwdG8ucmFuZG9tVVVJRCgpIDogXCJpZF9cIiArIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnNsaWNlKDIpO1xuXG4gIGNvbnN0IGNvbXBhcmVGb2xkZXIgPSAoYSwgYikgPT4gKGIucGlubmVkIC0gYS5waW5uZWQpIHx8IChhLm9yZGVyIC0gYi5vcmRlcik7XG5cbiAgQ0dQVC5mb2xkZXJzLmNyZWF0ZSA9IChuYW1lLCBwYXJlbnRJZCA9IG51bGwsIGljb24gPSBcIlwiKSA9PiB7XG4gICAgY29uc3QgaWQgPSB1aWQoKTtcbiAgICBGKClbaWRdID0ge1xuICAgICAgaWQsXG4gICAgICBuYW1lLFxuICAgICAgaWNvbixcbiAgICAgIGNvbG9yOiBcIiM2NmFhZmZcIixcbiAgICAgIHBhcmVudElkLFxuICAgICAgcGlubmVkOiBmYWxzZSxcbiAgICAgIGV4cGFuZGVkOiB0cnVlLFxuICAgICAgb3JkZXI6IERhdGUubm93KClcbiAgICB9O1xuICAgIENHUFQuc2F2ZUZvbGRlcnMoKTtcbiAgICBDR1BULmVtaXQoXCJmb2xkZXJzLXVwZGF0ZWRcIiwgRigpKTtcbiAgICByZXR1cm4gaWQ7XG4gIH07XG5cbiAgQ0dQVC5mb2xkZXJzLmRlbGV0ZSA9IChmb2xkZXJJZCkgPT4ge1xuICAgIGNvbnN0IGYgPSBGKClbZm9sZGVySWRdO1xuICAgIGlmICghZiB8fCBmb2xkZXJJZCA9PT0gXCJ1bmNhdGVnb3JpemVkXCIpIHJldHVybjtcblxuICAgIC8vIFJlLXBhcmVudCBjaGlsZHJlblxuICAgIE9iamVjdC52YWx1ZXMoRigpKS5mb3JFYWNoKCh4KSA9PiB7XG4gICAgICBpZiAoeC5wYXJlbnRJZCA9PT0gZm9sZGVySWQpIHgucGFyZW50SWQgPSBmLnBhcmVudElkID8/IG51bGw7XG4gICAgfSk7XG5cbiAgICAvLyBNb3ZlIGFzc2lnbmVkIGNoYXRzIHRvIHVuY2F0ZWdvcml6ZWRcbiAgICBPYmplY3Qua2V5cyhDR1BULnN0YXRlLmFzc2lnbikuZm9yRWFjaCgoY2lkKSA9PiB7XG4gICAgICBpZiAoQ0dQVC5zdGF0ZS5hc3NpZ25bY2lkXSA9PT0gZm9sZGVySWQpIENHUFQuc3RhdGUuYXNzaWduW2NpZF0gPSBcInVuY2F0ZWdvcml6ZWRcIjtcbiAgICB9KTtcblxuICAgIGRlbGV0ZSBGKClbZm9sZGVySWRdO1xuICAgIENHUFQuc2F2ZUZvbGRlcnMoKTtcbiAgICBDR1BULnNhdmVBc3NpZ24oKTtcbiAgICBDR1BULmVtaXQoXCJmb2xkZXJzLXVwZGF0ZWRcIiwgRigpKTtcbiAgICBDR1BULmVtaXQoXCJhc3NpZ24tdXBkYXRlZFwiLCBDR1BULnN0YXRlLmFzc2lnbik7XG4gIH07XG5cbiAgQ0dQVC5mb2xkZXJzLnJlbmFtZSA9IChmb2xkZXJJZCwgbmV3TmFtZSkgPT4ge1xuICAgIGlmIChGKClbZm9sZGVySWRdKSB7XG4gICAgICBGKClbZm9sZGVySWRdLm5hbWUgPSBuZXdOYW1lO1xuICAgICAgQ0dQVC5zYXZlRm9sZGVycygpO1xuICAgICAgQ0dQVC5lbWl0KFwiZm9sZGVycy11cGRhdGVkXCIsIEYoKSk7XG4gICAgfVxuICB9O1xuXG4gIENHUFQuZm9sZGVycy5zZXRJY29uID0gKGZvbGRlcklkLCBpY29uKSA9PiB7XG4gICAgaWYgKEYoKVtmb2xkZXJJZF0pIHtcbiAgICAgIEYoKVtmb2xkZXJJZF0uaWNvbiA9IGljb247XG4gICAgICBDR1BULnNhdmVGb2xkZXJzKCk7XG4gICAgICBDR1BULmVtaXQoXCJmb2xkZXJzLXVwZGF0ZWRcIiwgRigpKTtcbiAgICB9XG4gIH07XG5cbiAgQ0dQVC5mb2xkZXJzLnNldENvbG9yID0gKGZvbGRlcklkLCBjb2xvcikgPT4ge1xuICAgIGlmIChGKClbZm9sZGVySWRdKSB7XG4gICAgICBGKClbZm9sZGVySWRdLmNvbG9yID0gY29sb3I7XG4gICAgICBDR1BULnNhdmVGb2xkZXJzKCk7XG4gICAgICBDR1BULmVtaXQoXCJmb2xkZXJzLXVwZGF0ZWRcIiwgRigpKTtcbiAgICB9XG4gIH07XG5cbiAgQ0dQVC5mb2xkZXJzLnRvZ2dsZVBpbiA9IChmb2xkZXJJZCkgPT4ge1xuICAgIGlmIChGKClbZm9sZGVySWRdKSB7XG4gICAgICBGKClbZm9sZGVySWRdLnBpbm5lZCA9ICFGKClbZm9sZGVySWRdLnBpbm5lZDtcbiAgICAgIENHUFQuc2F2ZUZvbGRlcnMoKTtcbiAgICAgIENHUFQuZW1pdChcImZvbGRlcnMtdXBkYXRlZFwiLCBGKCkpO1xuICAgIH1cbiAgfTtcblxuICBDR1BULmZvbGRlcnMuc2V0UGFyZW50ID0gKGZvbGRlcklkLCBwYXJlbnRJZCkgPT4ge1xuICAgIGNvbnN0IG5vZGUgPSBGKClbZm9sZGVySWRdO1xuICAgIGlmICghbm9kZSB8fCBmb2xkZXJJZCA9PT0gXCJ1bmNhdGVnb3JpemVkXCIpIHJldHVybjtcblxuICAgIC8vIFByZXZlbnQgY3ljbGVzXG4gICAgbGV0IHAgPSBwYXJlbnRJZDtcbiAgICB3aGlsZSAocCkge1xuICAgICAgaWYgKHAgPT09IGZvbGRlcklkKSByZXR1cm47XG4gICAgICBwID0gKEYoKVtwXSB8fCB7fSkucGFyZW50SWQ7XG4gICAgfVxuXG4gICAgbm9kZS5wYXJlbnRJZCA9IHBhcmVudElkID8/IG51bGw7XG4gICAgQ0dQVC5zYXZlRm9sZGVycygpO1xuICAgIENHUFQuZW1pdChcImZvbGRlcnMtdXBkYXRlZFwiLCBGKCkpO1xuICB9O1xuXG4gIENHUFQuZm9sZGVycy5tb3ZlID0gKGZvbGRlcklkLCBkaXJlY3Rpb24pID0+IHtcbiAgICBjb25zdCBub2RlID0gRigpW2ZvbGRlcklkXTtcbiAgICBpZiAoIW5vZGUpIHJldHVybjtcblxuICAgIGNvbnN0IHNpYmxpbmdzID0gT2JqZWN0LnZhbHVlcyhGKCkpXG4gICAgICAuZmlsdGVyKCh4KSA9PiAoeC5wYXJlbnRJZCA/PyBudWxsKSA9PT0gKG5vZGUucGFyZW50SWQgPz8gbnVsbCkpXG4gICAgICAuc29ydCgoYSwgYikgPT4gYS5vcmRlciAtIGIub3JkZXIpO1xuXG4gICAgY29uc3QgaWR4ID0gc2libGluZ3MuZmluZEluZGV4KCh4KSA9PiB4LmlkID09PSBmb2xkZXJJZCk7XG4gICAgaWYgKGlkeCA8IDApIHJldHVybjtcblxuICAgIGNvbnN0IHN3YXBJZHggPSBkaXJlY3Rpb24gPT09IFwidXBcIiA/IGlkeCAtIDEgOiBpZHggKyAxO1xuICAgIGlmIChzd2FwSWR4IDwgMCB8fCBzd2FwSWR4ID49IHNpYmxpbmdzLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgY29uc3Qgb3RoZXIgPSBzaWJsaW5nc1tzd2FwSWR4XTtcbiAgICBjb25zdCB0ID0gbm9kZS5vcmRlcjtcbiAgICBub2RlLm9yZGVyID0gb3RoZXIub3JkZXI7XG4gICAgb3RoZXIub3JkZXIgPSB0O1xuXG4gICAgQ0dQVC5zYXZlRm9sZGVycygpO1xuICAgIENHUFQuZW1pdChcImZvbGRlcnMtdXBkYXRlZFwiLCBGKCkpO1xuICB9O1xuXG4gIENHUFQuZm9sZGVycy5nZXRUcmVlID0gKCkgPT4ge1xuICAgIGNvbnN0IGFsbCA9IE9iamVjdC52YWx1ZXMoRigpKTtcbiAgICBjb25zdCBieVBhcmVudCA9IG5ldyBNYXAoKTtcbiAgICBhbGwuZm9yRWFjaCgoZikgPT4ge1xuICAgICAgY29uc3QgayA9IGYucGFyZW50SWQgPz8gXCJyb290XCI7XG4gICAgICBjb25zdCBhcnIgPSBieVBhcmVudC5nZXQoayk7XG4gICAgICBpZiAoYXJyKSBhcnIucHVzaChmKTtcbiAgICAgIGVsc2UgYnlQYXJlbnQuc2V0KGssIFtmXSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBidWlsZCA9IChwYXJlbnRJZCwgbGV2ZWwpID0+XG4gICAgICAoYnlQYXJlbnQuZ2V0KHBhcmVudElkID8/IFwicm9vdFwiKSB8fCBbXSlcbiAgICAgICAgLnNvcnQoY29tcGFyZUZvbGRlcilcbiAgICAgICAgLm1hcCgoZikgPT4gKHsgZm9sZGVyOiBmLCBsZXZlbCwgY2hpbGRyZW46IGJ1aWxkKGYuaWQsIGxldmVsICsgMSkgfSkpO1xuXG4gICAgcmV0dXJuIGJ1aWxkKG51bGwsIDApO1xuICB9O1xuXG4gIENHUFQuZm9sZGVycy5hc3NpZ25DaGF0ID0gKGNoYXRJZCwgZm9sZGVySWQpID0+IHtcbiAgICBDR1BULnN0YXRlLmFzc2lnbltjaGF0SWRdID0gZm9sZGVySWQ7XG4gICAgQ0dQVC5zYXZlQXNzaWduKCk7XG4gICAgQ0dQVC5lbWl0KFwiYXNzaWduLXVwZGF0ZWRcIiwgQ0dQVC5zdGF0ZS5hc3NpZ24pO1xuICB9O1xuXG4gIC8vIEV4cG9zZSBoZWxwZXIgZm9yIGludGVybmFsIG1vZHVsZXNcbiAgQ0dQVC5fZm9sZGVycyA9IHsgRiB9O1xufVxuIiwgImltcG9ydCB7IGdldFNpZGViYXIgfSBmcm9tIFwiLi4vZG9tL3NpZGViYXIuanNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRDaGF0cyhDR1BUKSB7XG4gIENHUFQuY2hhdHMgPSB7IG1hcDoge30sIF9sYXN0U2NhbjogMCB9O1xuXG4gIENHUFQuc2NhbkNoYXRzID0gKCkgPT4ge1xuICAgIGNvbnN0IHN0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgY29uc3Qgc2lkZWJhciA9IGdldFNpZGViYXIoKTtcbiAgICBpZiAoIXNpZGViYXIpIHJldHVybjtcblxuICAgIC8vIEZhc3Qgc2Nhbjogb25seSBhbmNob3JzIHRoYXQgbG9vayBsaWtlIGNoYXRzLlxuICAgIGNvbnN0IG5vZGVzID0gc2lkZWJhci5xdWVyeVNlbGVjdG9yQWxsKFwiYVtocmVmKj0nL2MvJ11cIik7XG4gICAgY29uc3QgbWFwID0ge307XG5cbiAgICBub2Rlcy5mb3JFYWNoKChhKSA9PiB7XG4gICAgICAvLyBJZ25vcmUgb3VyIGluamVjdGVkIFVJIChwcmV2ZW50cyBzZWxmLXRyaWdnZXIgZmVlZGJhY2sgbG9vcHMpXG4gICAgICBpZiAoYS5jbG9zZXN0KCdbZGF0YS1jZ3B0LWluamVjdGVkPVwidHJ1ZVwiXScpKSByZXR1cm47XG5cbiAgICAgIGNvbnN0IGhyZWYgPSBhLmdldEF0dHJpYnV0ZShcImhyZWZcIikgfHwgXCJcIjtcbiAgICAgIGNvbnN0IG0gPSBocmVmLm1hdGNoKC9cXC9jXFwvKFtcXHctXSspLyk7XG4gICAgICBjb25zdCBpZCA9IG0gPyBtWzFdIDogaHJlZjtcbiAgICAgIGNvbnN0IHRpdGxlID0gKGEudGV4dENvbnRlbnQgfHwgXCJcIikudHJpbSgpIHx8IGhyZWY7XG4gICAgICBtYXBbaWRdID0geyBpZCwgdGl0bGUsIGhyZWYsIGVsOiBhIH07XG4gICAgfSk7XG5cbiAgICBDR1BULmNoYXRzLm1hcCA9IG1hcDtcbiAgICBDR1BULmNoYXRzLl9sYXN0U2NhbiA9IERhdGUubm93KCk7XG5cbiAgICAvLyBEaWFnIGNvdW50ZXJzXG4gICAgQ0dQVC5kaWFnLnNjYW5zICs9IDE7XG4gICAgQ0dQVC5kaWFnLmxhc3RTY2FuQXQgPSBEYXRlLm5vdygpO1xuICAgIENHUFQuZGlhZy5sYXN0U2NhbkR1cmF0aW9uTXMgPSBNYXRoLnJvdW5kKHBlcmZvcm1hbmNlLm5vdygpIC0gc3RhcnQpO1xuICAgIENHUFQuZGlhZy5jaGF0c0ZvdW5kTGFzdFNjYW4gPSBPYmplY3Qua2V5cyhtYXApLmxlbmd0aDtcblxuICAgIENHUFQuZW1pdChcImNoYXRzLXVwZGF0ZWRcIiwgbWFwKTtcbiAgfTtcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gZGVib3VuY2UoZm4sIG1zKSB7XG4gIGxldCB0O1xuICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICBpZiAodCkgY2xlYXJUaW1lb3V0KHQpO1xuICAgIHQgPSBzZXRUaW1lb3V0KCgpID0+IGZuKC4uLmFyZ3MpLCBtcyk7XG4gIH07XG59XG4iLCAiaW1wb3J0IHsgZGVib3VuY2UgfSBmcm9tIFwiLi4vY29yZS9kZWJvdW5jZS5qc1wiO1xuaW1wb3J0IHsgZ2V0U2lkZWJhciB9IGZyb20gXCIuLi9kb20vc2lkZWJhci5qc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gaW5pdFVJKENHUFQpIHtcbiAgQ0dQVC51aSA9IHt9O1xuICBDR1BULnVpLnBhbmVsSWQgPSBcImNncHQtZm9sZGVyLXBhbmVsLXY5XCI7XG4gIENHUFQudWkubGFzdFNlYXJjaCA9IFwiXCI7XG5cbiAgY29uc3QgSUNPTiA9IHtcbiAgICBhcnJvd0Rvd246IFwiXHUyNUJDXCIsXG4gICAgYXJyb3dSaWdodDogXCJcdTI1QjZcIixcbiAgICBwaW46IFwiXHVEODNEXHVEQ0NDXCIsXG4gICAgZm9sZGVyOiBcIlx1RDgzRFx1RENDMVwiLFxuICAgIGRlbDogXCJcdUQ4M0RcdURERDFcdUZFMEZcIixcbiAgICBzZXR0aW5nczogXCJcdTI2OTlcdUZFMEZcIlxuICB9O1xuXG4gIGxldCBjdXJyZW50TWVudSA9IG51bGw7XG5cbiAgQ0dQVC51aS5jbG9zZUNvbnRleHRNZW51ID0gKCkgPT4ge1xuICAgIGlmIChjdXJyZW50TWVudSkge1xuICAgICAgY3VycmVudE1lbnUucmVtb3ZlKCk7XG4gICAgICBjdXJyZW50TWVudSA9IG51bGw7XG4gICAgfVxuICB9O1xuXG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgIGlmIChjdXJyZW50TWVudSAmJiAhY3VycmVudE1lbnUuY29udGFpbnMoZS50YXJnZXQpKSBDR1BULnVpLmNsb3NlQ29udGV4dE1lbnUoKTtcbiAgfSk7XG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsIChlKSA9PiB7XG4gICAgaWYgKGUua2V5ID09PSBcIkVzY2FwZVwiKSBDR1BULnVpLmNsb3NlQ29udGV4dE1lbnUoKTtcbiAgfSk7XG5cbiAgQ0dQVC51aS5lbnN1cmVQYW5lbCA9ICgpID0+IHtcbiAgICBjb25zdCBzaWRlYmFyID0gZ2V0U2lkZWJhcigpO1xuICAgIGlmICghc2lkZWJhcikgcmV0dXJuIG51bGw7XG5cbiAgICBsZXQgY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoQ0dQVC51aS5wYW5lbElkICsgXCItY29udGFpbmVyXCIpO1xuICAgIGxldCBwYW5lbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKENHUFQudWkucGFuZWxJZCk7XG5cbiAgICBpZiAoIWNvbnRhaW5lcikge1xuICAgICAgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgIGNvbnRhaW5lci5pZCA9IENHUFQudWkucGFuZWxJZCArIFwiLWNvbnRhaW5lclwiO1xuICAgICAgY29udGFpbmVyLnNldEF0dHJpYnV0ZShcImRhdGEtY2dwdC1pbmplY3RlZFwiLCBcInRydWVcIik7XG4gICAgICBPYmplY3QuYXNzaWduKGNvbnRhaW5lci5zdHlsZSwge1xuICAgICAgICBtYXJnaW46IFwiOHB4XCIsXG4gICAgICAgIGJvcmRlclJhZGl1czogXCI4cHhcIixcbiAgICAgICAgYmFja2dyb3VuZDogQ0dQVC50aGVtZS5CRyxcbiAgICAgICAgYm9yZGVyOiBgMXB4IHNvbGlkICR7Q0dQVC50aGVtZS5GR19NVVRFRH1gLFxuICAgICAgICBib3hTaXppbmc6IFwiYm9yZGVyLWJveFwiLFxuICAgICAgICB3aWR0aDogXCJjYWxjKDEwMCUgLSAxNnB4KVwiLFxuICAgICAgICBtaW5IZWlnaHQ6IFwiMjAwcHhcIixcbiAgICAgICAgaGVpZ2h0OiBcIjIwMHB4XCIsXG4gICAgICAgIGRpc3BsYXk6IFwiZmxleFwiLFxuICAgICAgICBmbGV4RGlyZWN0aW9uOiBcImNvbHVtblwiLFxuICAgICAgICBhbGlnbkl0ZW1zOiBcInN0cmV0Y2hcIixcbiAgICAgICAgb3ZlcmZsb3c6IFwiaGlkZGVuXCIsXG4gICAgICAgIGZsZXhTaHJpbms6IFwiMFwiXG4gICAgICB9KTtcblxuICAgICAgcGFuZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgcGFuZWwuaWQgPSBDR1BULnVpLnBhbmVsSWQ7XG4gICAgICBPYmplY3QuYXNzaWduKHBhbmVsLnN0eWxlLCB7XG4gICAgICAgIHBhZGRpbmc6IFwiMTJweCA4cHggOHB4IDhweFwiLFxuICAgICAgICBib3hTaXppbmc6IFwiYm9yZGVyLWJveFwiLFxuICAgICAgICBvdmVyZmxvdzogXCJhdXRvXCIsXG4gICAgICAgIGZsZXg6IFwiMSAxIGF1dG9cIixcbiAgICAgICAgbWluSGVpZ2h0OiBcIjBcIixcbiAgICAgICAgd2lkdGg6IFwiMTAwJVwiXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVzaXplSGFuZGxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgIHJlc2l6ZUhhbmRsZS5zZXRBdHRyaWJ1dGUoXCJkYXRhLXJlc2l6ZS1oYW5kbGVcIiwgXCJ0cnVlXCIpO1xuICAgICAgT2JqZWN0LmFzc2lnbihyZXNpemVIYW5kbGUuc3R5bGUsIHtcbiAgICAgICAgaGVpZ2h0OiBcIjhweFwiLFxuICAgICAgICBmbGV4OiBcIjAgMCA4cHhcIixcbiAgICAgICAgY3Vyc29yOiBcIm5zLXJlc2l6ZVwiLFxuICAgICAgICBiYWNrZ3JvdW5kOiBgbGluZWFyLWdyYWRpZW50KHRvIGJvdHRvbSwgdHJhbnNwYXJlbnQsICR7Q0dQVC50aGVtZS5GR19NVVRFRH00NClgLFxuICAgICAgICBib3JkZXJSYWRpdXM6IFwiMCAwIDhweCA4cHhcIixcbiAgICAgICAgYWxpZ25TZWxmOiBcInN0cmV0Y2hcIlxuICAgICAgfSk7XG5cbiAgICAgIHJlc2l6ZUhhbmRsZS5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsIChlKSA9PiB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgY29uc3QgY29udGFpbmVyRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChDR1BULnVpLnBhbmVsSWQgKyBcIi1jb250YWluZXJcIik7XG4gICAgICAgIGlmICghY29udGFpbmVyRWwpIHJldHVybjtcblxuICAgICAgICBsZXQgc3RhcnRZID0gZS5jbGllbnRZO1xuICAgICAgICBsZXQgc3RhcnRIZWlnaHQgPSBjb250YWluZXJFbC5vZmZzZXRIZWlnaHQ7XG4gICAgICAgIHJlc2l6ZUhhbmRsZS5zdHlsZS5iYWNrZ3JvdW5kID0gYGxpbmVhci1ncmFkaWVudCh0byBib3R0b20sIHRyYW5zcGFyZW50LCAke0NHUFQudGhlbWUuRkdfTVVURUR9ODgpYDtcblxuICAgICAgICBjb25zdCBvbk1vdmUgPSAoZXYpID0+IHtcbiAgICAgICAgICBjb25zdCBkZWx0YSA9IGV2LmNsaWVudFkgLSBzdGFydFk7XG4gICAgICAgICAgY29uc3QgbmV3SGVpZ2h0ID0gTWF0aC5tYXgoMTUwLCBNYXRoLm1pbihzdGFydEhlaWdodCArIGRlbHRhLCB3aW5kb3cuaW5uZXJIZWlnaHQgLSA4MCkpO1xuICAgICAgICAgIGNvbnRhaW5lckVsLnN0eWxlLmhlaWdodCA9IG5ld0hlaWdodCArIFwicHhcIjtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgb25VcCA9ICgpID0+IHtcbiAgICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsIG9uTW92ZSk7XG4gICAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgb25VcCk7XG4gICAgICAgICAgcmVzaXplSGFuZGxlLnN0eWxlLmJhY2tncm91bmQgPSBgbGluZWFyLWdyYWRpZW50KHRvIGJvdHRvbSwgdHJhbnNwYXJlbnQsICR7Q0dQVC50aGVtZS5GR19NVVRFRH00NClgO1xuICAgICAgICB9O1xuXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgb25Nb3ZlKTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgb25VcCk7XG4gICAgICB9KTtcblxuICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKHBhbmVsKTtcbiAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChyZXNpemVIYW5kbGUpO1xuXG4gICAgICBpZiAoc2lkZWJhci5maXJzdENoaWxkKSBzaWRlYmFyLmluc2VydEJlZm9yZShjb250YWluZXIsIHNpZGViYXIuZmlyc3RDaGlsZCk7XG4gICAgICBlbHNlIHNpZGViYXIuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGFpbmVyLnNldEF0dHJpYnV0ZShcImRhdGEtY2dwdC1pbmplY3RlZFwiLCBcInRydWVcIik7XG4gICAgICBpZiAoIXBhbmVsKSB7XG4gICAgICAgIHBhbmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgcGFuZWwuaWQgPSBDR1BULnVpLnBhbmVsSWQ7XG4gICAgICAgIE9iamVjdC5hc3NpZ24ocGFuZWwuc3R5bGUsIHtcbiAgICAgICAgICBwYWRkaW5nOiBcIjEycHggOHB4IDhweCA4cHhcIixcbiAgICAgICAgICBib3hTaXppbmc6IFwiYm9yZGVyLWJveFwiLFxuICAgICAgICAgIG92ZXJmbG93OiBcImF1dG9cIixcbiAgICAgICAgICBmbGV4OiBcIjEgMSBhdXRvXCIsXG4gICAgICAgICAgbWluSGVpZ2h0OiBcIjBcIixcbiAgICAgICAgICB3aWR0aDogXCIxMDAlXCJcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnRhaW5lci5pbnNlcnRCZWZvcmUocGFuZWwsIGNvbnRhaW5lci5maXJzdENoaWxkIHx8IG51bGwpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChDR1BULnVpLnBhbmVsSWQpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIGRlYnVnTGluZSgpIHtcbiAgICBpZiAoIUNHUFQuZGVidWcpIHJldHVybiBudWxsO1xuXG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBzaW5jZVNjYW4gPSBDR1BULmRpYWcubGFzdFNjYW5BdCA/IChub3cgLSBDR1BULmRpYWcubGFzdFNjYW5BdCkgOiBudWxsO1xuICAgIGNvbnN0IHNpbmNlUmVuZGVyID0gQ0dQVC5kaWFnLmxhc3RSZW5kZXJBdCA/IChub3cgLSBDR1BULmRpYWcubGFzdFJlbmRlckF0KSA6IG51bGw7XG5cbiAgICBjb25zdCBsaW5lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBsaW5lLnRleHRDb250ZW50ID1cbiAgICAgIGBEQkcgc2NhbnM6JHtDR1BULmRpYWcuc2NhbnN9IChsYXN0ICR7Q0dQVC5kaWFnLmxhc3RTY2FuRHVyYXRpb25Nc31tcywgY2hhdHMgJHtDR1BULmRpYWcuY2hhdHNGb3VuZExhc3RTY2FufSR7c2luY2VTY2FuICE9PSBudWxsID8gXCIsIFwiICsgc2luY2VTY2FuICsgXCJtcyBhZ29cIiA6IFwiXCJ9KSAgYCArXG4gICAgICBgcmVuZGVyczoke0NHUFQuZGlhZy5yZW5kZXJzfSAobGFzdCAke0NHUFQuZGlhZy5sYXN0UmVuZGVyRHVyYXRpb25Nc31tcyR7c2luY2VSZW5kZXIgIT09IG51bGwgPyBcIiwgXCIgKyBzaW5jZVJlbmRlciArIFwibXMgYWdvXCIgOiBcIlwifSlgO1xuICAgIE9iamVjdC5hc3NpZ24obGluZS5zdHlsZSwge1xuICAgICAgbWFyZ2luVG9wOiBcIjZweFwiLFxuICAgICAgZm9udFNpemU6IFwiMTFweFwiLFxuICAgICAgY29sb3I6IENHUFQudGhlbWUuRkdfTVVURUQsXG4gICAgICB3aGl0ZVNwYWNlOiBcIm5vd3JhcFwiLFxuICAgICAgb3ZlcmZsb3c6IFwiaGlkZGVuXCIsXG4gICAgICB0ZXh0T3ZlcmZsb3c6IFwiZWxsaXBzaXNcIlxuICAgIH0pO1xuICAgIHJldHVybiBsaW5lO1xuICB9XG5cbiAgQ0dQVC51aS5yZW5kZXIgPSAoKSA9PiB7XG4gICAgY29uc3Qgc3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICBjb25zdCBwYW5lbCA9IENHUFQudWkuZW5zdXJlUGFuZWwoKTtcbiAgICBpZiAoIXBhbmVsKSByZXR1cm47XG5cbiAgICBwYW5lbC5pbm5lckhUTUwgPSBcIlwiO1xuXG4gICAgLy8gVG9wYmFyXG4gICAgY29uc3QgdG9wQmFyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBPYmplY3QuYXNzaWduKHRvcEJhci5zdHlsZSwgeyBkaXNwbGF5OiBcImZsZXhcIiwgZ2FwOiBcIjZweFwiLCBtYXJnaW5Cb3R0b206IFwiOHB4XCIsIGFsaWduSXRlbXM6IFwiY2VudGVyXCIgfSk7XG5cbiAgICBjb25zdCBzZWFyY2ggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG4gICAgc2VhcmNoLnBsYWNlaG9sZGVyID0gQ0dQVC5MLnNlYXJjaDtcbiAgICBzZWFyY2gudmFsdWUgPSBDR1BULnVpLmxhc3RTZWFyY2ggfHwgXCJcIjtcbiAgICBPYmplY3QuYXNzaWduKHNlYXJjaC5zdHlsZSwge1xuICAgICAgZmxleDogXCIxXCIsXG4gICAgICBwYWRkaW5nOiBcIjZweCA4cHhcIixcbiAgICAgIGJvcmRlcjogYDFweCBzb2xpZCAke0NHUFQudGhlbWUuRkdfTVVURUR9YCxcbiAgICAgIGJvcmRlclJhZGl1czogXCI2cHhcIixcbiAgICAgIGJhY2tncm91bmQ6IENHUFQudGhlbWUuZGFyayA/IFwiIzMzM1wiIDogXCIjZmZmXCIsXG4gICAgICBjb2xvcjogQ0dQVC50aGVtZS5GRyxcbiAgICAgIGJveFNpemluZzogXCJib3JkZXItYm94XCIsXG4gICAgICBtaW5XaWR0aDogXCIwXCJcbiAgICB9KTtcblxuICAgIGNvbnN0IGFwcGx5U2VhcmNoID0gZGVib3VuY2UoKCkgPT4ge1xuICAgICAgQ0dQVC51aS5sYXN0U2VhcmNoID0gc2VhcmNoLnZhbHVlO1xuICAgICAgQ0dQVC51aS5yZW5kZXIoKTtcbiAgICB9LCAyMDApO1xuXG4gICAgc2VhcmNoLmFkZEV2ZW50TGlzdGVuZXIoXCJpbnB1dFwiLCBhcHBseVNlYXJjaCk7XG5cbiAgICBjb25zdCBzZXR0aW5nc0J0biA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJidXR0b25cIik7XG4gICAgc2V0dGluZ3NCdG4udGV4dENvbnRlbnQgPSBJQ09OLnNldHRpbmdzO1xuICAgIHNldHRpbmdzQnRuLnRpdGxlID0gQ0dQVC5MLnNldHRpbmdzO1xuICAgIE9iamVjdC5hc3NpZ24oc2V0dGluZ3NCdG4uc3R5bGUsIHtcbiAgICAgIHBhZGRpbmc6IFwiNnB4IDEwcHhcIixcbiAgICAgIGJhY2tncm91bmQ6IENHUFQudGhlbWUuQlROX0JHLFxuICAgICAgYm9yZGVyOiBgMXB4IHNvbGlkICR7Q0dQVC50aGVtZS5GR19NVVRFRH1gLFxuICAgICAgYm9yZGVyUmFkaXVzOiBcIjZweFwiLFxuICAgICAgY3Vyc29yOiBcInBvaW50ZXJcIixcbiAgICAgIGNvbG9yOiBDR1BULnRoZW1lLkZHLFxuICAgICAgZmxleFNocmluazogXCIwXCIsXG4gICAgICBtaW5XaWR0aDogXCI0MHB4XCJcbiAgICB9KTtcbiAgICBzZXR0aW5nc0J0bi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBDR1BULnVpLnNob3dTZXR0aW5ncygpO1xuICAgIH0pO1xuXG4gICAgdG9wQmFyLmFwcGVuZENoaWxkKHNlYXJjaCk7XG4gICAgdG9wQmFyLmFwcGVuZENoaWxkKHNldHRpbmdzQnRuKTtcbiAgICBwYW5lbC5hcHBlbmRDaGlsZCh0b3BCYXIpO1xuXG4gICAgY29uc3QgZGJnID0gZGVidWdMaW5lKCk7XG4gICAgaWYgKGRiZykgcGFuZWwuYXBwZW5kQ2hpbGQoZGJnKTtcblxuICAgIGNvbnN0IHF1ZXJ5ID0gKHNlYXJjaC52YWx1ZSB8fCBcIlwiKS50b0xvd2VyQ2FzZSgpLnRyaW0oKTtcbiAgICBjb25zdCB0cmVlID0gQ0dQVC5mb2xkZXJzLmdldFRyZWUoKTtcbiAgICB0cmVlLmZvckVhY2goKG5vZGUpID0+IENHUFQudWkucmVuZGVyRm9sZGVyTm9kZShwYW5lbCwgbm9kZSwgcXVlcnkpKTtcblxuICAgIGNvbnN0IGFkZEJ0biA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJidXR0b25cIik7XG4gICAgYWRkQnRuLnRleHRDb250ZW50ID0gYFx1RkYwQiAke0NHUFQuTC5uZXdGb2xkZXJ9YDtcbiAgICBPYmplY3QuYXNzaWduKGFkZEJ0bi5zdHlsZSwge1xuICAgICAgd2lkdGg6IFwiMTAwJVwiLFxuICAgICAgbWFyZ2luVG9wOiBcIjEycHhcIixcbiAgICAgIHBhZGRpbmc6IFwiOHB4XCIsXG4gICAgICBiYWNrZ3JvdW5kOiBDR1BULnRoZW1lLkJUTl9CRyxcbiAgICAgIGJvcmRlcjogYDFweCBzb2xpZCAke0NHUFQudGhlbWUuRkdfTVVURUR9YCxcbiAgICAgIGJvcmRlclJhZGl1czogXCI2cHhcIixcbiAgICAgIGN1cnNvcjogXCJwb2ludGVyXCIsXG4gICAgICBjb2xvcjogQ0dQVC50aGVtZS5GRyxcbiAgICAgIGZvbnRXZWlnaHQ6IFwiNTAwXCJcbiAgICB9KTtcbiAgICBhZGRCdG4uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IG5hbWUgPSBwcm9tcHQoQ0dQVC5MLm5ld0ZvbGRlcikgfHwgXCJcIjtcbiAgICAgIGlmICghbmFtZS50cmltKCkpIHJldHVybjtcbiAgICAgIENHUFQuZm9sZGVycy5jcmVhdGUobmFtZS50cmltKCkpO1xuICAgIH0pO1xuXG4gICAgcGFuZWwuYXBwZW5kQ2hpbGQoYWRkQnRuKTtcblxuICAgIC8vIERpYWdcbiAgICBDR1BULmRpYWcucmVuZGVycyArPSAxO1xuICAgIENHUFQuZGlhZy5sYXN0UmVuZGVyQXQgPSBEYXRlLm5vdygpO1xuICAgIENHUFQuZGlhZy5sYXN0UmVuZGVyRHVyYXRpb25NcyA9IE1hdGgucm91bmQocGVyZm9ybWFuY2Uubm93KCkgLSBzdGFydCk7XG4gIH07XG5cbiAgQ0dQVC51aS5yZW5kZXJGb2xkZXJOb2RlID0gKHBhbmVsLCBub2RlLCBxdWVyeSkgPT4ge1xuICAgIGNvbnN0IHsgZm9sZGVyLCBsZXZlbCwgY2hpbGRyZW4gfSA9IG5vZGU7XG5cbiAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIE9iamVjdC5hc3NpZ24oY29udGFpbmVyLnN0eWxlLCB7IHBhZGRpbmdMZWZ0OiBgJHtsZXZlbCAqIDE0fXB4YCwgbWFyZ2luQm90dG9tOiBcIjRweFwiLCBtYXhXaWR0aDogXCIxMDAlXCIsIGJveFNpemluZzogXCJib3JkZXItYm94XCIgfSk7XG5cbiAgICBjb25zdCBoZWFkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBPYmplY3QuYXNzaWduKGhlYWQuc3R5bGUsIHtcbiAgICAgIGRpc3BsYXk6IFwiZmxleFwiLFxuICAgICAgYWxpZ25JdGVtczogXCJjZW50ZXJcIixcbiAgICAgIGdhcDogXCI2cHhcIixcbiAgICAgIGN1cnNvcjogXCJwb2ludGVyXCIsXG4gICAgICBwYWRkaW5nOiBcIjZweCA4cHhcIixcbiAgICAgIGJvcmRlclJhZGl1czogXCI2cHhcIixcbiAgICAgIGJhY2tncm91bmQ6IGZvbGRlci5jb2xvciA/IGAke2ZvbGRlci5jb2xvcn0yMmAgOiBcInJnYmEoMjU1LDI1NSwyNTUsMC4wNSlcIixcbiAgICAgIG1heFdpZHRoOiBcIjEwMCVcIixcbiAgICAgIG92ZXJmbG93OiBcImhpZGRlblwiXG4gICAgfSk7XG5cbiAgICBoZWFkLmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW92ZXJcIiwgKCkgPT4geyBoZWFkLnN0eWxlLmJhY2tncm91bmQgPSBmb2xkZXIuY29sb3IgPyBgJHtmb2xkZXIuY29sb3J9NDRgIDogXCJyZ2JhKDI1NSwyNTUsMjU1LDAuMSlcIjsgfSk7XG4gICAgaGVhZC5hZGRFdmVudExpc3RlbmVyKFwibW91c2VvdXRcIiwgKCkgPT4geyBoZWFkLnN0eWxlLmJhY2tncm91bmQgPSBmb2xkZXIuY29sb3IgPyBgJHtmb2xkZXIuY29sb3J9MjJgIDogXCJyZ2JhKDI1NSwyNTUsMjU1LDAuMDUpXCI7IH0pO1xuXG4gICAgY29uc3QgYXJyb3cgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcbiAgICBhcnJvdy50ZXh0Q29udGVudCA9IGZvbGRlci5leHBhbmRlZCA/IElDT04uYXJyb3dEb3duIDogSUNPTi5hcnJvd1JpZ2h0O1xuICAgIE9iamVjdC5hc3NpZ24oYXJyb3cuc3R5bGUsIHsgd2lkdGg6IFwiMTZweFwiLCBjb2xvcjogQ0dQVC50aGVtZS5GR19NVVRFRCwgZm9udFNpemU6IFwiMTBweFwiIH0pO1xuXG4gICAgY29uc3QgaWNvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO1xuICAgIGljb24udGV4dENvbnRlbnQgPSBmb2xkZXIuaWNvbiB8fCBJQ09OLmZvbGRlcjtcbiAgICBpY29uLnN0eWxlLmZvbnRTaXplID0gXCIxNnB4XCI7XG5cbiAgICBpZiAoZm9sZGVyLnBpbm5lZCkge1xuICAgICAgY29uc3QgcGluSWNvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO1xuICAgICAgcGluSWNvbi50ZXh0Q29udGVudCA9IElDT04ucGluO1xuICAgICAgT2JqZWN0LmFzc2lnbihwaW5JY29uLnN0eWxlLCB7IGZvbnRTaXplOiBcIjEwcHhcIiwgY29sb3I6IFwiI2Y1OWUwYlwiIH0pO1xuICAgICAgaGVhZC5hcHBlbmRDaGlsZChwaW5JY29uKTtcbiAgICB9XG5cbiAgICBjb25zdCB0aXRsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO1xuICAgIHRpdGxlLnRleHRDb250ZW50ID0gZm9sZGVyLm5hbWU7XG4gICAgT2JqZWN0LmFzc2lnbih0aXRsZS5zdHlsZSwge1xuICAgICAgZmxleDogXCIxXCIsXG4gICAgICBjb2xvcjogQ0dQVC50aGVtZS5GRyxcbiAgICAgIGZvbnRTaXplOiBcIjE0cHhcIixcbiAgICAgIGZvbnRXZWlnaHQ6IFwiNTAwXCIsXG4gICAgICBvdmVyZmxvdzogXCJoaWRkZW5cIixcbiAgICAgIHRleHRPdmVyZmxvdzogXCJlbGxpcHNpc1wiLFxuICAgICAgd2hpdGVTcGFjZTogXCJub3dyYXBcIixcbiAgICAgIG1pbldpZHRoOiBcIjBcIlxuICAgIH0pO1xuXG4gICAgaGVhZC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKCkgPT4ge1xuICAgICAgZm9sZGVyLmV4cGFuZGVkID0gIWZvbGRlci5leHBhbmRlZDtcbiAgICAgIENHUFQuc2F2ZUZvbGRlcnMoKTtcbiAgICAgIENHUFQudWkucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICBoZWFkLmFkZEV2ZW50TGlzdGVuZXIoXCJjb250ZXh0bWVudVwiLCAoZSkgPT4ge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgQ0dQVC51aS5vcGVuRm9sZGVyQ29udGV4dE1lbnUoZS5wYWdlWCwgZS5wYWdlWSwgZm9sZGVyKTtcbiAgICB9KTtcblxuICAgIGhlYWQuYXBwZW5kQ2hpbGQoYXJyb3cpO1xuICAgIGhlYWQuYXBwZW5kQ2hpbGQoaWNvbik7XG4gICAgaGVhZC5hcHBlbmRDaGlsZCh0aXRsZSk7XG5cbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoaGVhZCk7XG5cbiAgICBpZiAoZm9sZGVyLmV4cGFuZGVkKSB7XG4gICAgICBjb25zdCBjaGF0cyA9IE9iamVjdC52YWx1ZXMoQ0dQVC5jaGF0cy5tYXApLmZpbHRlcihcbiAgICAgICAgKGMpID0+IChDR1BULnN0YXRlLmFzc2lnbltjLmlkXSB8fCBcInVuY2F0ZWdvcml6ZWRcIikgPT09IGZvbGRlci5pZFxuICAgICAgKTtcblxuICAgICAgY2hhdHMuZm9yRWFjaCgoYykgPT4ge1xuICAgICAgICBpZiAocXVlcnkgJiYgIWMudGl0bGUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhxdWVyeSkpIHJldHVybjtcbiAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKENHUFQudWkucmVuZGVyQ2hhdEl0ZW0oYywgbGV2ZWwpKTtcbiAgICAgIH0pO1xuXG4gICAgICBjaGlsZHJlbi5mb3JFYWNoKChjaGlsZCkgPT4gQ0dQVC51aS5yZW5kZXJGb2xkZXJOb2RlKHBhbmVsLCBjaGlsZCwgcXVlcnkpKTtcbiAgICB9XG5cbiAgICBwYW5lbC5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuICB9O1xuXG4gIENHUFQudWkucmVuZGVyQ2hhdEl0ZW0gPSAoY2hhdCwgbGV2ZWwpID0+IHtcbiAgICBjb25zdCB3cmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBPYmplY3QuYXNzaWduKHdyYXBwZXIuc3R5bGUsIHsgcGFkZGluZ0xlZnQ6IGAkeyhsZXZlbCArIDEpICogMTR9cHhgLCBtYXhXaWR0aDogXCIxMDAlXCIsIGJveFNpemluZzogXCJib3JkZXItYm94XCIgfSk7XG5cbiAgICBjb25zdCByb3cgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIE9iamVjdC5hc3NpZ24ocm93LnN0eWxlLCB7IHBhZGRpbmc6IFwiNHB4IDhweFwiLCBib3JkZXJSYWRpdXM6IFwiNHB4XCIsIGN1cnNvcjogXCJwb2ludGVyXCIsIG92ZXJmbG93OiBcImhpZGRlblwiLCBib3hTaXppbmc6IFwiYm9yZGVyLWJveFwiIH0pO1xuICAgIHJvdy5hZGRFdmVudExpc3RlbmVyKFwibW91c2VvdmVyXCIsICgpID0+IHJvdy5zdHlsZS5iYWNrZ3JvdW5kID0gQ0dQVC50aGVtZS5CR19IT1ZFUik7XG4gICAgcm93LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW91dFwiLCAoKSA9PiByb3cuc3R5bGUuYmFja2dyb3VuZCA9IFwiXCIpO1xuXG4gICAgY29uc3QgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhXCIpO1xuICAgIGxpbmsudGV4dENvbnRlbnQgPSBjaGF0LnRpdGxlO1xuICAgIGxpbmsuaHJlZiA9IGNoYXQuaHJlZjtcbiAgICBPYmplY3QuYXNzaWduKGxpbmsuc3R5bGUsIHtcbiAgICAgIGNvbG9yOiBDR1BULnRoZW1lLkZHLFxuICAgICAgdGV4dERlY29yYXRpb246IFwibm9uZVwiLFxuICAgICAgZm9udFNpemU6IFwiMTNweFwiLFxuICAgICAgb3ZlcmZsb3c6IFwiaGlkZGVuXCIsXG4gICAgICB0ZXh0T3ZlcmZsb3c6IFwiZWxsaXBzaXNcIixcbiAgICAgIHdoaXRlU3BhY2U6IFwibm93cmFwXCIsXG4gICAgICBkaXNwbGF5OiBcImJsb2NrXCIsXG4gICAgICBtYXhXaWR0aDogXCIxMDAlXCJcbiAgICB9KTtcblxuICAgIHJvdy5hcHBlbmRDaGlsZChsaW5rKTtcbiAgICB3cmFwcGVyLmFwcGVuZENoaWxkKHJvdyk7XG4gICAgcmV0dXJuIHdyYXBwZXI7XG4gIH07XG5cbiAgQ0dQVC51aS5vcGVuRm9sZGVyQ29udGV4dE1lbnUgPSAoeCwgeSwgZm9sZGVyKSA9PiB7XG4gICAgQ0dQVC51aS5jbG9zZUNvbnRleHRNZW51KCk7XG4gICAgY29uc3QgbWVudSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgY3VycmVudE1lbnUgPSBtZW51O1xuXG4gICAgT2JqZWN0LmFzc2lnbihtZW51LnN0eWxlLCB7XG4gICAgICBwb3NpdGlvbjogXCJmaXhlZFwiLFxuICAgICAgbGVmdDogeCArIFwicHhcIixcbiAgICAgIHRvcDogeSArIFwicHhcIixcbiAgICAgIGJhY2tncm91bmQ6IENHUFQudGhlbWUuQkcsXG4gICAgICBjb2xvcjogQ0dQVC50aGVtZS5GRyxcbiAgICAgIGJvcmRlcjogYDFweCBzb2xpZCAke0NHUFQudGhlbWUuRkdfTVVURUR9YCxcbiAgICAgIGJvcmRlclJhZGl1czogXCI4cHhcIixcbiAgICAgIHBhZGRpbmc6IFwiNnB4XCIsXG4gICAgICB6SW5kZXg6IDk5OTksXG4gICAgICBtaW5XaWR0aDogXCIyMDBweFwiLFxuICAgICAgYm94U2hhZG93OiBcIjAgNHB4IDEycHggcmdiYSgwLDAsMCwwLjUpXCJcbiAgICB9KTtcblxuICAgIGNvbnN0IGFkZEl0ZW0gPSAobGFiZWwsIGhhbmRsZXIpID0+IHtcbiAgICAgIGNvbnN0IGIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYnV0dG9uXCIpO1xuICAgICAgYi50ZXh0Q29udGVudCA9IGxhYmVsO1xuICAgICAgT2JqZWN0LmFzc2lnbihiLnN0eWxlLCB7XG4gICAgICAgIHdpZHRoOiBcIjEwMCVcIixcbiAgICAgICAgZGlzcGxheTogXCJibG9ja1wiLFxuICAgICAgICBwYWRkaW5nOiBcIjhweCAxMnB4XCIsXG4gICAgICAgIGJhY2tncm91bmQ6IENHUFQudGhlbWUuQlROX0JHLFxuICAgICAgICBib3JkZXI6IFwibm9uZVwiLFxuICAgICAgICBib3JkZXJSYWRpdXM6IFwiNHB4XCIsXG4gICAgICAgIGNvbG9yOiBDR1BULnRoZW1lLkZHLFxuICAgICAgICBjdXJzb3I6IFwicG9pbnRlclwiLFxuICAgICAgICBtYXJnaW46IFwiNHB4IDBcIixcbiAgICAgICAgdGV4dEFsaWduOiBcImxlZnRcIlxuICAgICAgfSk7XG4gICAgICBiLmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW92ZXJcIiwgKCkgPT4gYi5zdHlsZS5iYWNrZ3JvdW5kID0gQ0dQVC50aGVtZS5CR19IT1ZFUik7XG4gICAgICBiLmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW91dFwiLCAoKSA9PiBiLnN0eWxlLmJhY2tncm91bmQgPSBDR1BULnRoZW1lLkJUTl9CRyk7XG4gICAgICBiLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoKSA9PiB7IGhhbmRsZXIoKTsgQ0dQVC51aS5jbG9zZUNvbnRleHRNZW51KCk7IH0pO1xuICAgICAgbWVudS5hcHBlbmRDaGlsZChiKTtcbiAgICB9O1xuXG4gICAgYWRkSXRlbShDR1BULkwucmVuYW1lLCAoKSA9PiB7XG4gICAgICBjb25zdCBuYW1lID0gcHJvbXB0KENHUFQuTC5yZW5hbWUsIGZvbGRlci5uYW1lKTtcbiAgICAgIGlmIChuYW1lICYmIG5hbWUudHJpbSgpKSBDR1BULmZvbGRlcnMucmVuYW1lKGZvbGRlci5pZCwgbmFtZS50cmltKCkpO1xuICAgIH0pO1xuXG4gICAgaWYgKGZvbGRlci5pZCAhPT0gXCJ1bmNhdGVnb3JpemVkXCIpIHtcbiAgICAgIGFkZEl0ZW0oQ0dQVC5MLmRlbGV0ZSwgKCkgPT4ge1xuICAgICAgICBpZiAoIWNvbmZpcm0oQ0dQVC5MLmNvbmZpcm1EZWxldGUoZm9sZGVyLm5hbWUpKSkgcmV0dXJuO1xuICAgICAgICBDR1BULmZvbGRlcnMuZGVsZXRlKGZvbGRlci5pZCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBhZGRJdGVtKENHUFQuTC5waW5uZWQsICgpID0+IENHUFQuZm9sZGVycy50b2dnbGVQaW4oZm9sZGVyLmlkKSk7XG4gICAgYWRkSXRlbShDR1BULkwuaWNvbiwgKCkgPT4ge1xuICAgICAgY29uc3QgaWMgPSBwcm9tcHQoQ0dQVC5MLmljb24sIGZvbGRlci5pY29uIHx8IFwiXCIpO1xuICAgICAgaWYgKGljICE9PSBudWxsKSBDR1BULmZvbGRlcnMuc2V0SWNvbihmb2xkZXIuaWQsIGljKTtcbiAgICB9KTtcblxuICAgIGFkZEl0ZW0oQ0dQVC5MLmNvbG9yLCAoKSA9PiBDR1BULnVpLnNob3dDb2xvclBpY2tlcihmb2xkZXIuaWQsIGZvbGRlci5jb2xvciB8fCBcIiM2NmFhZmZcIikpO1xuXG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChtZW51KTtcbiAgfTtcblxuICBDR1BULnVpLnNob3dDb2xvclBpY2tlciA9IChmb2xkZXJJZCwgY3VycmVudENvbG9yKSA9PiB7XG4gICAgY29uc3QgcGlja2VkID0gcHJvbXB0KFwiQ29sb3IgKGhleClcIiwgY3VycmVudENvbG9yIHx8IFwiIzY2YWFmZlwiKTtcbiAgICBpZiAoIXBpY2tlZCkgcmV0dXJuO1xuICAgIENHUFQuZm9sZGVycy5zZXRDb2xvcihmb2xkZXJJZCwgcGlja2VkLnRyaW0oKSk7XG4gIH07XG5cbiAgQ0dQVC51aS5zaG93U2V0dGluZ3MgPSAoKSA9PiB7XG4gICAgY29uc3QgYXV0b3N1Z2dlc3QgPSBjb25maXJtKGAke0NHUFQuTC5hdXRvc3VnZ2VzdH1cXG5cXG5PSyA9IE9OLCBDYW5jZWwgPSBPRkZgKTtcbiAgICBDR1BULnN0YXRlLnNldHRpbmdzLmF1dG9zdWdnZXN0ID0gYXV0b3N1Z2dlc3Q7XG5cbiAgICBjb25zdCBhdXRvc29ydCA9IGNvbmZpcm0oYCR7Q0dQVC5MLmF1dG9zb3J0fVxcblxcbk9LID0gT04sIENhbmNlbCA9IE9GRmApO1xuICAgIENHUFQuc3RhdGUuc2V0dGluZ3MuYXV0b3NvcnQgPSBhdXRvc29ydDtcblxuICAgIGNvbnN0IGNsb3VkVGl0bGVzID0gY29uZmlybShgJHtDR1BULkwuY2xvdWRUaXRsZXN9XFxuXFxuT0sgPSBPTiwgQ2FuY2VsID0gT0ZGYCk7XG4gICAgQ0dQVC5zdGF0ZS5zZXR0aW5ncy5jbG91ZFRpdGxlcyA9IGNsb3VkVGl0bGVzO1xuXG4gICAgQ0dQVC5zYXZlU2V0dGluZ3MoKTtcbiAgICBDR1BULnVpLnJlbmRlcigpO1xuICB9O1xuXG4gIC8vIEF1dG8tcmVuZGVyIG9uIGNoYW5nZXMgKGRlYm91bmNlZClcbiAgY29uc3QgZGVib3VuY2VkUmVuZGVyID0gZGVib3VuY2UoKCkgPT4gQ0dQVC51aS5yZW5kZXIoKSwgMTAwKTtcbiAgQ0dQVC5vbihcImNoYXRzLXVwZGF0ZWRcIiwgZGVib3VuY2VkUmVuZGVyKTtcbiAgQ0dQVC5vbihcImZvbGRlcnMtdXBkYXRlZFwiLCBkZWJvdW5jZWRSZW5kZXIpO1xuICBDR1BULm9uKFwiYXNzaWduLXVwZGF0ZWRcIiwgZGVib3VuY2VkUmVuZGVyKTtcbiAgQ0dQVC5vbihcInRoZW1lLWNoYW5nZWRcIiwgZGVib3VuY2VkUmVuZGVyKTtcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gaW5pdFN1Z2dlc3QoQ0dQVCkge1xuICBjb25zdCBTVUdHRVNUSU9OX1JVTEVTID0gW1xuICAgIHsgZm9sZGVyOiBcIlx1RDgzRFx1RENCQiBDb2RlXCIsIHdvcmRzOiBbXCJjb2RlXCIsIFwiamF2YXNjcmlwdFwiLCBcInB5dGhvblwiLCBcInJlZ2V4XCIsIFwiYnVnXCIsIFwiZGVidWdcIiwgXCJlcnJvclwiLCBcImZ1bmN0aW9uXCIsIFwiYXBpXCJdIH0sXG4gICAgeyBmb2xkZXI6IFwiXHUyNzA5XHVGRTBGIFdyaXRpbmdcIiwgd29yZHM6IFtcImVtYWlsXCIsIFwibGV0dGVyXCIsIFwidGV4dFwiLCBcIndyaXRlXCIsIFwiZHJhZnRcIiwgXCJlc3NheVwiLCBcImFydGljbGVcIl0gfSxcbiAgICB7IGZvbGRlcjogXCJcdUQ4M0NcdURGRUIgRWR1Y2F0aW9uXCIsIHdvcmRzOiBbXCJzY2hvb2xcIiwgXCJjbGFzc1wiLCBcInN0dWR5XCIsIFwibGVhcm5cIiwgXCJob21ld29ya1wiLCBcImV4YW1cIiwgXCJ1bml2ZXJzaXR5XCJdIH0sXG4gICAgeyBmb2xkZXI6IFwiXHVEODNEXHVEQ0MxIFdvcmtcIiwgd29yZHM6IFtcInByb2plY3RcIiwgXCJtZWV0aW5nXCIsIFwicGxhblwiLCBcInJlc2VhcmNoXCIsIFwicmVwb3J0XCIsIFwiYnVzaW5lc3NcIiwgXCJ0YXNrXCJdIH0sXG4gICAgeyBmb2xkZXI6IFwiXHUyNzY0XHVGRTBGIFBlcnNvbmFsXCIsIHdvcmRzOiBbXCJmYW1pbHlcIiwgXCJoZWFsdGhcIiwgXCJhZHZpY2VcIiwgXCJoZWxwXCIsIFwicGVyc29uYWxcIiwgXCJsaWZlXCJdIH1cbiAgXTtcblxuICBDR1BULnN1Z2dlc3QgPSAodGl0bGUpID0+IHtcbiAgICBjb25zdCB0ID0gKHRpdGxlIHx8IFwiXCIpLnRvTG93ZXJDYXNlKCk7XG4gICAgZm9yIChjb25zdCBydWxlIG9mIFNVR0dFU1RJT05fUlVMRVMpIHtcbiAgICAgIGZvciAoY29uc3QgdyBvZiBydWxlLndvcmRzKSB7XG4gICAgICAgIGlmICh0LmluY2x1ZGVzKHcpKSByZXR1cm4gcnVsZS5mb2xkZXI7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9O1xuXG4gIGNvbnN0IHN0cmlwTGVhZGluZ1N5bWJvbHMgPSAocykgPT4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gcy5yZXBsYWNlKC9eW15cXHB7TH1cXHB7Tn1dKy9ndSwgXCJcIik7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gcy5yZXBsYWNlKC9eW15BLVphLXowLTldKy8sIFwiXCIpO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBub3JtTmFtZSA9IChzKSA9PlxuICAgIHN0cmlwTGVhZGluZ1N5bWJvbHMoKHMgPz8gXCJcIikubm9ybWFsaXplKFwiTkZLQ1wiKSlcbiAgICAgIC50cmltKClcbiAgICAgIC5yZXBsYWNlKC9cXHMrL2csIFwiIFwiKVxuICAgICAgLnRvTG93ZXJDYXNlKCk7XG5cbiAgZnVuY3Rpb24gZmluZEZvbGRlckJ5TmFtZShuYW1lKSB7XG4gICAgY29uc3QgbiA9IG5vcm1OYW1lKG5hbWUpO1xuICAgIGNvbnN0IEYgPSBDR1BULl9mb2xkZXJzLkY7XG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXMoRigpKS5maW5kKChmKSA9PiBub3JtTmFtZShmLm5hbWUpID09PSBuKSB8fCBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gZW5zdXJlRm9sZGVyKG5hbWUpIHtcbiAgICBjb25zdCBjbGVhbiA9IChuYW1lIHx8IFwiXCIpLnRyaW0oKTtcbiAgICBjb25zdCBleGlzdGluZyA9IGZpbmRGb2xkZXJCeU5hbWUoY2xlYW4pO1xuICAgIGlmIChleGlzdGluZykgcmV0dXJuIGV4aXN0aW5nLmlkO1xuICAgIHJldHVybiBDR1BULmZvbGRlcnMuY3JlYXRlKGNsZWFuKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGF1dG9Tb3J0Q2hhdChjaGF0SWQsIGNoYXRUaXRsZSkge1xuICAgIGlmIChDR1BULnN0YXRlLmRpc21pc3NlZFtjaGF0SWRdKSByZXR1cm47XG4gICAgY29uc3Qgc3VnZ2VzdGlvbiA9IENHUFQuc3VnZ2VzdChjaGF0VGl0bGUpO1xuICAgIGlmICghc3VnZ2VzdGlvbikgcmV0dXJuO1xuICAgIGNvbnN0IGZvbGRlcklkID0gZW5zdXJlRm9sZGVyKHN1Z2dlc3Rpb24pO1xuICAgIENHUFQuZm9sZGVycy5hc3NpZ25DaGF0KGNoYXRJZCwgZm9sZGVySWQpO1xuICB9XG5cbiAgZnVuY3Rpb24gY29uZmlybVN1Z2dlc3RDaGF0KGNoYXRJZCwgY2hhdFRpdGxlKSB7XG4gICAgaWYgKENHUFQuc3RhdGUuZGlzbWlzc2VkW2NoYXRJZF0pIHJldHVybjtcbiAgICBjb25zdCBzdWdnZXN0aW9uID0gQ0dQVC5zdWdnZXN0KGNoYXRUaXRsZSk7XG4gICAgaWYgKCFzdWdnZXN0aW9uKSByZXR1cm47XG5cbiAgICBjb25zdCBjbGVhbiA9IHN1Z2dlc3Rpb24udHJpbSgpO1xuICAgIGNvbnN0IHRleHQgPSBgQ2hhdDogXCIke2NoYXRUaXRsZX1cIlxcblxcbiR7Q0dQVC5MLnN1Z2dlc3Rpb259ICR7Y2xlYW59XFxuXFxuQXNzaWduIHRvIHRoaXMgZm9sZGVyP2A7XG5cbiAgICBpZiAoIWNvbmZpcm0odGV4dCkpIHtcbiAgICAgIENHUFQuc3RhdGUuZGlzbWlzc2VkW2NoYXRJZF0gPSBEYXRlLm5vdygpO1xuICAgICAgQ0dQVC5zYXZlRGlzbWlzc2VkKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZm9sZGVySWQgPSBlbnN1cmVGb2xkZXIoY2xlYW4pO1xuICAgIENHUFQuZm9sZGVycy5hc3NpZ25DaGF0KGNoYXRJZCwgZm9sZGVySWQpO1xuICB9XG5cbiAgLy8gT25seSB0b3VjaCAqbmV3KiBjaGF0cyBhZnRlciBpbml0aWFsIGJvb3RzdHJhcCwgdG8gYXZvaWQgXHUyMDFDcHJvbXB0IHN0b3JtXHUyMDFELlxuICBsZXQgYm9vdHN0cmFwcGVkID0gZmFsc2U7XG4gIGNvbnN0IHNlZW5DaGF0SWRzID0gbmV3IFNldChPYmplY3Qua2V5cyhDR1BULnN0YXRlLmFzc2lnbiB8fCB7fSkpO1xuXG4gIENHUFQub24oXCJjaGF0cy11cGRhdGVkXCIsICgpID0+IHtcbiAgICBjb25zdCBhdXRvc29ydCA9ICEhQ0dQVC5zdGF0ZS5zZXR0aW5ncy5hdXRvc29ydDtcbiAgICBjb25zdCBhdXRvc3VnZ2VzdCA9ICEhQ0dQVC5zdGF0ZS5zZXR0aW5ncy5hdXRvc3VnZ2VzdDtcbiAgICBjb25zdCBjaGF0cyA9IE9iamVjdC52YWx1ZXMoQ0dQVC5jaGF0cy5tYXApO1xuXG4gICAgaWYgKCFib290c3RyYXBwZWQpIHtcbiAgICAgIGNoYXRzLmZvckVhY2goKGMpID0+IHNlZW5DaGF0SWRzLmFkZChjLmlkKSk7XG4gICAgICBib290c3RyYXBwZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNoYXRzLmZvckVhY2goKGMpID0+IHtcbiAgICAgIGlmIChzZWVuQ2hhdElkcy5oYXMoYy5pZCkpIHJldHVybjtcbiAgICAgIHNlZW5DaGF0SWRzLmFkZChjLmlkKTtcblxuICAgICAgaWYgKENHUFQuc3RhdGUuYXNzaWduW2MuaWRdKSByZXR1cm47XG5cbiAgICAgIGlmIChhdXRvc29ydCkgYXV0b1NvcnRDaGF0KGMuaWQsIGMudGl0bGUpO1xuICAgICAgZWxzZSBpZiAoYXV0b3N1Z2dlc3QpIGNvbmZpcm1TdWdnZXN0Q2hhdChjLmlkLCBjLnRpdGxlKTtcbiAgICB9KTtcblxuICAgIENHUFQuc2F2ZUFzc2lnbigpO1xuICAgIENHUFQuZW1pdChcImFzc2lnbi11cGRhdGVkXCIsIENHUFQuc3RhdGUuYXNzaWduKTtcbiAgfSk7XG5cbiAgQ0dQVC5zdWdnZXN0LnJlaW5kZXhBbGwgPSAobW9kZSA9IFwiY29uZmlybVwiKSA9PiB7XG4gICAgT2JqZWN0LnZhbHVlcyhDR1BULmNoYXRzLm1hcCkuZm9yRWFjaCgoYykgPT4ge1xuICAgICAgaWYgKG1vZGUgPT09IFwiYXV0b1wiKSBhdXRvU29ydENoYXQoYy5pZCwgYy50aXRsZSk7XG4gICAgICBlbHNlIGNvbmZpcm1TdWdnZXN0Q2hhdChjLmlkLCBjLnRpdGxlKTtcbiAgICB9KTtcbiAgICBDR1BULnNhdmVBc3NpZ24oKTtcbiAgICBDR1BULmVtaXQoXCJhc3NpZ24tdXBkYXRlZFwiLCBDR1BULnN0YXRlLmFzc2lnbik7XG4gIH07XG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGluaXRTeW5jKENHUFQpIHtcbiAgQ0dQVC5zeW5jID0ge307XG5cbiAgQ0dQVC5zeW5jLmV4cG9ydCA9ICgpID0+ICh7XG4gICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgIHZlcnNpb246IF9fQ0dQVF9WRVJTSU9OX18sXG4gICAgbG9jYWxlOiBDR1BULmxvY2FsZSxcbiAgICBkYXRhOiB7XG4gICAgICBmb2xkZXJzOiBDR1BULnN0YXRlLmZvbGRlcnMsXG4gICAgICBhc3NpZ246IENHUFQuc3RhdGUuYXNzaWduLFxuICAgICAgc2V0dGluZ3M6IENHUFQuc3RhdGUuc2V0dGluZ3MsXG4gICAgICBkaXNtaXNzZWQ6IENHUFQuc3RhdGUuZGlzbWlzc2VkXG4gICAgfVxuICB9KTtcblxuICBDR1BULnN5bmMuaW1wb3J0ID0gKHBheWxvYWQpID0+IHtcbiAgICB0cnkge1xuICAgICAgaWYgKCFwYXlsb2FkIHx8ICFwYXlsb2FkLmRhdGEpIHJldHVybiBmYWxzZTtcblxuICAgICAgaWYgKHBheWxvYWQuZGF0YS5mb2xkZXJzKSBDR1BULnN0YXRlLmZvbGRlcnMgPSBwYXlsb2FkLmRhdGEuZm9sZGVycztcbiAgICAgIGlmIChwYXlsb2FkLmRhdGEuYXNzaWduKSBDR1BULnN0YXRlLmFzc2lnbiA9IHBheWxvYWQuZGF0YS5hc3NpZ247XG4gICAgICBpZiAocGF5bG9hZC5kYXRhLnNldHRpbmdzKSBDR1BULnN0YXRlLnNldHRpbmdzID0gcGF5bG9hZC5kYXRhLnNldHRpbmdzO1xuICAgICAgaWYgKHBheWxvYWQuZGF0YS5kaXNtaXNzZWQpIENHUFQuc3RhdGUuZGlzbWlzc2VkID0gcGF5bG9hZC5kYXRhLmRpc21pc3NlZDtcblxuICAgICAgQ0dQVC5zYXZlRm9sZGVycygpO1xuICAgICAgQ0dQVC5zYXZlQXNzaWduKCk7XG4gICAgICBDR1BULnNhdmVTZXR0aW5ncygpO1xuICAgICAgQ0dQVC5zYXZlRGlzbWlzc2VkKCk7XG5cbiAgICAgIENHUFQuZW1pdChcImZvbGRlcnMtdXBkYXRlZFwiLCBDR1BULnN0YXRlLmZvbGRlcnMpO1xuICAgICAgQ0dQVC5lbWl0KFwiYXNzaWduLXVwZGF0ZWRcIiwgQ0dQVC5zdGF0ZS5hc3NpZ24pO1xuICAgICAgQ0dQVC5lbWl0KFwidGhlbWUtY2hhbmdlZFwiLCBDR1BULnRoZW1lKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUud2FybihcIltDR1BUXSBpbXBvcnQgZmFpbGVkXCIsIGUpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBnZXRTaWRlYmFyIH0gZnJvbSBcIi4uL2RvbS9zaWRlYmFyLmpzXCI7XG5pbXBvcnQgeyBkZWJvdW5jZSB9IGZyb20gXCIuLi9jb3JlL2RlYm91bmNlLmpzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbml0U3RhcnQoQ0dQVCkge1xuICBDR1BULnN0YXJ0ID0gKCkgPT4ge1xuICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaCk7XG4gICAgQ0dQVC5kZWJ1ZyA9IHBhcmFtcy5nZXQoXCJjZ3B0ZGVidWdcIikgPT09IFwiMVwiO1xuXG4gICAgQ0dQVC5sb2coXCJzdGFydGluZ1wiLCB7IHZlcnNpb246IF9fQ0dQVF9WRVJTSU9OX18sIGRlYnVnOiBDR1BULmRlYnVnIH0pO1xuXG4gICAgLy8gSW5pdGlhbCBzY2FuICsgcmVuZGVyXG4gICAgQ0dQVC5zY2FuQ2hhdHMoKTtcbiAgICBDR1BULnVpLnJlbmRlcigpO1xuXG4gICAgY29uc3Qgc2lkZWJhciA9IGdldFNpZGViYXIoKTtcbiAgICBpZiAoIXNpZGViYXIpIHJldHVybjtcblxuICAgIGNvbnN0IGRlYm91bmNlZFNjYW4gPSBkZWJvdW5jZSgoKSA9PiBDR1BULnNjYW5DaGF0cygpLCAyMDApO1xuXG4gICAgY29uc3QgY2hhdE9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKG11dHMpID0+IHtcbiAgICAgIGNvbnN0IGluamVjdGVkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtY2dwdC1pbmplY3RlZD1cInRydWVcIl0nKTtcbiAgICAgIGNvbnN0IHJlbGV2YW50ID0gbXV0cy5zb21lKChtKSA9PiAhKGluamVjdGVkICYmIGluamVjdGVkLmNvbnRhaW5zKG0udGFyZ2V0KSkpO1xuICAgICAgaWYgKHJlbGV2YW50KSBkZWJvdW5jZWRTY2FuKCk7XG4gICAgfSk7XG5cbiAgICBjaGF0T2JzZXJ2ZXIub2JzZXJ2ZShzaWRlYmFyLCB7XG4gICAgICBjaGlsZExpc3Q6IHRydWUsXG4gICAgICBzdWJ0cmVlOiB0cnVlLFxuICAgICAgY2hhcmFjdGVyRGF0YTogdHJ1ZSxcbiAgICAgIGF0dHJpYnV0ZXM6IHRydWUsXG4gICAgICBhdHRyaWJ1dGVGaWx0ZXI6IFtcImhyZWZcIiwgXCJhcmlhLWxhYmVsXCIsIFwidGl0bGVcIl1cbiAgICB9KTtcblxuICAgIC8vIFJlLWNyZWF0ZSBwYW5lbCBpZiBDaGF0R1BUIG51a2VzIHNpZGViYXIgY2hpbGRyZW5cbiAgICBjb25zdCBjb250YWluZXJPYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKCgpID0+IHtcbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKENHUFQudWkucGFuZWxJZCArIFwiLWNvbnRhaW5lclwiKTtcbiAgICAgIGNvbnN0IGN1cnJlbnRTaWRlYmFyID0gZ2V0U2lkZWJhcigpO1xuICAgICAgaWYgKCFjb250YWluZXIgJiYgY3VycmVudFNpZGViYXIpIHtcbiAgICAgICAgQ0dQVC5sb2coXCJwYW5lbCBtaXNzaW5nIC0+IHJlY3JlYXRpbmdcIik7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gQ0dQVC51aS5yZW5kZXIoKSwgMTAwKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb250YWluZXJPYnNlcnZlci5vYnNlcnZlKHNpZGViYXIsIHsgY2hpbGRMaXN0OiB0cnVlLCBzdWJ0cmVlOiBmYWxzZSB9KTtcblxuICAgIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKENHUFQudWkucGFuZWxJZCArIFwiLWNvbnRhaW5lclwiKTtcbiAgICAgIGNvbnN0IGN1cnJlbnRTaWRlYmFyID0gZ2V0U2lkZWJhcigpO1xuICAgICAgaWYgKCFjb250YWluZXIgJiYgY3VycmVudFNpZGViYXIpIHtcbiAgICAgICAgQ0dQVC5sb2coXCJwYW5lbCBtaXNzaW5nIChpbnRlcnZhbCkgLT4gcmVjcmVhdGluZ1wiKTtcbiAgICAgICAgQ0dQVC51aS5yZW5kZXIoKTtcbiAgICAgIH1cbiAgICB9LCAyNTAwKTtcblxuICAgIENHUFQubG9nKFwic3RhcnRlZFwiKTtcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBjcmVhdGVFdmVudEJ1cyB9IGZyb20gXCIuL2NvcmUvZXZlbnRzLmpzXCI7XG5pbXBvcnQgeyBpbml0TG9nZ2luZyB9IGZyb20gXCIuL2NvcmUvbG9nLmpzXCI7XG5pbXBvcnQgeyBjcmVhdGVHTVN0b3JlIH0gZnJvbSBcIi4vY29yZS9zdG9yYWdlLmpzXCI7XG5pbXBvcnQgeyBpbml0STE4biB9IGZyb20gXCIuL2NvcmUvaTE4bi5qc1wiO1xuaW1wb3J0IHsgaW5pdFRoZW1lIH0gZnJvbSBcIi4vY29yZS90aGVtZS5qc1wiO1xuaW1wb3J0IHsgb25TaWRlYmFyUmVhZHkgfSBmcm9tIFwiLi9kb20vc2lkZWJhci5qc1wiO1xuaW1wb3J0IHsgaW5pdFN0YXRlIH0gZnJvbSBcIi4vc3RhdGUvc3RhdGUuanNcIjtcbmltcG9ydCB7IGluaXRGb2xkZXJzIH0gZnJvbSBcIi4vZm9sZGVycy9mb2xkZXJzLmpzXCI7XG5pbXBvcnQgeyBpbml0Q2hhdHMgfSBmcm9tIFwiLi9jaGF0cy9zY2FuLmpzXCI7XG5pbXBvcnQgeyBpbml0VUkgfSBmcm9tIFwiLi91aS9wYW5lbC5qc1wiO1xuaW1wb3J0IHsgaW5pdFN1Z2dlc3QgfSBmcm9tIFwiLi9zdWdnZXN0L3N1Z2dlc3QuanNcIjtcbmltcG9ydCB7IGluaXRTeW5jIH0gZnJvbSBcIi4vc3luYy9zeW5jLmpzXCI7XG5pbXBvcnQgeyBpbml0U3RhcnQgfSBmcm9tIFwiLi9tYWluL3N0YXJ0LmpzXCI7XG5cbihmdW5jdGlvbiAoKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuXG4gIGNvbnN0IENHUFQgPSAod2luZG93LkNHUFQgPSB3aW5kb3cuQ0dQVCB8fCB7fSk7XG5cbiAgLy8gRXZlbnQgYnVzIGZpcnN0XG4gIGNvbnN0IGJ1cyA9IGNyZWF0ZUV2ZW50QnVzKCk7XG4gIENHUFQub24gPSBidXMub247XG4gIENHUFQub2ZmID0gYnVzLm9mZjtcbiAgQ0dQVC5lbWl0ID0gYnVzLmVtaXQ7XG5cbiAgaW5pdExvZ2dpbmcoQ0dQVCk7XG4gIENHUFQuc3RvcmUgPSBjcmVhdGVHTVN0b3JlKCk7XG4gIGluaXRJMThuKENHUFQpO1xuICBpbml0U3RhdGUoQ0dQVCk7XG4gIGluaXRUaGVtZShDR1BUKTtcbiAgaW5pdEZvbGRlcnMoQ0dQVCk7XG4gIGluaXRDaGF0cyhDR1BUKTtcbiAgaW5pdFVJKENHUFQpO1xuICBpbml0U3VnZ2VzdChDR1BUKTtcbiAgaW5pdFN5bmMoQ0dQVCk7XG4gIGluaXRTdGFydChDR1BUKTtcblxuICBvblNpZGViYXJSZWFkeSgoKSA9PiB7XG4gICAgQ0dQVC5zdGFydCgpO1xuICB9KTtcbn0pKCk7XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7TUFB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RUFDaUIsUUFBUUUsRUFBUyxDQUFFLFVBQVcsR0FBTSxRQUFTLEVBQU0sQ0FBQyxFQUV0RSxZQUFZLElBQU0sQ0FDaEIsSUFBTU8sRUFBWSxTQUFTLGVBQWVULEVBQUssR0FBRyxRQUFVLFlBQVksRUFDbEVVLEVBQWlCUCxFQUFXLEVBQzlCLENBQUNNLEdBQWFDLElBQ2hCVixFQUFLLElBQUksd0NBQXdDLEVBQ2pEQSxFQUFLLEdBQUcsT0FBTyxFQUVuQixFQUFHLElBQUksRUFFUEEsRUFBSyxJQUFJLFNBQVMsQ0FDcEIsQ0FDRixFQ3pDQyxVQUFZLENBQ1gsYUFFQSxJQUFNVyxFQUFRLE9BQU8sS0FBTyxPQUFPLE1BQVEsQ0FBQyxFQUd0Q0MsRUFBTUMsRUFBZSxFQUMzQkYsRUFBSyxHQUFLQyxFQUFJLEdBQ2RELEVBQUssSUFBTUMsRUFBSSxJQUNmRCxFQUFLLEtBQU9DLEVBQUksS0FFaEJFLEVBQVlILENBQUksRUFDaEJBLEVBQUssTUFBUUksRUFBYyxFQUMzQkMsRUFBU0wsQ0FBSSxFQUNiTSxFQUFVTixDQUFJLEVBQ2RPLEVBQVVQLENBQUksRUFDZFEsRUFBWVIsQ0FBSSxFQUNoQlMsRUFBVVQsQ0FBSSxFQUNkVSxFQUFPVixDQUFJLEVBQ1hXLEVBQVlYLENBQUksRUFDaEJZLEVBQVNaLENBQUksRUFDYmEsRUFBVWIsQ0FBSSxFQUVkYyxFQUFlLElBQU0sQ0FDbkJkLEVBQUssTUFBTSxDQUNiLENBQUMsQ0FDSCxHQUFHIiwKICAibmFtZXMiOiBbImNyZWF0ZUV2ZW50QnVzIiwgImxpc3RlbmVycyIsICJvbiIsICJldnQiLCAiZm4iLCAib2ZmIiwgImFyciIsICJpIiwgImVtaXQiLCAicGF5bG9hZCIsICJlIiwgImluaXRMb2dnaW5nIiwgIkNHUFQiLCAiYXJncyIsICJjcmVhdGVHTVN0b3JlIiwgInNhZmVQYXJzZSIsICJyYXciLCAic2FmZVN0cmluZ2lmeSIsICJ2YWx1ZSIsICJrZXkiLCAiZmFsbGJhY2siLCAicGFyc2VkIiwgImUiLCAiaW5pdEkxOG4iLCAiQ0dQVCIsICJzdXBwb3J0ZWQiLCAic2hvcnQiLCAibGFuZyIsICJMIiwgIm5hbWUiLCAiaW5pdFRoZW1lIiwgIkNHUFQiLCAibXEiLCAiY29tcHV0ZVRoZW1lIiwgImlzRGFyayIsICJvbkNoYW5nZSIsICJnZXRTaWRlYmFyIiwgIm9uU2lkZWJhclJlYWR5IiwgImNiIiwgInRyeUl0IiwgImVsIiwgImluaXRTdGF0ZSIsICJDR1BUIiwgImluaXRGb2xkZXJzIiwgIkNHUFQiLCAiRiIsICJ1aWQiLCAiY29tcGFyZUZvbGRlciIsICJhIiwgImIiLCAibmFtZSIsICJwYXJlbnRJZCIsICJpY29uIiwgImlkIiwgImZvbGRlcklkIiwgImYiLCAieCIsICJjaWQiLCAibmV3TmFtZSIsICJjb2xvciIsICJub2RlIiwgInAiLCAiZGlyZWN0aW9uIiwgInNpYmxpbmdzIiwgImlkeCIsICJzd2FwSWR4IiwgIm90aGVyIiwgInQiLCAiYWxsIiwgImJ5UGFyZW50IiwgImsiLCAiYXJyIiwgImJ1aWxkIiwgImxldmVsIiwgImNoYXRJZCIsICJpbml0Q2hhdHMiLCAiQ0dQVCIsICJzdGFydCIsICJzaWRlYmFyIiwgImdldFNpZGViYXIiLCAibm9kZXMiLCAibWFwIiwgImEiLCAiaHJlZiIsICJtIiwgImlkIiwgInRpdGxlIiwgImRlYm91bmNlIiwgImZuIiwgIm1zIiwgInQiLCAiYXJncyIsICJpbml0VUkiLCAiQ0dQVCIsICJJQ09OIiwgImN1cnJlbnRNZW51IiwgImUiLCAic2lkZWJhciIsICJnZXRTaWRlYmFyIiwgImNvbnRhaW5lciIsICJwYW5lbCIsICJyZXNpemVIYW5kbGUiLCAiY29udGFpbmVyRWwiLCAic3RhcnRZIiwgInN0YXJ0SGVpZ2h0IiwgIm9uTW92ZSIsICJldiIsICJkZWx0YSIsICJuZXdIZWlnaHQiLCAib25VcCIsICJkZWJ1Z0xpbmUiLCAibm93IiwgInNpbmNlU2NhbiIsICJzaW5jZVJlbmRlciIsICJsaW5lIiwgInN0YXJ0IiwgInRvcEJhciIsICJzZWFyY2giLCAiYXBwbHlTZWFyY2giLCAiZGVib3VuY2UiLCAic2V0dGluZ3NCdG4iLCAiZGJnIiwgInF1ZXJ5IiwgIm5vZGUiLCAiYWRkQnRuIiwgIm5hbWUiLCAiZm9sZGVyIiwgImxldmVsIiwgImNoaWxkcmVuIiwgImhlYWQiLCAiYXJyb3ciLCAiaWNvbiIsICJwaW5JY29uIiwgInRpdGxlIiwgImMiLCAiY2hpbGQiLCAiY2hhdCIsICJ3cmFwcGVyIiwgInJvdyIsICJsaW5rIiwgIngiLCAieSIsICJtZW51IiwgImFkZEl0ZW0iLCAibGFiZWwiLCAiaGFuZGxlciIsICJiIiwgImljIiwgImZvbGRlcklkIiwgImN1cnJlbnRDb2xvciIsICJwaWNrZWQiLCAiYXV0b3N1Z2dlc3QiLCAiYXV0b3NvcnQiLCAiY2xvdWRUaXRsZXMiLCAiZGVib3VuY2VkUmVuZGVyIiwgImluaXRTdWdnZXN0IiwgIkNHUFQiLCAiU1VHR0VTVElPTl9SVUxFUyIsICJ0aXRsZSIsICJ0IiwgInJ1bGUiLCAidyIsICJzdHJpcExlYWRpbmdTeW1ib2xzIiwgInMiLCAibm9ybU5hbWUiLCAiZmluZEZvbGRlckJ5TmFtZSIsICJuYW1lIiwgIm4iLCAiRiIsICJmIiwgImVuc3VyZUZvbGRlciIsICJjbGVhbiIsICJleGlzdGluZyIsICJhdXRvU29ydENoYXQiLCAiY2hhdElkIiwgImNoYXRUaXRsZSIsICJzdWdnZXN0aW9uIiwgImZvbGRlcklkIiwgImNvbmZpcm1TdWdnZXN0Q2hhdCIsICJ0ZXh0IiwgImJvb3RzdHJhcHBlZCIsICJzZWVuQ2hhdElkcyIsICJhdXRvc29ydCIsICJhdXRvc3VnZ2VzdCIsICJjaGF0cyIsICJjIiwgIm1vZGUiLCAiaW5pdFN5bmMiLCAiQ0dQVCIsICJwYXlsb2FkIiwgImUiLCAiaW5pdFN0YXJ0IiwgIkNHUFQiLCAicGFyYW1zIiwgInNpZGViYXIiLCAiZ2V0U2lkZWJhciIsICJkZWJvdW5jZWRTY2FuIiwgImRlYm91bmNlIiwgIm11dHMiLCAiaW5qZWN0ZWQiLCAibSIsICJjb250YWluZXIiLCAiY3VycmVudFNpZGViYXIiLCAiQ0dQVCIsICJidXMiLCAiY3JlYXRlRXZlbnRCdXMiLCAiaW5pdExvZ2dpbmciLCAiY3JlYXRlR01TdG9yZSIsICJpbml0STE4biIsICJpbml0U3RhdGUiLCAiaW5pdFRoZW1lIiwgImluaXRGb2xkZXJzIiwgImluaXRDaGF0cyIsICJpbml0VUkiLCAiaW5pdFN1Z2dlc3QiLCAiaW5pdFN5bmMiLCAiaW5pdFN0YXJ0IiwgIm9uU2lkZWJhclJlYWR5Il0KfQo=
// ==UserScript==
// @name ChatGPT Sidebar Folders v9.4 (Modular)
// @namkespace https://chatgpt.com
// @version 9.4
// @description Folder system for the ChatGPT sidebar (modular source, bundled build, debug counters)
// @author https://gist.github.com/DickHorner
// @match https://chat.openai.com/*
// @match https://chatgpt.com/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @run-at document-idle
// ==/UserScript==
(()=>{function v(){let e=Object.create(null);function n(o,r){(e[o]=e[o]||[]).push(r)}function a(o,r){let s=e[o]||[],t=s.indexOf(r);t>=0&&s.splice(t,1)}function p(o,r){(e[o]||[]).forEach(s=>{try{s(r)}catch(t){console.error("[CGPT] Listener error:",t)}})}return{on:n,off:a,emit:p}}function E(e){e.debug=!1,e.log=(...n)=>{e.debug&&console.log("[CGPT]",...n)}}function w(){function e(a){if(a==null||typeof a!="string")return a;try{return JSON.parse(a)}catch{return a}}function n(a){return typeof a=="string"?a:JSON.stringify(a)}return{get(a,p){try{let o=GM_getValue(a),r=e(o);return r??p}catch(o){return console.warn("[CGPT] Storage get error:",o),p}},set(a,p){try{GM_setValue(a,n(p))}catch(o){console.warn("[CGPT] Storage set error:",o)}},del(a){try{GM_deleteValue(a)}catch(p){console.warn("[CGPT] Storage delete error:",p)}}}}function y(e){let n=["de","en"],p=(navigator.language||"en").toLowerCase().slice(0,2),o=n.includes(p)?p:"en";e.locale=o;let r={de:{unsorted:"Unsortiert",newFolder:"Neuer Ordner",search:"Suchen\u2026",rename:"Umbenennen",delete:"L\xF6schen",export:"Exportieren",import:"Importieren",confirmDelete:s=>`Ordner "${s}" l\xF6schen?`,icon:"Symbol",suggestion:"Vorschlag:",autosort:"Automatisch einsortieren",autosuggest:"Vorschl\xE4ge anzeigen",pinned:"Angeheftet",reindex:"Alle Chats neu kategorisieren",cloudTitles:"Titel in Cloud-Sync einschlie\xDFen",settings:"Einstellungen",color:"Farbe"},en:{unsorted:"Unsorted",newFolder:"New Folder",search:"Search\u2026",rename:"Rename",delete:"Delete",export:"Export",import:"Import",confirmDelete:s=>`Delete folder "${s}"?`,icon:"Icon",suggestion:"Suggestion:",autosort:"Auto-sort",autosuggest:"Show suggestions",pinned:"Pinned",reindex:"Re-categorize all chats",cloudTitles:"Include titles in Cloud Sync",settings:"Settings",color:"Color"}};e.L=r[e.locale]||r.en}function L(e){let n=window.matchMedia?window.matchMedia("(prefers-color-scheme: dark)"):{matches:!0,addEventListener:null,addListener:null},a=()=>{let o=!!n.matches;return{dark:o,FG:o?"#ececec":"#222",FG_MUTED:o?"#999":"#555",BG:o?"#2a2b32":"#eaeaea",BG_HOVER:o?"rgba(255,255,255,0.1)":"rgba(0,0,0,0.08)",BTN_BG:o?"#3b3b3b":"#fff"}};e.theme=a();let p=()=>{e.theme=a(),e.emit("theme-changed",e.theme)};n&&n.addEventListener?n.addEventListener("change",p):n&&n.addListener&&n.addListener(p)}function x(){return document.querySelector("nav")||document.querySelector('[class*="sidebar"]')}function F(e){let n=0,a=()=>{let p=x();p?e(p):n++<50?setTimeout(a,200):console.warn("[CGPT] Failed to find nav after 50 retries")};a()}function O(e){e.state={FOLDERS_KEY:"cgpt_folders_v9",ASSIGN_KEY:"cgpt_assign_v9",SETTINGS_KEY:"cgpt_settings_v9",DISMISSED_KEY:"cgpt_dismissed_v9",folders:{},assign:{},dismissed:{},settings:{autosuggest:!0,autosort:!1,theme:"auto",lang:e.locale,cloudTitles:!0}},e.state.folders=e.store.get(e.state.FOLDERS_KEY,{uncategorized:{id:"uncategorized",name:e.L.unsorted,icon:"",color:"#888",expanded:!0,order:0,pinned:!1,parentId:null}}),e.state.assign=e.store.get(e.state.ASSIGN_KEY,{}),e.state.settings=e.store.get(e.state.SETTINGS_KEY,e.state.settings),e.state.dismissed=e.store.get(e.state.DISMISSED_KEY,{}),e.saveFolders=()=>e.store.set(e.state.FOLDERS_KEY,e.state.folders),e.saveAssign=()=>e.store.set(e.state.ASSIGN_KEY,e.state.assign),e.saveSettings=()=>e.store.set(e.state.SETTINGS_KEY,e.state.settings),e.saveDismissed=()=>e.store.set(e.state.DISMISSED_KEY,e.state.dismissed),e.diag={scans:0,renders:0,lastScanAt:0,lastRenderAt:0,lastScanDurationMs:0,lastRenderDurationMs:0,chatsFoundLastScan:0}}function _(e){e.folders={};let n=()=>e.state.folders,a=()=>crypto.randomUUID?crypto.randomUUID():"id_"+Math.random().toString(36).slice(2),p=(o,r)=>r.pinned-o.pinned||o.order-r.order;e.folders.create=(o,r=null,s="")=>{let t=a();return n()[t]={id:t,name:o,icon:s,color:"#66aaff",parentId:r,pinned:!1,expanded:!0,order:Date.now()},e.saveFolders(),e.emit("folders-updated",n()),t},e.folders.delete=o=>{let r=n()[o];!r||o==="uncategorized"||(Object.values(n()).forEach(s=>{s.parentId===o&&(s.parentId=r.parentId??null)}),Object.keys(e.state.assign).forEach(s=>{e.state.assign[s]===o&&(e.state.assign[s]="uncategorized")}),delete n()[o],e.saveFolders(),e.saveAssign(),e.emit("folders-updated",n()),e.emit("assign-updated",e.state.assign))},e.folders.rename=(o,r)=>{n()[o]&&(n()[o].name=r,e.saveFolders(),e.emit("folders-updated",n()))},e.folders.setIcon=(o,r)=>{n()[o]&&(n()[o].icon=r,e.saveFolders(),e.emit("folders-updated",n()))},e.folders.setColor=(o,r)=>{n()[o]&&(n()[o].color=r,e.saveFolders(),e.emit("folders-updated",n()))},e.folders.togglePin=o=>{n()[o]&&(n()[o].pinned=!n()[o].pinned,e.saveFolders(),e.emit("folders-updated",n()))},e.folders.setParent=(o,r)=>{let s=n()[o];if(!s||o==="uncategorized")return;let t=r;for(;t;){if(t===o)return;t=(n()[t]||{}).parentId}s.parentId=r??null,e.saveFolders(),e.emit("folders-updated",n())},e.folders.move=(o,r)=>{let s=n()[o];if(!s)return;let t=Object.values(n()).filter(d=>(d.parentId??null)===(s.parentId??null)).sort((d,g)=>d.order-g.order),i=t.findIndex(d=>d.id===o);if(i<0)return;let l=r==="up"?i-1:i+1;if(l<0||l>=t.length)return;let c=t[l],u=s.order;s.order=c.order,c.order=u,e.saveFolders(),e.emit("folders-updated",n())},e.folders.getTree=()=>{let o=Object.values(n()),r=new Map;o.forEach(t=>{let i=t.parentId??"root",l=r.get(i);l?l.push(t):r.set(i,[t])});let s=(t,i)=>(r.get(t??"root")||[]).sort(p).map(l=>({folder:l,level:i,children:s(l.id,i+1)}));return s(null,0)},e.folders.assignChat=(o,r)=>{e.state.assign[o]=r,e.saveAssign(),e.emit("assign-updated",e.state.assign)},e._folders={F:n}}function D(e){e.chats={map:{},_lastScan:0},e.scanChats=()=>{let n=performance.now(),a=x();if(!a)return;let p=a.querySelectorAll("a[href*='/c/']"),o={};p.forEach(r=>{if(r.closest('[data-cgpt-injected="true"]'))return;let s=r.getAttribute("href")||"",t=s.match(/\/c\/([\w-]+)/),i=t?t[1]:s,l=(r.textContent||"").trim()||s;o[i]={id:i,title:l,href:s,el:r}}),e.chats.map=o,e.chats._lastScan=Date.now(),e.diag.scans+=1,e.diag.lastScanAt=Date.now(),e.diag.lastScanDurationMs=Math.round(performance.now()-n),e.diag.chatsFoundLastScan=Object.keys(o).length,e.emit("chats-updated",o)}}function S(e,n){let a;return(...p)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...p),n)}}function UI(e){e.ui={},e.ui.panelId="cgpt-folder-panel-v9",e.ui.lastSearch="";let n={arrowDown:"\u25BC",arrowRight:"\u25B6",pin:"\u{1F4CC}",folder:"\u{1F4C1}",del:"\u{1F5D1}\uFE0F",settings:"\u2699\uFE0F"},a=null;e.ui.closeContextMenu=()=>{a&&(a.remove(),a=null)},document.addEventListener("click",r=>{a&&!a.contains(r.target)&&e.ui.closeContextMenu()}),document.addEventListener("keydown",r=>{r.key==="Escape"&&e.ui.closeContextMenu()}),e.ui.ensurePanel=()=>{let r=x();if(!r)return null;let s=document.getElementById(e.ui.panelId+"-container"),t=document.getElementById(e.ui.panelId);if(s)s.setAttribute("data-cgpt-injected","true"),t||(t=document.createElement("div"),t.id=e.ui.panelId,Object.assign(t.style,{padding:"12px 8px 8px 8px",boxSizing:"border-box",overflow:"auto",flex:"1 1 auto",minHeight:"0",width:"100%"}),s.insertBefore(t,s.firstChild||null));else{s=document.createElement("div"),s.id=e.ui.panelId+"-container",s.setAttribute("data-cgpt-injected","true"),Object.assign(s.style,{margin:"8px",borderRadius:"8px",background:e.theme.BG,border:`1px solid ${e.theme.FG_MUTED}`,boxSizing:"border-box",width:"calc(100% - 16px)",minHeight:"200px",height:"200px",display:"flex",flexDirection:"column",alignItems:"stretch",overflow:"hidden",flexShrink:"0"}),t=document.createElement("div"),t.id=e.ui.panelId,Object.assign(t.style,{padding:"12px 8px 8px 8px",boxSizing:"border-box",overflow:"auto",flex:"1 1 auto",minHeight:"0",width:"100%"});let i=document.createElement("div");i.setAttribute("data-resize-handle","true"),Object.assign(i.style,{height:"8px",flex:"0 0 8px",cursor:"ns-resize",background:`linear-gradient(to bottom, transparent, ${e.theme.FG_MUTED}44)`,borderRadius:"0 0 8px 8px",alignSelf:"stretch"}),i.addEventListener("mousedown",l=>{l.preventDefault();let c=document.getElementById(e.ui.panelId+"-container");if(!c)return;let u=l.clientY,d=c.offsetHeight;i.style.background=`linear-gradient(to bottom, transparent, ${e.theme.FG_MUTED}88)`;let g=m=>{let h=m.clientY-u,b=Math.max(150,Math.min(d+h,window.innerHeight-80));c.style.height=b+"px"},f=()=>{document.removeEventListener("mousemove",g),document.removeEventListener("mouseup",f),i.style.background=`linear-gradient(to bottom, transparent, ${e.theme.FG_MUTED}44)`};document.addEventListener("mousemove",g),document.addEventListener("mouseup",f)}),s.appendChild(t),s.appendChild(i),r.firstChild?r.insertBefore(s,r.firstChild):r.appendChild(s)}return document.getElementById(e.ui.panelId)};function p(){if(!e.debug)return null;let r=Date.now(),s=e.diag.lastScanAt?r-e.diag.lastScanAt:null,t=e.diag.lastRenderAt?r-e.diag.lastRenderAt:null,i=document.createElement("div");return i.textContent=`DBG scans:${e.diag.scans} (last ${e.diag.lastScanDurationMs}ms, chats ${e.diag.chatsFoundLastScan}${s!==null?", "+s+"ms ago":""}) renders:${e.diag.renders} (last ${e.diag.lastRenderDurationMs}ms${t!==null?", "+t+"ms ago":""})`,Object.assign(i.style,{marginTop:"6px",fontSize:"11px",color:e.theme.FG_MUTED,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}),i}e.ui.render=()=>{let r=performance.now(),s=e.ui.ensurePanel();if(!s)return;s.innerHTML="";let t=document.createElement("div");Object.assign(t.style,{display:"flex",gap:"6px",marginBottom:"8px",alignItems:"center"});let i=document.createElement("input");i.placeholder=e.L.search,i.value=e.ui.lastSearch||"",Object.assign(i.style,{flex:"1",padding:"6px 8px",border:`1px solid ${e.theme.FG_MUTED}`,borderRadius:"6px",background:e.theme.dark?"#333":"#fff",color:e.theme.FG,boxSizing:"border-box",minWidth:"0"});let l=S(()=>{e.ui.lastSearch=i.value,e.ui.render()},200);i.addEventListener("input",l);let c=document.createElement("button");c.textContent=n.settings,c.title=e.L.settings,Object.assign(c.style,{padding:"6px 10px",background:e.theme.BTN_BG,border:`1px solid ${e.theme.FG_MUTED}`,borderRadius:"6px",cursor:"pointer",color:e.theme.FG,flexShrink:"0",minWidth:"40px"}),c.addEventListener("click",m=>{m.preventDefault(),m.stopPropagation(),e.ui.showSettings()}),t.appendChild(i),t.appendChild(c),s.appendChild(t);let u=p();u&&s.appendChild(u);let d=(i.value||"").toLowerCase().trim();e.folders.getTree().forEach(m=>e.ui.renderFolderNode(s,m,d));let f=document.createElement("button");f.textContent=`\uFF0B ${e.L.newFolder}`,Object.assign(f.style,{width:"100%",marginTop:"12px",padding:"8px",background:e.theme.BTN_BG,border:`1px solid ${e.theme.FG_MUTED}`,borderRadius:"6px",cursor:"pointer",color:e.theme.FG,fontWeight:"500"}),f.addEventListener("click",()=>{let m=prompt(e.L.newFolder)||"";m.trim()&&e.folders.create(m.trim())}),s.appendChild(f),e.diag.renders+=1,e.diag.lastRenderAt=Date.now(),e.diag.lastRenderDurationMs=Math.round(performance.now()-r)},e.ui.renderFolderNode=(r,s,t)=>{let{folder:i,level:l,children:c}=s,u=document.createElement("div");Object.assign(u.style,{paddingLeft:`${l*14}px`,marginBottom:"4px",maxWidth:"100%",boxSizing:"border-box"});let d=document.createElement("div");Object.assign(d.style,{display:"flex",alignItems:"center",gap:"6px",cursor:"pointer",padding:"6px 8px",borderRadius:"6px",background:i.color?`${i.color}22`:"rgba(255,255,255,0.05)",maxWidth:"100%",overflow:"hidden"}),d.addEventListener("mouseover",()=>{d.style.background=i.color?`${i.color}44`:"rgba(255,255,255,0.1)"}),d.addEventListener("mouseout",()=>{d.style.background=i.color?`${i.color}22`:"rgba(255,255,255,0.05)"});let g=document.createElement("span");g.textContent=i.expanded?n.arrowDown:n.arrowRight,Object.assign(g.style,{width:"16px",color:e.theme.FG_MUTED,fontSize:"10px"});let f=document.createElement("span");if(f.textContent=i.icon||n.folder,f.style.fontSize="16px",i.pinned){let h=document.createElement("span");h.textContent=n.pin,Object.assign(h.style,{fontSize:"10px",color:"#f59e0b"}),d.appendChild(h)}let m=document.createElement("span");m.textContent=i.name,Object.assign(m.style,{flex:"1",color:e.theme.FG,fontSize:"14px",fontWeight:"500",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:"0"}),d.addEventListener("click",()=>{i.expanded=!i.expanded,e.saveFolders(),e.ui.render()}),d.addEventListener("contextmenu",h=>{h.preventDefault(),e.ui.openFolderContextMenu(h.pageX,h.pageY,i)}),d.appendChild(g),d.appendChild(f),d.appendChild(m),u.appendChild(d),i.expanded&&(Object.values(e.chats.map).filter(b=>(e.state.assign[b.id]||"uncategorized")===i.id).forEach(b=>{t&&!b.title.toLowerCase().includes(t)||u.appendChild(e.ui.renderChatItem(b,l))}),c.forEach(b=>e.ui.renderFolderNode(r,b,t))),r.appendChild(u)},e.ui.renderChatItem=(r,s)=>{let t=document.createElement("div");Object.assign(t.style,{paddingLeft:`${(s+1)*14}px`,maxWidth:"100%",boxSizing:"border-box"});let i=document.createElement("div");Object.assign(i.style,{padding:"4px 8px",borderRadius:"4px",cursor:"pointer",overflow:"hidden",boxSizing:"border-box"}),i.addEventListener("mouseover",()=>i.style.background=e.theme.BG_HOVER),i.addEventListener("mouseout",()=>i.style.background="");let l=document.createElement("a");return l.textContent=r.title,l.href=r.href,Object.assign(l.style,{color:e.theme.FG,textDecoration:"none",fontSize:"13px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"block",maxWidth:"100%"}),i.appendChild(l),t.appendChild(i),t},e.ui.openFolderContextMenu=(r,s,t)=>{e.ui.closeContextMenu();let i=document.createElement("div");a=i;let l=Math.min(r,window.innerWidth-220),c=Math.min(s,window.innerHeight-300);Object.assign(i.style,{position:"fixed",left:l+"px",top:c+"px",background:e.theme.BG,color:e.theme.FG,border:`1px solid ${e.theme.FG_MUTED}`,borderRadius:"8px",padding:"6px",zIndex:9999,minWidth:"200px",boxShadow:"0 4px 12px rgba(0,0,0,0.5)"});let b=(c,u)=>{let d=document.createElement("button");d.textContent=c,Object.assign(d.style,{width:"100%",display:"block",padding:"8px 12px",background:e.theme.BTN_BG,border:"none",borderRadius:"4px",color:e.theme.FG,cursor:"pointer",margin:"4px 0",textAlign:"left"}),d.addEventListener("mouseover",()=>d.style.background=e.theme.BG_HOVER),d.addEventListener("mouseout",()=>d.style.background=e.theme.BTN_BG),d.addEventListener("click",()=>{u(),e.ui.closeContextMenu()}),i.appendChild(d)};l(e.L.rename,()=>{let c=prompt(e.L.rename,t.name);c&&c.trim()&&e.folders.rename(t.id,c.trim())}),t.id!=="uncategorized"&&l(e.L.delete,()=>{confirm(e.L.confirmDelete(t.name))&&e.folders.delete(t.id)}),l(e.L.pinned,()=>e.folders.togglePin(t.id)),l(e.L.icon,()=>{let c=prompt(e.L.icon,t.icon||"");c!==null&&e.folders.setIcon(t.id,c)}),l(e.L.color,()=>e.ui.showColorPicker(t.id,t.color||"#66aaff")),document.body.appendChild(i)},e.ui.showColorPicker=(r,s)=>{let t=prompt("Color (hex)",s||"#66aaff");if(t){let i=t.trim();/^#[0-9A-Fa-f]{6}$/.test(i)?e.folders.setColor(r,i):alert("Invalid hex color. Use format: #RRGGBB")}},e.ui.showSettings=()=>{let r=confirm(`${e.L.autosuggest}
OK = ON, Cancel = OFF`);e.state.settings.autosuggest=r;let s=confirm(`${e.L.autosort}
OK = ON, Cancel = OFF`);e.state.settings.autosort=s;let t=confirm(`${e.L.cloudTitles}
OK = ON, Cancel = OFF`);e.state.settings.cloudTitles=t,e.saveSettings(),e.ui.render()};let o=S(()=>e.ui.render(),100);e.on("chats-updated",o),e.on("folders-updated",o),e.on("assign-updated",o),e.on("theme-changed",o)}function M(e){let n=[{folder:"\u{1F4BB} Code",words:["code","javascript","python","regex","bug","debug","error","function","api"]},{folder:"\u2709\uFE0F Writing",words:["email","letter","text","write","draft","essay","article"]},{folder:"\u{1F3EB} Education",words:["school","class","study","learn","homework","exam","university"]},{folder:"\u{1F4C1} Work",words:["project","meeting","plan","research","report","business","task"]},{folder:"\u2764\uFE0F Personal",words:["family","health","advice","help","personal","life"]}];e.suggest=c=>{let u=(c||"").toLowerCase();for(let d of n)for(let g of d.words)if(u.includes(g))return d.folder;return null};let a=c=>{try{return c.replace(/^[^\p{L}\p{N}]+/gu,"")}catch{return c.replace(/^[^A-Za-z0-9]+/,"")}},p=c=>a((c??"").normalize("NFKC")).trim().replace(/\s+/g," ").toLowerCase();function o(c){let u=p(c),d=e._folders.F;return Object.values(d()).find(g=>p(g.name)===u)||null}function r(c){let u=(c||"").trim(),d=o(u);return d?d.id:e.folders.create(u)}function s(c,u){if(e.state.dismissed[c])return;let d=e.suggest(u);if(!d)return;let g=r(d);e.folders.assignChat(c,g)}function t(c,u){if(e.state.dismissed[c])return;let d=e.suggest(u);if(!d)return;let g=d.trim(),f=`Chat: "${u}"
${e.L.suggestion} ${g}
Assign to this folder?`;if(!confirm(f)){e.state.dismissed[c]=Date.now(),e.saveDismissed();return}let m=r(g);e.folders.assignChat(c,m)}let i=!1,l=new Set(Object.keys(e.state.assign||{}));e.on("chats-updated",()=>{let c=!!e.state.settings.autosort,u=!!e.state.settings.autosuggest,d=Object.values(e.chats.map);if(!i){d.forEach(g=>l.add(g.id)),i=!0;return}d.forEach(g=>{l.has(g.id)||(l.add(g.id),!e.state.assign[g.id]&&(c?s(g.id,g.title):u&&t(g.id,g.title)))}),e.saveAssign(),e.emit("assign-updated",e.state.assign)}),e.suggest.reindexAll=(c="confirm")=>{Object.values(e.chats.map).forEach(u=>{c==="auto"?s(u.id,u.title):t(u.id,u.title)}),e.saveAssign(),e.emit("assign-updated",e.state.assign)}}function k(e){e.sync={},e.sync.export=()=>({timestamp:Date.now(),version:"9.4",locale:e.locale,data:{folders:e.state.folders,assign:e.state.assign,settings:e.state.settings,dismissed:e.state.dismissed}}),e.sync.import=n=>{try{return!n||!n.data?!1:(n.data.folders&&(e.state.folders=n.data.folders),n.data.assign&&(e.state.assign=n.data.assign),n.data.settings&&(e.state.settings=n.data.settings),n.data.dismissed&&(e.state.dismissed=n.data.dismissed),e.saveFolders(),e.saveAssign(),e.saveSettings(),e.saveDismissed(),e.emit("folders-updated",e.state.folders),e.emit("assign-updated",e.state.assign),e.emit("theme-changed",e.theme),!0)}catch(a){return console.warn("[CGPT] import failed",a),!1}}}function j(e){e._observers=[],e.cleanup=()=>{e._observers.forEach(n=>n.disconnect()),e._observers=[]},e.start=()=>{let n=new URLSearchParams(window.location.search);e.debug=n.get("cgptdebug")==="1",e.log("starting",{version:"9.4",debug:e.debug}),e.scanChats(),e.ui.render();let a=x();if(!a)return;let p=S(()=>e.scanChats(),200),o=new MutationObserver(s=>{let t=document.querySelector('[data-cgpt-injected="true"]');s.some(l=>!(t&&t.contains(l.target)))&&p()});o.observe(a,{childList:!0,subtree:!0,characterData:!0,attributes:!0,attributeFilter:["href","aria-label","title"]}),e._observers.push(o);let r=new MutationObserver(()=>{let s=document.getElementById(e.ui.panelId+"-container"),t=x();!s&&t&&(e.log("panel missing -> recreating"),setTimeout(()=>e.ui.render(),100))});r.observe(a,{childList:!0,subtree:!1}),e._observers.push(r),e.log("started")}}(function(){"use strict";let e=window.CGPT=window.CGPT||{},n=v();e.on=n.on,e.off=n.off,e.emit=n.emit,E(e),e.store=w(),y(e),O(e),L(e),_(e),D(e),UI(e),M(e),k(e),j(e),F(()=>{e.start()})})();})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment