From aa6c74a576f47406b693abf7f3fa2ae998cb79df Mon Sep 17 00:00:00 2001 From: Bikash Panda Date: Sat, 8 Aug 2026 10:00:16 +0530 Subject: [PATCH 01/18] Added download trackign and download feature --- electron/lib/core/appMenu.cjs | 6 + electron/lib/core/mainHelpers.cjs | 29 -- electron/lib/documents/documentIpc.cjs | 29 +- electron/lib/export/exportHistoryIpc.cjs | 58 ++++ electron/lib/export/exportHistoryStore.cjs | 153 ++++++++++ electron/lib/export/notePackageIpc.cjs | 53 +++- electron/lib/export/workspaceExportIpc.cjs | 36 +-- electron/lib/media/imageMedia.cjs | 29 +- electron/main.cjs | 36 ++- electron/preload.cjs | 10 + src/App.jsx | 36 ++- src/components/DownloadsPage.jsx | 334 +++++++++++++++++++++ src/components/layout/TitleBar.jsx | 19 +- src/services/electronService.js | 46 +++ src/styles/DownloadsPage.css | 275 +++++++++++++++++ tests/exportHistoryStore.test.js | 72 +++++ 16 files changed, 1130 insertions(+), 91 deletions(-) create mode 100644 electron/lib/export/exportHistoryIpc.cjs create mode 100644 electron/lib/export/exportHistoryStore.cjs create mode 100644 src/components/DownloadsPage.jsx create mode 100644 src/styles/DownloadsPage.css create mode 100644 tests/exportHistoryStore.test.js diff --git a/electron/lib/core/appMenu.cjs b/electron/lib/core/appMenu.cjs index d09a9a78..80f33a9a 100644 --- a/electron/lib/core/appMenu.cjs +++ b/electron/lib/core/appMenu.cjs @@ -572,6 +572,12 @@ function buildAppMenuTemplate(win, context = {}) { label: "Assets Library", click: () => sendMenuAction(win, "open-assets") }, + { + label: "Downloads & Export History", + accelerator: "CmdOrCtrl+J", + action: "open-downloads-page", + click: () => sendMenuAction(win, "open-downloads-page") + }, { label: "Trash / Removed Items", click: () => sendMenuAction(win, "open-trash") diff --git a/electron/lib/core/mainHelpers.cjs b/electron/lib/core/mainHelpers.cjs index 31eabc53..27a87aa4 100644 --- a/electron/lib/core/mainHelpers.cjs +++ b/electron/lib/core/mainHelpers.cjs @@ -51,34 +51,7 @@ function createMainHelpers(deps) { fs.writeFileSync(userConfigPath, JSON.stringify(nextSettings, null, 2), "utf8"); } - function getLastPdfExportPath() { - const settings = readUserSettings(); - const rawLastPath = typeof settings?.lastPdfExportPath === "string" - ? settings.lastPdfExportPath.trim() - : ""; - if (!rawLastPath) return ""; - try { - const resolvedLastPath = path.resolve(rawLastPath); - const lastExportDir = path.extname(resolvedLastPath).toLowerCase() === ".pdf" - ? path.dirname(resolvedLastPath) - : resolvedLastPath; - if (fs.existsSync(lastExportDir)) { - return lastExportDir; - } - } catch { - return ""; - } - - return ""; - } - - function rememberPdfExportPath(filePath) { - if (!filePath || typeof filePath !== "string") return; - const settings = readUserSettings(); - settings.lastPdfExportPath = path.dirname(path.resolve(filePath)); - writeUserSettings(settings); - } function resolveInitialNotesRoot() { const envNotesRoot = process.env.NOTES_ROOT; @@ -291,8 +264,6 @@ function createMainHelpers(deps) { return { readUserSettings, writeUserSettings, - getLastPdfExportPath, - rememberPdfExportPath, resolveInitialNotesRoot, readP2PStatusSnapshot, listProjectsState, diff --git a/electron/lib/documents/documentIpc.cjs b/electron/lib/documents/documentIpc.cjs index d8a11126..9cdc6fa8 100644 --- a/electron/lib/documents/documentIpc.cjs +++ b/electron/lib/documents/documentIpc.cjs @@ -1,11 +1,9 @@ +const { app, BrowserWindow, dialog, shell } = require("electron"); const { assertTrustedIpcSender } = require("../ipc/ipcSecurity.cjs"); const { buildWorkspaceGraph } = require("./workspaceGraph.cjs"); function registerDocumentIpcHandlers(ipcMain, deps) { const { - BrowserWindow, - dialog, - shell, fs, os, path, @@ -32,11 +30,10 @@ function registerDocumentIpcHandlers(ipcMain, deps) { prepareDocumentPreview, syncWebPreviewScope, tryOpenInChrome, - getLastPdfExportPath, - rememberPdfExportPath, buildPdfExportMarkdown, buildPdfExportHtml, getAppDataDir, + exportHistoryStore, } = deps; const PDF_WRITE_RETRY_DELAYS_MS = [120, 320, 700]; @@ -419,10 +416,11 @@ function registerDocumentIpcHandlers(ipcMain, deps) { const focusedWindow = BrowserWindow.getFocusedWindow() || BrowserWindow.getAllWindows()[0] || null; const defaultName = `${path.basename(resolved, ".md") || "note"}.pdf`; - const lastPdfExportPath = getLastPdfExportPath(); - const defaultSavePath = lastPdfExportPath - ? path.join(lastPdfExportPath, defaultName) + const downloadsDir = app ? app.getPath("downloads") : ""; + const defaultSavePath = downloadsDir + ? path.join(downloadsDir, defaultName) : path.join(path.dirname(resolved), defaultName); + const saveResult = await dialog.showSaveDialog(focusedWindow, { title: "Save note as PDF", defaultPath: defaultSavePath, @@ -482,7 +480,20 @@ function registerDocumentIpcHandlers(ipcMain, deps) { } throw error; } - rememberPdfExportPath(saveResult.filePath); + + if (exportHistoryStore && saveResult.filePath) { + try { + const stat = fs.statSync(saveResult.filePath); + await exportHistoryStore.addRecord({ + filename: path.basename(saveResult.filePath), + filePath: saveResult.filePath, + fileSize: stat.size, + exportType: "pdf", + category: "document", + sourceNote: path.basename(resolved) + }); + } catch {} + } } finally { if (!pdfWindow.isDestroyed()) { pdfWindow.close(); diff --git a/electron/lib/export/exportHistoryIpc.cjs b/electron/lib/export/exportHistoryIpc.cjs new file mode 100644 index 00000000..28aaa6da --- /dev/null +++ b/electron/lib/export/exportHistoryIpc.cjs @@ -0,0 +1,58 @@ +const { assertTrustedIpcSender } = require("../ipc/ipcSecurity.cjs"); + +function registerExportHistoryIpc({ ipcMain, BrowserWindow, shell, app, exportHistoryStore }) { + function registerTrustedHandler(channel, handler) { + ipcMain.handle(channel, (event, payload) => { + assertTrustedIpcSender(BrowserWindow, event, channel); + return handler(event, payload); + }); + } + + registerTrustedHandler("exports:getHistory", async () => { + return await exportHistoryStore.getHistory(); + }); + + registerTrustedHandler("exports:addRecord", async (_, record) => { + return await exportHistoryStore.addRecord(record); + }); + + registerTrustedHandler("exports:removeRecord", async (_, { id }) => { + return await exportHistoryStore.removeRecord(id); + }); + + registerTrustedHandler("exports:clearHistory", async () => { + return await exportHistoryStore.clearHistory(); + }); + + registerTrustedHandler("exports:showInFolder", async (_, { filePath }) => { + if (!filePath || typeof filePath !== "string") return false; + try { + shell.showItemInFolder(filePath); + return true; + } catch (err) { + console.warn("[exportHistoryIpc] Failed to show in folder:", err); + return false; + } + }); + + registerTrustedHandler("exports:openFile", async (_, { filePath }) => { + if (!filePath || typeof filePath !== "string") return false; + try { + const result = await shell.openPath(filePath); + return result === ""; // empty string means success in Electron shell.openPath + } catch (err) { + console.warn("[exportHistoryIpc] Failed to open file:", err); + return false; + } + }); + + registerTrustedHandler("exports:getDefaultDownloadDir", async () => { + try { + return app.getPath("downloads"); + } catch { + return app.getPath("documents"); + } + }); +} + +module.exports = { registerExportHistoryIpc }; diff --git a/electron/lib/export/exportHistoryStore.cjs b/electron/lib/export/exportHistoryStore.cjs new file mode 100644 index 00000000..c046efa6 --- /dev/null +++ b/electron/lib/export/exportHistoryStore.cjs @@ -0,0 +1,153 @@ +const fs = require("fs"); +const path = require("path"); +const crypto = require("crypto"); +const { DatabaseSync } = require("node:sqlite"); + +const DB_DIR = ".notes-app"; +const DB_FILE = "export-history.db"; + +const SCHEMA = ` + PRAGMA journal_mode = WAL; + CREATE TABLE IF NOT EXISTS export_history ( + id TEXT PRIMARY KEY, + filename TEXT NOT NULL, + file_path TEXT NOT NULL, + file_size INTEGER DEFAULT 0, + export_type TEXT NOT NULL, + category TEXT NOT NULL, + timestamp TEXT NOT NULL, + source_note TEXT DEFAULT '' + ); + CREATE INDEX IF NOT EXISTS idx_export_timestamp ON export_history(timestamp); + CREATE INDEX IF NOT EXISTS idx_export_file_path ON export_history(file_path); +`; + +class ExportHistoryStore { + constructor(appDataPath, getNotesRootFn = null) { + this.appDataPath = appDataPath; + this.getNotesRootFn = getNotesRootFn; + this.db = null; + this.currentDbPath = null; + } + + _getDbDir() { + let workspaceRoot = ""; + if (typeof this.getNotesRootFn === "function") { + try { workspaceRoot = this.getNotesRootFn(); } catch { /* ignore */ } + } + if (workspaceRoot && fs.existsSync(workspaceRoot)) { + const dir = path.join(workspaceRoot, DB_DIR); + if (!fs.existsSync(dir)) { + try { fs.mkdirSync(dir, { recursive: true }); } catch { /* ignore */ } + } + return dir; + } + return this.appDataPath; + } + + _ensureConnection() { + const targetDir = this._getDbDir(); + const targetDbPath = path.join(targetDir, DB_FILE); + + if (this.currentDbPath === targetDbPath && this.db) { + return; + } + + this.close(); + this.currentDbPath = targetDbPath; + + try { + this.db = new DatabaseSync(targetDbPath); + this.db.exec(SCHEMA); + } catch (err) { + console.error("[ExportHistoryStore] Failed to open SQLite connection:", err); + this.db = null; + } + } + + close() { + if (this.db) { + try { this.db.close(); } catch { /* ignore */ } + this.db = null; + } + } + + async addRecord({ filename, filePath, fileSize = 0, exportType = "document", category = "document", sourceNote = "" }) { + this._ensureConnection(); + if (!this.db) return null; + + const record = { + id: "exp_" + Date.now() + "_" + crypto.randomBytes(4).toString("hex"), + filename: filename || path.basename(filePath || "exported_file"), + filePath: filePath || "", + fileSize: Number(fileSize) || 0, + exportType: exportType, + category: category, + timestamp: new Date().toISOString(), + sourceNote: sourceNote || "" + }; + + try { + // Remove previous entries with exact same file_path + this.db.prepare("DELETE FROM export_history WHERE LOWER(file_path) = LOWER(?)").run(record.filePath); + } catch {} + + const stmt = this.db.prepare(` + INSERT INTO export_history (id, filename, file_path, file_size, export_type, category, timestamp, source_note) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + `); + stmt.run(record.id, record.filename, record.filePath, record.fileSize, record.exportType, record.category, record.timestamp, record.sourceNote); + + return record; + } + + async getHistory() { + this._ensureConnection(); + if (!this.db) return []; + + let rows = []; + try { + const rawRows = this.db.prepare("SELECT * FROM export_history ORDER BY timestamp DESC LIMIT 200").all(); + rows = rawRows.map(r => ({ + id: r.id, + filename: r.filename, + filePath: r.file_path, + fileSize: r.file_size, + exportType: r.export_type, + category: r.category, + timestamp: r.timestamp, + sourceNote: r.source_note + })); + } catch (err) { + console.warn("[ExportHistoryStore] DB query error:", err); + rows = []; + } + + return rows.map(rec => ({ + ...rec, + exists: rec.filePath ? fs.existsSync(rec.filePath) : false + })); + } + + async removeRecord(id) { + this._ensureConnection(); + if (!this.db) return false; + + try { + this.db.prepare("DELETE FROM export_history WHERE id = ?").run(id); + } catch {} + return true; + } + + async clearHistory() { + this._ensureConnection(); + if (!this.db) return false; + + try { + this.db.prepare("DELETE FROM export_history").run(); + } catch {} + return true; + } +} + +module.exports = { ExportHistoryStore }; diff --git a/electron/lib/export/notePackageIpc.cjs b/electron/lib/export/notePackageIpc.cjs index 4ebebdb4..5313080c 100644 --- a/electron/lib/export/notePackageIpc.cjs +++ b/electron/lib/export/notePackageIpc.cjs @@ -103,20 +103,20 @@ function ensureDirSync(dirPath) { /** * Register note package IPC handlers */ -function registerNotePackageIpc(ipcMain, deps) { - const { BrowserWindow, dialog, getNotesRoot, filePathWithin, readUserSettings, getActiveProject } = deps; +function registerNotePackageIpc(ipcMain, deps = {}) { + const { BrowserWindow, dialog, getNotesRoot, filePathWithin, readUserSettings, getActiveProject, exportHistoryStore } = deps; + const { app } = require("electron"); - function handleTrusted(channel, handler) { - ipcMain.handle(channel, async (event, payload) => { - // Basic trusted sender check - try { - const win = BrowserWindow.fromWebContents(event.sender); - if (!win || win.isDestroyed()) throw new Error("Invalid sender window"); - } catch (err) { - return { ok: false, error: err.message }; - } + function assertTrustedIpcSender(BrowserWindow, event, channel) { + const win = BrowserWindow.fromWebContents(event.sender); + if (!win || win.isDestroyed()) throw new Error("Invalid sender window"); + } + + function handleTrusted(channel, fn) { + ipcMain.handle(channel, async (event, ...args) => { + assertTrustedIpcSender(BrowserWindow, event, channel); try { - return await handler(event, payload); + return await fn(event, ...args); } catch (err) { console.error(`[notePackageIpc] ${channel} error:`, err); return { ok: false, error: err.message }; @@ -148,6 +148,15 @@ function registerNotePackageIpc(ipcMain, deps) { } } + if (!destPath) { + try { + const downloadsPath = app ? app.getPath("downloads") : ""; + if (downloadsPath && fsSync.existsSync(downloadsPath)) { + destPath = downloadsPath; + } + } catch {} + } + if (!destPath) { const activeProject = typeof getActiveProject === "function" ? getActiveProject() : null; destPath = path.resolve(activeProject?.rootPath || notesRoot); @@ -163,9 +172,12 @@ function registerNotePackageIpc(ipcMain, deps) { // --- Browse Export Destination --- handleTrusted("note-package:browse-export-destination", async (event, { defaultFileName }) => { const focusedWindow = BrowserWindow.fromWebContents(event.sender); + let defaultDir = ""; + try { defaultDir = app ? app.getPath("downloads") : ""; } catch {} + const defaultPath = defaultDir ? path.join(defaultDir, defaultFileName || "notes_package.nly") : (defaultFileName || "notes_package.nly"); const result = await dialog.showSaveDialog(focusedWindow, { title: "Export Note Package", - defaultPath: defaultFileName || "notes_package.nly", + defaultPath, filters: [{ name: "Notely Shareable Package", extensions: ["nly", "note"] }], }); if (result.canceled || !result.filePath) { @@ -400,6 +412,21 @@ function registerNotePackageIpc(ipcMain, deps) { try { await fs.unlink(finalDestTmp); } catch { /* ignore */ } } + if (exportHistoryStore) { + try { + const stat = fsSync.statSync(finalDest); + await exportHistoryStore.addRecord({ + filename: path.basename(finalDest), + filePath: finalDest, + fileSize: stat.size, + exportType: "note_package", + category: "document" + }); + } catch (err) { + console.warn("[notePackageIpc] Failed to log export history:", err); + } + } + return { success: true, destination: finalDest, diff --git a/electron/lib/export/workspaceExportIpc.cjs b/electron/lib/export/workspaceExportIpc.cjs index 87decfd1..db560aeb 100644 --- a/electron/lib/export/workspaceExportIpc.cjs +++ b/electron/lib/export/workspaceExportIpc.cjs @@ -471,6 +471,7 @@ function registerWorkspaceExportIpcHandlers(ipcMain, deps) { parseDocument, buildPdfExportMarkdown, buildPdfExportHtml, + exportHistoryStore, } = deps; function registerTrustedHandler(channel, handler) { @@ -481,26 +482,15 @@ function registerWorkspaceExportIpcHandlers(ipcMain, deps) { } function getDefaultDestinationPath() { - const settings = readUserSettings(); - const lastPath = typeof settings.lastWorkspaceExportPath === "string" - ? settings.lastWorkspaceExportPath.trim() - : ""; - - if (lastPath) { - const resolved = path.resolve(lastPath); - if (fs.existsSync(resolved)) return resolved; - } - + const { app } = require("electron"); + try { + const downloads = app ? app.getPath("downloads") : ""; + if (downloads && fs.existsSync(downloads)) return downloads; + } catch {} const activeProject = getActiveProject(); return path.resolve(activeProject?.rootPath || getNotesRoot()); } - function rememberExportPath(destinationPath) { - const settings = readUserSettings(); - settings.lastWorkspaceExportPath = path.resolve(destinationPath); - writeUserSettings(settings); - } - registerTrustedHandler("workspace-export:get-defaults", () => { const mode = DEFAULT_EXPORT_MODE; const notesRoot = path.resolve(getNotesRoot()); @@ -632,9 +622,21 @@ function registerWorkspaceExportIpcHandlers(ipcMain, deps) { sendProgress({ phase: "Compressing zip", percent: 88 }); const zipResult = await zipDirectory(fs, path, stagingRoot, outputPath, { rootFolderName: archiveRootName }); - rememberExportPath(destinationPath); sendProgress({ phase: "Export complete", percent: 100, done: true, filePath: outputPath }); + if (exportHistoryStore) { + try { + const stat = fs.statSync(outputPath); + await exportHistoryStore.addRecord({ + filename: path.basename(outputPath), + filePath: outputPath, + fileSize: stat.size, + exportType: mode === "pdf" ? "pdf" : mode === "web" ? "html" : "workspace_zip", + category: "document" + }); + } catch {} + } + return { canceled: false, filePath: outputPath, diff --git a/electron/lib/media/imageMedia.cjs b/electron/lib/media/imageMedia.cjs index 324cb929..29c8a104 100644 --- a/electron/lib/media/imageMedia.cjs +++ b/electron/lib/media/imageMedia.cjs @@ -27,8 +27,7 @@ function createImageMedia(deps) { getAppDataDir, emitLocalP2PSyncEvent, hashContent, - getLastPdfExportPath, - rememberPdfExportPath + exportHistoryStore } = deps; const THUMBNAIL_DIR_NAME = "thumbnails"; @@ -732,12 +731,12 @@ registerTrustedHandler("images:download", async (event, payload) => { throw new Error("Invalid download data."); } - const { dialog } = require("electron"); + const { app, dialog } = require("electron"); const fs = require("fs"); - const lastPdfExportPath = typeof getLastPdfExportPath === "function" ? getLastPdfExportPath() : ""; - const defaultSavePath = lastPdfExportPath - ? path.join(lastPdfExportPath, defaultFilename || "diagram.png") + const downloadsDir = app ? app.getPath("downloads") : ""; + const defaultSavePath = downloadsDir + ? path.join(downloadsDir, defaultFilename || "diagram.png") : defaultFilename || "diagram.png"; const { filePath } = await dialog.showSaveDialog(BrowserWindow.fromWebContents(event.sender), { @@ -756,8 +755,22 @@ registerTrustedHandler("images:download", async (event, payload) => { const buffer = Buffer.from(base64Data.split(",")[1], "base64"); fs.writeFileSync(filePath, buffer); - if (typeof rememberPdfExportPath === "function") { - rememberPdfExportPath(filePath); + if (exportHistoryStore) { + try { + const filename = path.basename(filePath); + const isDiagram = (defaultFilename || filename).toLowerCase().includes("diagram") + || (defaultFilename || filename).toLowerCase().includes("excali") + || (defaultFilename || filename).toLowerCase().includes("drawio"); + await exportHistoryStore.addRecord({ + filename, + filePath, + fileSize: buffer.length, + exportType: isDiagram ? "diagram_excalidraw" : "image", + category: isDiagram ? "diagram" : "media" + }); + } catch (err) { + console.error("Failed to record image download in export history:", err); + } } return { success: true, filePath }; diff --git a/electron/main.cjs b/electron/main.cjs index 9dee0996..879391d0 100644 --- a/electron/main.cjs +++ b/electron/main.cjs @@ -46,8 +46,14 @@ const { registerGitIpcHandlers } = require("./lib/git/gitIpc.cjs"); const gitService = require("./lib/git/gitService.cjs"); const { registerNotePackageIpc } = require("./lib/export/notePackageIpc.cjs"); const { registerTaskIpc } = require("./lib/tasks/taskIpc.cjs"); +const { ExportHistoryStore } = require("./lib/export/exportHistoryStore.cjs"); +const { registerExportHistoryIpc } = require("./lib/export/exportHistoryIpc.cjs"); +const exportHistoryStore = new ExportHistoryStore(app.getPath("userData"), () => notesRoot); const rendererUrl = process.env.ELECTRON_RENDERER_URL; + + + const projectRoot = app.getAppPath(); const generatedVersionPath = path.join(projectRoot, "electron", "app-version.generated.json"); const sessionDataPath = path.join(app.getPath("userData"), "session-data"); @@ -426,14 +432,6 @@ function broadcastThemeChange() { } } -function getLastPdfExportPath() { - return mainHelpers.getLastPdfExportPath(); -} - -function rememberPdfExportPath(filePath) { - return mainHelpers.rememberPdfExportPath(filePath); -} - function resolveInitialNotesRoot() { return mainHelpers.resolveInitialNotesRoot(); } @@ -739,8 +737,7 @@ const imageMedia = createImageMedia({ getAppDataDir: () => appDataDir, emitLocalP2PSyncEvent: (payload) => p2pSyncEngine.emitLocalP2PSyncEvent(payload), hashContent, - getLastPdfExportPath, - rememberPdfExportPath, + exportHistoryStore, }); const { @@ -1093,6 +1090,11 @@ ipcMain.on("window:execute-menu-item", (event, { indexPath, role, action }) => { const win = BrowserWindow.fromWebContents(event.sender); if (!win) return; + if (action) { + sendMenuAction(win, action); + return; + } + if (Array.isArray(indexPath)) { const rawTemplate = buildAppMenuTemplate(win, win.__menuContext || {}); let currentItems = rawTemplate; @@ -1224,11 +1226,10 @@ registerDocumentIpcHandlers(ipcMain, { prepareDocumentPreview: webPreview.prepareDocumentPreview, syncWebPreviewScope: webPreview.syncScopeToActiveProject, tryOpenInChrome: webPreview.tryOpenInChrome, - getLastPdfExportPath, - rememberPdfExportPath, buildPdfExportMarkdown, buildPdfExportHtml, getAppDataDir: () => appDataDir, + exportHistoryStore, }); registerWorkspaceExportIpcHandlers(ipcMain, { @@ -1247,6 +1248,7 @@ registerWorkspaceExportIpcHandlers(ipcMain, { parseDocument, buildPdfExportMarkdown, buildPdfExportHtml, + exportHistoryStore, }); registerNotePackageIpc(ipcMain, { @@ -1256,6 +1258,15 @@ registerNotePackageIpc(ipcMain, { filePathWithin, readUserSettings, getActiveProject, + exportHistoryStore, +}); + +registerExportHistoryIpc({ + ipcMain, + BrowserWindow, + shell, + app, + exportHistoryStore, }); imageMedia.registerIpcHandlers(ipcMain); @@ -1279,3 +1290,4 @@ registerTaskIpc(ipcMain, { getMetadataStore: () => metadataStore, getAppDataDir: () => appDataDir, }); + diff --git a/electron/preload.cjs b/electron/preload.cjs index 04a01689..80639f68 100644 --- a/electron/preload.cjs +++ b/electron/preload.cjs @@ -373,5 +373,15 @@ contextBridge.exposeInMainWorld("notesApi", { listPersons: () => ipcRenderer.invoke("persons:list"), upsertPerson: (p) => ipcRenderer.invoke("persons:upsert", p), deletePerson: (p) => ipcRenderer.invoke("persons:delete", p), + + // ── Exports & Downloads ────────────────────────────────────────────────── + getExportHistory: () => ipcRenderer.invoke("exports:getHistory"), + addExportRecord: (payload) => ipcRenderer.invoke("exports:addRecord", payload), + removeExportRecord: (payload) => ipcRenderer.invoke("exports:removeRecord", { id: payload }), + clearExportHistory: () => ipcRenderer.invoke("exports:clearHistory"), + showInFolder: (filePath) => ipcRenderer.invoke("exports:showInFolder", { filePath }), + openExportFile: (filePath) => ipcRenderer.invoke("exports:openFile", { filePath }), + getDefaultDownloadDir: () => ipcRenderer.invoke("exports:getDefaultDownloadDir"), }); + diff --git a/src/App.jsx b/src/App.jsx index 637abfc4..6b1d9f08 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -26,6 +26,8 @@ const AIHealthPage = lazy(() => import("./components/AIHealthPage")); const AppLogsPage = lazy(() => import("./components/AppLogsPage")); const TaskWorkspacePage = lazy(() => import("./components/TaskWorkspacePage").then((m) => ({ default: m.TaskWorkspacePage }))); const CalendarPage = lazy(() => import("./components/CalendarPage").then((m) => ({ default: m.CalendarPage }))); +const DownloadsPage = lazy(() => import("./components/DownloadsPage").then((m) => ({ default: m.DownloadsPage }))); + import { SettingsModal } from "./components/SettingsModal"; @@ -680,6 +682,8 @@ export default function App() { } }, []); + const [downloadsPageOpen, setDownloadsPageOpen] = useState(false); + useEffect(() => { if (window.notesApi?.getWorkspaceInfo) { window.notesApi.getWorkspaceInfo().then((info) => { @@ -1149,11 +1153,14 @@ export default function App() { const subscribe = api?.onMenuAction || api?.onAppMenuAction; if (!subscribe) return undefined; return subscribe((action) => { + if (!action) return; if (action === "restart-app") { void handleRestartApp(); + return; } + void handleRunPaletteCommand(action); }); - }, [handleRestartApp]); + }, [handleRestartApp, handleRunPaletteCommand]); useEffect(() => { const api = window.electronAPI || window.notesApi; @@ -1323,6 +1330,10 @@ export default function App() { e.preventDefault(); setMarkdownGuideOpen(true); } + if (e.key && e.key.toLowerCase() === "j" && (e.ctrlKey || e.metaKey)) { + e.preventDefault(); + setDownloadsPageOpen((prev) => !prev); + } if (e.key === "," && (e.ctrlKey || e.metaKey)) { e.preventDefault(); openSettings("general"); @@ -2308,6 +2319,13 @@ export default function App() { disabled: !current, aliases: "home notes list landing back", }, + { + id: "open-downloads-page", + label: "Open Downloads & Export History", + group: "Exports", + shortcut: "Ctrl/Cmd+J", + aliases: "downloads export history pdf html zip package files", + }, { id: "toggle-focus-mode", label: focusModeEnabled ? "Exit Focus Mode" : "Enter Focus Mode", @@ -2583,6 +2601,11 @@ export default function App() { return; } + if (resolvedCommandId === "open-downloads-page" || resolvedCommandId === "open-downloads") { + setDownloadsPageOpen(true); + return; + } + if (resolvedCommandId === "open-recent-workspaces") { setRecentWorkspacesDialogOpen(true); return; @@ -2989,6 +3012,7 @@ export default function App() { title={current ? current.title : (workspaceInfoState?.name || (activeProject ? activeProject.name : "Notely"))} workspaceIcon={current ? null : (workspaceInfoState?.icon || "📝")} onOpenWebsite={current ? handleOpenWebsiteForCurrent : handleOpenWebsiteFromLanding} + onOpenDownloads={() => setDownloadsPageOpen(true)} />
@@ -4021,6 +4045,16 @@ export default function App() {
)} + {downloadsPageOpen && ( +
+ Loading Downloads & Export History…
}> + setDownloadsPageOpen(false)} + /> + +
+ )} + diff --git a/src/components/DownloadsPage.jsx b/src/components/DownloadsPage.jsx new file mode 100644 index 00000000..0f036dc6 --- /dev/null +++ b/src/components/DownloadsPage.jsx @@ -0,0 +1,334 @@ +import React, { useState, useEffect, useMemo } from "react"; +import { + Download, + Folder, + FileText, + FileCode, + Image, + Archive, + Search, + Trash2, + ExternalLink, + RefreshCw, + FolderOpen +} from "lucide-react"; +import { + getExportHistory, + removeExportRecord, + clearExportHistory, + showInFolder, + openExportFile, + getDefaultDownloadDir +} from "../services/electronService.js"; +import "../styles/DownloadsPage.css"; + +function formatBytes(bytes) { + if (!bytes || bytes === 0) return "0 B"; + const k = 1024; + const sizes = ["B", "KB", "MB", "GB"]; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + " " + sizes[i]; +} + +function formatTimestamp(isoString) { + if (!isoString) return ""; + try { + const date = new Date(isoString); + const now = new Date(); + const diffMs = now - date; + const diffMins = Math.floor(diffMs / (1000 * 60)); + const diffHours = Math.floor(diffMs / (1000 * 60 * 60)); + const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); + + if (diffMins < 1) return "Just now"; + if (diffMins < 60) return `${diffMins}m ago`; + if (diffHours < 24) return `${diffHours}h ago`; + if (diffDays === 1) return "Yesterday"; + if (diffDays < 7) return `${diffDays}d ago`; + + return date.toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" }); + } catch { + return isoString; + } +} + +function getIconForType(type) { + switch (type) { + case "pdf": + return ; + case "note_package": + return ; + case "html": + return ; + case "diagram_excalidraw": + case "diagram_drawio": + return ; + case "image": + case "media": + return ; + case "zip": + return ; + default: + return ; + } +} + +export function DownloadsPage({ onBack }) { + const [history, setHistory] = useState([]); + const [loading, setLoading] = useState(true); + const [activeTab, setActiveTab] = useState("all"); + const [searchQuery, setSearchQuery] = useState(""); + const [defaultDir, setDefaultDir] = useState(""); + + const loadHistory = async () => { + setLoading(true); + try { + const records = await getExportHistory(); + setHistory(Array.isArray(records) ? records : []); + } catch (err) { + console.error("Failed to load export history:", err); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + loadHistory(); + getDefaultDownloadDir().then((dir) => { + if (dir) setDefaultDir(dir); + }).catch(() => {}); + }, []); + + const handleShowInFolder = async (filePath) => { + if (!filePath) return; + await showInFolder(filePath); + }; + + const handleOpenFile = async (filePath) => { + if (!filePath) return; + await openExportFile(filePath); + }; + + const handleRemove = async (id) => { + await removeExportRecord(id); + setHistory((prev) => prev.filter((item) => item.id !== id)); + }; + + const handleClearAll = async () => { + if (!window.confirm("Are you sure you want to clear export history? (Exported files on disk will not be deleted)")) { + return; + } + await clearExportHistory(); + setHistory([]); + }; + + const handleOpenDownloadsFolder = async () => { + if (defaultDir) { + await showInFolder(defaultDir); + } + }; + + const docCount = useMemo(() => { + return history.filter((i) => ["pdf", "html", "note_package", "markdown"].includes(i.exportType)).length; + }, [history]); + + const diagramCount = useMemo(() => { + return history.filter((i) => ["diagram_excalidraw", "diagram_drawio"].includes(i.exportType)).length; + }, [history]); + + const mediaCount = useMemo(() => { + return history.filter((i) => ["image", "media"].includes(i.exportType) || i.category === "media").length; + }, [history]); + + const filteredHistory = useMemo(() => { + return history.filter((item) => { + // Category filter + if (activeTab === "documents" && !["pdf", "html", "note_package", "markdown"].includes(item.exportType)) { + return false; + } + if (activeTab === "diagrams" && !["diagram_excalidraw", "diagram_drawio"].includes(item.exportType)) { + return false; + } + if (activeTab === "media" && !["image", "media"].includes(item.exportType) && item.category !== "media") { + return false; + } + + // Search filter + if (searchQuery.trim()) { + const q = searchQuery.toLowerCase().trim(); + const nameMatch = item.filename?.toLowerCase().includes(q); + const pathMatch = item.filePath?.toLowerCase().includes(q); + return nameMatch || pathMatch; + } + + return true; + }); + }, [history, activeTab, searchQuery]); + + return ( +
+ {/* Unified App-Standard Topbar Navigation & Actions */} +
+ + +
+
+ + {filteredHistory.length} items +
+ + {defaultDir && ( + + )} + + {history.length > 0 && ( + + )} + + +
+
+ +
+
+
+ + + + +
+ +
+ + setSearchQuery(e.target.value)} + /> +
+
+ + {filteredHistory.length === 0 ? ( +
+ +

No exports found

+

Exported notes, workspace zip archives, diagrams, and rendered files will appear here.

+
+ ) : ( +
+ {filteredHistory.map((item) => ( +
+
{getIconForType(item.exportType)}
+ +
+
+ {item.filename} +
+
+ + {item.exportType ? item.exportType.replace("_", " ") : "file"} + + {formatBytes(item.fileSize)} + + {formatTimestamp(item.timestamp)} + {item.sourceNote && ( + <> + + Note: {item.sourceNote} + + )} +
+
+ {item.filePath} +
+
+ +
+ + + + + +
+
+ ))} +
+ )} +
+
+ ); +} diff --git a/src/components/layout/TitleBar.jsx b/src/components/layout/TitleBar.jsx index 38405e26..c5f8d1ca 100644 --- a/src/components/layout/TitleBar.jsx +++ b/src/components/layout/TitleBar.jsx @@ -67,6 +67,8 @@ const MENU_ICON_MAP = { "tasks": CheckSquare, "calendar": Clock, "assets library": ImageIcon, + "downloads & export history": Download, + "downloads export history": Download, "workspace": FolderOpen, "workspace information": Info, "workspace activity": Activity, @@ -156,7 +158,7 @@ function getItemIcon(item) { return ; } -export function TitleBar({ title = "Notely", workspaceIcon, onOpenWebsite }) { +export function TitleBar({ title = "Notely", workspaceIcon, onOpenWebsite, onOpenDownloads }) { const [isMaximized, setIsMaximized] = useState(false); const [menuStructure, setMenuStructure] = useState([]); const [activeMenuIndex, setActiveMenuIndex] = useState(null); @@ -257,7 +259,8 @@ export function TitleBar({ title = "Notely", workspaceIcon, onOpenWebsite }) { if (item.submenu) return; // Submenus open on hover/interaction window.notesApi?.executeMenuItem?.({ - indexPath + indexPath, + action: item.action }); closeAllMenus(); }; @@ -388,6 +391,18 @@ export function TitleBar({ title = "Notely", workspaceIcon, onOpenWebsite }) {
+ {onOpenDownloads && ( + + )} {onOpenWebsite && ( )} {history.length > 0 && ( )} -
@@ -264,7 +264,7 @@ export function DownloadsPage({ onBack }) { {filteredHistory.length === 0 ? (
- +

No exports found

Exported notes, workspace zip archives, diagrams, and rendered files will appear here.

@@ -303,7 +303,7 @@ export function DownloadsPage({ onBack }) { onClick={() => handleShowInFolder(item.filePath)} title="Show in File Explorer" > - + Show in Folder @@ -312,16 +312,16 @@ export function DownloadsPage({ onBack }) { onClick={() => handleOpenFile(item.filePath)} title="Open File" > - + Open From c7ba9341bb5d1eb1a93fc858c29980a00811454e Mon Sep 17 00:00:00 2001 From: Bikash Panda Date: Sat, 8 Aug 2026 10:47:05 +0530 Subject: [PATCH 05/18] cleaned yp --- src/components/DownloadsPage.jsx | 194 ++++++--- src/styles/DownloadsPage.css | 409 ++++++++++++++---- .../DownloadsPage.integration.test.jsx | 137 ++++++ 3 files changed, 590 insertions(+), 150 deletions(-) create mode 100644 src/tests/components/DownloadsPage.integration.test.jsx diff --git a/src/components/DownloadsPage.jsx b/src/components/DownloadsPage.jsx index 20fb34fc..4aa9d723 100644 --- a/src/components/DownloadsPage.jsx +++ b/src/components/DownloadsPage.jsx @@ -1,25 +1,31 @@ -import React, { useState, useEffect, useMemo } from "react"; +import React, { useEffect, useState, useMemo } from "react"; import { + FolderOpen, + Trash2, Download, - Folder, FileText, FileCode, - Image, Archive, + Image, + RefreshCw, Search, - Trash2, ExternalLink, - RefreshCw, - FolderOpen + Folder, + X, + Loader2, } from "lucide-react"; import { getExportHistory, - removeExportRecord, clearExportHistory, - showInFolder, + removeExportRecord, openExportFile, - getDefaultDownloadDir + showInFolder, + getDefaultDownloadDir, } from "../services/electronService.js"; +import AppButton from "./AppButton.jsx"; +import AppIconButton from "./AppIconButton.jsx"; +import { AppCard } from "./AppCard.jsx"; +import useConfirm from "../hooks/useConfirm.js"; import "../styles/DownloadsPage.css"; function formatBytes(bytes) { @@ -74,6 +80,7 @@ function getIconForType(type) { } export function DownloadsPage({ onBack }) { + const { confirm } = useConfirm(); const [history, setHistory] = useState([]); const [loading, setLoading] = useState(true); const [activeTab, setActiveTab] = useState("all"); @@ -94,9 +101,11 @@ export function DownloadsPage({ onBack }) { useEffect(() => { loadHistory(); - getDefaultDownloadDir().then((dir) => { - if (dir) setDefaultDir(dir); - }).catch(() => {}); + getDefaultDownloadDir() + .then((dir) => { + if (dir) setDefaultDir(dir); + }) + .catch(() => {}); }, []); const handleShowInFolder = async (filePath) => { @@ -115,9 +124,16 @@ export function DownloadsPage({ onBack }) { }; const handleClearAll = async () => { - if (!window.confirm("Are you sure you want to clear export history? (Exported files on disk will not be deleted)")) { - return; - } + const isConfirmed = await confirm({ + title: "Clear Export History", + message: + "Are you sure you want to clear export history? (Exported files on disk will not be deleted)", + confirmText: "Clear History", + cancelText: "Cancel", + danger: true, + }); + if (!isConfirmed) return; + await clearExportHistory(); setHistory([]); }; @@ -129,36 +145,48 @@ export function DownloadsPage({ onBack }) { }; const docCount = useMemo(() => { - return history.filter((i) => ["pdf", "html", "note_package", "markdown"].includes(i.exportType)).length; + return history.filter((i) => + ["pdf", "html", "note_package", "markdown"].includes(i.exportType) + ).length; }, [history]); const diagramCount = useMemo(() => { - return history.filter((i) => ["diagram_excalidraw", "diagram_drawio"].includes(i.exportType)).length; + return history.filter((i) => + ["diagram_excalidraw", "diagram_drawio"].includes(i.exportType) + ).length; }, [history]); const mediaCount = useMemo(() => { - return history.filter((i) => ["image", "media"].includes(i.exportType) || i.category === "media").length; + return history.filter( + (i) => ["image", "media"].includes(i.exportType) || i.category === "media" + ).length; }, [history]); const filteredHistory = useMemo(() => { return history.filter((item) => { - // Category filter - if (activeTab === "documents" && !["pdf", "html", "note_package", "markdown"].includes(item.exportType)) { + if ( + activeTab === "documents" && + !["pdf", "html", "note_package", "markdown"].includes(item.exportType) + ) { return false; } - if (activeTab === "diagrams" && !["diagram_excalidraw", "diagram_drawio"].includes(item.exportType)) { + if ( + activeTab === "diagrams" && + !["diagram_excalidraw", "diagram_drawio"].includes(item.exportType) + ) { return false; } - if (activeTab === "media" && !["image", "media"].includes(item.exportType) && item.category !== "media") { + if ( + activeTab === "media" && + !["image", "media"].includes(item.exportType) && + item.category !== "media" + ) { return false; } - // Search filter if (searchQuery.trim()) { const q = searchQuery.toLowerCase().trim(); - const nameMatch = item.filename?.toLowerCase().includes(q); - const pathMatch = item.filePath?.toLowerCase().includes(q); - return nameMatch || pathMatch; + return item.filename?.toLowerCase().includes(q) || item.filePath?.toLowerCase().includes(q); } return true; @@ -167,57 +195,64 @@ export function DownloadsPage({ onBack }) { return (
- {/* Unified App-Standard Topbar Navigation & Actions */}
-
+
{filteredHistory.length} items
{defaultDir && ( - + )} {history.length > 0 && ( - + )} - + Refresh +
-
+
+ )}
- {filteredHistory.length === 0 ? ( + {loading && history.length === 0 ? ( +
+ + Loading export history... +
+ ) : filteredHistory.length === 0 ? (
- -

No exports found

-

Exported notes, workspace zip archives, diagrams, and rendered files will appear here.

+ {searchQuery ? ( + <> + +

No matching exports

+

No export history items found matching “{searchQuery}”

+ setSearchQuery("")} style={{ marginTop: "12px" }}> + Clear Search + + + ) : ( + <> + +

No exports found

+

Exported notes, workspace zip archives, diagrams, and rendered files will appear here.

+ + )}
) : (
{filteredHistory.map((item) => ( -
+
{getIconForType(item.exportType)}
-
- {item.filename} -
-
+
+
+ {item.filename} +
{item.exportType ? item.exportType.replace("_", " ") : "file"} +
+
{formatBytes(item.fileSize)} - + {formatTimestamp(item.timestamp)} {item.sourceNote && ( <> - + Note: {item.sourceNote} )} @@ -298,33 +368,35 @@ export function DownloadsPage({ onBack }) {
- + - + - + Remove +
-
+ ))}
)} @@ -332,3 +404,5 @@ export function DownloadsPage({ onBack }) {
); } + +export default DownloadsPage; diff --git a/src/styles/DownloadsPage.css b/src/styles/DownloadsPage.css index da1dafb2..302f0396 100644 --- a/src/styles/DownloadsPage.css +++ b/src/styles/DownloadsPage.css @@ -6,11 +6,13 @@ height: 100%; width: 100%; background: var(--app-bg); - color: var(--text-strong); + color: var(--app-text); font-family: var(--font-sans, inherit); overflow: hidden; } +/* ── Topbar Navigation & Actions ─────────────────────────────────────────── */ + .downloads-page .detail-topbar { display: flex; align-items: center; @@ -19,10 +21,7 @@ min-height: 44px; padding: 0 16px; background: var(--surface-bg); - border: none; border-bottom: 1px solid var(--border-soft); - border-radius: 0; - box-shadow: none; flex-wrap: nowrap; flex-shrink: 0; gap: 12px; @@ -32,7 +31,7 @@ .downloads-page .detail-topbar-actions { display: flex; align-items: center; - gap: 10px; + gap: 8px; flex-shrink: 0; } @@ -40,20 +39,80 @@ display: inline-flex; align-items: center; gap: 6px; - padding: 4px 10px; - font-size: 0.78rem; + height: 28px; + padding: 0 10px; + font-size: 11px; font-weight: 600; - border-radius: var(--radius-pill, 999px); - background: var(--surface-bg); + border-radius: var(--radius-md); + background: var(--surface-muted); + border: 1px solid var(--border-soft); + color: var(--text-muted); + white-space: nowrap; +} + +.downloads-page .detail-topbar-actions .small-button { + display: inline-flex; + align-items: center; + gap: 6px; + height: 28px; + min-height: 28px; + padding: 0 10px; + font-size: 12px; + font-weight: 500; + border: 1px solid var(--border-soft); + background: var(--surface-muted); + color: var(--text-strong); + border-radius: var(--radius-md); + cursor: pointer; + transition: background var(--motion-fast), border-color var(--motion-fast), color var(--motion-fast); +} + +.downloads-page .detail-topbar-actions .small-button:hover:not(:disabled) { + background: var(--surface-subtle); + border-color: var(--border-default); + color: var(--text-strong); +} + +.downloads-page .detail-topbar-actions .small-button.danger { + color: var(--status-danger-text); + background: var(--status-danger-bg); + border-color: var(--status-danger-border); +} + +.downloads-page .detail-topbar-actions .small-button.danger:hover:not(:disabled) { + background: var(--status-danger-bg); + border-color: var(--accent-red); +} + +.downloads-page .detail-topbar-actions .icon-button { + display: inline-flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + min-height: 28px; + padding: 0; border: 1px solid var(--border-soft); + background: var(--surface-muted); color: var(--text-muted); + border-radius: var(--radius-md); + cursor: pointer; + transition: background var(--motion-fast), border-color var(--motion-fast), color var(--motion-fast); +} + +.downloads-page .detail-topbar-actions .icon-button:hover:not(:disabled) { + background: var(--surface-subtle); + border-color: var(--border-default); + color: var(--text-strong); } +/* ── Main Body Container ─────────────────────────────────────────────────── */ + .downloads-body { flex: 1; display: flex; flex-direction: column; - padding: 20px 24px; + padding: var(--space-7) var(--space-8); overflow-y: auto; box-sizing: border-box; } @@ -62,38 +121,40 @@ display: flex; align-items: center; justify-content: space-between; - gap: 16px; - margin-bottom: 20px; + gap: var(--space-6); + margin-bottom: var(--space-7); flex-wrap: wrap; } +/* ── Category Filter Tabs ────────────────────────────────────────────────── */ + .downloads-tabs { display: inline-flex; align-items: center; - gap: 4px; - background: var(--surface-bg); + gap: var(--space-1); + background: var(--surface-muted); border: 1px solid var(--border-soft); - border-radius: var(--radius-lg, 8px); + border-radius: var(--radius-lg); padding: 3px; } .downloads-tab { display: inline-flex; align-items: center; - gap: 6px; - padding: 5px 12px; - font-size: 0.82rem; + gap: var(--space-3); + padding: var(--space-2) var(--space-5); + font-size: var(--font-size-label); font-weight: 500; border: none; - border-radius: var(--radius-md, 6px); + border-radius: var(--radius-md); background: transparent; color: var(--text-muted); cursor: pointer; - transition: all 0.15s ease; + transition: background var(--motion-fast), color var(--motion-fast); } .downloads-tab:hover { - background: var(--surface-muted, rgba(127, 127, 127, 0.08)); + background: var(--surface-subtle); color: var(--text-strong); } @@ -109,71 +170,106 @@ justify-content: center; min-width: 18px; height: 18px; - padding: 0 5px; - font-size: 0.7rem; + padding: 0 var(--space-2); + font-size: var(--font-size-caption); font-weight: 700; - border-radius: 999px; - background: var(--border-soft); - color: var(--text-strong); + border-radius: var(--radius-pill); + background: var(--surface-subtle); + color: var(--text-muted); box-sizing: border-box; } .downloads-tab.active .downloads-tab-count { - background: rgba(255, 255, 255, 0.25); + background: rgba(255, 255, 255, 0.22); color: var(--text-on-accent); } +/* ── Search Input Box ────────────────────────────────────────────────────── */ + .downloads-search { + position: relative; + display: flex; + align-items: center; flex: 1; max-width: 320px; - position: relative; + height: 32px; + background: var(--surface-muted); + border: 1px solid var(--border-soft); + border-radius: var(--radius-md); + padding: 0 var(--space-4); + transition: border-color var(--motion-fast), box-shadow var(--motion-fast), background var(--motion-fast); } -.downloads-search input { - width: 100%; - padding: 6px 12px 6px 34px; - font-size: 0.85rem; +.downloads-search:focus-within { + border-color: var(--accent-solid); + box-shadow: 0 0 0 2px var(--focus-ring-color); background: var(--surface-bg); - border: 1px solid var(--border-soft); - border-radius: var(--radius-sm); - color: var(--text-strong); - box-sizing: border-box; } -.downloads-search input:focus { +.downloads-search input { + flex: 1; + width: 100%; + border: none; + background: transparent; + padding: 0 0 0 var(--space-5); + font-size: var(--font-size-body-sm); + color: var(--app-text); outline: none; - border-color: var(--accent-solid); +} + +.downloads-search input::placeholder { + color: var(--text-subtle); } .downloads-search-icon { - position: absolute; - left: 10px; - top: 50%; - transform: translateY(-50%); color: var(--text-muted); + flex-shrink: 0; pointer-events: none; } +.downloads-search-clear { + display: flex; + align-items: center; + justify-content: center; + width: 18px; + height: 18px; + padding: 0; + border: none; + background: transparent; + color: var(--text-muted); + border-radius: var(--radius-pill); + cursor: pointer; + transition: color var(--motion-fast), background var(--motion-fast); +} + +.downloads-search-clear:hover { + background: var(--surface-subtle); + color: var(--text-strong); +} + +/* ── Export Card List ────────────────────────────────────────────────────── */ + .downloads-list { display: flex; flex-direction: column; - gap: 10px; + gap: var(--space-4); } .downloads-card { display: flex; align-items: center; - gap: 14px; + gap: var(--space-6); + padding: var(--space-5) var(--space-6); background: var(--surface-bg); border: 1px solid var(--border-soft); - border-radius: var(--radius-md); - padding: 14px 18px; - transition: border-color 0.15s ease, box-shadow 0.15s ease; + border-radius: var(--radius-xl); + box-shadow: var(--shadow-sm); + transition: border-color var(--motion-fast), box-shadow var(--motion-fast); } .downloads-card:hover { - border-color: var(--accent-solid); - box-shadow: var(--shadow-sm); + border-color: var(--border-default); + box-shadow: var(--shadow-md); } .downloads-card-icon { @@ -182,94 +278,227 @@ justify-content: center; width: 40px; height: 40px; - border-radius: var(--radius-md); + border-radius: var(--radius-lg); background: var(--surface-muted); - color: var(--accent-solid); + border: 1px solid var(--border-soft); flex-shrink: 0; } .downloads-card-info { flex: 1; min-width: 0; + display: flex; + flex-direction: column; + gap: var(--space-1); +} + +.downloads-card-header-row { + display: flex; + align-items: center; + gap: var(--space-4); + min-width: 0; } .downloads-card-name { - font-size: 0.92rem; + font-size: var(--font-size-title); font-weight: 600; - margin-bottom: 3px; + color: var(--text-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - color: var(--text-strong); } .downloads-card-meta { display: flex; align-items: center; - gap: 8px; - font-size: 0.78rem; + gap: var(--space-3); + font-size: var(--font-size-caption); color: var(--text-muted); } +.downloads-meta-dot { + color: var(--text-subtle); + opacity: 0.6; +} + .downloads-card-path { - font-size: 0.73rem; - color: var(--text-muted); + font-size: var(--font-size-caption); + font-family: var(--font-mono, monospace); + color: var(--text-subtle); + background: var(--surface-subtle); + padding: 2px var(--space-4); + border-radius: var(--radius-sm); + border: 1px solid var(--border-subtle); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - margin-top: 3px; - opacity: 0.85; + max-width: fit-content; + margin-top: var(--space-1); } .downloads-card-actions { display: flex; align-items: center; - gap: 8px; + gap: var(--space-3); flex-shrink: 0; } +.downloads-card-actions .small-button, +.downloads-card-actions .primary-button { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 6px; + height: 28px; + min-height: 28px; + max-height: 28px; + padding: 0 10px; + font-size: 12px; + font-weight: 500; + border-radius: var(--radius-md); + box-sizing: border-box; +} + +/* ── File Type Tags (Theme Adaptive Tokens) ─────────────────────────────── */ + +.downloads-tag { + display: inline-flex; + align-items: center; + padding: 2px var(--space-3); + font-size: var(--font-size-meta); + font-weight: 700; + border-radius: var(--radius-sm); + text-transform: uppercase; + letter-spacing: 0.4px; + border: 1px solid transparent; + white-space: nowrap; + flex-shrink: 0; +} + +.downloads-tag-pdf { + background: var(--status-danger-bg); + color: var(--status-danger-text); + border-color: var(--status-danger-border); +} + +.downloads-tag-note_package { + background: var(--kg-concept-bg); + color: var(--kg-concept-border); + border-color: var(--kg-concept-border); +} + +.downloads-tag-html { + background: var(--status-warning-bg); + color: var(--status-warning-text); + border-color: var(--status-warning-border); +} + +.downloads-tag-diagram, +.downloads-tag-diagram_excalidraw, +.downloads-tag-diagram_drawio { + background: var(--kg-project-bg); + color: var(--kg-project-border); + border-color: var(--kg-project-border); +} + +.downloads-tag-media, +.downloads-tag-image { + background: var(--kg-company-bg); + color: var(--kg-company-border); + border-color: var(--kg-company-border); +} + +.downloads-tag-zip { + background: var(--status-info-bg); + color: var(--status-info-text); + border-color: var(--status-info-border); +} + +/* Icon Type Color Highlights */ +.downloads-type-icon.pdf { color: var(--status-danger-text); } +.downloads-type-icon.note-pkg { color: var(--kg-concept-border); } +.downloads-type-icon.html { color: var(--status-warning-text); } +.downloads-type-icon.diagram { color: var(--kg-project-border); } +.downloads-type-icon.media { color: var(--kg-company-border); } +.downloads-type-icon.zip { color: var(--status-info-text); } +.downloads-type-icon.default { color: var(--accent-solid); } + +/* ── Empty & Loading States ──────────────────────────────────────────────── */ + +.downloads-loading { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 60px var(--space-6); + gap: var(--space-5); + color: var(--text-muted); + font-size: var(--font-size-body-sm); +} + +.downloads-loading-icon { + color: var(--accent-solid); +} + .downloads-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; - padding: 60px 20px; + padding: 60px var(--space-6); text-align: center; color: var(--text-muted); + background: var(--surface-bg); + border: 1px dashed var(--border-soft); + border-radius: var(--radius-xl); + margin-top: var(--space-4); } .downloads-empty-icon { - margin-bottom: 16px; - color: var(--text-muted); - opacity: 0.5; + color: var(--text-subtle); + margin-bottom: var(--space-4); + opacity: 0.6; } .downloads-empty h3 { - margin: 0 0 6px 0; - font-size: 1.05rem; + margin: 0 0 var(--space-2) 0; + font-size: var(--font-size-heading-md); + font-weight: 600; color: var(--text-strong); } -.downloads-tag { - display: inline-block; - padding: 2px 6px; - font-size: 0.68rem; - font-weight: 600; - border-radius: var(--radius-xs); - text-transform: uppercase; - letter-spacing: 0.5px; -} - -.downloads-tag-pdf { background: rgba(243, 139, 168, 0.15); color: #f38ba8; } -.downloads-tag-note_package { background: rgba(203, 166, 247, 0.15); color: #cba6f7; } -.downloads-tag-html { background: rgba(250, 179, 135, 0.15); color: #fab387; } -.downloads-tag-diagram { background: rgba(166, 227, 161, 0.15); color: #a6e3a1; } -.downloads-tag-media { background: rgba(148, 226, 213, 0.15); color: #94e2d5; } -.downloads-tag-zip { background: rgba(137, 180, 250, 0.15); color: #89b4fa; } - -.downloads-type-icon.pdf { color: #f38ba8; } -.downloads-type-icon.note-pkg { color: #cba6f7; } -.downloads-type-icon.html { color: #fab387; } -.downloads-type-icon.diagram { color: #a6e3a1; } -.downloads-type-icon.media { color: #94e2d5; } -.downloads-type-icon.zip { color: #89b4fa; } +.downloads-empty p { + margin: 0; + font-size: var(--font-size-body-sm); + color: var(--text-muted); + max-width: 400px; + line-height: 1.4; +} + +/* ── Responsive Adaptations ──────────────────────────────────────────────── */ + +@media (max-width: 768px) { + .downloads-body { + padding: var(--space-5) var(--space-6); + } + + .downloads-controls { + flex-direction: column; + align-items: stretch; + } + + .downloads-search { + max-width: 100%; + } + + .downloads-card { + flex-direction: column; + align-items: flex-start; + } + + .downloads-card-actions { + width: 100%; + justify-content: flex-end; + margin-top: var(--space-3); + } +} diff --git a/src/tests/components/DownloadsPage.integration.test.jsx b/src/tests/components/DownloadsPage.integration.test.jsx new file mode 100644 index 00000000..4863d043 --- /dev/null +++ b/src/tests/components/DownloadsPage.integration.test.jsx @@ -0,0 +1,137 @@ +// @vitest-environment jsdom +import { act } from "react"; +import { createRoot } from "react-dom/client"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +import { DownloadsPage } from "../../components/DownloadsPage"; +import * as electronService from "../../services/electronService"; + +globalThis.IS_REACT_ACT_ENVIRONMENT = true; + +vi.mock("../../services/electronService", () => ({ + getExportHistory: vi.fn(), + clearExportHistory: vi.fn(), + removeExportRecord: vi.fn(), + openExportFile: vi.fn(), + showInFolder: vi.fn(), + getDefaultDownloadDir: vi.fn(), +})); + +const mockRecords = [ + { + id: "exp-1", + filename: "Summary_Report.pdf", + filePath: "C:/Users/test/Downloads/Summary_Report.pdf", + exportType: "pdf", + fileSize: 1048576, + timestamp: new Date().toISOString(), + sourceNote: "Quarterly Summary", + }, + { + id: "exp-2", + filename: "Architecture.excalidraw", + filePath: "C:/Users/test/Downloads/Architecture.excalidraw", + exportType: "diagram_excalidraw", + fileSize: 524288, + timestamp: new Date().toISOString(), + sourceNote: "System Design", + }, +]; + +function renderDownloadsPage(props = {}) { + const host = document.createElement("div"); + document.body.appendChild(host); + const root = createRoot(host); + + const defaultProps = { + onBack: vi.fn(), + ...props, + }; + + act(() => { + root.render(); + }); + + return { + host, + props: defaultProps, + unmount() { + act(() => { + root.unmount(); + }); + host.remove(); + }, + }; +} + +describe("DownloadsPage component", () => { + beforeEach(() => { + vi.resetAllMocks(); + electronService.getExportHistory.mockResolvedValue(mockRecords); + electronService.getDefaultDownloadDir.mockResolvedValue("C:/Users/test/Downloads"); + }); + + afterEach(() => { + document.body.innerHTML = ""; + }); + + it("renders export history list and topbar controls", async () => { + const view = renderDownloadsPage(); + + await act(async () => { + await Promise.resolve(); + }); + + expect(view.host.querySelector(".detail-breadcrumb-current")?.textContent).toBe( + "Downloads & Export History" + ); + + const cards = view.host.querySelectorAll(".downloads-card"); + expect(cards.length).toBe(2); + expect(cards[0].textContent).toContain("Summary_Report.pdf"); + expect(cards[1].textContent).toContain("Architecture.excalidraw"); + + view.unmount(); + }); + + it("filters history by category tabs and search input", async () => { + const view = renderDownloadsPage(); + + await act(async () => { + await Promise.resolve(); + }); + + const tabs = view.host.querySelectorAll(".downloads-tab"); + const docsTab = Array.from(tabs).find((t) => t.textContent.includes("Documents")); + expect(docsTab).toBeTruthy(); + + act(() => { + docsTab.click(); + }); + + let cards = view.host.querySelectorAll(".downloads-card"); + expect(cards.length).toBe(1); + expect(cards[0].textContent).toContain("Summary_Report.pdf"); + + const allTab = Array.from(tabs).find((t) => t.textContent.includes("All")); + act(() => { + allTab.click(); + }); + + const searchInput = view.host.querySelector(".downloads-search input"); + act(() => { + const nativeInputValueSetter = Object.getOwnPropertyDescriptor( + window.HTMLInputElement.prototype, + "value" + )?.set; + nativeInputValueSetter?.call(searchInput, "Architecture"); + searchInput.dispatchEvent(new Event("change", { bubbles: true })); + }); + + cards = view.host.querySelectorAll(".downloads-card"); + expect(cards.length).toBe(1); + expect(cards[0].textContent).toContain("Architecture.excalidraw"); + + view.unmount(); + }); +}); From a973c8b4bce8913c2bec8bc93a7da43982f237df Mon Sep 17 00:00:00 2001 From: Bikash Panda Date: Sat, 8 Aug 2026 11:03:39 +0530 Subject: [PATCH 06/18] Added download popover --- electron/lib/core/appMenu.cjs | 12 -- src/App.jsx | 16 +- src/components/DownloadsPopover.jsx | 169 +++++++++++++++++ src/components/layout/TitleBar.jsx | 126 +++++++++---- src/styles/titlebar.css | 280 ++++++++++++++++++++++++++++ 5 files changed, 555 insertions(+), 48 deletions(-) create mode 100644 src/components/DownloadsPopover.jsx diff --git a/electron/lib/core/appMenu.cjs b/electron/lib/core/appMenu.cjs index 80f33a9a..5d052adc 100644 --- a/electron/lib/core/appMenu.cjs +++ b/electron/lib/core/appMenu.cjs @@ -572,12 +572,6 @@ function buildAppMenuTemplate(win, context = {}) { label: "Assets Library", click: () => sendMenuAction(win, "open-assets") }, - { - label: "Downloads & Export History", - accelerator: "CmdOrCtrl+J", - action: "open-downloads-page", - click: () => sendMenuAction(win, "open-downloads-page") - }, { label: "Trash / Removed Items", click: () => sendMenuAction(win, "open-trash") @@ -602,12 +596,6 @@ function buildAppMenuTemplate(win, context = {}) { label: "Export Workspace as Zip", accelerator: "CmdOrCtrl+Shift+E", click: () => sendMenuAction(win, "export-workspace-zip") - }, - { type: "separator" }, - { - label: screen === "document" ? "Open Current Note Website View" : "Open Project Website", - accelerator: "CmdOrCtrl+Shift+W", - click: () => sendMenuAction(win, "open-website") } ] }, diff --git a/src/App.jsx b/src/App.jsx index 59643d2c..1f71171a 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1435,8 +1435,20 @@ export default function App() { const currentPath = normalizePathLikeValue(landingFolderPath || rootPath).replace(/[\\/]+$/, ""); const canRemoveFolder = Boolean(rootPath && currentPath && rootPath.toLowerCase() !== currentPath.toLowerCase()); + const isSubpageActive = Boolean( + downloadsPageOpen || + calendarPageOpen || + taskWorkspaceOpen || + appLogsOpen || + healthPageOpen || + gitVCOpen || + embeddingsPageOpen || + graphPanelOpen || + personasPageOpen + ); + updateMenuContext({ - screen: current ? "document" : "landing", + screen: (current && !isSubpageActive) ? "document" : "landing", viewMode: notesViewMode, densityMode: notesDensityMode, typoCheckEnabled, @@ -1457,7 +1469,7 @@ export default function App() { recentWorkspacePaths: normalizePathLikeList(recentWorkspacePaths), autosaveEnabled, }); - }, [current, notesViewMode, notesDensityMode, typoCheckEnabled, previewImageMode, embeddedMarkdownMode, screenCaptureMode, themePreference, dirty, activeDocumentChangedOnDisk, activeProject, notesFolderPath, landingFolderPath, showTerminal, terminalShellPreference, outlineEnabled, mode, focusModeEnabled, scrollSyncEnabled, tableEditorEnabled, recentWorkspacePaths, autosaveEnabled]); + }, [current, downloadsPageOpen, calendarPageOpen, taskWorkspaceOpen, appLogsOpen, healthPageOpen, gitVCOpen, embeddingsPageOpen, graphPanelOpen, personasPageOpen, notesViewMode, notesDensityMode, typoCheckEnabled, previewImageMode, embeddedMarkdownMode, screenCaptureMode, themePreference, dirty, activeDocumentChangedOnDisk, activeProject, notesFolderPath, landingFolderPath, showTerminal, terminalShellPreference, outlineEnabled, mode, focusModeEnabled, scrollSyncEnabled, tableEditorEnabled, recentWorkspacePaths, autosaveEnabled]); useEffect(() => { const handleAction = (action) => { diff --git a/src/components/DownloadsPopover.jsx b/src/components/DownloadsPopover.jsx new file mode 100644 index 00000000..53f0d825 --- /dev/null +++ b/src/components/DownloadsPopover.jsx @@ -0,0 +1,169 @@ +import React, { useEffect, useRef } from "react"; +import { + Download, + Folder, + ExternalLink, + Archive, + ChevronRight, + FileText, + FileCode, + Image as ImageIcon, +} from "lucide-react"; +import { openExportFile, showInFolder } from "../services/electronService.js"; + +function formatBytes(bytes) { + if (!bytes || bytes === 0) return "0 B"; + const k = 1024; + const sizes = ["B", "KB", "MB", "GB"]; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + " " + sizes[i]; +} + +function formatTimestamp(isoString) { + if (!isoString) return ""; + try { + const date = new Date(isoString); + const now = new Date(); + const diffMs = now - date; + const diffMins = Math.floor(diffMs / (1000 * 60)); + const diffHours = Math.floor(diffMs / (1000 * 60 * 60)); + + if (diffMins < 1) return "Just now"; + if (diffMins < 60) return `${diffMins}m ago`; + if (diffHours < 24) return `${diffHours}h ago`; + + return date.toLocaleDateString(undefined, { month: "short", day: "numeric" }); + } catch { + return isoString; + } +} + +function getPopoverIconForType(type) { + switch (type) { + case "pdf": + return ; + case "note_package": + case "zip": + return ; + case "html": + return ; + case "diagram_excalidraw": + case "diagram_drawio": + case "image": + case "media": + return ; + default: + return ; + } +} + +export function DownloadsPopover({ + isOpen, + onClose, + onOpenDownloads, + recentDownloads = [], +}) { + const popoverRef = useRef(null); + + useEffect(() => { + if (!isOpen) return; + + const handleOutsideClick = (e) => { + if (popoverRef.current && !popoverRef.current.contains(e.target)) { + onClose?.(); + } + }; + + const handleKeyDown = (e) => { + if (e.key === "Escape") { + onClose?.(); + } + }; + + document.addEventListener("mousedown", handleOutsideClick); + document.addEventListener("keydown", handleKeyDown); + return () => { + document.removeEventListener("mousedown", handleOutsideClick); + document.removeEventListener("keydown", handleKeyDown); + }; + }, [isOpen, onClose]); + + if (!isOpen) return null; + + return ( +
+
+
+ + Downloads +
+
+ +
+ {recentDownloads.length === 0 ? ( +
+ + No recent downloads +
+ ) : ( + recentDownloads.slice(0, 5).map((item) => ( +
+
+ {getPopoverIconForType(item.exportType)} +
+
+
+ {item.filename} +
+
+ {formatBytes(item.fileSize)} + + {formatTimestamp(item.timestamp)} +
+
+
+ + +
+
+ )) + )} +
+ +
+ +
+
+ ); +} + +export default DownloadsPopover; diff --git a/src/components/layout/TitleBar.jsx b/src/components/layout/TitleBar.jsx index c5f8d1ca..13786256 100644 --- a/src/components/layout/TitleBar.jsx +++ b/src/components/layout/TitleBar.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef } from "react"; +import React, { useState, useEffect, useRef, useCallback } from "react"; import { Minus, Square, Copy, X, Check, ChevronRight, Globe, FilePlus, FolderPlus, FolderOpen, Clock, Save, RefreshCw, Package, Edit2, Trash2, ArrowLeft, RotateCcw, Power, @@ -10,6 +10,8 @@ import { Upload, Download } from "lucide-react"; import notelyMark from "../../assets/branding/notely-mark.png"; +import { getExportHistory } from "../../services/electronService"; +import DownloadsPopover from "../DownloadsPopover"; const MENU_ICON_MAP = { "new": FilePlus, @@ -162,12 +164,48 @@ export function TitleBar({ title = "Notely", workspaceIcon, onOpenWebsite, onOpe const [isMaximized, setIsMaximized] = useState(false); const [menuStructure, setMenuStructure] = useState([]); const [activeMenuIndex, setActiveMenuIndex] = useState(null); - const [activeSubmenuPath, setActiveSubmenuPath] = useState([]); // Array of indexes tracing active submenus + const [activeSubmenuPath, setActiveSubmenuPath] = useState([]); + const [showDownloadsPopover, setShowDownloadsPopover] = useState(false); + const [recentDownloads, setRecentDownloads] = useState([]); + const [hasUnreadDownload, setHasUnreadDownload] = useState(false); const containerRef = useRef(null); + const loadRecentDownloads = useCallback(async () => { + try { + const recs = await getExportHistory(); + if (Array.isArray(recs)) { + setRecentDownloads(recs.slice(0, 5)); + } + } catch (err) { + console.error("Failed to fetch recent downloads", err); + } + }, []); + + useEffect(() => { + const handleDownloadEvent = () => { + loadRecentDownloads(); + setHasUnreadDownload(true); + setShowDownloadsPopover(true); + }; + + window.addEventListener("app:download-complete", handleDownloadEvent); + + const handleToastEvent = (e) => { + const msg = String(e.detail?.message || "").toLowerCase(); + if (msg.includes("export") || msg.includes("download") || msg.includes("saved to")) { + handleDownloadEvent(); + } + }; + window.addEventListener("app:toast", handleToastEvent); + + return () => { + window.removeEventListener("app:download-complete", handleDownloadEvent); + window.removeEventListener("app:toast", handleToastEvent); + }; + }, [loadRecentDownloads]); + useEffect(() => { - // Check initial maximized state if (window.notesApi?.isWindowMaximized) { window.notesApi.isWindowMaximized().then(setIsMaximized).catch(() => {}); } @@ -178,16 +216,13 @@ export function TitleBar({ title = "Notely", workspaceIcon, onOpenWebsite, onOpe } }; - // Fetch initial dynamic menu structure loadMenuStructure(); - // Subscribe to menu updates from main process let unsubscribeMenu = () => {}; if (window.notesApi?.onMenuUpdated) { unsubscribeMenu = window.notesApi.onMenuUpdated(loadMenuStructure); } - // Subscribe to state changes from main process let unsubscribeMax = () => {}; if (window.notesApi?.onWindowMaximizedChanged) { unsubscribeMax = window.notesApi.onWindowMaximizedChanged((maximized) => { @@ -201,7 +236,6 @@ export function TitleBar({ title = "Notely", workspaceIcon, onOpenWebsite, onOpe }; }, []); - // Handle clicking outside to close menus useEffect(() => { const handleOutsideClick = (e) => { if (containerRef.current && !containerRef.current.contains(e.target)) { @@ -254,9 +288,19 @@ export function TitleBar({ title = "Notely", workspaceIcon, onOpenWebsite, onOpe } }; + const toggleDownloadsPopover = () => { + if (!showDownloadsPopover) { + loadRecentDownloads(); + setHasUnreadDownload(false); + setShowDownloadsPopover(true); + } else { + setShowDownloadsPopover(false); + } + }; + const handleItemClick = (item, indexPath) => { if (item.enabled === false) return; - if (item.submenu) return; // Submenus open on hover/interaction + if (item.submenu) return; window.notesApi?.executeMenuItem?.({ indexPath, @@ -265,7 +309,6 @@ export function TitleBar({ title = "Notely", workspaceIcon, onOpenWebsite, onOpe closeAllMenus(); }; - // Helper to format shortcuts/accelerators (e.g. CmdOrCtrl+N -> Ctrl+N) const formatAccelerator = (acc) => { if (!acc) return ""; const isMac = navigator.userAgent.toLowerCase().includes("mac"); @@ -298,7 +341,6 @@ export function TitleBar({ title = "Notely", workspaceIcon, onOpenWebsite, onOpe return ""; }; - // Recursive submenu renderer const renderDropdownItems = (items, path = []) => { return (
    @@ -385,35 +427,48 @@ export function TitleBar({ title = "Notely", workspaceIcon, onOpenWebsite, onOpe
-
+
{workspaceIcon && {workspaceIcon}} {title}
- {onOpenDownloads && ( - - )} - {onOpenWebsite && ( - + {(onOpenDownloads || onOpenWebsite) && ( +
+ {onOpenDownloads && ( +
+ + + setShowDownloadsPopover(false)} + onOpenDownloads={onOpenDownloads} + recentDownloads={recentDownloads} + /> +
+ )} + + {onOpenWebsite && ( + + )} +
)}

- Create a portable zip bundle for this workspace. Choose the output format, metadata inclusion, destination, and filename. + Export a zip bundle of this workspace directly to your Downloads folder.

@@ -84,27 +84,7 @@ export function WorkspaceExportDialog({ - +
diff --git a/src/components/ExportImportModal.jsx b/src/components/ExportImportModal.jsx index d640beeb..dd05a5f1 100644 --- a/src/components/ExportImportModal.jsx +++ b/src/components/ExportImportModal.jsx @@ -2,7 +2,6 @@ import React, { useState, useEffect } from "react"; import { Download, Upload, X, CheckSquare, Square, FolderOpen } from "lucide-react"; import { OverlayDialog } from "./OverlayDialog"; import AppInput from "./AppInput"; -import { addExportRecord } from "../services/electronService"; import "../styles/ExportImportModal.css"; export function ExportImportModal({ isOpen, mode = "export", onClose, notify, reloadDocuments }) { @@ -152,32 +151,20 @@ export function ExportImportModal({ isOpen, mode = "export", onClose, notify, re notify("Please select at least one note to export.", "warning"); return; } - if (!destinationPath) { - notify("Please select a save location.", "warning"); - return; - } setLoading(true); try { + const { runExport } = await import("../services/electronService"); const notePaths = Array.from(selectedNotes); - const outputName = fileName.endsWith(".nly") ? fileName : `${fileName}.nly`; - const fullOutputPath = `${destinationPath}/${outputName}`; + const outputName = fileName ? (fileName.endsWith(".nly") ? fileName : `${fileName}.nly`) : undefined; - const res = await window.notesApi.exportNotePackage({ + const res = await runExport("note_package", { notePaths, - outputPath: fullOutputPath, + fileName: outputName, password: exportPassword || undefined, }); if (res?.success) { - notify(`Exported ${res.exportedNotesCount} note(s) to ${res.outputPath}`, "success"); - void addExportRecord({ - filename: outputName, - filePath: res.outputPath || fullOutputPath, - fileSize: res.fileSize || 0, - exportType: "note_package", - category: "document", - }); onClose(); } else { notify("Export failed: " + (res?.error || "Unknown error"), "error"); diff --git a/src/components/MediaPreviewPane.jsx b/src/components/MediaPreviewPane.jsx index 5428e8a7..e731b872 100644 --- a/src/components/MediaPreviewPane.jsx +++ b/src/components/MediaPreviewPane.jsx @@ -13,7 +13,7 @@ import { getImageFileSize, formatFileSize, } from "../utils/imageProcessingUtils"; -import { readImage, replaceImage, getImageAnnotation, setImageAnnotation, getImageOriginalStatus, restoreImageOriginal, openMediaInDefaultApp, addExportRecord, saveToDownloads } from "../services/electronService"; +import { readImage, replaceImage, getImageAnnotation, setImageAnnotation, getImageOriginalStatus, restoreImageOriginal, openMediaInDefaultApp, saveToDownloads } from "../services/electronService"; import "../styles/mediaPreview.css"; // Initialize the pdf.js worker once via a Vite-bundled module worker so it diff --git a/src/components/WorkspaceExportDialog.jsx b/src/components/WorkspaceExportDialog.jsx index 3e9b8ca9..fe66be18 100644 --- a/src/components/WorkspaceExportDialog.jsx +++ b/src/components/WorkspaceExportDialog.jsx @@ -10,7 +10,7 @@ export function WorkspaceExportDialog({ progress, onClose, onChange, - onBrowse, + _onBrowse, onExport, }) { if (!isOpen) return null; diff --git a/src/components/layout/TitleBar.jsx b/src/components/layout/TitleBar.jsx index 339eaefb..eec14dc9 100644 --- a/src/components/layout/TitleBar.jsx +++ b/src/components/layout/TitleBar.jsx @@ -257,6 +257,12 @@ export function TitleBar({ title = "Notely", workspaceIcon, onOpenWebsite, onOpe }; }, []); + const closeAllMenus = useCallback(() => { + setActiveMenuIndex(null); + setActiveSubmenuPath([]); + setShowDownloadsPopover(false); + }, []); + useEffect(() => { const handleOutsideClick = (e) => { if (containerRef.current && !containerRef.current.contains(e.target)) { @@ -274,13 +280,7 @@ export function TitleBar({ title = "Notely", workspaceIcon, onOpenWebsite, onOpe document.removeEventListener("mousedown", handleOutsideClick); document.removeEventListener("keydown", handleKeyDown); }; - }, []); - - const closeAllMenus = useCallback(() => { - setActiveMenuIndex(null); - setActiveSubmenuPath([]); - setShowDownloadsPopover(false); - }, []); + }, [closeAllMenus]); const handleMinimize = () => { window.notesApi?.minimizeWindow?.(); diff --git a/src/services/electronService.js b/src/services/electronService.js index 0dd6e326..e2314b85 100644 --- a/src/services/electronService.js +++ b/src/services/electronService.js @@ -779,26 +779,31 @@ export async function revealWorkspaceInExplorer(folderPath) { } -export async function downloadPdf(payload) { +export async function runExport(type, payload = {}) { const api = getNotesApi(); - if (typeof api?.downloadPdf !== "function") { - throw new Error("PDF download action unavailable. Please restart the app to load the latest desktop API."); - } - - const res = await api.downloadPdf(payload); - if (res && !res.canceled && res.filePath) { - if (typeof window !== "undefined") { - const filename = res.filePath.split(/[/\\]/).pop() || "note.pdf"; - window.dispatchEvent(new CustomEvent("app:download-complete", { detail: { ...res, filename } })); - window.dispatchEvent(new CustomEvent("app:toast", { - detail: { - message: `Exported PDF: ${filename}`, - type: "success", - }, - })); + if (typeof api?.exportFile === "function") { + const res = await api.exportFile(type, payload); + if (res?.success && typeof window !== "undefined") { + window.dispatchEvent(new CustomEvent("app:download-complete", { detail: res })); } + return res; } - return res; + + // Fallbacks for legacy/web environment + if (type === "pdf" && typeof api?.downloadPdf === "function") { + return api.downloadPdf(payload); + } + if (type === "workspace_zip" && typeof api?.exportWorkspaceZip === "function") { + return api.exportWorkspaceZip(payload); + } + if ((type === "media" || type === "diagram_image") && typeof api?.saveToDownloads === "function") { + return api.saveToDownloads(payload); + } + throw new Error(`Export service is unavailable for type: ${type}`); +} + +export async function downloadPdf(payload) { + return runExport("pdf", payload); } export async function getWorkspaceExportDefaults() { @@ -823,25 +828,7 @@ export async function browseWorkspaceExportDestination() { } export async function exportWorkspaceZip(payload) { - const api = getNotesApi(); - if (typeof api?.exportWorkspaceZip !== "function") { - throw new Error("Workspace export is unavailable. Please restart the app."); - } - - const res = await api.exportWorkspaceZip(payload || {}); - if (res && !res.canceled && res.filePath) { - if (typeof window !== "undefined") { - const filename = res.filePath.split(/[/\\]/).pop() || "workspace.zip"; - window.dispatchEvent(new CustomEvent("app:download-complete", { detail: { ...res, filename } })); - window.dispatchEvent(new CustomEvent("app:toast", { - detail: { - message: `Exported Workspace Zip: ${filename}`, - type: "success", - }, - })); - } - } - return res; + return runExport("workspace_zip", payload); } export function onWorkspaceExportProgress(callback) { @@ -945,24 +932,7 @@ export async function renameImage(basePath, assetPath, nextFileName) { } export async function downloadImage(base64Data, defaultFilename) { - const api = getNotesApi(); - if (typeof api?.downloadImage !== "function") { - throw new Error("Image download action unavailable. Please restart the app."); - } - const res = await api.downloadImage({ base64Data, defaultFilename }); - if (res && res.success && res.filePath) { - if (typeof window !== "undefined") { - const filename = res.filePath.split(/[/\\]/).pop() || defaultFilename || "diagram.png"; - window.dispatchEvent(new CustomEvent("app:download-complete", { detail: { ...res, filename } })); - window.dispatchEvent(new CustomEvent("app:toast", { - detail: { - message: `Downloaded ${filename}`, - type: "success", - }, - })); - } - } - return res; + return runExport("diagram_image", { base64Data, defaultFilename }); } export async function createTerminalSession(cwd, options = {}) { @@ -1531,28 +1501,7 @@ export async function addExportRecord(record) { } export async function saveToDownloads({ dataUrl, srcPath, filename }) { - const api = getNotesApi(); - let res = null; - if (typeof api?.saveToDownloads === "function") { - try { - res = await api.saveToDownloads({ dataUrl, srcPath, filename }); - } catch (err) { - console.warn("[saveToDownloads] IPC error:", err); - } - } - - if (res?.success) { - if (typeof window !== "undefined") { - window.dispatchEvent(new CustomEvent("app:download-complete", { detail: res })); - window.dispatchEvent(new CustomEvent("app:toast", { - detail: { - message: `Downloaded ${res.filename}`, - type: "success", - }, - })); - } - } - return res; + return runExport("media", { dataUrl, srcPath, filename }); } export async function removeExportRecord(id) { @@ -1585,4 +1534,12 @@ export async function getDefaultDownloadDir() { return api.getDefaultDownloadDir(); } +export function onExportRecordAdded(callback) { + const api = getNotesApi(); + if (typeof api?.onExportRecordAdded === "function") { + return api.onExportRecordAdded(callback); + } + return () => {}; +} + From ff7ff7757cc7e16ef0cb989c6d6bf2dbd7e1234b Mon Sep 17 00:00:00 2001 From: Bikash Panda Date: Sat, 8 Aug 2026 15:16:11 +0530 Subject: [PATCH 11/18] Removed desktop notification --- electron/lib/export/ExportManager.cjs | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/electron/lib/export/ExportManager.cjs b/electron/lib/export/ExportManager.cjs index d3dbebab..4668053f 100644 --- a/electron/lib/export/ExportManager.cjs +++ b/electron/lib/export/ExportManager.cjs @@ -3,8 +3,6 @@ const fsAsync = require("fs").promises; const path = require("path"); const os = require("os"); const crypto = require("crypto"); -const { pathToFileURL } = require("url"); -const { Notification } = require("electron"); const { ZipFile } = require("yazl"); const PDF_WRITE_RETRY_DELAYS_MS = [120, 320, 700]; @@ -129,10 +127,7 @@ class ExportManager { } } - // 2. Dispatch EXACTLY ONE system notification - this._notifyCompletion(filename); - - // 3. Broadcast record-added event to all windows + // 2. Broadcast record-added event to all windows if (this.BrowserWindow) { const payloadRecord = record || { filename, @@ -185,19 +180,6 @@ class ExportManager { return { targetPath, targetName }; } - _notifyCompletion(filename) { - try { - if (Notification && Notification.isSupported()) { - new Notification({ - title: "Export Complete", - body: `Saved "${filename}" to Downloads`, - }).show(); - } - } catch (err) { - console.warn("[ExportManager] Notification failed:", err); - } - } - _sendWorkspaceExportProgress(progressPayload) { if (!this.BrowserWindow) return; this.BrowserWindow.getAllWindows().forEach((win) => { From b634fa25e02431d7ce3d1119a7f611d4cca3dadf Mon Sep 17 00:00:00 2001 From: Bikash Panda Date: Sat, 8 Aug 2026 21:54:39 +0530 Subject: [PATCH 12/18] feat(export): standardize download UX and block action popovers Route all media, diagram, table, and file downloads through ExportManager. Unify hover popovers with icons, translucent 1px vertical dividers, and dark glassmorphic styling across Tables, Mermaid, Excalidraw, Draw.io, Images, and Links. --- electron/lib/export/ExportManager.cjs | 34 +++- src/components/DrawioBlock.jsx | 57 ++++-- src/components/ExcalidrawBlock.jsx | 59 ++++-- src/components/MarkdownPreview.jsx | 173 +++++++++++++++++- src/components/MediaPreviewPane.jsx | 14 +- src/components/MermaidBlock.jsx | 103 +++++++++-- src/styles/ExcalidrawBlock.css | 5 +- src/styles/editor.css | 159 +++++++++++++++- .../DownloadsPage.integration.test.jsx | 1 + src/tests/utils/exportUtils.test.js | 12 ++ src/tests/utils/tableUtils.test.js | 16 ++ src/utils/exportUtils.js | 110 +++++++++++ src/utils/renderUtils.js | 4 +- src/utils/tableUtils.js | 40 ++++ 14 files changed, 711 insertions(+), 76 deletions(-) create mode 100644 src/tests/utils/exportUtils.test.js create mode 100644 src/utils/exportUtils.js diff --git a/electron/lib/export/ExportManager.cjs b/electron/lib/export/ExportManager.cjs index 4668053f..506f8bd0 100644 --- a/electron/lib/export/ExportManager.cjs +++ b/electron/lib/export/ExportManager.cjs @@ -571,12 +571,20 @@ class ExportManager { // --- Type 4 & 5: Diagram Image & Media Download --- async _exportMediaOrDiagram(payload, downloadDir, exportType) { - const { dataUrl, srcPath, base64Data, defaultFilename, filename } = payload; + const { dataUrl, srcPath, base64Data, defaultFilename, filename, customExportType, category: customCategory } = payload || {}; const rawName = filename || defaultFilename || (exportType === "diagram_image" ? "diagram.png" : "image.png"); const { targetPath, targetName } = this._resolveCollisionFreePath(downloadDir, rawName); - let resolvedSrc = srcPath && typeof srcPath === "string" ? srcPath : ""; + let rawSrc = srcPath && typeof srcPath === "string" ? srcPath.trim() : ""; + let effectiveDataUrl = dataUrl || base64Data || ""; + + if (rawSrc.startsWith("data:")) { + effectiveDataUrl = rawSrc; + rawSrc = ""; + } + + let resolvedSrc = rawSrc; if (resolvedSrc.startsWith("file://")) { try { const { fileURLToPath } = require("url"); @@ -585,11 +593,21 @@ class ExportManager { resolvedSrc = resolvedSrc.replace(/^file:\/\/\/?/, ""); } } + resolvedSrc = resolvedSrc.split(/[?#]/)[0]; + + const notesRoot = typeof this.getNotesRoot === "function" ? this.getNotesRoot() : null; + + if (resolvedSrc && !fs.existsSync(resolvedSrc) && notesRoot) { + const candidate = path.resolve(notesRoot, resolvedSrc); + if (fs.existsSync(candidate)) { + resolvedSrc = candidate; + } + } if (resolvedSrc && fs.existsSync(resolvedSrc)) { fs.copyFileSync(resolvedSrc, targetPath); - } else if (dataUrl || base64Data) { - const rawBase64 = (dataUrl || base64Data).replace(/^data:[^;]+;base64,/, ""); + } else if (effectiveDataUrl) { + const rawBase64 = effectiveDataUrl.replace(/^data:[^;]+;base64,/, ""); const buffer = Buffer.from(rawBase64, "base64"); fs.writeFileSync(targetPath, buffer); } else { @@ -599,13 +617,17 @@ class ExportManager { let fileSize = 0; try { fileSize = fs.statSync(targetPath).size; } catch { /* ignore */ } + const ext = path.extname(targetName).toLowerCase().replace(/^\./, ""); + const derivedExportType = customExportType || (exportType === "diagram_image" ? "diagram_excalidraw" : ext || "image"); + const derivedCategory = customCategory || (exportType === "diagram_image" ? "diagram" : ["pdf", "csv", "txt", "md", "doc", "docx", "xls", "xlsx"].includes(ext) ? "document" : "media"); + return { success: true, targetPath, filename: targetName, fileSize, - exportType: exportType === "diagram_image" ? "diagram_excalidraw" : "image", - category: exportType === "diagram_image" ? "diagram" : "media" + exportType: derivedExportType, + category: derivedCategory }; } diff --git a/src/components/DrawioBlock.jsx b/src/components/DrawioBlock.jsx index 5a552ef3..eb2053d1 100644 --- a/src/components/DrawioBlock.jsx +++ b/src/components/DrawioBlock.jsx @@ -1,7 +1,7 @@ import { useEffect, useState } from "react"; -import { Download } from "lucide-react"; +import { Download, Pencil } from "lucide-react"; import { readDrawioImage, readDrawioSource, writeDrawioSource } from "../services/drawioService"; -import { downloadImage } from "../services/electronService"; +import { runExport } from "../services/electronService"; import DrawioEditor from "./DrawioEditor"; import "../styles/ExcalidrawBlock.css"; // Reuse block styles @@ -56,9 +56,16 @@ export function DrawioBlock({ imagePath, diagramId, onUpdate, onNotify, onForceS if (!thumbnail) return; try { const filename = `${diagramId || "drawio-diagram"}.png`; - const result = await downloadImage(thumbnail, filename); + const result = await runExport("diagram_image", { + dataUrl: thumbnail, + filename, + customExportType: "diagram_drawio", + category: "diagram", + }); if (result?.success) { - onNotify?.("Diagram exported successfully.", "success"); + onNotify?.(`Diagram exported to ${result.filename}`, "success"); + } else { + onNotify?.(result?.error || "Failed to export diagram.", "error"); } } catch (err) { console.error("Failed to download diagram:", err); @@ -117,25 +124,41 @@ export function DrawioBlock({ imagePath, diagramId, onUpdate, onNotify, onForceS {thumbnail && !loading ? (
+
+ + + +
Draw.io Diagram preview setThumbnail(null)} /> - - (Click to edit)
) : !loading ? (
diff --git a/src/components/ExcalidrawBlock.jsx b/src/components/ExcalidrawBlock.jsx index 0bef5054..2a876659 100644 --- a/src/components/ExcalidrawBlock.jsx +++ b/src/components/ExcalidrawBlock.jsx @@ -1,7 +1,7 @@ import { useEffect, useState } from "react"; -import { Download } from "lucide-react"; +import { Download, Pencil } from "lucide-react"; import { readDiagramImage, readDiagramSource, writeDiagramSource } from "../services/diagramService"; -import { downloadImage } from "../services/electronService"; +import { runExport } from "../services/electronService"; import ExcalidrawComponent from "./ExcalidrawEditor"; import "../styles/ExcalidrawBlock.css"; @@ -56,10 +56,17 @@ export function ExcalidrawBlock({ imagePath, diagramId, documentPath, originAsse const handleDownload = async () => { if (!thumbnail) return; try { - const filename = `${diagramId || "diagram"}.png`; - const result = await downloadImage(thumbnail, filename); + const filename = `${diagramId || "excalidraw-diagram"}.png`; + const result = await runExport("diagram_image", { + dataUrl: thumbnail, + filename, + customExportType: "diagram_excalidraw", + category: "diagram", + }); if (result?.success) { - onNotify?.("Diagram exported successfully.", "success"); + onNotify?.(`Diagram exported to ${result.filename}`, "success"); + } else { + onNotify?.(result?.error || "Failed to export diagram.", "error"); } } catch (err) { console.error("Failed to download diagram:", err); @@ -121,25 +128,41 @@ export function ExcalidrawBlock({ imagePath, diagramId, documentPath, originAsse {thumbnail && !loading ? (
+
+ + + +
Diagram preview setThumbnail(null)} /> - - (Click to edit)
) : !loading ? (
diff --git a/src/components/MarkdownPreview.jsx b/src/components/MarkdownPreview.jsx index 11e828f9..730b99eb 100644 --- a/src/components/MarkdownPreview.jsx +++ b/src/components/MarkdownPreview.jsx @@ -6,13 +6,15 @@ import { parseDiagramBlocks, normalizeMarkdownImagePaths, } from "../utils/renderUtils"; -import { readMarkdownSource, openFolder, openMediaInDefaultApp } from "../services/electronService"; +import { readMarkdownSource, openFolder, openMediaInDefaultApp, runExport } from "../services/electronService"; import { readImage, replaceImage, deleteImage, renameImage, getImageAnnotation, setImageAnnotation, getImageOriginalStatus, restoreImageOriginal } from "../services/electronService"; import { readFileAsDataUrl } from "../utils/mediaTypeUtils"; import { createImageMarkdown, normalizeImagePathForMarkdown } from "../utils/markdownUtils"; import { createDiagramMarkdown, generateDiagramId } from "../utils/diagramFileUtils"; import { writeDiagramSource, writeDiagramImage } from "../services/diagramService"; import { getMediaTypeFromExtension } from "../utils/mediaUtils"; +import { tableElementToPngDataUrl } from "../utils/exportUtils"; +import { tableElementToCsv } from "../utils/tableUtils"; import { formatImageDeleteResult } from "../utils/imageDeleteResult"; import { removeImageReferenceFromMarkdown, toComparableAssetPath, replaceFirstImageReferenceWithDiagram } from "../utils/imageMarkdownReferences"; import useConfirm from "../hooks/useConfirm"; @@ -447,6 +449,74 @@ export const MarkdownPreview = memo(function MarkdownPreviewContent({ setActiveLinkPopup(null); }; + const handleDirectDownloadFileFromPreview = async (href) => { + if (!href) return; + try { + const resolvedPath = resolveMarkdownLinkPath(basePath, href); + const cleanPath = resolvedPath || String(href || "").trim().replace(/^file:\/\/\/?/i, "").split(/[?#]/)[0]; + const filename = cleanPath.split(/[/\\]/).pop() || "file"; + + const result = await runExport("media", { + srcPath: cleanPath, + filename, + }); + + if (result?.success) { + onNotify?.(`Downloaded ${result.filename} to Downloads folder`, "success"); + } else { + onNotify?.(result?.error || "Failed to download file.", "error"); + } + } catch (err) { + onNotify?.(err?.message || "Failed to download file.", "error"); + } finally { + setActiveLinkPopup(null); + } + }; + + const handleExportTableImage = async (tableWrapper) => { + if (!tableWrapper) return; + try { + const dataUrl = await tableElementToPngDataUrl(tableWrapper); + const result = await runExport("media", { + dataUrl, + filename: "table.png", + customExportType: "image", + category: "media", + }); + if (result?.success) { + onNotify?.(`Table image exported to ${result.filename}`, "success"); + } else { + onNotify?.(result?.error || "Export failed", "error"); + } + } catch (err) { + onNotify?.(`Failed to export table image: ${err?.message || "Unknown error"}`, "error"); + } + }; + + const handleExportTableCsv = async (tableWrapper) => { + if (!tableWrapper) return; + try { + const csvContent = tableElementToCsv(tableWrapper); + if (!csvContent) { + throw new Error("Table content is empty."); + } + const dataUrl = `data:text/csv;charset=utf-8,${encodeURIComponent(csvContent)}`; + const result = await runExport("media", { + dataUrl, + filename: "table.csv", + customExportType: "csv", + category: "document", + }); + if (result?.success) { + onNotify?.(`Table CSV exported to ${result.filename}`, "success"); + } else { + onNotify?.(result?.error || "Export failed", "error"); + } + } catch (err) { + onNotify?.(`Failed to export table CSV: ${err?.message || "Unknown error"}`, "error"); + } + }; + const [menuIndex, setMenuIndex] = useState(0); const [cropSaving, setCropSaving] = useState(false); const [replaceState, setReplaceState] = useState({ busy: false, assetPath: "" }); @@ -674,7 +744,8 @@ export const MarkdownPreview = memo(function MarkdownPreviewContent({ onMediaClick({ path: src, type: mediaType }); }; - const openImageEditor = async (imageElement, event) => { + const openImageEditor = async (imageElement, event, options = {}) => { + const { annotationOnly = false } = options; const assetPath = imageElement.getAttribute("data-asset-path") || ""; const isWorkspaceImage = Boolean(basePath && assetPath && !/^(https?:|data:|blob:)/i.test(assetPath)); if (!isWorkspaceImage) { @@ -729,7 +800,7 @@ export const MarkdownPreview = memo(function MarkdownPreviewContent({ imageLabel: imageElement.getAttribute("alt") || assetPath, annotation, hasOriginal, - annotationOnly: true, + annotationOnly, }); }; @@ -909,9 +980,28 @@ export const MarkdownPreview = memo(function MarkdownPreviewContent({ return; } + const exportImgBtn = target.closest('[data-table-action="export-image"]'); + if (exportImgBtn) { + event.preventDefault(); + event.stopPropagation(); + const tableWrapper = exportImgBtn.closest(".markdown-table-wrapper"); + void handleExportTableImage(tableWrapper); + return; + } + + const exportCsvBtn = target.closest('[data-table-action="export-csv"]'); + if (exportCsvBtn) { + event.preventDefault(); + event.stopPropagation(); + const tableWrapper = exportCsvBtn.closest(".markdown-table-wrapper"); + void handleExportTableCsv(tableWrapper); + return; + } + const tableWrapper = target.closest(".markdown-table-wrapper"); if (tableWrapper) { - if (target.closest("a, button, input, select, textarea")) return; + if (target.closest(".markdown-table-dropdown-popover")) return; + if (target.closest("a, input, select, textarea")) return; event.preventDefault(); event.stopPropagation(); @@ -977,8 +1067,69 @@ export const MarkdownPreview = memo(function MarkdownPreviewContent({ const imageElement = getImageActionElement(imageAction); if (!imageElement) return; + if (imageAction.dataset.imageAction === "annotate") { + void openImageEditor(imageElement, event, { annotationOnly: true }); + return; + } + if (imageAction.dataset.imageAction === "edit") { - void openImageEditor(imageElement, event); + void openImageEditor(imageElement, event, { annotationOnly: false }); + return; + } + + if (imageAction.dataset.imageAction === "download") { + event.preventDefault(); + event.stopPropagation(); + const assetPath = imageElement.getAttribute("data-asset-path") || imageElement.getAttribute("src") || ""; + const altText = imageElement.getAttribute("alt") || "image.png"; + const rawName = (assetPath || altText).split(/[?#]/)[0].split(/[/\\]/).pop() || "image.png"; + + (async () => { + try { + let downloadSrc = assetPath; + if (basePath && assetPath && !/^(https?:|data:|blob:)/i.test(assetPath)) { + try { + downloadSrc = (await readImage(basePath, assetPath)) || assetPath; + } catch { /* fallback */ } + } + if (!downloadSrc) { + downloadSrc = imageElement.currentSrc || imageElement.src || ""; + } + + let dataUrl; + let srcPath; + + if (typeof downloadSrc === "string" && downloadSrc.startsWith("data:")) { + dataUrl = downloadSrc; + } else if (typeof downloadSrc === "string" && (downloadSrc.startsWith("http") || downloadSrc.startsWith("blob:"))) { + const resp = await fetch(downloadSrc); + const blob = await resp.blob(); + dataUrl = await new Promise((resolve) => { + const reader = new FileReader(); + reader.onloadend = () => resolve(reader.result); + reader.readAsDataURL(blob); + }); + } else { + srcPath = downloadSrc; + } + + const result = await runExport("media", { + dataUrl, + srcPath, + filename: rawName, + customExportType: "image", + category: "media", + }); + + if (result?.success) { + onNotify?.(`Downloaded ${result.filename} to Downloads folder`, "success"); + } else { + onNotify?.(result?.error || "Failed to download image.", "error"); + } + } catch (err) { + onNotify?.(`Image download failed: ${err.message}`, "error"); + } + })(); return; } @@ -1900,6 +2051,7 @@ export const MarkdownPreview = memo(function MarkdownPreviewContent({ code={part.value} index={index} key={blockKey} + onNotify={onNotify} onEdit={(codeToEdit) => { if (!readOnly) { setMermaidEditState({ @@ -2104,9 +2256,18 @@ export const MarkdownPreview = memo(function MarkdownPreviewContent({ className="link-hover-popup-btn" onClick={() => handleDownloadFileFromPreview(activeLinkPopup.href)} > - + Open File +
+ )}
, diff --git a/src/components/MediaPreviewPane.jsx b/src/components/MediaPreviewPane.jsx index e731b872..ccf2a0e2 100644 --- a/src/components/MediaPreviewPane.jsx +++ b/src/components/MediaPreviewPane.jsx @@ -13,7 +13,7 @@ import { getImageFileSize, formatFileSize, } from "../utils/imageProcessingUtils"; -import { readImage, replaceImage, getImageAnnotation, setImageAnnotation, getImageOriginalStatus, restoreImageOriginal, openMediaInDefaultApp, saveToDownloads } from "../services/electronService"; +import { readImage, replaceImage, getImageAnnotation, setImageAnnotation, getImageOriginalStatus, restoreImageOriginal, openMediaInDefaultApp, runExport } from "../services/electronService"; import "../styles/mediaPreview.css"; // Initialize the pdf.js worker once via a Vite-bundled module worker so it @@ -286,10 +286,12 @@ export function MediaPreviewPane({ mediaPath, mediaType, basePath, showOriginalI srcPath = resolvedPath || mediaPath; } - await saveToDownloads({ + await runExport("media", { dataUrl, srcPath, filename: name, + customExportType: mediaType === "pdf" ? "pdf" : mediaType === "video" ? "video" : mediaType === "audio" ? "audio" : mediaType === "image" ? "image" : fileExtension || "media", + category: mediaType === "pdf" || mediaType === "document" ? "document" : "media", }); } catch (err) { console.error("[MediaPreviewPane] Download media error:", err); @@ -597,6 +599,14 @@ export function MediaPreviewPane({ mediaPath, mediaType, basePath, showOriginalI {fileExtension ? {fileExtension.toUpperCase()} : null}
+ + + + ) : null} + +
+
onEdit?.(code)} + style={{ + cursor: onEdit ? "pointer" : "default", + minHeight: "40px", + display: "flex", + alignItems: "center", + justifyContent: "center", + width: "100%", + }} + title={onEdit ? "Click to edit Mermaid diagram visually" : ""} + dangerouslySetInnerHTML={{ __html: svg }} + /> +
); } + diff --git a/src/styles/ExcalidrawBlock.css b/src/styles/ExcalidrawBlock.css index 40101157..171777fb 100644 --- a/src/styles/ExcalidrawBlock.css +++ b/src/styles/ExcalidrawBlock.css @@ -143,8 +143,11 @@ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05); } -.excalidraw-preview-thumbnail:hover .excalidraw-download-btn { +.excalidraw-preview-thumbnail:hover .markdown-block-actions, +.excalidraw-preview-thumbnail:focus-within .markdown-block-actions { opacity: 1; + transform: translateY(0); + pointer-events: auto; } .excalidraw-download-btn:hover { diff --git a/src/styles/editor.css b/src/styles/editor.css index 809339d0..903f5323 100644 --- a/src/styles/editor.css +++ b/src/styles/editor.css @@ -263,12 +263,19 @@ top: 10px; z-index: 4; display: flex; - gap: 6px; + align-items: center; + gap: 4px; opacity: 0; transform: translateY(-4px); transition: opacity 0.16s ease, transform 0.16s ease; + background: var(--tooltip-bg, rgba(20, 30, 33, 0.94)); + border: 1px solid rgba(255, 255, 255, 0.14); + border-radius: var(--radius-md, 6px); + padding: 3px 6px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25); + backdrop-filter: blur(8px); } .preview .markdown-image-frame:hover .markdown-image-actions, @@ -278,20 +285,28 @@ } .preview .markdown-image-action { - border: 1px solid rgba(255, 255, 255, 0.28); - border-radius: 999px; - background: rgba(10, 28, 32, 0.82); - color: #ffffff; + border: none; + background: transparent; + color: var(--tooltip-text, #ffffff); font-size: 11px; - font-weight: 700; - line-height: 1; - padding: 6px 10px; + font-weight: 600; + line-height: 1.2; + padding: 3px 7px; + border-radius: var(--radius-sm, 4px); cursor: pointer; + display: flex; + align-items: center; } .preview .markdown-image-action:hover, .preview .markdown-image-action:focus-visible { - background: rgba(20, 52, 58, 0.92); + background: rgba(255, 255, 255, 0.15); +} + +.preview .markdown-image-action-separator { + width: 1px; + height: 12px; + background: rgba(255, 255, 255, 0.2); } .preview .markdown-image-name { @@ -340,6 +355,132 @@ box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-solid, #3b82f6) 35%, transparent); } +/* Compact Hover Action Bar for Tables and Mermaid Blocks */ +.preview .markdown-block-actions { + position: absolute; + right: 8px; + top: 8px; + z-index: 10; + display: flex; + align-items: center; + gap: 4px; + opacity: 0; + transform: translateY(-4px); + transition: opacity 0.16s ease, transform 0.16s ease; + pointer-events: none; + background: var(--tooltip-bg, rgba(20, 30, 33, 0.94)); + border: 1px solid rgba(255, 255, 255, 0.14); + border-radius: var(--radius-md, 6px); + padding: 3px 6px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25); + backdrop-filter: blur(8px); +} + +.preview .markdown-table-wrapper:hover .markdown-block-actions, +.preview .markdown-table-wrapper:focus-within .markdown-block-actions, +.preview .mermaid-block-container:hover .markdown-block-actions, +.preview .mermaid-block-container:focus-within .markdown-block-actions { + opacity: 1; + transform: translateY(0); + pointer-events: auto; +} + +.preview .markdown-block-action-btn { + border: none; + background: transparent; + color: var(--tooltip-text, #ffffff); + font-size: 11px; + font-weight: 600; + line-height: 1.2; + padding: 3px 7px; + border-radius: var(--radius-sm, 4px); + cursor: pointer; + display: inline-flex; + align-items: center; + gap: 3px; + transition: background 0.14s ease; +} + +.preview .markdown-block-action-btn:hover:not(:disabled), +.preview .markdown-block-action-btn:focus-visible { + background: rgba(255, 255, 255, 0.15); +} + +.preview .markdown-block-action-btn:disabled { + opacity: 0.6; + cursor: not-allowed; +} + +.preview .markdown-block-action-separator { + width: 1px; + height: 12px; + background: rgba(255, 255, 255, 0.2); + flex-shrink: 0; + display: inline-block; + align-self: center; +} + +/* Table Download Popover Dropdown */ +.preview .markdown-table-download-menu { + position: relative; + display: inline-flex; + align-items: center; +} + +.preview .markdown-table-dropdown-popover { + position: absolute; + right: 0; + top: calc(100% + 6px); + z-index: 20; + display: flex; + flex-direction: column; + gap: 2px; + min-width: 135px; + padding: 4px; + border: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.2)); + border-radius: var(--radius-md, 6px); + background: var(--tooltip-bg, rgba(10, 28, 32, 0.92)); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35); + backdrop-filter: blur(12px); + opacity: 0; + visibility: hidden; + transform: translateY(-4px); + transition: opacity 0.14s ease, transform 0.14s ease, visibility 0.14s; + pointer-events: none; +} + +.preview .markdown-table-download-menu:hover .markdown-table-dropdown-popover, +.preview .markdown-table-download-menu:focus-within .markdown-table-dropdown-popover { + opacity: 1; + visibility: visible; + transform: translateY(0); + pointer-events: auto; +} + +.preview .markdown-table-dropdown-item { + border: none; + background: transparent; + color: var(--text-strong, #f8fafc); + font-size: 11px; + font-weight: 500; + padding: 6px 10px; + border-radius: var(--radius-sm, 4px); + cursor: pointer; + display: flex; + align-items: center; + gap: 6px; + white-space: nowrap; + width: 100%; + text-align: left; + transition: background 0.12s ease; +} + +.preview .markdown-table-dropdown-item:hover, +.preview .markdown-table-dropdown-item:focus-visible { + background: var(--surface-accent, rgba(59, 130, 246, 0.15)); + color: var(--accent-solid, #3b82f6); +} + .preview .markdown-image-annotation { position: absolute; left: 10px; diff --git a/src/tests/components/DownloadsPage.integration.test.jsx b/src/tests/components/DownloadsPage.integration.test.jsx index 4863d043..f459764c 100644 --- a/src/tests/components/DownloadsPage.integration.test.jsx +++ b/src/tests/components/DownloadsPage.integration.test.jsx @@ -15,6 +15,7 @@ vi.mock("../../services/electronService", () => ({ openExportFile: vi.fn(), showInFolder: vi.fn(), getDefaultDownloadDir: vi.fn(), + onExportRecordAdded: vi.fn(() => () => {}), })); const mockRecords = [ diff --git a/src/tests/utils/exportUtils.test.js b/src/tests/utils/exportUtils.test.js new file mode 100644 index 00000000..dc3d38d8 --- /dev/null +++ b/src/tests/utils/exportUtils.test.js @@ -0,0 +1,12 @@ +import { describe, expect, it } from "vitest"; +import { tableElementToPngDataUrl, svgElementToPngDataUrl } from "../../utils/exportUtils"; + +describe("exportUtils", () => { + it("rejects invalid table elements gracefully", async () => { + await expect(tableElementToPngDataUrl(null)).rejects.toThrow("Invalid Table element"); + }); + + it("rejects invalid SVG elements gracefully", async () => { + await expect(svgElementToPngDataUrl(null)).rejects.toThrow("Invalid SVG element"); + }); +}); diff --git a/src/tests/utils/tableUtils.test.js b/src/tests/utils/tableUtils.test.js index fa1034fb..f00341c7 100644 --- a/src/tests/utils/tableUtils.test.js +++ b/src/tests/utils/tableUtils.test.js @@ -81,4 +81,20 @@ describe("tableUtils", () => { "|x|y|", ].join("\n")); }); + + it("converts markdown table to CSV string correctly", () => { + const { markdownTableToCsv } = require("../../utils/tableUtils"); + const markdown = [ + "| Name | Role | Location |", + "| --- | --- | --- |", + "| Alice | Dev | NYC |", + '| Bob | "Lead, UX" | SF |', + ].join("\n"); + + const csv = markdownTableToCsv(markdown); + expect(csv).toContain("Name,Role,Location"); + expect(csv).toContain("Alice,Dev,NYC"); + expect(csv).toContain('Bob,"""Lead, UX""",SF'); + }); }); + diff --git a/src/utils/exportUtils.js b/src/utils/exportUtils.js new file mode 100644 index 00000000..fb39d124 --- /dev/null +++ b/src/utils/exportUtils.js @@ -0,0 +1,110 @@ +/** + * Utility functions for rendering DOM elements (SVG, HTML Tables) to PNG Data URLs + * for export through ExportManager. + */ + +export async function svgElementToPngDataUrl(svgElement) { + if (!svgElement || !(svgElement instanceof SVGElement)) { + throw new Error("Invalid SVG element provided for image export."); + } + + const clonedSvg = svgElement.cloneNode(true); + if (!clonedSvg.getAttribute("xmlns")) { + clonedSvg.setAttribute("xmlns", "http://www.w3.org/2000/svg"); + } + + const rect = svgElement.getBoundingClientRect(); + const width = Math.ceil(rect.width || svgElement.viewBox?.baseVal?.width || 800); + const height = Math.ceil(rect.height || svgElement.viewBox?.baseVal?.height || 600); + clonedSvg.setAttribute("width", String(width)); + clonedSvg.setAttribute("height", String(height)); + + const svgString = new XMLSerializer().serializeToString(clonedSvg); + const svgBlob = new Blob([svgString], { type: "image/svg+xml;charset=utf-8" }); + const url = URL.createObjectURL(svgBlob); + + return new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => { + try { + const canvas = document.createElement("canvas"); + const scale = 2; // 2x resolution for high DPI crisp export + canvas.width = width * scale; + canvas.height = height * scale; + const ctx = canvas.getContext("2d"); + ctx.fillStyle = "#ffffff"; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.scale(scale, scale); + ctx.drawImage(img, 0, 0, width, height); + URL.revokeObjectURL(url); + resolve(canvas.toDataURL("image/png")); + } catch (err) { + URL.revokeObjectURL(url); + reject(err); + } + }; + img.onerror = () => { + URL.revokeObjectURL(url); + reject(new Error("Failed to render SVG image for export.")); + }; + img.src = url; + }); +} + +export async function tableElementToPngDataUrl(tableElement) { + if (!tableElement) { + throw new Error("Invalid Table element provided for image export."); + } + + const targetTable = tableElement.tagName === "TABLE" ? tableElement : tableElement.querySelector("table") || tableElement; + const rect = targetTable.getBoundingClientRect(); + const width = Math.max(Math.ceil(rect.width), 400); + const height = Math.max(Math.ceil(rect.height), 120); + + const clone = targetTable.cloneNode(true); + const wrapperHtml = ` + + +
+ + ${clone.outerHTML} +
+
+
+ `; + + const blob = new Blob([wrapperHtml], { type: "image/svg+xml;charset=utf-8" }); + const url = URL.createObjectURL(blob); + + return new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => { + try { + const canvas = document.createElement("canvas"); + const scale = 2; + canvas.width = width * scale; + canvas.height = height * scale; + const ctx = canvas.getContext("2d"); + ctx.fillStyle = "#ffffff"; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.scale(scale, scale); + ctx.drawImage(img, 0, 0, width, height); + URL.revokeObjectURL(url); + resolve(canvas.toDataURL("image/png")); + } catch (err) { + URL.revokeObjectURL(url); + reject(err); + } + }; + img.onerror = () => { + URL.revokeObjectURL(url); + reject(new Error("Failed to render table image for export.")); + }; + img.src = url; + }); +} diff --git a/src/utils/renderUtils.js b/src/utils/renderUtils.js index 6d47addd..eca95d3b 100644 --- a/src/utils/renderUtils.js +++ b/src/utils/renderUtils.js @@ -137,7 +137,7 @@ md.renderer.rules.table_open = (tokens, idx, options, env) => { const attrLine = Number(token.attrGet("data-source-line")) || 0; const sourceStartLine = mappedLine || attrLine; const lineAttr = sourceStartLine > 0 ? ` data-source-line="${sourceStartLine}"` : ""; - return `
`; + return `
`; }; md.renderer.rules.table_close = () => { @@ -152,7 +152,7 @@ md.renderer.rules.image = (tokens, idx, options, env, self) => { } const label = getImageDisplayName(src, token.content || token.attrGet("alt") || "Image"); const imageHtml = defaultImageRenderer(tokens, idx, options, env, self); - return `${imageHtml}${escapeHtml(label)}`; + return `${imageHtml}${escapeHtml(label)}`; }; /** diff --git a/src/utils/tableUtils.js b/src/utils/tableUtils.js index 487beb06..1a4a3e76 100644 --- a/src/utils/tableUtils.js +++ b/src/utils/tableUtils.js @@ -241,3 +241,43 @@ export function htmlTableToMarkdown(htmlString) { return null; } } + +export function tableElementToCsv(tableElement) { + if (!tableElement) return ""; + const target = tableElement.tagName === "TABLE" ? tableElement : tableElement.querySelector("table") || tableElement; + const rows = Array.from(target.querySelectorAll("tr")); + const escapeCsvCell = (cell) => { + const text = String(cell?.innerText || cell?.textContent || "").trim(); + if (text.includes('"') || text.includes(',') || text.includes('\n')) { + return `"${text.replace(/"/g, '""')}"`; + } + return text; + }; + + const csvRows = rows.map((row) => { + const cells = Array.from(row.querySelectorAll("th, td")); + return cells.map(escapeCsvCell).join(","); + }); + + return csvRows.join("\n"); +} + +export function markdownTableToCsv(markdownText) { + const { headers, rows } = parseMarkdownTable(markdownText); + if (!headers.length && !rows.length) return ""; + + const escapeCsvCell = (cell) => { + const text = String(cell || "").trim(); + if (text.includes('"') || text.includes(',') || text.includes('\n')) { + return `"${text.replace(/"/g, '""')}"`; + } + return text; + }; + + const csvRows = [ + headers.map(escapeCsvCell).join(","), + ...rows.map((row) => row.map(escapeCsvCell).join(",")) + ]; + return csvRows.join("\n"); +} + From 5329aad939d5626b431d1c98c051c5baf3615fa1 Mon Sep 17 00:00:00 2001 From: Bikash Panda Date: Sat, 8 Aug 2026 22:19:35 +0530 Subject: [PATCH 13/18] fix(export): resolve diagram and table export issues - Target diagram SVG in MermaidBlock instead of Lucide pencil icon - Fix table popover text color for theme contrast - Support plaintext/urlencoded data URLs in ExportManager for CSV export - Add XHTML tag sanitization and vertical buffer to table image export - Expand table action bar with direct Download Image/CSV buttons --- electron/lib/export/ExportManager.cjs | 15 +++++-- src/components/MermaidBlock.jsx | 2 +- src/styles/editor.css | 2 +- src/utils/exportUtils.js | 63 +++++++++++++++++---------- src/utils/renderUtils.js | 2 +- 5 files changed, 54 insertions(+), 30 deletions(-) diff --git a/electron/lib/export/ExportManager.cjs b/electron/lib/export/ExportManager.cjs index 506f8bd0..d6f500af 100644 --- a/electron/lib/export/ExportManager.cjs +++ b/electron/lib/export/ExportManager.cjs @@ -607,9 +607,18 @@ class ExportManager { if (resolvedSrc && fs.existsSync(resolvedSrc)) { fs.copyFileSync(resolvedSrc, targetPath); } else if (effectiveDataUrl) { - const rawBase64 = effectiveDataUrl.replace(/^data:[^;]+;base64,/, ""); - const buffer = Buffer.from(rawBase64, "base64"); - fs.writeFileSync(targetPath, buffer); + if (effectiveDataUrl.includes(";base64,")) { + const rawBase64 = effectiveDataUrl.replace(/^data:[^;]+;base64,/, ""); + const buffer = Buffer.from(rawBase64, "base64"); + fs.writeFileSync(targetPath, buffer); + } else if (effectiveDataUrl.startsWith("data:")) { + const commaIdx = effectiveDataUrl.indexOf(","); + const rawContent = commaIdx >= 0 ? effectiveDataUrl.slice(commaIdx + 1) : effectiveDataUrl; + const decodedContent = decodeURIComponent(rawContent); + fs.writeFileSync(targetPath, decodedContent, "utf8"); + } else { + fs.writeFileSync(targetPath, effectiveDataUrl, "utf8"); + } } else { throw new Error("Invalid image or media source provided for export."); } diff --git a/src/components/MermaidBlock.jsx b/src/components/MermaidBlock.jsx index 1a56e9b2..d53ea4d1 100644 --- a/src/components/MermaidBlock.jsx +++ b/src/components/MermaidBlock.jsx @@ -71,7 +71,7 @@ export function MermaidBlock({ code, onEdit, onNotify }) { try { setIsExporting(true); - const svgElement = containerRef.current?.querySelector?.("svg"); + const svgElement = containerRef.current?.querySelector?.(".mermaid-render svg") || containerRef.current?.querySelector?.("svg:not(.lucide)"); if (!svgElement) { throw new Error("Rendered diagram SVG not found."); } diff --git a/src/styles/editor.css b/src/styles/editor.css index 903f5323..4dc4d891 100644 --- a/src/styles/editor.css +++ b/src/styles/editor.css @@ -460,7 +460,7 @@ .preview .markdown-table-dropdown-item { border: none; background: transparent; - color: var(--text-strong, #f8fafc); + color: var(--tooltip-text, #f0f8f5); font-size: 11px; font-weight: 500; padding: 6px 10px; diff --git a/src/utils/exportUtils.js b/src/utils/exportUtils.js index fb39d124..27252939 100644 --- a/src/utils/exportUtils.js +++ b/src/utils/exportUtils.js @@ -3,6 +3,14 @@ * for export through ExportManager. */ +function toXhtmlString(htmlString) { + if (!htmlString) return ""; + let xhtml = String(htmlString) + .replace(/<(br|img|hr|input|col|link|meta|area|embed|param)([^>]*?)(?/gi, "<$1$2 />") + .replace(/&(?!amp;|lt;|gt;|quot;|apos;|#\d+;|#x[0-9a-fA-F]+;)/g, "&"); + return xhtml; +} + export async function svgElementToPngDataUrl(svgElement) { if (!svgElement || !(svgElement instanceof SVGElement)) { throw new Error("Invalid SVG element provided for image export."); @@ -14,17 +22,17 @@ export async function svgElementToPngDataUrl(svgElement) { } const rect = svgElement.getBoundingClientRect(); - const width = Math.ceil(rect.width || svgElement.viewBox?.baseVal?.width || 800); - const height = Math.ceil(rect.height || svgElement.viewBox?.baseVal?.height || 600); + const width = Math.max(Math.ceil(rect.width || svgElement.viewBox?.baseVal?.width || 800), 100); + const height = Math.max(Math.ceil(rect.height || svgElement.viewBox?.baseVal?.height || 600), 100); clonedSvg.setAttribute("width", String(width)); clonedSvg.setAttribute("height", String(height)); const svgString = new XMLSerializer().serializeToString(clonedSvg); - const svgBlob = new Blob([svgString], { type: "image/svg+xml;charset=utf-8" }); - const url = URL.createObjectURL(svgBlob); + const dataUrl = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`; return new Promise((resolve, reject) => { const img = new Image(); + img.crossOrigin = "anonymous"; img.onload = () => { try { const canvas = document.createElement("canvas"); @@ -36,18 +44,15 @@ export async function svgElementToPngDataUrl(svgElement) { ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.scale(scale, scale); ctx.drawImage(img, 0, 0, width, height); - URL.revokeObjectURL(url); resolve(canvas.toDataURL("image/png")); } catch (err) { - URL.revokeObjectURL(url); reject(err); } }; img.onerror = () => { - URL.revokeObjectURL(url); reject(new Error("Failed to render SVG image for export.")); }; - img.src = url; + img.src = dataUrl; }); } @@ -57,54 +62,64 @@ export async function tableElementToPngDataUrl(tableElement) { } const targetTable = tableElement.tagName === "TABLE" ? tableElement : tableElement.querySelector("table") || tableElement; + if (!targetTable || targetTable.tagName !== "TABLE") { + throw new Error("Invalid Table element provided for image export."); + } + const rect = targetTable.getBoundingClientRect(); - const width = Math.max(Math.ceil(rect.width), 400); - const height = Math.max(Math.ceil(rect.height), 120); + const paddingHorizontal = 24; + const paddingVertical = 24; + const verticalBuffer = 16; + + const tableWidth = Math.max(Math.ceil(rect.width || targetTable.offsetWidth || 600), 400); + const tableHeight = Math.max(Math.ceil(rect.height || targetTable.offsetHeight || 200), 80); + + const totalWidth = tableWidth + (paddingHorizontal * 2); + const totalHeight = tableHeight + (paddingVertical * 2) + verticalBuffer; const clone = targetTable.cloneNode(true); + const cleanedTableHtml = toXhtmlString(clone.outerHTML); + const wrapperHtml = ` - + -
+
- ${clone.outerHTML} + ${cleanedTableHtml}
`; - const blob = new Blob([wrapperHtml], { type: "image/svg+xml;charset=utf-8" }); - const url = URL.createObjectURL(blob); + const dataUrl = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(wrapperHtml)}`; return new Promise((resolve, reject) => { const img = new Image(); + img.crossOrigin = "anonymous"; img.onload = () => { try { const canvas = document.createElement("canvas"); const scale = 2; - canvas.width = width * scale; - canvas.height = height * scale; + canvas.width = totalWidth * scale; + canvas.height = totalHeight * scale; const ctx = canvas.getContext("2d"); ctx.fillStyle = "#ffffff"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.scale(scale, scale); - ctx.drawImage(img, 0, 0, width, height); - URL.revokeObjectURL(url); + ctx.drawImage(img, 0, 0, totalWidth, totalHeight); resolve(canvas.toDataURL("image/png")); } catch (err) { - URL.revokeObjectURL(url); reject(err); } }; img.onerror = () => { - URL.revokeObjectURL(url); reject(new Error("Failed to render table image for export.")); }; - img.src = url; + img.src = dataUrl; }); } diff --git a/src/utils/renderUtils.js b/src/utils/renderUtils.js index eca95d3b..39184055 100644 --- a/src/utils/renderUtils.js +++ b/src/utils/renderUtils.js @@ -137,7 +137,7 @@ md.renderer.rules.table_open = (tokens, idx, options, env) => { const attrLine = Number(token.attrGet("data-source-line")) || 0; const sourceStartLine = mappedLine || attrLine; const lineAttr = sourceStartLine > 0 ? ` data-source-line="${sourceStartLine}"` : ""; - return `
`; + return `
`; }; md.renderer.rules.table_close = () => { From 1dc8d80d92bc880ed5ab8e0842a411e7d513d743 Mon Sep 17 00:00:00 2001 From: Bikash Panda Date: Sat, 8 Aug 2026 23:01:28 +0530 Subject: [PATCH 14/18] Updated popover for dowloads t o open file on click --- src/components/DownloadsPopover.jsx | 28 ++-- src/styles/titlebar.css | 12 ++ .../components/DownloadsPopover.test.jsx | 127 ++++++++++++++++++ 3 files changed, 156 insertions(+), 11 deletions(-) create mode 100644 src/tests/components/DownloadsPopover.test.jsx diff --git a/src/components/DownloadsPopover.jsx b/src/components/DownloadsPopover.jsx index 4f8b62d0..0e877c9a 100644 --- a/src/components/DownloadsPopover.jsx +++ b/src/components/DownloadsPopover.jsx @@ -2,7 +2,6 @@ import React, { useEffect, useRef } from "react"; import { Download, Folder, - ExternalLink, Archive, ChevronRight, FileText, @@ -104,7 +103,19 @@ export function DownloadsPopover({ ) : ( recentDownloads.slice(0, 5).map((item) => ( -
+
openExportFile(item.filePath)} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + openExportFile(item.filePath); + } + }} + >
{getPopoverIconForType(item.exportType)}
@@ -122,19 +133,14 @@ export function DownloadsPopover({ -
)) diff --git a/src/styles/titlebar.css b/src/styles/titlebar.css index 356aed52..f2a8c4ba 100644 --- a/src/styles/titlebar.css +++ b/src/styles/titlebar.css @@ -445,6 +445,8 @@ border-bottom: 1px solid var(--border-subtle); box-shadow: none; transition: background var(--motion-fast); + cursor: pointer; + outline: none; } .downloads-popover-item:last-child { @@ -455,6 +457,16 @@ background: var(--surface-accent); } +.downloads-popover-item:focus-visible { + outline: 2px solid var(--focus-ring-color); + outline-offset: -2px; + background: var(--surface-accent); +} + +.downloads-popover-item:active { + background: var(--surface-muted); +} + .downloads-popover-item-icon { display: flex; align-items: center; diff --git a/src/tests/components/DownloadsPopover.test.jsx b/src/tests/components/DownloadsPopover.test.jsx new file mode 100644 index 00000000..13074d70 --- /dev/null +++ b/src/tests/components/DownloadsPopover.test.jsx @@ -0,0 +1,127 @@ +// @vitest-environment jsdom +import React, { act } from "react"; +import { createRoot } from "react-dom/client"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { DownloadsPopover } from "../../components/DownloadsPopover"; + +const openExportFileMock = vi.fn(); +const showInFolderMock = vi.fn(); + +vi.mock("../../services/electronService.js", () => ({ + openExportFile: (...args) => openExportFileMock(...args), + showInFolder: (...args) => showInFolderMock(...args), +})); + +describe("DownloadsPopover interaction tests", () => { + let container = null; + let root = null; + + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + root = createRoot(container); + openExportFileMock.mockClear(); + showInFolderMock.mockClear(); + }); + + afterEach(() => { + if (root) { + act(() => { + root.unmount(); + }); + } + if (container && container.parentNode) { + container.parentNode.removeChild(container); + } + }); + + function renderPopover(props) { + act(() => { + root.render(); + }); + } + + it("calls openExportFile when clicking a download item directly", () => { + const recent = [ + { + id: "1", + filename: "test-doc.pdf", + filePath: "/downloads/test-doc.pdf", + fileSize: 1024, + timestamp: new Date().toISOString(), + exportType: "pdf", + }, + ]; + + renderPopover({ + isOpen: true, + onClose: vi.fn(), + recentDownloads: recent, + }); + + const itemEl = container.querySelector(".downloads-popover-item"); + expect(itemEl).not.toBeNull(); + + act(() => { + itemEl.click(); + }); + + expect(openExportFileMock).toHaveBeenCalledWith("/downloads/test-doc.pdf"); + expect(showInFolderMock).not.toHaveBeenCalled(); + }); + + it("calls showInFolder without calling openExportFile when folder button is clicked", () => { + const recent = [ + { + id: "1", + filename: "test-doc.pdf", + filePath: "/downloads/test-doc.pdf", + fileSize: 1024, + timestamp: new Date().toISOString(), + exportType: "pdf", + }, + ]; + + renderPopover({ + isOpen: true, + onClose: vi.fn(), + recentDownloads: recent, + }); + + const folderBtn = container.querySelector(".downloads-popover-action-btn"); + expect(folderBtn).not.toBeNull(); + expect(folderBtn.getAttribute("title")).toBe("Show in Folder"); + + act(() => { + folderBtn.click(); + }); + + expect(showInFolderMock).toHaveBeenCalledWith("/downloads/test-doc.pdf"); + expect(openExportFileMock).not.toHaveBeenCalled(); + }); + + it("does not render a separate Open File button on download items", () => { + const recent = [ + { + id: "1", + filename: "test-doc.pdf", + filePath: "/downloads/test-doc.pdf", + fileSize: 1024, + timestamp: new Date().toISOString(), + exportType: "pdf", + }, + ]; + + renderPopover({ + isOpen: true, + onClose: vi.fn(), + recentDownloads: recent, + }); + + const openBtn = container.querySelector('[title="Open File"]'); + expect(openBtn).toBeNull(); + + const actionBtns = container.querySelectorAll(".downloads-popover-action-btn"); + expect(actionBtns.length).toBe(1); + }); +}); From 664ac1c301703e26c50a0c3f1f3386da9dcfd252 Mon Sep 17 00:00:00 2001 From: Bikash Panda Date: Sun, 9 Aug 2026 11:06:22 +0530 Subject: [PATCH 15/18] fix(preview): convert link popover to pure CSS and resolve attachment paths - Move link action popover to pure CSS wrapper to eliminate flickering - Resolve non-markdown file links and decode URI paths for downloads - Handle missing export file sources gracefully in ExportManager --- electron/lib/export/ExportManager.cjs | 10 +- src/components/MarkdownPreview.jsx | 260 +++++++++++--------------- src/styles/components.css | 33 +++- src/utils/renderUtils.js | 30 +++ 4 files changed, 177 insertions(+), 156 deletions(-) diff --git a/electron/lib/export/ExportManager.cjs b/electron/lib/export/ExportManager.cjs index d6f500af..e5322a92 100644 --- a/electron/lib/export/ExportManager.cjs +++ b/electron/lib/export/ExportManager.cjs @@ -594,6 +594,11 @@ class ExportManager { } } resolvedSrc = resolvedSrc.split(/[?#]/)[0]; + try { + resolvedSrc = decodeURIComponent(resolvedSrc); + } catch { + /* keep original */ + } const notesRoot = typeof this.getNotesRoot === "function" ? this.getNotesRoot() : null; @@ -620,7 +625,10 @@ class ExportManager { fs.writeFileSync(targetPath, effectiveDataUrl, "utf8"); } } else { - throw new Error("Invalid image or media source provided for export."); + return { + success: false, + error: `File not found on disk or invalid media source: ${rawSrc || "unknown"}` + }; } let fileSize = 0; diff --git a/src/components/MarkdownPreview.jsx b/src/components/MarkdownPreview.jsx index 730b99eb..7f34a28d 100644 --- a/src/components/MarkdownPreview.jsx +++ b/src/components/MarkdownPreview.jsx @@ -380,6 +380,63 @@ function resolveMarkdownLinkPath(basePath, href) { return absolute.replace(/\//g, "\\"); } +function resolveAnyLocalLinkPath(basePath, href) { + const cleaned = String(href || "").trim(); + if (!cleaned || /^(https?:|data:|blob:|mailto:|#)/i.test(cleaned)) { + return ""; + } + + let withoutQuery = cleaned.split(/[?#]/)[0]; + let decoded = withoutQuery; + try { + decoded = decodeURIComponent(withoutQuery); + } catch { /* keep original */ } + + if (/^file:/i.test(decoded)) { + try { + const parsed = new URL(decoded); + let pathname = parsed.pathname || ""; + if (/^\/[A-Za-z]:\//.test(pathname)) { + pathname = pathname.slice(1); + } + return decodeURIComponent(pathname || "").replace(/\//g, "\\"); + } catch { + return decoded.replace(/^file:\/\/\/?/i, "").replace(/\//g, "\\"); + } + } + + if (/^[a-zA-Z]:[/\\]/.test(decoded)) { + return decoded.replace(/\//g, "\\"); + } + + if (decoded.startsWith("/")) { + return decoded; + } + + if (basePath) { + const normalizedBase = String(basePath).replace(/\//g, "\\"); + const lastSlash = normalizedBase.lastIndexOf("\\"); + const dir = lastSlash >= 0 ? normalizedBase.slice(0, lastSlash) : normalizedBase; + const parts = decoded.replace(/\//g, "\\").split("\\"); + const dirParts = dir.split("\\").filter(Boolean); + + for (const part of parts) { + if (part === ".") continue; + if (part === "..") { + if (dirParts.length > 0) dirParts.pop(); + } else if (part) { + dirParts.push(part); + } + } + + const driveMatch = normalizedBase.match(/^([a-zA-Z]:)/); + const prefix = driveMatch ? driveMatch[1] : ""; + return (prefix ? "" : "") + dirParts.join("\\"); + } + + return decoded.replace(/\//g, "\\"); +} + function clearInlineLinkedPreview(linkElement) { const next = linkElement?.nextElementSibling; if (next instanceof HTMLElement && next.classList.contains("inline-linked-note")) { @@ -420,44 +477,63 @@ export const MarkdownPreview = memo(function MarkdownPreviewContent({ annotationOnly: false, }); const [contextMenu, setContextMenu] = useState(null); - const [activeLinkPopup, setActiveLinkPopup] = useState(null); - const linkHideTimerRef = useRef(null); - const isPopupHoveredRef = useRef(false); const handleLinkNavigateRef = useRef(null); const handleCopyLinkFromPreview = (href) => { if (!href) return; navigator.clipboard.writeText(href); onNotify?.(`Copied link path: ${href}`, "success"); - setActiveLinkPopup(null); }; const handleDownloadFileFromPreview = (href) => { if (!href) return; - const cleanHref = String(href || "").trim().replace(/^file:\/\/\/?/i, ""); - const normalizedHref = cleanHref.split(/[?#]/)[0]; - const ext = normalizedHref.split(".").pop()?.toLowerCase(); + const resolvedPath = resolveAnyLocalLinkPath(basePath, href) || String(href || "").trim().replace(/^file:\/\/\/?/i, "").split(/[?#]/)[0]; + const ext = resolvedPath.split(".").pop()?.toLowerCase(); const mediaType = getMediaTypeFromExtension(ext) || "document"; if (typeof onMediaClick === "function") { - onMediaClick({ path: normalizedHref, type: mediaType }); + onMediaClick({ path: resolvedPath, type: mediaType }); } else if (basePath && typeof openMediaInDefaultApp === "function") { - openMediaInDefaultApp(basePath, normalizedHref).catch((err) => { + openMediaInDefaultApp(basePath, resolvedPath).catch((err) => { onNotify?.(err?.message || "Failed to open file.", "error"); }); } - setActiveLinkPopup(null); }; const handleDirectDownloadFileFromPreview = async (href) => { if (!href) return; try { - const resolvedPath = resolveMarkdownLinkPath(basePath, href); - const cleanPath = resolvedPath || String(href || "").trim().replace(/^file:\/\/\/?/i, "").split(/[?#]/)[0]; - const filename = cleanPath.split(/[/\\]/).pop() || "file"; + const resolvedPath = resolveAnyLocalLinkPath(basePath, href) || String(href || "").trim().replace(/^file:\/\/\/?/i, "").split(/[?#]/)[0]; + const filename = resolvedPath.split(/[/\\]/).pop() || "file"; + + let downloadSrc = resolvedPath; + if (basePath && downloadSrc && !/^(https?:|data:|blob:)/i.test(downloadSrc)) { + try { + const loaded = await readImage(basePath, downloadSrc); + if (loaded) downloadSrc = loaded; + } catch { /* keep resolvedPath */ } + } + + let dataUrl; + let srcPath; + + if (typeof downloadSrc === "string" && downloadSrc.startsWith("data:")) { + dataUrl = downloadSrc; + } else if (typeof downloadSrc === "string" && (downloadSrc.startsWith("blob:") || downloadSrc.startsWith("http"))) { + const resp = await fetch(downloadSrc); + const blob = await resp.blob(); + dataUrl = await new Promise((resolve) => { + const reader = new FileReader(); + reader.onloadend = () => resolve(reader.result); + reader.readAsDataURL(blob); + }); + } else { + srcPath = downloadSrc; + } const result = await runExport("media", { - srcPath: cleanPath, + dataUrl, + srcPath, filename, }); @@ -468,8 +544,6 @@ export const MarkdownPreview = memo(function MarkdownPreviewContent({ } } catch (err) { onNotify?.(err?.message || "Failed to download file.", "error"); - } finally { - setActiveLinkPopup(null); } }; @@ -1137,8 +1211,30 @@ export const MarkdownPreview = memo(function MarkdownPreviewContent({ return; } + const linkActionBtn = target.closest('[data-link-action]'); + if (linkActionBtn) { + event.preventDefault(); + event.stopPropagation(); + const action = linkActionBtn.getAttribute("data-link-action"); + const href = linkActionBtn.getAttribute("data-href") || ""; + const wrapper = linkActionBtn.closest(".markdown-link-wrapper"); + const linkElement = wrapper?.querySelector("a") || target.closest("a"); + + if (action === "copy") { + handleCopyLinkFromPreview(href); + } else if (action === "reveal") { + if (linkElement) handleLinkNavigateRef.current?.(linkElement); + } else if (action === "open-file") { + handleDownloadFileFromPreview(href); + } else if (action === "download") { + handleDirectDownloadFileFromPreview(href); + } + return; + } + const linkElement = target.closest("a"); if (linkElement instanceof HTMLAnchorElement) { + if (target.closest('[data-link-action]')) return; event.preventDefault(); event.stopPropagation(); handleLinkNavigateRef.current?.(linkElement); @@ -1189,69 +1285,7 @@ export const MarkdownPreview = memo(function MarkdownPreviewContent({ }; }, [basePath, inlineLinkedMarkdown, onMediaClick, onNotify, content, onContentChange, confirm]); - useEffect(() => { - const previewElement = previewRef.current; - if (!previewElement) return; - - const handleMouseOver = (e) => { - const link = e.target?.closest?.("a"); - if (link && previewElement.contains(link)) { - if (linkHideTimerRef.current) { - clearTimeout(linkHideTimerRef.current); - linkHideTimerRef.current = null; - } - const href = link.getAttribute("href"); - if (!href) return; - - const rect = link.getBoundingClientRect(); - - setActiveLinkPopup({ - href, - text: link.innerText, - element: link, - position: { - top: rect.top - 6, - left: rect.left + rect.width / 2, - }, - }); - } - }; - - const handleMouseOut = (e) => { - const link = e.target?.closest?.("a"); - const related = e.relatedTarget; - // Check if mouse moved into popover or still within link - if (related && (link?.contains(related) || related.closest?.(".link-hover-popup"))) { - return; - } - if (linkHideTimerRef.current) clearTimeout(linkHideTimerRef.current); - linkHideTimerRef.current = setTimeout(() => { - if (!isPopupHoveredRef.current) { - setActiveLinkPopup(null); - } - }, 200); - }; - - const handleScroll = () => { - if (linkHideTimerRef.current) clearTimeout(linkHideTimerRef.current); - linkHideTimerRef.current = setTimeout(() => { - if (!isPopupHoveredRef.current) { - setActiveLinkPopup(null); - } - }, 100); - }; - - previewElement.addEventListener("mouseover", handleMouseOver); - previewElement.addEventListener("mouseout", handleMouseOut); - previewElement.addEventListener("scroll", handleScroll, { passive: true }); - return () => { - previewElement.removeEventListener("mouseover", handleMouseOver); - previewElement.removeEventListener("mouseout", handleMouseOut); - previewElement.removeEventListener("scroll", handleScroll); - if (linkHideTimerRef.current) clearTimeout(linkHideTimerRef.current); - }; - }, [content, basePath]); useEffect(() => { if (!contextMenu) return undefined; @@ -2203,76 +2237,6 @@ export const MarkdownPreview = memo(function MarkdownPreviewContent({ } }} /> - {activeLinkPopup && createPortal( -
{ - isPopupHoveredRef.current = true; - if (linkHideTimerRef.current) { - clearTimeout(linkHideTimerRef.current); - linkHideTimerRef.current = null; - } - }} - onMouseLeave={() => { - isPopupHoveredRef.current = false; - if (linkHideTimerRef.current) clearTimeout(linkHideTimerRef.current); - linkHideTimerRef.current = setTimeout(() => { - if (!isPopupHoveredRef.current) { - setActiveLinkPopup(null); - } - }, 150); - }} - > - -
- - {!/^https?:\/\/|^\/\//i.test(activeLinkPopup.href || "") && ( - <> -
- -
- - - )} -
, - document.body - )} {tableEditState.open && ( { return `
`; }; +const defaultLinkOpenRenderer = md.renderer.rules.link_open || ((tokens, idx, options, env, self) => self.renderToken(tokens, idx, options)); +const defaultLinkCloseRenderer = md.renderer.rules.link_close || ((tokens, idx, options, env, self) => self.renderToken(tokens, idx, options)); + +md.renderer.rules.link_open = (tokens, idx, options, env, self) => { + const openHtml = defaultLinkOpenRenderer(tokens, idx, options, env, self); + return `${openHtml}`; +}; + +md.renderer.rules.link_close = (tokens, idx, options, env, self) => { + let href = ""; + for (let i = idx - 1; i >= 0; i--) { + if (tokens[i].type === "link_open") { + href = tokens[i].attrGet("href") || ""; + break; + } + } + const isWebUrl = /^https?:\/\/|^\/\//i.test(href); + const closeHtml = defaultLinkCloseRenderer(tokens, idx, options, env, self); + const safeHref = escapeHtml(href); + + const copyBtn = ``; + const revealBtn = ``; + const openFileBtn = !isWebUrl ? `` : ""; + const downloadBtn = !isWebUrl ? `` : ""; + + const popoverHtml = `${copyBtn}${revealBtn}${openFileBtn}${downloadBtn}`; + + return `${closeHtml}${popoverHtml}`; +}; + md.renderer.rules.image = (tokens, idx, options, env, self) => { const token = tokens[idx]; const src = token.attrGet("src") || ""; From bccde44feb1b3adf7146133e277a125d2d60d3f2 Mon Sep 17 00:00:00 2001 From: Bikash Panda Date: Sun, 9 Aug 2026 11:11:03 +0530 Subject: [PATCH 16/18] Docs updated --- docs/editor/diagrams.md | 7 +++++++ docs/editor/tables.md | 12 ++++++++++++ docs/export-reference.md | 5 +++++ 3 files changed, 24 insertions(+) diff --git a/docs/editor/diagrams.md b/docs/editor/diagrams.md index 50d17b17..a4e1ebc7 100644 --- a/docs/editor/diagrams.md +++ b/docs/editor/diagrams.md @@ -54,6 +54,13 @@ graph TD E -- No --> G[Stay local] ``` +### Interactive Diagram Actions + +In Preview and Split modes, hovering over any rendered Mermaid diagram reveals the top action bar: + +* **Edit**: Opens the Mermaid visual editor modal to modify diagram elements visually. +* **Download**: Renders and exports the Mermaid diagram as a high-resolution PNG image saved directly to your system Downloads folder. + ### Troubleshooting Mermaid If your diagram does not render: diff --git a/docs/editor/tables.md b/docs/editor/tables.md index ecc826ef..201979c7 100644 --- a/docs/editor/tables.md +++ b/docs/editor/tables.md @@ -97,6 +97,18 @@ While the table editor is open, background page scrolling is locked. The table c When you edit a table that already exists in your note, Notely preserves the original Markdown formatting style (column spacing and delimiter style) where the table shape hasn't changed. +## Export Table as Image or CSV + +In Preview mode and Split View, hovering over any rendered Markdown table displays the action bar with direct 1-click export buttons: + +| Action | Icon | Result | +|---|---|---| +| **Edit** | `✏️` | Opens the inline visual table editor modal | +| **Download Image** | `🖼️` | Exports the table as a high-resolution, unclipped PNG image with white background and clean padding | +| **Download CSV** | `📄` | Exports raw tabular data as a clean UTF-8 encoded `.csv` file | + +Exported tables are saved directly to your system Downloads folder and automatically logged in the [Downloads & Export History Manager](/export-reference#2-downloads--export-history-manager). + ## Tips ::: tip Large Tables & Full Screen Mode diff --git a/docs/export-reference.md b/docs/export-reference.md index cacd08d3..8743b2af 100644 --- a/docs/export-reference.md +++ b/docs/export-reference.md @@ -32,6 +32,11 @@ Exports the currently active markdown note as a standalone rendered document. * Produces a self-contained HTML file with inline CSS and resolved media references. * Suitable for publishing notes to static web servers or opening in any browser without Notely. +### Block-Level Exports (Tables & Diagrams) +* **Table Image Export (`Download Image`)**: Exports any rendered table as a high-resolution, unclipped PNG image with clean padding and solid background styling via `ExportManager`. +* **Table CSV Export (`Download CSV`)**: Exports raw markdown table rows and columns as a clean UTF-8 encoded `.csv` file with a byte order mark (`\uFEFF`) for immediate compatibility with Excel and spreadsheet tools. +* **Mermaid Diagram Export (`Download`)**: Converts rendered Mermaid SVG diagrams into high-resolution PNG image files via `ExportManager`. + --- ## 2. Downloads & Export History Manager From f014045dca3de45b0be7dd4a5bb45d6af9243577 Mon Sep 17 00:00:00 2001 From: Bikash Panda Date: Sun, 9 Aug 2026 11:38:51 +0530 Subject: [PATCH 17/18] feat(export): audit remediation & unified export engine - Centralize export handling in ExportManager with SQLite history persistence - Add PDF, Web HTML, note package, and ZIP workspace export pipelines - Support high-DPI image and CSV exports for tables and diagrams - Add Downloads page, titlebar popover, and Ctrl+J shortcut - Fix pathToFileURL import, duplicate toast notifications, and .notes-app exclusion --- electron/lib/documents/documentIpc.cjs | 7 +- electron/lib/export/ExportManager.cjs | 332 ++++++++++++++++++++--- electron/lib/export/exportHistoryIpc.cjs | 12 +- src/components/DownloadsPage.jsx | 30 +- src/components/DownloadsPopover.jsx | 27 +- src/components/MediaPreviewPane.jsx | 2 +- src/components/WorkspaceExportDialog.jsx | 1 - src/services/electronService.js | 17 -- src/utils/formatUtils.js | 33 +++ src/utils/tableUtils.js | 23 +- 10 files changed, 342 insertions(+), 142 deletions(-) create mode 100644 src/utils/formatUtils.js diff --git a/electron/lib/documents/documentIpc.cjs b/electron/lib/documents/documentIpc.cjs index 735ee809..7d3f53fd 100644 --- a/electron/lib/documents/documentIpc.cjs +++ b/electron/lib/documents/documentIpc.cjs @@ -363,12 +363,7 @@ function registerDocumentIpcHandlers(ipcMain, deps) { }; }); - registerTrustedHandler("documents:download-pdf", async (_event, payload) => { - const { getExportManager } = require("../export/ExportManager.cjs"); - const res = await getExportManager().runExport({ type: "pdf", payload }); - if (!res?.success) return res; - return { canceled: false, filePath: res.filePath }; - }); + diff --git a/electron/lib/export/ExportManager.cjs b/electron/lib/export/ExportManager.cjs index e5322a92..09ee62b9 100644 --- a/electron/lib/export/ExportManager.cjs +++ b/electron/lib/export/ExportManager.cjs @@ -3,6 +3,7 @@ const fsAsync = require("fs").promises; const path = require("path"); const os = require("os"); const crypto = require("crypto"); +const { pathToFileURL, fileURLToPath } = require("node:url"); const { ZipFile } = require("yazl"); const PDF_WRITE_RETRY_DELAYS_MS = [120, 320, 700]; @@ -501,12 +502,231 @@ class ExportManager { } } + _walkFiles(rootDir, options = {}) { + const exclude = new Set(options.excludeDirs || []); + const files = []; + + const visit = (currentDir) => { + if (!fs.existsSync(currentDir)) return; + const entries = fs.readdirSync(currentDir, { withFileTypes: true }); + for (const entry of entries) { + const nextPath = path.join(currentDir, entry.name); + if (entry.isDirectory()) { + if (exclude.has(entry.name)) continue; + visit(nextPath); + continue; + } + if (entry.isFile()) { + files.push(nextPath); + } + } + }; + + visit(rootDir); + return files; + } + + _copyDirRecursive(sourceRoot, targetRoot, options = {}) { + const exclude = new Set(options.excludeDirs || []); + + const copyDir = (currentSource, currentTarget) => { + fs.mkdirSync(currentTarget, { recursive: true }); + const entries = fs.readdirSync(currentSource, { withFileTypes: true }); + for (const entry of entries) { + if (entry.isDirectory() && exclude.has(entry.name)) continue; + const sourcePath = path.join(currentSource, entry.name); + const targetPath = path.join(currentTarget, entry.name); + + if (entry.isDirectory()) { + copyDir(sourcePath, targetPath); + continue; + } + + if (entry.isFile()) { + fs.mkdirSync(path.dirname(targetPath), { recursive: true }); + try { fs.copyFileSync(sourcePath, targetPath); } catch { /* ignore */ } + } + } + }; + + copyDir(sourceRoot, targetRoot); + } + + async _exportPdfWorkspace({ notesRoot, stagingRoot, contentMode }) { + const markdownFiles = this._walkFiles(notesRoot, { + excludeDirs: [".notes-app", "node_modules", ".git", ".artifacts", "dist", "build"], + }).filter((filePath) => path.extname(filePath).toLowerCase() === ".md"); + + const tempHtmlDir = path.join(stagingRoot, "_pdf-html"); + fs.mkdirSync(tempHtmlDir, { recursive: true }); + + const outputRoot = path.join(stagingRoot, "pdf"); + fs.mkdirSync(outputRoot, { recursive: true }); + + for (const markdownPath of markdownFiles) { + const content = fs.readFileSync(markdownPath, "utf8"); + const parsed = typeof this.parseDocument === "function" ? this.parseDocument(content, markdownPath) : { title: path.basename(markdownPath, ".md") }; + const relativeMdPath = path.relative(notesRoot, markdownPath); + + const markdownContent = typeof this.buildPdfExportMarkdown === "function" + ? this.buildPdfExportMarkdown(parsed, { includeRawNotes: true, includeCleansed: true }) + : content; + const html = typeof this.buildPdfExportHtml === "function" + ? this.buildPdfExportHtml({ + title: parsed.title || path.basename(markdownPath, ".md"), + markdownContent, + baseHref: pathToFileURL(`${path.dirname(markdownPath)}${path.sep}`).href, + sourceDir: path.dirname(markdownPath), + downsampleImages: false, + pdfQualityPreset: "full", + }) + : `${markdownContent}`; + + const relativePdfPath = relativeMdPath.replace(/\.md$/i, ".pdf"); + const htmlTempPath = path.join(tempHtmlDir, `${relativePdfPath.replace(/[\\/]/g, "__")}.html`); + const pdfOutputPath = path.join(outputRoot, relativePdfPath); + + fs.mkdirSync(path.dirname(pdfOutputPath), { recursive: true }); + fs.writeFileSync(htmlTempPath, html, "utf8"); + + if (this.BrowserWindow) { + const pdfWindow = new this.BrowserWindow({ + show: false, + width: 1280, + height: 1600, + backgroundColor: "#ffffff", + webPreferences: { + backgroundThrottling: false, + contextIsolation: true, + nodeIntegration: false, + sandbox: true, + webviewTag: false, + }, + }); + + try { + await pdfWindow.loadFile(htmlTempPath); + await pdfWindow.webContents.executeJavaScript("document.fonts ? document.fonts.ready : Promise.resolve()", true); + + const pdfData = await pdfWindow.webContents.printToPDF({ + printBackground: true, + preferCSSPageSize: true, + }); + + await writeFileWithRetries(pdfOutputPath, pdfData); + } finally { + if (!pdfWindow.isDestroyed()) { + pdfWindow.close(); + } + } + } + } + } + + _exportWebWorkspace({ notesRoot, stagingRoot, contentMode }) { + const allFiles = this._walkFiles(notesRoot, { + excludeDirs: [".notes-app", "node_modules", ".git", ".artifacts", "dist", "build"], + }); + const markdownFiles = allFiles.filter((filePath) => path.extname(filePath).toLowerCase() === ".md"); + const nonMarkdownFiles = allFiles.filter((filePath) => path.extname(filePath).toLowerCase() !== ".md"); + + const webRoot = path.join(stagingRoot, "web"); + fs.mkdirSync(webRoot, { recursive: true }); + + const mdToHtmlMap = new Map(); + for (const markdownPath of markdownFiles) { + const relMdPath = path.relative(notesRoot, markdownPath).replace(/\\/g, "/"); + const relHtmlPath = relMdPath.replace(/\.md$/i, ".html"); + mdToHtmlMap.set(relMdPath, relHtmlPath); + } + + let markdownIt = null; + if (typeof this.getMarkdownIt === "function") { + try { + const MarkdownItCtor = this.getMarkdownIt(); + markdownIt = new MarkdownItCtor({ html: false, linkify: true, typographer: true }); + } catch { /* fallback */ } + } + + const indexLinks = []; + + for (const markdownPath of markdownFiles) { + const relMdPath = path.relative(notesRoot, markdownPath).replace(/\\/g, "/"); + const relHtmlPath = mdToHtmlMap.get(relMdPath); + const htmlPath = path.join(webRoot, relHtmlPath); + const content = fs.readFileSync(markdownPath, "utf8"); + + const title = path.basename(markdownPath, ".md"); + const renderedHtml = markdownIt ? markdownIt.render(content) : `
${content}
`; + const pageHtml = ` + + + + + ${title} + + + +
+

${title}

+ ${renderedHtml} +
+ +`; + + fs.mkdirSync(path.dirname(htmlPath), { recursive: true }); + fs.writeFileSync(htmlPath, pageHtml, "utf8"); + indexLinks.push({ title, href: relHtmlPath }); + } + + for (const assetPath of nonMarkdownFiles) { + const relPath = path.relative(notesRoot, assetPath); + const targetPath = path.join(webRoot, relPath); + fs.mkdirSync(path.dirname(targetPath), { recursive: true }); + try { fs.copyFileSync(assetPath, targetPath); } catch { /* ignore unreadable */ } + } + + indexLinks.sort((left, right) => left.title.localeCompare(right.title)); + const indexHtml = ` + + + + Notely Workspace Export + + + +
+

Workspace Notes

+ +
+ +`; + fs.writeFileSync(path.join(webRoot, "index.html"), indexHtml, "utf8"); + } + // --- Type 3: Workspace ZIP Backup --- async _exportWorkspaceZip(payload, downloadDir) { const notesRoot = typeof this.getNotesRoot === "function" ? this.getNotesRoot() : null; if (!notesRoot) throw new Error("No notes root configured."); - const mode = payload.mode || "raw"; + const mode = ["raw", "pdf", "web"].includes(payload.mode) ? payload.mode : "raw"; + const contentMode = payload.contentMode || "combined"; const includeMetadata = Boolean(payload.includeMetadata); const requestedFileName = typeof payload.fileName === "string" ? payload.fileName.trim() : ""; const folderName = path.basename(notesRoot) || "workspace"; @@ -517,56 +737,84 @@ class ExportManager { const defaultName = requestedFileName || `${folderName}_backup.zip`; const { targetPath, targetName } = this._resolveCollisionFreePath(destinationPath, defaultName); - this._sendWorkspaceExportProgress({ phase: "Preparing export", percent: 5 }); - - const zipfile = new ZipFile(); - let entryCount = 0; const start = Date.now(); + const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "notely-workspace-export-")); + const stagingRoot = path.join(tempRoot, "staging"); + fs.mkdirSync(stagingRoot, { recursive: true }); - const walk = (dir) => { - const list = fs.readdirSync(dir); - for (const item of list) { - if (item === ".git" || item === "node_modules" || item === "dist") continue; - if (!includeMetadata && item === ".notes-app") continue; - const fullPath = path.join(dir, item); - const stat = fs.statSync(fullPath); - if (stat.isDirectory()) { - walk(fullPath); - } else { - const relPath = path.relative(notesRoot, fullPath).replace(/\\/g, "/"); - zipfile.addFile(fullPath, relPath); - entryCount += 1; + try { + this._sendWorkspaceExportProgress({ phase: "Preparing export", percent: 5 }); + + if (mode === "raw") { + this._sendWorkspaceExportProgress({ phase: "Collecting workspace files", percent: 20 }); + const defaultExcludes = ["node_modules", ".git", "dist", ".artifacts", "build"]; + const excludeDirs = includeMetadata ? defaultExcludes : [".notes-app", ...defaultExcludes]; + this._copyDirRecursive(notesRoot, stagingRoot, { excludeDirs }); + this._sendWorkspaceExportProgress({ phase: "Workspace files staged", percent: 70 }); + } else if (mode === "pdf") { + this._sendWorkspaceExportProgress({ phase: "Rendering PDF files", percent: 15 }); + await this._exportPdfWorkspace({ notesRoot, stagingRoot, contentMode }); + this._sendWorkspaceExportProgress({ phase: "PDF files rendered", percent: 75 }); + + if (includeMetadata) { + const metadataPath = path.join(notesRoot, ".notes-app"); + if (fs.existsSync(metadataPath)) { + this._sendWorkspaceExportProgress({ phase: "Adding metadata", percent: 80 }); + this._copyDirRecursive(metadataPath, path.join(stagingRoot, ".notes-app")); + } + } + } else { + this._sendWorkspaceExportProgress({ phase: "Rendering web pages", percent: 15 }); + this._exportWebWorkspace({ notesRoot, stagingRoot, contentMode }); + this._sendWorkspaceExportProgress({ phase: "Web pages rendered", percent: 75 }); + + if (includeMetadata) { + const metadataPath = path.join(notesRoot, ".notes-app"); + if (fs.existsSync(metadataPath)) { + this._sendWorkspaceExportProgress({ phase: "Adding metadata", percent: 80 }); + this._copyDirRecursive(metadataPath, path.join(stagingRoot, ".notes-app")); + } } } - }; - this._sendWorkspaceExportProgress({ phase: "Collecting workspace files", percent: 25 }); - walk(notesRoot); - this._sendWorkspaceExportProgress({ phase: "Compressing workspace archive", percent: 70 }); + this._sendWorkspaceExportProgress({ phase: "Compressing zip", percent: 85 }); + const zipfile = new ZipFile(); + let entryCount = 0; + + const stagedFiles = this._walkFiles(stagingRoot); + for (const absFile of stagedFiles) { + const relPath = path.relative(stagingRoot, absFile).replace(/\\/g, "/"); + const archivedPath = folderName ? `${folderName}/${relPath}` : relPath; + zipfile.addFile(absFile, archivedPath); + entryCount += 1; + } - await new Promise((resolve, reject) => { - const writeStream = fs.createWriteStream(targetPath); - zipfile.outputStream.pipe(writeStream); - zipfile.outputStream.on("end", resolve); - zipfile.outputStream.on("error", reject); - zipfile.end(); - }); + await new Promise((resolve, reject) => { + const writeStream = fs.createWriteStream(targetPath); + zipfile.outputStream.pipe(writeStream); + zipfile.outputStream.on("end", resolve); + zipfile.outputStream.on("error", reject); + zipfile.end(); + }); - this._sendWorkspaceExportProgress({ phase: "Export complete", percent: 100, done: true, filePath: targetPath }); + this._sendWorkspaceExportProgress({ phase: "Export complete", percent: 100, done: true, filePath: targetPath }); - let fileSize = 0; - try { fileSize = fs.statSync(targetPath).size; } catch { /* ignore */ } + let fileSize = 0; + try { fileSize = fs.statSync(targetPath).size; } catch { /* ignore */ } - return { - success: true, - targetPath, - filename: targetName, - fileSize, - exportType: mode === "pdf" ? "pdf" : mode === "web" ? "html" : "workspace_zip", - category: "document", - entryCount, - elapsedMs: Date.now() - start - }; + return { + success: true, + targetPath, + filename: targetName, + fileSize, + exportType: mode === "pdf" ? "pdf" : mode === "web" ? "html" : "workspace_zip", + category: "document", + entryCount, + elapsedMs: Date.now() - start + }; + } finally { + try { fs.rmSync(tempRoot, { recursive: true, force: true }); } catch { /* ignore */ } + } } // --- Type 4 & 5: Diagram Image & Media Download --- diff --git a/electron/lib/export/exportHistoryIpc.cjs b/electron/lib/export/exportHistoryIpc.cjs index dc88fd5f..d76e6dd7 100644 --- a/electron/lib/export/exportHistoryIpc.cjs +++ b/electron/lib/export/exportHistoryIpc.cjs @@ -32,11 +32,13 @@ function registerExportHistoryIpc({ ipcMain, BrowserWindow, shell, app, exportHi registerTrustedHandler("exports:addRecord", async (_, record) => { const res = await exportHistoryStore.addRecord(record); - BrowserWindow.getAllWindows().forEach((win) => { - if (!win.isDestroyed()) { - win.webContents.send("exports:record-added", record); - } - }); + if (res && BrowserWindow) { + BrowserWindow.getAllWindows().forEach((win) => { + if (!win.isDestroyed()) { + win.webContents.send("exports:record-added", res); + } + }); + } return res; }); diff --git a/src/components/DownloadsPage.jsx b/src/components/DownloadsPage.jsx index 6cc78380..b736ea68 100644 --- a/src/components/DownloadsPage.jsx +++ b/src/components/DownloadsPage.jsx @@ -28,35 +28,7 @@ import { AppCard } from "./AppCard.jsx"; import useConfirm from "../hooks/useConfirm.js"; import "../styles/DownloadsPage.css"; -function formatBytes(bytes) { - if (!bytes || bytes === 0) return "0 B"; - const k = 1024; - const sizes = ["B", "KB", "MB", "GB"]; - const i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + " " + sizes[i]; -} - -function formatTimestamp(isoString) { - if (!isoString) return ""; - try { - const date = new Date(isoString); - const now = new Date(); - const diffMs = now - date; - const diffMins = Math.floor(diffMs / (1000 * 60)); - const diffHours = Math.floor(diffMs / (1000 * 60 * 60)); - const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); - - if (diffMins < 1) return "Just now"; - if (diffMins < 60) return `${diffMins}m ago`; - if (diffHours < 24) return `${diffHours}h ago`; - if (diffDays === 1) return "Yesterday"; - if (diffDays < 7) return `${diffDays}d ago`; - - return date.toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" }); - } catch { - return isoString; - } -} +import { formatBytes, formatTimestamp } from "../utils/formatUtils.js"; function getIconForType(type) { switch (type) { diff --git a/src/components/DownloadsPopover.jsx b/src/components/DownloadsPopover.jsx index 0e877c9a..564f31fd 100644 --- a/src/components/DownloadsPopover.jsx +++ b/src/components/DownloadsPopover.jsx @@ -10,32 +10,7 @@ import { } from "lucide-react"; import { openExportFile, showInFolder } from "../services/electronService.js"; -function formatBytes(bytes) { - if (!bytes || bytes === 0) return "0 B"; - const k = 1024; - const sizes = ["B", "KB", "MB", "GB"]; - const i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + " " + sizes[i]; -} - -function formatTimestamp(isoString) { - if (!isoString) return ""; - try { - const date = new Date(isoString); - const now = new Date(); - const diffMs = now - date; - const diffMins = Math.floor(diffMs / (1000 * 60)); - const diffHours = Math.floor(diffMs / (1000 * 60 * 60)); - - if (diffMins < 1) return "Just now"; - if (diffMins < 60) return `${diffMins}m ago`; - if (diffHours < 24) return `${diffHours}h ago`; - - return date.toLocaleDateString(undefined, { month: "short", day: "numeric" }); - } catch { - return isoString; - } -} +import { formatBytes, formatTimestamp } from "../utils/formatUtils.js"; function getPopoverIconForType(type) { switch (type) { diff --git a/src/components/MediaPreviewPane.jsx b/src/components/MediaPreviewPane.jsx index ccf2a0e2..a1a31232 100644 --- a/src/components/MediaPreviewPane.jsx +++ b/src/components/MediaPreviewPane.jsx @@ -13,7 +13,7 @@ import { getImageFileSize, formatFileSize, } from "../utils/imageProcessingUtils"; -import { readImage, replaceImage, getImageAnnotation, setImageAnnotation, getImageOriginalStatus, restoreImageOriginal, openMediaInDefaultApp, runExport } from "../services/electronService"; +import { readImage, replaceImage, getImageAnnotation, setImageAnnotation, getImageOriginalStatus, restoreImageOriginal, openMediaInDefaultApp, runExport, saveToDownloads } from "../services/electronService"; import "../styles/mediaPreview.css"; // Initialize the pdf.js worker once via a Vite-bundled module worker so it diff --git a/src/components/WorkspaceExportDialog.jsx b/src/components/WorkspaceExportDialog.jsx index fe66be18..1336ba34 100644 --- a/src/components/WorkspaceExportDialog.jsx +++ b/src/components/WorkspaceExportDialog.jsx @@ -10,7 +10,6 @@ export function WorkspaceExportDialog({ progress, onClose, onChange, - _onBrowse, onExport, }) { if (!isOpen) return null; diff --git a/src/services/electronService.js b/src/services/electronService.js index e2314b85..e53ecff0 100644 --- a/src/services/electronService.js +++ b/src/services/electronService.js @@ -788,17 +788,6 @@ export async function runExport(type, payload = {}) { } return res; } - - // Fallbacks for legacy/web environment - if (type === "pdf" && typeof api?.downloadPdf === "function") { - return api.downloadPdf(payload); - } - if (type === "workspace_zip" && typeof api?.exportWorkspaceZip === "function") { - return api.exportWorkspaceZip(payload); - } - if ((type === "media" || type === "diagram_image") && typeof api?.saveToDownloads === "function") { - return api.saveToDownloads(payload); - } throw new Error(`Export service is unavailable for type: ${type}`); } @@ -1490,12 +1479,6 @@ export async function addExportRecord(record) { if (typeof window !== "undefined") { window.dispatchEvent(new CustomEvent("app:download-complete", { detail: cleanRecord })); - window.dispatchEvent(new CustomEvent("app:toast", { - detail: { - message: `Downloaded ${filename}`, - type: "success", - }, - })); } return res; } diff --git a/src/utils/formatUtils.js b/src/utils/formatUtils.js new file mode 100644 index 00000000..53445ba6 --- /dev/null +++ b/src/utils/formatUtils.js @@ -0,0 +1,33 @@ +/** + * Utility functions for formatting byte sizes and timestamps across UI components. + */ + +export function formatBytes(bytes) { + if (!bytes || bytes === 0) return "0 B"; + const k = 1024; + const sizes = ["B", "KB", "MB", "GB"]; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + " " + sizes[i]; +} + +export function formatTimestamp(isoString) { + if (!isoString) return ""; + try { + const date = new Date(isoString); + const now = new Date(); + const diffMs = now - date; + const diffMins = Math.floor(diffMs / (1000 * 60)); + const diffHours = Math.floor(diffMs / (1000 * 60 * 60)); + const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); + + if (diffMins < 1) return "Just now"; + if (diffMins < 60) return `${diffMins}m ago`; + if (diffHours < 24) return `${diffHours}h ago`; + if (diffDays === 1) return "Yesterday"; + if (diffDays < 7) return `${diffDays}d ago`; + + return date.toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" }); + } catch { + return isoString; + } +} diff --git a/src/utils/tableUtils.js b/src/utils/tableUtils.js index 1a4a3e76..0355d639 100644 --- a/src/utils/tableUtils.js +++ b/src/utils/tableUtils.js @@ -242,17 +242,18 @@ export function htmlTableToMarkdown(htmlString) { } } +function escapeCsvCell(value) { + const text = String(value?.innerText || value?.textContent || value || "").trim(); + if (text.includes('"') || text.includes(',') || text.includes('\n')) { + return `"${text.replace(/"/g, '""')}"`; + } + return text; +} + export function tableElementToCsv(tableElement) { if (!tableElement) return ""; const target = tableElement.tagName === "TABLE" ? tableElement : tableElement.querySelector("table") || tableElement; const rows = Array.from(target.querySelectorAll("tr")); - const escapeCsvCell = (cell) => { - const text = String(cell?.innerText || cell?.textContent || "").trim(); - if (text.includes('"') || text.includes(',') || text.includes('\n')) { - return `"${text.replace(/"/g, '""')}"`; - } - return text; - }; const csvRows = rows.map((row) => { const cells = Array.from(row.querySelectorAll("th, td")); @@ -266,14 +267,6 @@ export function markdownTableToCsv(markdownText) { const { headers, rows } = parseMarkdownTable(markdownText); if (!headers.length && !rows.length) return ""; - const escapeCsvCell = (cell) => { - const text = String(cell || "").trim(); - if (text.includes('"') || text.includes(',') || text.includes('\n')) { - return `"${text.replace(/"/g, '""')}"`; - } - return text; - }; - const csvRows = [ headers.map(escapeCsvCell).join(","), ...rows.map((row) => row.map(escapeCsvCell).join(",")) From 8cd12c0137f5a37c38a5227646338b8721099e9d Mon Sep 17 00:00:00 2001 From: Bikash Panda Date: Sun, 9 Aug 2026 11:46:58 +0530 Subject: [PATCH 18/18] Lint Fixed --- .../.temp/@localSearchIndexroot.BUwey-h1.js | 4 + .../.temp/VPLocalSearchBox.B_D79mPK.js | 367 + .../.vitepress/.temp/ai_architecture.md.js | 60 + docs-site/.vitepress/.temp/ai_features.md.js | 19 + docs-site/.vitepress/.temp/ai_index.md.js | 19 + .../.vitepress/.temp/ai_knowledge-graph.md.js | 76 + docs-site/.vitepress/.temp/ai_setup.md.js | 19 + docs-site/.vitepress/.temp/app.js | 5461 +++++++++++++++ docs-site/.vitepress/.temp/architecture.md.js | 70 + docs-site/.vitepress/.temp/assets/icon.png | Bin 0 -> 3843 bytes .../.temp/assets/style.DFNPDK03.css | 5943 +++++++++++++++++ .../.vitepress/.temp/data-sync-security.md.js | 19 + .../.vitepress/.temp/developer_index.md.js | 46 + .../documentation-audit-2026-07-03.md.js | 19 + .../.vitepress/.temp/editor_code-blocks.md.js | 22 + .../.vitepress/.temp/editor_diagrams.md.js | 40 + .../.vitepress/.temp/editor_focus-mode.md.js | 19 + docs-site/.vitepress/.temp/editor_index.md.js | 19 + .../.temp/editor_markdown-guide.md.js | 81 + .../.temp/editor_markdown-toolbar.md.js | 19 + .../.vitepress/.temp/editor_tables.md.js | 23 + .../.vitepress/.temp/export-import.md.js | 19 + .../.vitepress/.temp/export-reference.md.js | 19 + docs-site/.vitepress/.temp/faq.md.js | 19 + .../.temp/feature-availability.md.js | 42 + .../.vitepress/.temp/feature-reference.md.js | 19 + .../.temp/getting-started_first-note.md.js | 32 + .../.temp/getting-started_index.md.js | 19 + docs-site/.vitepress/.temp/git_branches.md.js | 19 + docs-site/.vitepress/.temp/git_commit.md.js | 19 + docs-site/.vitepress/.temp/git_history.md.js | 19 + docs-site/.vitepress/.temp/git_index.md.js | 34 + docs-site/.vitepress/.temp/git_setup.md.js | 19 + docs-site/.vitepress/.temp/index.md.js | 19 + .../.vitepress/.temp/keyboard-shortcuts.md.js | 19 + docs-site/.vitepress/.temp/license.md.js | 19 + docs-site/.vitepress/.temp/package.json | 1 + .../plugin-vue_export-helper.1tPrXgE0.js | 10 + .../.vitepress/.temp/release-notes.md.js | 19 + docs-site/.vitepress/.temp/search.md.js | 19 + .../.vitepress/.temp/settings-reference.md.js | 19 + docs-site/.vitepress/.temp/sync_index.md.js | 19 + docs-site/.vitepress/.temp/top-tasks.md.js | 19 + .../.vitepress/.temp/troubleshooting.md.js | 19 + docs-site/.vitepress/.temp/user-guide.md.js | 19 + .../.vitepress/.temp/ux-writing-guide.md.js | 19 + .../.temp/virtual_mermaid-config.CM0F1BUC.js | 4 + docs-site/.vitepress/.temp/web-view.md.js | 19 + .../.vitepress/.temp/workspace_calendar.md.js | 19 + .../.temp/workspace_downloads.md.js | 19 + .../.vitepress/.temp/workspace_export.md.js | 19 + .../.vitepress/.temp/workspace_graph.md.js | 19 + .../.vitepress/.temp/workspace_index.md.js | 19 + .../.vitepress/.temp/workspace_media.md.js | 19 + .../.temp/workspace_screen-capture.md.js | 19 + .../.vitepress/.temp/workspace_tasks.md.js | 25 + .../.vitepress/.temp/workspace_terminal.md.js | 19 + electron/lib/export/ExportManager.cjs | 6 +- src/components/MarkdownPreview.jsx | 225 +- 59 files changed, 13159 insertions(+), 116 deletions(-) create mode 100644 docs-site/.vitepress/.temp/@localSearchIndexroot.BUwey-h1.js create mode 100644 docs-site/.vitepress/.temp/VPLocalSearchBox.B_D79mPK.js create mode 100644 docs-site/.vitepress/.temp/ai_architecture.md.js create mode 100644 docs-site/.vitepress/.temp/ai_features.md.js create mode 100644 docs-site/.vitepress/.temp/ai_index.md.js create mode 100644 docs-site/.vitepress/.temp/ai_knowledge-graph.md.js create mode 100644 docs-site/.vitepress/.temp/ai_setup.md.js create mode 100644 docs-site/.vitepress/.temp/app.js create mode 100644 docs-site/.vitepress/.temp/architecture.md.js create mode 100644 docs-site/.vitepress/.temp/assets/icon.png create mode 100644 docs-site/.vitepress/.temp/assets/style.DFNPDK03.css create mode 100644 docs-site/.vitepress/.temp/data-sync-security.md.js create mode 100644 docs-site/.vitepress/.temp/developer_index.md.js create mode 100644 docs-site/.vitepress/.temp/documentation-audit-2026-07-03.md.js create mode 100644 docs-site/.vitepress/.temp/editor_code-blocks.md.js create mode 100644 docs-site/.vitepress/.temp/editor_diagrams.md.js create mode 100644 docs-site/.vitepress/.temp/editor_focus-mode.md.js create mode 100644 docs-site/.vitepress/.temp/editor_index.md.js create mode 100644 docs-site/.vitepress/.temp/editor_markdown-guide.md.js create mode 100644 docs-site/.vitepress/.temp/editor_markdown-toolbar.md.js create mode 100644 docs-site/.vitepress/.temp/editor_tables.md.js create mode 100644 docs-site/.vitepress/.temp/export-import.md.js create mode 100644 docs-site/.vitepress/.temp/export-reference.md.js create mode 100644 docs-site/.vitepress/.temp/faq.md.js create mode 100644 docs-site/.vitepress/.temp/feature-availability.md.js create mode 100644 docs-site/.vitepress/.temp/feature-reference.md.js create mode 100644 docs-site/.vitepress/.temp/getting-started_first-note.md.js create mode 100644 docs-site/.vitepress/.temp/getting-started_index.md.js create mode 100644 docs-site/.vitepress/.temp/git_branches.md.js create mode 100644 docs-site/.vitepress/.temp/git_commit.md.js create mode 100644 docs-site/.vitepress/.temp/git_history.md.js create mode 100644 docs-site/.vitepress/.temp/git_index.md.js create mode 100644 docs-site/.vitepress/.temp/git_setup.md.js create mode 100644 docs-site/.vitepress/.temp/index.md.js create mode 100644 docs-site/.vitepress/.temp/keyboard-shortcuts.md.js create mode 100644 docs-site/.vitepress/.temp/license.md.js create mode 100644 docs-site/.vitepress/.temp/package.json create mode 100644 docs-site/.vitepress/.temp/plugin-vue_export-helper.1tPrXgE0.js create mode 100644 docs-site/.vitepress/.temp/release-notes.md.js create mode 100644 docs-site/.vitepress/.temp/search.md.js create mode 100644 docs-site/.vitepress/.temp/settings-reference.md.js create mode 100644 docs-site/.vitepress/.temp/sync_index.md.js create mode 100644 docs-site/.vitepress/.temp/top-tasks.md.js create mode 100644 docs-site/.vitepress/.temp/troubleshooting.md.js create mode 100644 docs-site/.vitepress/.temp/user-guide.md.js create mode 100644 docs-site/.vitepress/.temp/ux-writing-guide.md.js create mode 100644 docs-site/.vitepress/.temp/virtual_mermaid-config.CM0F1BUC.js create mode 100644 docs-site/.vitepress/.temp/web-view.md.js create mode 100644 docs-site/.vitepress/.temp/workspace_calendar.md.js create mode 100644 docs-site/.vitepress/.temp/workspace_downloads.md.js create mode 100644 docs-site/.vitepress/.temp/workspace_export.md.js create mode 100644 docs-site/.vitepress/.temp/workspace_graph.md.js create mode 100644 docs-site/.vitepress/.temp/workspace_index.md.js create mode 100644 docs-site/.vitepress/.temp/workspace_media.md.js create mode 100644 docs-site/.vitepress/.temp/workspace_screen-capture.md.js create mode 100644 docs-site/.vitepress/.temp/workspace_tasks.md.js create mode 100644 docs-site/.vitepress/.temp/workspace_terminal.md.js diff --git a/docs-site/.vitepress/.temp/@localSearchIndexroot.BUwey-h1.js b/docs-site/.vitepress/.temp/@localSearchIndexroot.BUwey-h1.js new file mode 100644 index 00000000..b317236d --- /dev/null +++ b/docs-site/.vitepress/.temp/@localSearchIndexroot.BUwey-h1.js @@ -0,0 +1,4 @@ +const _localSearchIndexroot = '{"documentCount":543,"nextId":543,"documentIds":{"0":"/ai/architecture.html#ai-subsystem-master-flow-architecture","1":"/ai/architecture.html#_13-domain-decoupled-module-facade-blueprint","2":"/ai/architecture.html#_1-master-flow-orchestrator-aiflow-js-5-stage-execution-pipeline","3":"/ai/architecture.html#_2-4-layer-decoupled-planning-architecture","4":"/ai/architecture.html#layer-1-intent-analysis-intentanalyzer-js","5":"/ai/architecture.html#layer-2-capability-resolution-capabilityresolver-js","6":"/ai/architecture.html#layer-3-plan-dag-generation-planner-js","7":"/ai/architecture.html#layer-4-multi-tool-context-orchestration-contextorchestrator-js","8":"/ai/architecture.html#_3-persona-registry-markdown-source-of-truth","9":"/ai/architecture.html#_4-static-prompt-assembly-caching-promptpipeline-js","10":"/ai/architecture.html#_4-multi-tier-llm-provider-fallback-queryexecutor-js","11":"/ai/architecture.html#_5-zero-latency-context-compaction-engine-ai-compaction","12":"/ai/architecture.html#_6-ui-diagnostics-flow-telemetry-aihealthpage-jsx","13":"/ai/architecture.html#_7-automated-test-verification","14":"/ai/features.html#ai-features","15":"/ai/features.html#_1-global-note-scoped-chat-panel","16":"/ai/features.html#context-scope-options","17":"/ai/features.html#sourced-references","18":"/ai/features.html#_2-ai-palette-actions","19":"/ai/features.html#_3-persona-customization-markdown-source-of-truth","20":"/ai/features.html#_4-diagnostics-flow-telemetry-prompt-tracker-log","21":"/ai/#ai-subsystem-overview","22":"/ai/#capabilities-at-a-glance","23":"/ai/#_1-master-flow-orchestrator-aiflow-js-13-domain-architecture","24":"/ai/#_2-zero-latency-context-compaction-ai-compaction","25":"/ai/#_3-sqlite-knowledge-graph","26":"/ai/#_4-local-embedding-indexer","27":"/ai/#_5-persona-registry-markdown-source-of-truth","28":"/ai/#_6-diagnostics-flow-telemetry-trace-logs","29":"/ai/knowledge-graph.html#knowledge-graph-generation-engine","30":"/ai/knowledge-graph.html#architecture-overview","31":"/ai/knowledge-graph.html#the-8-pipeline-stages","32":"/ai/knowledge-graph.html#stage-1-ast-structural-parser-pre-cleansing","33":"/ai/knowledge-graph.html#stage-2-linguistic-noun-phrase-prose-isolator","34":"/ai/knowledge-graph.html#stage-3-deterministic-domain-pattern-mining","35":"/ai/knowledge-graph.html#stage-4-gliner2-onnx-neural-zero-shot-extraction","36":"/ai/knowledge-graph.html#stage-5-universal-quality-gate-noise-filtering","37":"/ai/knowledge-graph.html#stage-6-algorithmic-entity-type-sanitization-coercion","38":"/ai/knowledge-graph.html#stage-7-onnx-vector-embedding-concept-deduplication-alias-fusion","39":"/ai/knowledge-graph.html#stage-8-evidence-fusion-engine-plausibility-matrix-community-detection","40":"/ai/knowledge-graph.html#ingestion-lifecycle","41":"/ai/knowledge-graph.html#full-rebuild-flow-graphbuilder-rebuild","42":"/ai/knowledge-graph.html#incremental-indexing-flow-graphworker","43":"/ai/knowledge-graph.html#database-schema-vector-storage","44":"/ai/knowledge-graph.html#sqlite-indexes","45":"/ai/knowledge-graph.html#graph-quality-provenance-validation","46":"/ai/knowledge-graph.html#universal-quality-gate-entityresolver-isvalidentityname","47":"/ai/knowledge-graph.html#semantic-relationship-plausibility-matrix-evidencefusionengine-js","48":"/ai/knowledge-graph.html#evidence-provenance-evidencestore-js","49":"/ai/knowledge-graph.html#post-build-validation-graphvalidationengine-js","50":"/ai/knowledge-graph.html#community-detection-maintenance","51":"/ai/setup.html#ai-setup","52":"/ai/setup.html#_1-text-generation-providers","53":"/ai/setup.html#_2-embedding-index-setup","54":"/ai/setup.html#_3-knowledge-graph-engine","55":"/ai/setup.html#_4-sqlite-database-locality","56":"/architecture.html#notely-application-architecture","57":"/architecture.html#_1-high-level-architecture-overview","58":"/architecture.html#_2-renderer-layer-react-editor-architecture","59":"/architecture.html#component-structure","60":"/architecture.html#state-management-contexts","61":"/architecture.html#_3-main-process-application-subsystems","62":"/architecture.html#a-document-file-system-service","63":"/architecture.html#b-git-version-control-subsystem-gitservice-cjs","64":"/architecture.html#c-p2p-local-sync-engine-p2pservice-cjs","65":"/architecture.html#d-package-import-export-subsystem-notepackageipc-cjs","66":"/architecture.html#e-ai-context-engine-subsystem-aiservice-cjs","67":"/architecture.html#ai-layer-architecture","68":"/architecture.html#_4-centralized-system-logging-infrastructure-logdb-js","69":"/architecture.html#database-schema","70":"/architecture.html#log-subsystem-categories","71":"/architecture.html#user-diagnostics-management-ui","72":"/architecture.html#_5-data-storage-workspace-directory-structure","73":"/architecture.html#workspace-storage-diagram","74":"/architecture.html#global-configuration","75":"/architecture.html#workspace-file-structure","76":"/data-sync-security.html#data-sync","77":"/data-sync-security.html#_1-where-notely-stores-app-data","78":"/data-sync-security.html#_2-keep-your-notes-safe","79":"/data-sync-security.html#_3-sync-with-other-peers-p2p","80":"/data-sync-security.html#_4-ai-features-for-daily-use","81":"/data-sync-security.html#_5-when-to-use-workspace-graph","82":"/data-sync-security.html#_6-before-sharing-or-releasing-notes","83":"/developer/#developer-documentation","84":"/developer/#_1-core-architecture-process-model","85":"/developer/#_2-ipc-channel-security-guard-pattern","86":"/developer/#_3-development-workflow-commands","87":"/developer/#development-server","88":"/developer/#build-production-bundle","89":"/developer/#documentation-site","90":"/developer/#_4-test-suite-execution","91":"/developer/#key-test-directories","92":"/developer/#_5-build-packaging-scripts","93":"/documentation-audit-2026-07-03.html#notely-documentation-audit","94":"/documentation-audit-2026-07-03.html#executive-summary","95":"/documentation-audit-2026-07-03.html#phase-1-verified-feature-inventory","96":"/documentation-audit-2026-07-03.html#documentation-coverage-matrix","97":"/documentation-audit-2026-07-03.html#readme-audit","98":"/documentation-audit-2026-07-03.html#what-is-correct","99":"/documentation-audit-2026-07-03.html#what-is-inaccurate-or-incomplete","100":"/documentation-audit-2026-07-03.html#readme-verdict","101":"/documentation-audit-2026-07-03.html#docs-folder-audit","102":"/documentation-audit-2026-07-03.html#strong-areas","103":"/documentation-audit-2026-07-03.html#systemic-issues","104":"/documentation-audit-2026-07-03.html#per-document-findings","105":"/documentation-audit-2026-07-03.html#built-in-help-audit","106":"/documentation-audit-2026-07-03.html#menu-documentation-audit","107":"/documentation-audit-2026-07-03.html#settings-documentation-audit","108":"/documentation-audit-2026-07-03.html#workflow-documentation-audit","109":"/documentation-audit-2026-07-03.html#missing-documentation-by-severity","110":"/documentation-audit-2026-07-03.html#critical","111":"/documentation-audit-2026-07-03.html#high","112":"/documentation-audit-2026-07-03.html#medium","113":"/documentation-audit-2026-07-03.html#low","114":"/documentation-audit-2026-07-03.html#keyboard-shortcut-audit","115":"/documentation-audit-2026-07-03.html#key-findings","116":"/documentation-audit-2026-07-03.html#shortcut-table","117":"/documentation-audit-2026-07-03.html#inconsistencies","118":"/documentation-audit-2026-07-03.html#obsolete-documentation","119":"/documentation-audit-2026-07-03.html#documentation-quality-review","120":"/documentation-audit-2026-07-03.html#end-user-perspective","121":"/documentation-audit-2026-07-03.html#suggested-improvements","122":"/documentation-audit-2026-07-03.html#_1-critical-fixes","123":"/documentation-audit-2026-07-03.html#_2-high-value-additions","124":"/documentation-audit-2026-07-03.html#_3-ux-improvements","125":"/documentation-audit-2026-07-03.html#_4-documentation-restructuring","126":"/documentation-audit-2026-07-03.html#_5-navigation-improvements","127":"/documentation-audit-2026-07-03.html#_6-onboarding-enhancements","128":"/documentation-audit-2026-07-03.html#_7-help-system-improvements","129":"/documentation-audit-2026-07-03.html#_8-keyboard-guide-improvements","130":"/documentation-audit-2026-07-03.html#final-scorecard","131":"/documentation-audit-2026-07-03.html#release-readiness-roadmap","132":"/editor/code-blocks.html#code-blocks","133":"/editor/code-blocks.html#insert-a-code-block","134":"/editor/code-blocks.html#auto-detect-language","135":"/editor/code-blocks.html#auto-format-with-prettier","136":"/editor/code-blocks.html#dedicated-code-editor","137":"/editor/code-blocks.html#code-execution","138":"/editor/code-blocks.html#supported-languages","139":"/editor/code-blocks.html#tips","140":"/editor/diagrams.html#diagrams","141":"/editor/diagrams.html#mermaid-diagrams","142":"/editor/diagrams.html#insert-a-mermaid-block","143":"/editor/diagrams.html#diagram-types","144":"/editor/diagrams.html#example-—-git-workflow","145":"/editor/diagrams.html#interactive-diagram-actions","146":"/editor/diagrams.html#troubleshooting-mermaid","147":"/editor/diagrams.html#excalidraw-diagrams","148":"/editor/diagrams.html#insert-an-excalidraw-diagram","149":"/editor/diagrams.html#re-edit-an-existing-diagram","150":"/editor/diagrams.html#convert-an-image-to-excalidraw","151":"/editor/diagrams.html#restore-the-original-image","152":"/editor/diagrams.html#draw-io-diagrams","153":"/editor/diagrams.html#insert-a-draw-io-diagram","154":"/editor/diagrams.html#import-diagrams-via-drag-and-drop","155":"/editor/diagrams.html#choosing-a-diagram-tool","156":"/editor/focus-mode.html#focus-mode-outline","157":"/editor/focus-mode.html#outline-panel","158":"/editor/focus-mode.html#open-the-outline","159":"/editor/focus-mode.html#using-the-outline","160":"/editor/focus-mode.html#focus-mode","161":"/editor/focus-mode.html#toggle-focus-mode","162":"/editor/focus-mode.html#what-changes-in-focus-mode","163":"/editor/focus-mode.html#exit-focus-mode","164":"/editor/focus-mode.html#tips","165":"/editor/#editor-overview","166":"/editor/#view-modes","167":"/editor/#status-bar","168":"/editor/#breadcrumbs","169":"/editor/#copy-and-export-actions","170":"/editor/#copy-link-path","171":"/editor/#link-hover-preview","172":"/editor/#validation-indicators","173":"/editor/#tab-context-menu","174":"/editor/#external-disk-change-detection","175":"/editor/#keyboard-shortcuts","176":"/editor/markdown-guide.html#markdown-guide","177":"/editor/markdown-guide.html#headings","178":"/editor/markdown-guide.html#text-formatting","179":"/editor/markdown-guide.html#paragraphs-and-line-breaks","180":"/editor/markdown-guide.html#lists","181":"/editor/markdown-guide.html#unordered","182":"/editor/markdown-guide.html#ordered","183":"/editor/markdown-guide.html#task-lists","184":"/editor/markdown-guide.html#links","185":"/editor/markdown-guide.html#images","186":"/editor/markdown-guide.html#blockquotes-callouts","187":"/editor/markdown-guide.html#github-style-callouts-admonitions","188":"/editor/markdown-guide.html#code-blocks","189":"/editor/markdown-guide.html#tables","190":"/editor/markdown-guide.html#horizontal-rules","191":"/editor/markdown-guide.html#footnotes","192":"/editor/markdown-guide.html#html","193":"/editor/markdown-guide.html#escape-characters","194":"/editor/markdown-guide.html#mermaid-diagrams","195":"/editor/markdown-toolbar.html#toolbar-reference","196":"/editor/markdown-toolbar.html#formatting-buttons","197":"/editor/markdown-toolbar.html#insert-buttons","198":"/editor/markdown-toolbar.html#diagram-buttons","199":"/editor/markdown-toolbar.html#validation-and-quality","200":"/editor/markdown-toolbar.html#capture-button-windows","201":"/editor/markdown-toolbar.html#view-mode-controls","202":"/editor/markdown-toolbar.html#tips","203":"/editor/tables.html#tables","204":"/editor/tables.html#create-a-table","205":"/editor/tables.html#open-the-inline-table-editor","206":"/editor/tables.html#edit-cells","207":"/editor/tables.html#paste-excel-web-tables-directly","208":"/editor/tables.html#add-and-remove-rows","209":"/editor/tables.html#column-alignment","210":"/editor/tables.html#save-and-cancel","211":"/editor/tables.html#formatting-preservation","212":"/editor/tables.html#export-table-as-image-or-csv","213":"/editor/tables.html#tips","214":"/export-import.html#export-import-note-package","215":"/export-import.html#opening-the-dialog","216":"/export-import.html#exporting","217":"/export-import.html#what-gets-bundled","218":"/export-import.html#security","219":"/export-import.html#importing","220":"/export-import.html#troubleshooting","221":"/export-reference.html#export-import-reference","222":"/export-reference.html#_1-single-note-export-pdf-html","223":"/export-reference.html#pdf-export","224":"/export-reference.html#html-export","225":"/export-reference.html#block-level-exports-tables-diagrams","226":"/export-reference.html#_2-downloads-export-history-manager","227":"/export-reference.html#features-capabilities","228":"/export-reference.html#_2-workspace-export-full-zip-bundle","229":"/export-reference.html#export-modes","230":"/export-reference.html#content-modes-for-pdf-web","231":"/export-reference.html#archive-structure","232":"/export-reference.html#_3-note-package-export-import-note-bundle","233":"/export-reference.html#exporting-a-package","234":"/export-reference.html#security","235":"/export-reference.html#importing-a-package","236":"/export-reference.html#troubleshooting","237":"/faq.html#faq","238":"/faq.html#what-is-a-workspace-in-notely","239":"/faq.html#where-does-notely-store-my-data","240":"/faq.html#does-notely-work-offline","241":"/faq.html#which-features-require-internet","242":"/faq.html#what-is-notes-app","243":"/faq.html#should-notes-app-be-committed-to-git","244":"/faq.html#can-i-restore-deleted-or-changed-notes","245":"/faq.html#how-do-i-reopen-a-workspace-quickly","246":"/faq.html#does-notely-have-a-plugin-system","247":"/faq.html#what-happens-if-i-configure-ai","248":"/faq.html#what-is-the-easiest-way-to-learn-shortcuts","249":"/feature-availability.html#feature-availability","250":"/feature-reference.html#notely-feature-reference","251":"/feature-reference.html#_1-notes-and-workspace","252":"/feature-reference.html#workspace-selection","253":"/feature-reference.html#opening-the-workspace-externally","254":"/feature-reference.html#opening-the-website-view","255":"/feature-reference.html#project-aware-workspace","256":"/feature-reference.html#landing-dashboard","257":"/feature-reference.html#note-and-folder-creation","258":"/feature-reference.html#trash-recovery-bin","259":"/feature-reference.html#_2-editor-and-writing-experience","260":"/feature-reference.html#multiple-edit-modes","261":"/feature-reference.html#markdown-toolbar","262":"/feature-reference.html#inline-table-editor","263":"/feature-reference.html#code-blocks","264":"/feature-reference.html#find-and-replace","265":"/feature-reference.html#outline-navigation","266":"/feature-reference.html#focus-mode","267":"/feature-reference.html#terminal-and-workspace-tools","268":"/feature-reference.html#appearance-and-layout","269":"/feature-reference.html#note-statistics","270":"/feature-reference.html#copy-and-export","271":"/feature-reference.html#breadcrumb-navigation","272":"/feature-reference.html#_3-quality-and-validation","273":"/feature-reference.html#markdown-validation","274":"/feature-reference.html#typo-checking-spelling-dictionary","275":"/feature-reference.html#quick-problem-fixing","276":"/feature-reference.html#_4-search-and-discovery","277":"/feature-reference.html#global-search","278":"/feature-reference.html#advanced-search-patterns","279":"/feature-reference.html#code-aware-search","280":"/feature-reference.html#content-snippets","281":"/feature-reference.html#workspace-graph","282":"/feature-reference.html#_5-tasks-and-workflow","283":"/feature-reference.html#tasks-overview","284":"/feature-reference.html#open-tasks-panel","285":"/feature-reference.html#opening-the-open-tasks-panel","286":"/feature-reference.html#using-the-open-tasks-panel","287":"/feature-reference.html#all-tasks-panel","288":"/feature-reference.html#use-cases","289":"/feature-reference.html#_6-git-version-control-and-history","290":"/feature-reference.html#native-git-repository","291":"/feature-reference.html#compare-restore-and-tagging","292":"/feature-reference.html#branch-stash-and-sync-management","293":"/feature-reference.html#_7-media-management","294":"/feature-reference.html#image-and-file-linking","295":"/feature-reference.html#media-actions","296":"/feature-reference.html#screen-capture-windows","297":"/feature-reference.html#media-preview-tools","298":"/feature-reference.html#workspace-health-media-checks","299":"/feature-reference.html#image-annotation-and-lifecycle","300":"/feature-reference.html#original-image-backup-and-restore","301":"/feature-reference.html#_8-diagram-features","302":"/feature-reference.html#mermaid-diagrams","303":"/feature-reference.html#excalidraw-diagrams","304":"/feature-reference.html#_9-ai-assistance","305":"/feature-reference.html#ai-settings","306":"/feature-reference.html#ai-chat-and-commands","307":"/feature-reference.html#semantic-features","308":"/feature-reference.html#what-each-ai-service-can-do","309":"/feature-reference.html#ai-operation-feedback","310":"/feature-reference.html#how-recent-the-ai-search-data-is","311":"/feature-reference.html#_10-peer-to-peer-sync","312":"/feature-reference.html#discovery-and-pairing","313":"/feature-reference.html#sync-status-and-conflicts","314":"/feature-reference.html#security-controls","315":"/feature-reference.html#_11-help-and-product-info","316":"/feature-reference.html#documentation","317":"/feature-reference.html#keyboard-shortcuts","318":"/feature-reference.html#about-dialog","319":"/feature-reference.html#_12-preview-and-export","320":"/feature-reference.html#web-preview","321":"/feature-reference.html#pdf-export","322":"/feature-reference.html#website-style-rendering","323":"/feature-reference.html#workspace-zip-export","324":"/getting-started/first-note.html#your-first-note","325":"/getting-started/first-note.html#step-1-—-create-a-note","326":"/getting-started/first-note.html#step-2-—-write-in-markdown","327":"/getting-started/first-note.html#quick-markdown-reference","328":"/getting-started/first-note.html#step-3-—-preview-your-note","329":"/getting-started/first-note.html#step-4-—-use-the-toolbar","330":"/getting-started/first-note.html#step-5-—-save","331":"/getting-started/first-note.html#what-s-next","332":"/getting-started/#getting-started","333":"/getting-started/#requirements","334":"/getting-started/#download-install","335":"/getting-started/#release-types","336":"/getting-started/#_1-nsis-installer-exe","337":"/getting-started/#_2-portable-executable-exe","338":"/getting-started/#_3-zip-archive-zip","339":"/getting-started/#cons-limitations-of-packaged-electron-applications","340":"/getting-started/#open-your-workspace","341":"/getting-started/#key-concepts","342":"/getting-started/#what-to-do-next","343":"/getting-started/#help-at-any-time","344":"/git/branches.html#branches-remote","345":"/git/branches.html#_1-branch-management","346":"/git/branches.html#_2-remote-synchronization-push-pull","347":"/git/branches.html#_3-stashing-changes","348":"/git/commit.html#commit-stage","349":"/git/commit.html#_1-staging-files","350":"/git/commit.html#_2-writing-a-commit","351":"/git/history.html#history-restore","352":"/git/history.html#_1-opening-revision-history","353":"/git/history.html#_2-comparing-diffs","354":"/git/history.html#_3-restoring-notes","355":"/git/#git-version-control","356":"/git/#why-git","357":"/git/setup.html#git-setup-repository","358":"/git/setup.html#_1-initializing-a-repository","359":"/git/setup.html#_2-cloning-a-repository","360":"/git/setup.html#_3-ignoring-app-metadata-notes-app","361":"/keyboard-shortcuts.html#keyboard-shortcuts","362":"/keyboard-shortcuts.html#global-navigation","363":"/keyboard-shortcuts.html#note-editor","364":"/keyboard-shortcuts.html#search-find-panel","365":"/keyboard-shortcuts.html#ai-features","366":"/keyboard-shortcuts.html#view-media-tools","367":"/license.html#license","368":"/license.html#attribution-noncommercial-4-0-international","369":"/license.html#third-party-open-source-software","370":"/release-notes.html#release-notes","371":"/release-notes.html#_2026-07-25-latest","372":"/release-notes.html#ai-architecture-ui-telemetry","373":"/release-notes.html#_2026-07-17","374":"/release-notes.html#new-features","375":"/release-notes.html#_2026-07-11","376":"/release-notes.html#refinements","377":"/release-notes.html#fixes","378":"/release-notes.html#_2026-07-03-latest","379":"/release-notes.html#new-features-1","380":"/release-notes.html#refinements-1","381":"/release-notes.html#fixes-1","382":"/release-notes.html#_2026-07-03","383":"/release-notes.html#documentation-updates","384":"/release-notes.html#shortcut-updates","385":"/release-notes.html#help-center-updates","386":"/release-notes.html#notes-for-existing-users","387":"/search.html#search","388":"/search.html#_1-find-in-current-note","389":"/search.html#_2-global-workspace-search","390":"/search.html#synonym-term-support","391":"/search.html#_3-regular-expression-search-regex","392":"/search.html#_4-code-block-search","393":"/search.html#_5-semantic-search-ai-powered","394":"/settings-reference.html#settings-reference","395":"/settings-reference.html#_1-appearance","396":"/settings-reference.html#theme","397":"/settings-reference.html#zoom","398":"/settings-reference.html#_2-landing-view","399":"/settings-reference.html#view-mode","400":"/settings-reference.html#density","401":"/settings-reference.html#_3-editor-and-writing","402":"/settings-reference.html#typo-check","403":"/settings-reference.html#outline","404":"/settings-reference.html#focus-mode","405":"/settings-reference.html#_4-terminal","406":"/settings-reference.html#show-terminal","407":"/settings-reference.html#terminal-shell","408":"/settings-reference.html#_5-screen-capture","409":"/settings-reference.html#_6-ai-settings","410":"/settings-reference.html#provider-setup","411":"/settings-reference.html#feature-toggles","412":"/settings-reference.html#advanced-generation-tuning","413":"/settings-reference.html#data-and-privacy-controls","414":"/settings-reference.html#_7-workspace-metadata-and-git-safety","415":"/settings-reference.html#_8-environment-variables","416":"/sync/#p2p-sync","417":"/sync/#_1-network-discovery-transport-security","418":"/sync/#_2-pairing-devices-invite-flow","419":"/sync/#_3-delta-note-merging-conflict-resolution","420":"/sync/#_4-key-rotation-security-controls","421":"/top-tasks.html#top-common-tasks","422":"/top-tasks.html#_1-open-or-change-workspace","423":"/top-tasks.html#_2-create-a-new-note","424":"/top-tasks.html#_3-create-a-folder","425":"/top-tasks.html#_4-find-text-in-current-note","426":"/top-tasks.html#_5-replace-text-in-current-note","427":"/top-tasks.html#_6-switch-between-edit-split-and-preview","428":"/top-tasks.html#_7-show-document-outline","429":"/top-tasks.html#_8-enable-focus-mode","430":"/top-tasks.html#_9-insert-an-image-into-a-note","431":"/top-tasks.html#_10-insert-a-mermaid-diagram","432":"/top-tasks.html#_11-insert-an-excalidraw-diagram","433":"/top-tasks.html#_11b-convert-an-image-to-excalidraw","434":"/top-tasks.html#_12-view-or-restore-note-history","435":"/top-tasks.html#_13-search-across-all-notes","436":"/top-tasks.html#_14-open-keyboard-shortcuts","437":"/top-tasks.html#_15-open-troubleshooting","438":"/top-tasks.html#_16-run-ai-setup-and-test","439":"/top-tasks.html#_17-refresh-semantic-graph-data","440":"/top-tasks.html#_18-clean-unused-media","441":"/top-tasks.html#_19-restore-original-image-after-edits","442":"/top-tasks.html#_19b-restore-original-image-from-converted-excalidraw","443":"/top-tasks.html#_20-export-a-note-to-pdf","444":"/top-tasks.html#_21-capture-a-screen-area-into-a-note","445":"/top-tasks.html#_22-review-open-and-completed-tasks-across-workspace","446":"/top-tasks.html#_23-export-workspace-as-zip","447":"/troubleshooting.html#notely-troubleshooting","448":"/troubleshooting.html#_1-notes-are-not-showing","449":"/troubleshooting.html#_2-preview-looks-wrong","450":"/troubleshooting.html#_3-a-linked-file-or-image-does-not-open","451":"/troubleshooting.html#_4-sync-conflicts-keep-appearing","452":"/troubleshooting.html#_5-ai-features-are-disabled","453":"/troubleshooting.html#_6-app-feels-slow-in-large-workspaces","454":"/troubleshooting.html#_7-quick-support-details-to-share","455":"/troubleshooting.html#_8-screen-capture-mode-looks-incorrect-a-r","456":"/troubleshooting.html#_9-review-mode-save-appears-unresponsive","457":"/troubleshooting.html#_10-embedded-terminal-does-not-start","458":"/troubleshooting.html#_11-workspace-export-does-not-finish","459":"/troubleshooting.html#_12-project-website-shows-notes-from-an-older-workspace","460":"/user-guide.html#notely-user-guide","461":"/user-guide.html#_1-set-up-your-workspace","462":"/user-guide.html#_2-create-and-organize-notes","463":"/user-guide.html#_3-write-and-edit-faster","464":"/user-guide.html#_4-recover-changes-with-git-version-control","465":"/user-guide.html#_5-work-with-images-and-files","466":"/user-guide.html#_6-capture-screen-areas-into-notes-windows","467":"/user-guide.html#_7-use-diagrams-mermaid-and-excalidraw","468":"/user-guide.html#mermaid","469":"/user-guide.html#excalidraw","470":"/user-guide.html#convert-an-image-to-excalidraw","471":"/user-guide.html#restore-original-image-from-converted-diagram","472":"/user-guide.html#_8-navigate-large-workspaces","473":"/user-guide.html#_9-track-tasks-across-notes","474":"/user-guide.html#_10-export-workspace-as-zip","475":"/user-guide.html#_11-get-help-quickly","476":"/ux-writing-guide.html#ux-writing-guide","477":"/ux-writing-guide.html#core-rules","478":"/ux-writing-guide.html#buttons-and-actions","479":"/ux-writing-guide.html#empty-error-and-status-text","480":"/ux-writing-guide.html#examples","481":"/web-view.html#website-view","482":"/web-view.html#opening-the-website-view","483":"/web-view.html#how-it-works","484":"/web-view.html#local-http-server","485":"/web-view.html#live-content-overrides","486":"/web-view.html#page-rendering-pipeline-websiterenderer-cjs","487":"/web-view.html#what-renders-in-website-view","488":"/web-view.html#project-index-page","489":"/web-view.html#full-text-search","490":"/web-view.html#website-scope","491":"/web-view.html#comparison-website-view-vs-preview-pane-vs-pdf-export","492":"/workspace/calendar.html#calendar-scheduling","493":"/workspace/calendar.html#_1-task-scheduling-due-dates","494":"/workspace/calendar.html#_2-calendar-views","495":"/workspace/calendar.html#month-view","496":"/workspace/calendar.html#week-view","497":"/workspace/calendar.html#day-view","498":"/workspace/calendar.html#_3-interactive-drag-drop-scheduling","499":"/workspace/calendar.html#_4-date-filtering-overdue-tracking","500":"/workspace/downloads.html#downloads-export-history","501":"/workspace/downloads.html#_1-features-capabilities","502":"/workspace/downloads.html#_2-storage-database-architecture","503":"/workspace/downloads.html#_3-supported-export-download-formats","504":"/workspace/downloads.html#_4-system-downloads-directory","505":"/workspace/export.html#export","506":"/workspace/export.html#_1-export-formats","507":"/workspace/export.html#_2-advanced-options","508":"/workspace/graph.html#workspace-graph","509":"/workspace/graph.html#_1-navigating-the-graph","510":"/workspace/graph.html#_2-node-types","511":"/workspace/graph.html#_3-semantic-clustering-ai-powered","512":"/workspace/#workspace-overview","513":"/workspace/#_1-landing-dashboard","514":"/workspace/#_2-note-and-folder-creation","515":"/workspace/#_3-density-layout-views","516":"/workspace/#_4-workspace-tools-embedded-terminal","517":"/workspace/#_5-workspace-document-reloading","518":"/workspace/media.html#media","519":"/workspace/media.html#_1-asset-storage","520":"/workspace/media.html#_2-image-tools-annotation","521":"/workspace/media.html#_3-workspace-health-checks","522":"/workspace/tasks.html#tasks-checklists","523":"/workspace/tasks.html#_1-creating-tasks-in-notes","524":"/workspace/tasks.html#supported-formats","525":"/workspace/tasks.html#_2-interactive-preview-toggling-task-modal","526":"/workspace/tasks.html#_3-bi-directional-markdown-synchronization","527":"/workspace/tasks.html#_4-smart-alignment-deduplication-engine","528":"/workspace/tasks.html#_5-note-level-task-bar-workspace-dashboard","529":"/workspace/tasks.html#note-level-task-summary","530":"/workspace/tasks.html#workspace-task-page","531":"/workspace/screen-capture.html#screen-capture","532":"/workspace/screen-capture.html#_1-how-to-capture","533":"/workspace/screen-capture.html#_2-capture-modes","534":"/workspace/screen-capture.html#_3-toolbar-indicators","535":"/workspace/terminal.html#embedded-terminal","536":"/workspace/terminal.html#_1-opening-toggling-the-terminal","537":"/workspace/terminal.html#_2-shell-selection-configuration","538":"/workspace/terminal.html#custom-shell-path-overrides-environment-variables","539":"/workspace/terminal.html#_3-working-directory-lifecycle","540":"/workspace/terminal.html#_4-security-policies-strict-allowlist-mode","541":"/workspace/terminal.html#policy-modes-notely-terminal-policy","542":"/workspace/terminal.html#environment-variable-security-flags"},"fieldIds":{"title":0,"titles":1,"text":2},"fieldLength":{"0":[6,0,41],"1":[6,6,56],"2":[10,6,103],"3":[6,6,19],"4":[5,11,40],"5":[5,11,18],"6":[6,11,42],"7":[7,11,97],"8":[8,6,82],"9":[6,6,84],"10":[7,6,41],"11":[9,6,71],"12":[7,6,63],"13":[4,6,59],"14":[2,0,15],"15":[7,2,53],"16":[3,8,43],"17":[2,8,30],"18":[4,2,34],"19":[8,2,73],"20":[8,2,86],"21":[3,0,33],"22":[4,3,0],"23":[9,6,30],"24":[8,6,27],"25":[4,6,15],"26":[4,6,36],"27":[7,6,42],"28":[7,6,28],"29":[4,0,47],"30":[2,4,24],"31":[4,4,0],"32":[8,7,43],"33":[8,7,44],"34":[6,7,51],"35":[8,7,44],"36":[8,7,97],"37":[8,7,46],"38":[10,7,60],"39":[10,7,49],"40":[2,4,0],"41":[4,5,9],"42":[4,5,26],"43":[5,4,25],"44":[2,8,41],"45":[5,4,0],"46":[4,8,26],"47":[5,8,34],"48":[3,8,35],"49":[4,8,129],"50":[4,4,68],"51":[2,0,15],"52":[4,2,77],"53":[4,2,47],"54":[4,2,76],"55":[4,2,73],"56":[3,0,21],"57":[5,3,21],"58":[7,3,19],"59":[2,9,136],"60":[4,9,29],"61":[6,3,16],"62":[6,7,32],"63":[6,7,33],"64":[6,7,22],"65":[7,7,110],"66":[7,7,94],"67":[3,12,29],"68":[6,3,13],"69":[2,8,44],"70":[3,8,47],"71":[5,8,57],"72":[7,3,17],"73":[3,9,1],"74":[2,9,22],"75":[3,9,150],"76":[3,0,15],"77":[6,3,39],"78":[5,3,35],"79":[6,3,44],"80":[6,3,34],"81":[6,3,19],"82":[6,3,21],"83":[2,0,8],"84":[6,2,72],"85":[6,2,71],"86":[5,2,0],"87":[2,6,11],"88":[3,6,13],"89":[2,6,17],"90":[4,2,30],"91":[3,5,43],"92":[5,2,44],"93":[3,0,112],"94":[2,3,130],"95":[5,3,185],"96":[3,3,246],"97":[2,3,0],"98":[3,4,37],"99":[5,4,135],"100":[2,4,19],"101":[3,3,0],"102":[2,5,34],"103":[2,5,124],"104":[3,5,158],"105":[4,3,113],"106":[3,3,70],"107":[3,3,77],"108":[3,3,69],"109":[4,3,0],"110":[1,5,26],"111":[1,5,29],"112":[1,5,28],"113":[1,5,20],"114":[3,3,0],"115":[2,5,59],"116":[2,5,236],"117":[1,3,89],"118":[2,3,47],"119":[3,3,73],"120":[3,3,127],"121":[2,3,0],"122":[3,4,23],"123":[4,4,15],"124":[3,4,23],"125":[3,4,24],"126":[3,4,19],"127":[3,4,19],"128":[4,4,14],"129":[4,4,21],"130":[2,3,27],"131":[3,3,92],"132":[2,0,24],"133":[4,2,35],"134":[3,2,52],"135":[4,2,49],"136":[3,2,58],"137":[2,2,138],"138":[2,2,42],"139":[1,2,45],"140":[1,0,25],"141":[2,1,19],"142":[4,2,30],"143":[2,2,54],"144":[4,2,1],"145":[3,2,40],"146":[2,2,35],"147":[2,1,18],"148":[4,2,33],"149":[5,2,21],"150":[5,2,50],"151":[4,2,41],"152":[2,1,17],"153":[4,2,37],"154":[6,2,28],"155":[4,1,36],"156":[4,0,0],"157":[2,4,23],"158":[3,5,16],"159":[3,5,50],"160":[2,4,14],"161":[3,4,10],"162":[5,4,26],"163":[3,4,15],"164":[1,4,62],"165":[2,0,25],"166":[2,2,62],"167":[2,2,41],"168":[1,2,31],"169":[4,2,42],"170":[3,5,28],"171":[3,2,45],"172":[2,2,71],"173":[3,3,52],"174":[4,3,52],"175":[2,2,41],"176":[2,0,15],"177":[1,2,39],"178":[2,2,19],"179":[4,2,28],"180":[1,2,0],"181":[1,2,10],"182":[1,2,8],"183":[2,2,27],"184":[1,2,17],"185":[1,2,25],"186":[3,2,13],"187":[4,4,78],"188":[2,2,41],"189":[1,2,45],"190":[2,2,4],"191":[1,2,12],"192":[1,2,24],"193":[2,2,19],"194":[2,2,27],"195":[2,0,15],"196":[2,2,59],"197":[2,2,40],"198":[2,2,8],"199":[3,2,18],"200":[3,2,31],"201":[3,2,33],"202":[1,2,39],"203":[1,0,22],"204":[3,1,34],"205":[5,1,77],"206":[2,1,42],"207":[6,1,34],"208":[4,1,37],"209":[2,1,33],"210":[3,1,56],"211":[2,1,27],"212":[6,1,74],"213":[1,1,47],"214":[4,0,30],"215":[3,4,33],"216":[1,4,65],"217":[3,4,50],"218":[1,4,59],"219":[1,4,74],"220":[1,4,74],"221":[4,0,47],"222":[7,4,11],"223":[2,8,71],"224":[2,8,28],"225":[6,8,55],"226":[6,4,36],"227":[3,7,90],"228":[6,4,15],"229":[2,8,34],"230":[6,8,29],"231":[2,8,41],"232":[8,4,15],"233":[3,8,84],"234":[1,8,41],"235":[3,8,61],"236":[1,4,83],"237":[1,0,0],"238":[6,1,26],"239":[6,1,36],"240":[4,1,24],"241":[4,1,31],"242":[4,1,20],"243":[7,1,29],"244":[7,1,30],"245":[7,1,13],"246":[6,1,13],"247":[6,1,34],"248":[8,1,21],"249":[2,0,16],"250":[3,0,10],"251":[4,3,0],"252":[2,6,21],"253":[4,6,48],"254":[4,6,43],"255":[3,6,14],"256":[2,6,39],"257":[4,6,43],"258":[3,6,51],"259":[5,3,0],"260":[3,7,22],"261":[2,7,12],"262":[3,7,59],"263":[2,7,114],"264":[3,7,10],"265":[2,7,12],"266":[2,7,9],"267":[4,7,25],"268":[3,7,38],"269":[2,7,46],"270":[3,7,37],"271":[2,7,34],"272":[4,3,0],"273":[2,6,7],"274":[5,6,76],"275":[3,6,15],"276":[4,3,0],"277":[2,6,12],"278":[3,7,57],"279":[3,7,54],"280":[2,6,12],"281":[2,6,50],"282":[4,3,0],"283":[2,6,43],"284":[3,6,16],"285":[5,7,27],"286":[5,7,60],"287":[3,6,33],"288":[2,7,26],"289":[6,3,0],"290":[3,8,22],"291":[4,8,52],"292":[5,8,24],"293":[3,3,0],"294":[4,5,12],"295":[2,5,9],"296":[3,5,67],"297":[3,5,10],"298":[4,5,23],"299":[4,5,29],"300":[5,5,23],"301":[3,3,0],"302":[2,5,13],"303":[2,5,53],"304":[3,3,0],"305":[2,5,26],"306":[4,5,11],"307":[2,5,18],"308":[6,5,27],"309":[3,5,14],"310":[7,5,12],"311":[4,3,0],"312":[3,6,10],"313":[4,6,11],"314":[2,6,9],"315":[5,3,0],"316":[1,7,9],"317":[2,7,9],"318":[2,7,12],"319":[4,3,0],"320":[2,6,13],"321":[2,6,22],"322":[3,6,13],"323":[3,6,60],"324":[3,0,13],"325":[6,3,52],"326":[6,3,51],"327":[3,8,29],"328":[6,3,40],"329":[6,3,37],"330":[4,3,45],"331":[2,3,21],"332":[2,0,27],"333":[1,2,22],"334":[3,2,35],"335":[2,2,17],"336":[4,3,39],"337":[4,3,41],"338":[4,3,34],"339":[7,2,123],"340":[3,2,51],"341":[2,2,33],"342":[4,2,21],"343":[4,2,20],"344":[3,0,12],"345":[3,3,30],"346":[5,3,65],"347":[3,3,34],"348":[3,0,14],"349":[3,3,53],"350":[4,3,40],"351":[3,0,17],"352":[4,3,29],"353":[3,3,40],"354":[3,3,34],"355":[3,0,27],"356":[2,3,50],"357":[4,0,13],"358":[4,4,34],"359":[4,4,27],"360":[6,4,38],"361":[2,0,10],"362":[3,2,39],"363":[2,2,57],"364":[4,2,26],"365":[3,2,22],"366":[4,2,53],"367":[1,0,16],"368":[4,1,51],"369":[5,1,48],"370":[2,0,0],"371":[4,2,0],"372":[5,5,95],"373":[3,2,0],"374":[2,4,216],"375":[3,2,19],"376":[1,4,52],"377":[1,4,35],"378":[4,2,0],"379":[2,5,91],"380":[1,5,80],"381":[1,5,41],"382":[3,2,13],"383":[2,4,28],"384":[2,4,26],"385":[3,4,21],"386":[4,2,31],"387":[1,0,24],"388":[5,1,35],"389":[4,1,36],"390":[4,4,28],"391":[5,1,47],"392":[4,1,30],"393":[5,1,48],"394":[2,0,15],"395":[2,2,0],"396":[1,3,35],"397":[1,3,29],"398":[3,2,0],"399":[2,4,25],"400":[1,4,30],"401":[4,2,0],"402":[2,5,31],"403":[1,5,28],"404":[2,5,23],"405":[2,2,0],"406":[2,3,21],"407":[2,3,33],"408":[3,2,35],"409":[3,2,4],"410":[2,3,73],"411":[2,3,62],"412":[3,3,30],"413":[4,3,19],"414":[6,2,51],"415":[3,2,83],"416":[2,0,27],"417":[6,2,88],"418":[6,2,60],"419":[7,2,102],"420":[6,2,37],"421":[3,0,9],"422":[5,3,8],"423":[5,3,14],"424":[4,3,10],"425":[6,3,11],"426":[6,3,10],"427":[7,3,13],"428":[4,3,10],"429":[4,3,9],"430":[7,3,9],"431":[5,3,13],"432":[5,3,9],"433":[6,3,21],"434":[6,3,30],"435":[5,3,7],"436":[4,3,12],"437":[3,3,11],"438":[6,3,19],"439":[5,3,12],"440":[4,3,15],"441":[6,3,13],"442":[7,3,14],"443":[6,3,11],"444":[7,3,33],"445":[8,3,25],"446":[5,3,40],"447":[2,0,8],"448":[5,2,25],"449":[4,2,24],"450":[9,2,21],"451":[5,2,24],"452":[5,2,28],"453":[7,2,30],"454":[6,2,26],"455":[8,2,42],"456":[6,2,33],"457":[6,2,32],"458":[6,2,33],"459":[9,2,44],"460":[3,0,19],"461":[5,3,38],"462":[5,3,29],"463":[5,3,86],"464":[7,3,63],"465":[6,3,41],"466":[7,3,57],"467":[6,3,0],"468":[1,8,15],"469":[1,8,15],"470":[5,8,28],"471":[6,8,22],"472":[4,3,28],"473":[5,3,45],"474":[5,3,51],"475":[4,3,20],"476":[3,0,9],"477":[2,3,52],"478":[3,3,26],"479":[5,3,22],"480":[1,3,31],"481":[2,0,39],"482":[4,2,49],"483":[3,2,0],"484":[3,4,92],"485":[3,4,29],"486":[4,2,97],"487":[5,5,57],"488":[3,2,28],"489":[3,2,52],"490":[2,2,40],"491":[8,2,88],"492":[3,0,30],"493":[6,3,45],"494":[3,3,20],"495":[2,4,31],"496":[2,4,24],"497":[2,4,13],"498":[6,3,50],"499":[6,3,64],"500":[4,0,61],"501":[4,4,89],"502":[5,4,53],"503":[6,4,31],"504":[4,4,25],"505":[1,0,17],"506":[3,1,70],"507":[3,1,57],"508":[2,0,19],"509":[4,2,33],"510":[3,2,19],"511":[5,2,24],"512":[2,0,27],"513":[3,2,52],"514":[5,2,39],"515":[5,2,53],"516":[6,2,47],"517":[5,2,90],"518":[1,0,16],"519":[3,1,25],"520":[5,1,51],"521":[4,1,40],"522":[3,0,35],"523":[5,3,25],"524":[2,6,14],"525":[7,3,92],"526":[5,3,81],"527":[6,3,68],"528":[8,3,0],"529":[4,9,38],"530":[3,9,48],"531":[2,0,22],"532":[4,2,30],"533":[3,2,41],"534":[3,2,16],"535":[2,0,26],"536":[6,2,27],"537":[5,2,41],"538":[6,6,26],"539":[5,2,49],"540":[7,2,16],"541":[5,8,28],"542":[4,8,46]},"averageFieldLength":[3.771639042357274,3.5156537753222823,36.99999999999996],"storedFields":{"0":{"title":"AI Subsystem & Master Flow Architecture","titles":[]},"1":{"title":"13-Domain Decoupled Module Facade Blueprint","titles":["AI Subsystem & Master Flow Architecture"]},"2":{"title":"1. Master Flow Orchestrator (AIFlow.js) & 5-Stage Execution Pipeline","titles":["AI Subsystem & Master Flow Architecture"]},"3":{"title":"2. 4-Layer Decoupled Planning Architecture","titles":["AI Subsystem & Master Flow Architecture"]},"4":{"title":"Layer 1: Intent Analysis (IntentAnalyzer.js)","titles":["AI Subsystem & Master Flow Architecture","2. 4-Layer Decoupled Planning Architecture"]},"5":{"title":"Layer 2: Capability Resolution (CapabilityResolver.js)","titles":["AI Subsystem & Master Flow Architecture","2. 4-Layer Decoupled Planning Architecture"]},"6":{"title":"Layer 3: Plan DAG Generation (Planner.js)","titles":["AI Subsystem & Master Flow Architecture","2. 4-Layer Decoupled Planning Architecture"]},"7":{"title":"Layer 4: Multi-Tool Context Orchestration (ContextOrchestrator.js)","titles":["AI Subsystem & Master Flow Architecture","2. 4-Layer Decoupled Planning Architecture"]},"8":{"title":"3. Persona Registry & Markdown Source of Truth","titles":["AI Subsystem & Master Flow Architecture"]},"9":{"title":"4. Static Prompt Assembly Caching (PromptPipeline.js)","titles":["AI Subsystem & Master Flow Architecture"]},"10":{"title":"4. Multi-Tier LLM Provider Fallback (QueryExecutor.js)","titles":["AI Subsystem & Master Flow Architecture"]},"11":{"title":"5. Zero-Latency Context Compaction Engine (ai/compaction/)","titles":["AI Subsystem & Master Flow Architecture"]},"12":{"title":"6. UI Diagnostics & Flow Telemetry (AIHealthPage.jsx)","titles":["AI Subsystem & Master Flow Architecture"]},"13":{"title":"7. Automated Test Verification","titles":["AI Subsystem & Master Flow Architecture"]},"14":{"title":"AI Features","titles":[]},"15":{"title":"1. Global & Note-Scoped Chat Panel","titles":["AI Features"]},"16":{"title":"Context Scope Options","titles":["AI Features","1. Global & Note-Scoped Chat Panel"]},"17":{"title":"Sourced References","titles":["AI Features","1. Global & Note-Scoped Chat Panel"]},"18":{"title":"2. AI Palette Actions","titles":["AI Features"]},"19":{"title":"3. Persona Customization & Markdown Source of Truth","titles":["AI Features"]},"20":{"title":"4. Diagnostics, Flow Telemetry & Prompt Tracker Log","titles":["AI Features"]},"21":{"title":"AI Subsystem Overview","titles":[]},"22":{"title":"Capabilities at a Glance","titles":["AI Subsystem Overview"]},"23":{"title":"1. Master Flow Orchestrator (AIFlow.js) & 13-Domain Architecture","titles":["AI Subsystem Overview","Capabilities at a Glance"]},"24":{"title":"2. Zero-Latency Context Compaction (ai/compaction/)","titles":["AI Subsystem Overview","Capabilities at a Glance"]},"25":{"title":"3. SQLite Knowledge Graph","titles":["AI Subsystem Overview","Capabilities at a Glance"]},"26":{"title":"4. Local Embedding Indexer","titles":["AI Subsystem Overview","Capabilities at a Glance"]},"27":{"title":"5. Persona Registry (Markdown Source of Truth)","titles":["AI Subsystem Overview","Capabilities at a Glance"]},"28":{"title":"6. Diagnostics, Flow Telemetry & Trace Logs","titles":["AI Subsystem Overview","Capabilities at a Glance"]},"29":{"title":"Knowledge Graph Generation Engine","titles":[]},"30":{"title":"Architecture Overview","titles":["Knowledge Graph Generation Engine"]},"31":{"title":"The 8 Pipeline Stages","titles":["Knowledge Graph Generation Engine"]},"32":{"title":"Stage 1: AST Structural Parser & Pre-Cleansing","titles":["Knowledge Graph Generation Engine","The 8 Pipeline Stages"]},"33":{"title":"Stage 2: Linguistic Noun-Phrase & Prose Isolator","titles":["Knowledge Graph Generation Engine","The 8 Pipeline Stages"]},"34":{"title":"Stage 3: Deterministic Domain Pattern Mining","titles":["Knowledge Graph Generation Engine","The 8 Pipeline Stages"]},"35":{"title":"Stage 4: GLiNER2 ONNX Neural Zero-Shot Extraction","titles":["Knowledge Graph Generation Engine","The 8 Pipeline Stages"]},"36":{"title":"Stage 5: Universal Quality Gate & Noise Filtering","titles":["Knowledge Graph Generation Engine","The 8 Pipeline Stages"]},"37":{"title":"Stage 6: Algorithmic Entity Type Sanitization & Coercion","titles":["Knowledge Graph Generation Engine","The 8 Pipeline Stages"]},"38":{"title":"Stage 7: ONNX Vector Embedding Concept Deduplication & Alias Fusion","titles":["Knowledge Graph Generation Engine","The 8 Pipeline Stages"]},"39":{"title":"Stage 8: Evidence Fusion Engine, Plausibility Matrix & Community Detection","titles":["Knowledge Graph Generation Engine","The 8 Pipeline Stages"]},"40":{"title":"Ingestion Lifecycle","titles":["Knowledge Graph Generation Engine"]},"41":{"title":"Full Rebuild Flow (GraphBuilder.rebuild())","titles":["Knowledge Graph Generation Engine","Ingestion Lifecycle"]},"42":{"title":"Incremental Indexing Flow (GraphWorker)","titles":["Knowledge Graph Generation Engine","Ingestion Lifecycle"]},"43":{"title":"Database Schema & Vector Storage","titles":["Knowledge Graph Generation Engine"]},"44":{"title":"SQLite Indexes","titles":["Knowledge Graph Generation Engine","Database Schema & Vector Storage"]},"45":{"title":"Graph Quality & Provenance Validation","titles":["Knowledge Graph Generation Engine"]},"46":{"title":"Universal Quality Gate (EntityResolver.isValidEntityName())","titles":["Knowledge Graph Generation Engine","Graph Quality & Provenance Validation"]},"47":{"title":"Semantic Relationship Plausibility Matrix (EvidenceFusionEngine.js)","titles":["Knowledge Graph Generation Engine","Graph Quality & Provenance Validation"]},"48":{"title":"Evidence Provenance (EvidenceStore.js)","titles":["Knowledge Graph Generation Engine","Graph Quality & Provenance Validation"]},"49":{"title":"Post-Build Validation (GraphValidationEngine.js)","titles":["Knowledge Graph Generation Engine","Graph Quality & Provenance Validation"]},"50":{"title":"Community Detection & Maintenance","titles":["Knowledge Graph Generation Engine"]},"51":{"title":"AI Setup","titles":[]},"52":{"title":"1. Text Generation Providers","titles":["AI Setup"]},"53":{"title":"2. Embedding Index Setup","titles":["AI Setup"]},"54":{"title":"3. Knowledge Graph Engine","titles":["AI Setup"]},"55":{"title":"4. SQLite Database Locality","titles":["AI Setup"]},"56":{"title":"Notely Application Architecture","titles":[]},"57":{"title":"1. High-Level Architecture Overview","titles":["Notely Application Architecture"]},"58":{"title":"2. Renderer Layer (React & Editor Architecture)","titles":["Notely Application Architecture"]},"59":{"title":"Component Structure","titles":["Notely Application Architecture","2. Renderer Layer (React & Editor Architecture)"]},"60":{"title":"State Management & Contexts","titles":["Notely Application Architecture","2. Renderer Layer (React & Editor Architecture)"]},"61":{"title":"3. Main Process & Application Subsystems","titles":["Notely Application Architecture"]},"62":{"title":"A. Document & File System Service","titles":["Notely Application Architecture","3. Main Process & Application Subsystems"]},"63":{"title":"B. Git Version Control Subsystem (gitService.cjs)","titles":["Notely Application Architecture","3. Main Process & Application Subsystems"]},"64":{"title":"C. P2P Local Sync Engine (p2pService.cjs)","titles":["Notely Application Architecture","3. Main Process & Application Subsystems"]},"65":{"title":"D. Package, Import & Export Subsystem (notePackageIpc.cjs)","titles":["Notely Application Architecture","3. Main Process & Application Subsystems"]},"66":{"title":"E. AI & Context Engine Subsystem (aiService.cjs)","titles":["Notely Application Architecture","3. Main Process & Application Subsystems"]},"67":{"title":"AI Layer Architecture","titles":["Notely Application Architecture","3. Main Process & Application Subsystems","E. AI & Context Engine Subsystem (aiService.cjs)"]},"68":{"title":"4. Centralized System Logging Infrastructure (LogDB.js)","titles":["Notely Application Architecture"]},"69":{"title":"Database Schema","titles":["Notely Application Architecture","4. Centralized System Logging Infrastructure (LogDB.js)"]},"70":{"title":"Log Subsystem Categories","titles":["Notely Application Architecture","4. Centralized System Logging Infrastructure (LogDB.js)"]},"71":{"title":"User Diagnostics & Management UI","titles":["Notely Application Architecture","4. Centralized System Logging Infrastructure (LogDB.js)"]},"72":{"title":"5. Data Storage & Workspace Directory Structure","titles":["Notely Application Architecture"]},"73":{"title":"Workspace Storage Diagram","titles":["Notely Application Architecture","5. Data Storage & Workspace Directory Structure"]},"74":{"title":"Global Configuration","titles":["Notely Application Architecture","5. Data Storage & Workspace Directory Structure"]},"75":{"title":"Workspace File Structure","titles":["Notely Application Architecture","5. Data Storage & Workspace Directory Structure"]},"76":{"title":"Data & Sync","titles":[]},"77":{"title":"1. Where Notely Stores App Data","titles":["Data & Sync"]},"78":{"title":"2. Keep Your Notes Safe","titles":["Data & Sync"]},"79":{"title":"3. Sync with Other Peers (P2P)","titles":["Data & Sync"]},"80":{"title":"4. AI Features for Daily Use","titles":["Data & Sync"]},"81":{"title":"5. When to Use Workspace Graph","titles":["Data & Sync"]},"82":{"title":"6. Before Sharing or Releasing Notes","titles":["Data & Sync"]},"83":{"title":"Developer Documentation","titles":[]},"84":{"title":"1. Core Architecture & Process Model","titles":["Developer Documentation"]},"85":{"title":"2. IPC Channel Security Guard Pattern","titles":["Developer Documentation"]},"86":{"title":"3. Development Workflow & Commands","titles":["Developer Documentation"]},"87":{"title":"Development Server","titles":["Developer Documentation","3. Development Workflow & Commands"]},"88":{"title":"Build Production Bundle","titles":["Developer Documentation","3. Development Workflow & Commands"]},"89":{"title":"Documentation Site","titles":["Developer Documentation","3. Development Workflow & Commands"]},"90":{"title":"4. Test Suite Execution","titles":["Developer Documentation"]},"91":{"title":"Key Test Directories","titles":["Developer Documentation","4. Test Suite Execution"]},"92":{"title":"5. Build & Packaging Scripts","titles":["Developer Documentation"]},"93":{"title":"Notely Documentation Audit","titles":[]},"94":{"title":"Executive Summary","titles":["Notely Documentation Audit"]},"95":{"title":"Phase 1: Verified Feature Inventory","titles":["Notely Documentation Audit"]},"96":{"title":"Documentation Coverage Matrix","titles":["Notely Documentation Audit"]},"97":{"title":"README Audit","titles":["Notely Documentation Audit"]},"98":{"title":"What is correct","titles":["Notely Documentation Audit","README Audit"]},"99":{"title":"What is inaccurate or incomplete","titles":["Notely Documentation Audit","README Audit"]},"100":{"title":"README verdict","titles":["Notely Documentation Audit","README Audit"]},"101":{"title":"docs/ Folder Audit","titles":["Notely Documentation Audit"]},"102":{"title":"Strong areas","titles":["Notely Documentation Audit","docs/ Folder Audit"]},"103":{"title":"Systemic issues","titles":["Notely Documentation Audit","docs/ Folder Audit"]},"104":{"title":"Per-document findings","titles":["Notely Documentation Audit","docs/ Folder Audit"]},"105":{"title":"Built-in Help Audit","titles":["Notely Documentation Audit"]},"106":{"title":"Menu Documentation Audit","titles":["Notely Documentation Audit"]},"107":{"title":"Settings Documentation Audit","titles":["Notely Documentation Audit"]},"108":{"title":"Workflow Documentation Audit","titles":["Notely Documentation Audit"]},"109":{"title":"Missing Documentation by Severity","titles":["Notely Documentation Audit"]},"110":{"title":"Critical","titles":["Notely Documentation Audit","Missing Documentation by Severity"]},"111":{"title":"High","titles":["Notely Documentation Audit","Missing Documentation by Severity"]},"112":{"title":"Medium","titles":["Notely Documentation Audit","Missing Documentation by Severity"]},"113":{"title":"Low","titles":["Notely Documentation Audit","Missing Documentation by Severity"]},"114":{"title":"Keyboard Shortcut Audit","titles":["Notely Documentation Audit"]},"115":{"title":"Key findings","titles":["Notely Documentation Audit","Keyboard Shortcut Audit"]},"116":{"title":"Shortcut table","titles":["Notely Documentation Audit","Keyboard Shortcut Audit"]},"117":{"title":"Inconsistencies","titles":["Notely Documentation Audit"]},"118":{"title":"Obsolete Documentation","titles":["Notely Documentation Audit"]},"119":{"title":"Documentation Quality Review","titles":["Notely Documentation Audit"]},"120":{"title":"End-User Perspective","titles":["Notely Documentation Audit"]},"121":{"title":"Suggested Improvements","titles":["Notely Documentation Audit"]},"122":{"title":"1. Critical fixes","titles":["Notely Documentation Audit","Suggested Improvements"]},"123":{"title":"2. High-value additions","titles":["Notely Documentation Audit","Suggested Improvements"]},"124":{"title":"3. UX improvements","titles":["Notely Documentation Audit","Suggested Improvements"]},"125":{"title":"4. Documentation restructuring","titles":["Notely Documentation Audit","Suggested Improvements"]},"126":{"title":"5. Navigation improvements","titles":["Notely Documentation Audit","Suggested Improvements"]},"127":{"title":"6. Onboarding enhancements","titles":["Notely Documentation Audit","Suggested Improvements"]},"128":{"title":"7. Help system improvements","titles":["Notely Documentation Audit","Suggested Improvements"]},"129":{"title":"8. Keyboard guide improvements","titles":["Notely Documentation Audit","Suggested Improvements"]},"130":{"title":"Final Scorecard","titles":["Notely Documentation Audit"]},"131":{"title":"Release-Readiness Roadmap","titles":["Notely Documentation Audit"]},"132":{"title":"Code Blocks","titles":[]},"133":{"title":"Insert a Code Block","titles":["Code Blocks"]},"134":{"title":"Auto-Detect Language","titles":["Code Blocks"]},"135":{"title":"Auto-Format with Prettier","titles":["Code Blocks"]},"136":{"title":"Dedicated Code Editor","titles":["Code Blocks"]},"137":{"title":"Code Execution","titles":["Code Blocks"]},"138":{"title":"Supported Languages","titles":["Code Blocks"]},"139":{"title":"Tips","titles":["Code Blocks"]},"140":{"title":"Diagrams","titles":[]},"141":{"title":"Mermaid Diagrams","titles":["Diagrams"]},"142":{"title":"Insert a Mermaid Block","titles":["Diagrams","Mermaid Diagrams"]},"143":{"title":"Diagram Types","titles":["Diagrams","Mermaid Diagrams"]},"144":{"title":"Example — Git Workflow","titles":["Diagrams","Mermaid Diagrams"]},"145":{"title":"Interactive Diagram Actions","titles":["Diagrams","Mermaid Diagrams"]},"146":{"title":"Troubleshooting Mermaid","titles":["Diagrams","Mermaid Diagrams"]},"147":{"title":"Excalidraw Diagrams","titles":["Diagrams"]},"148":{"title":"Insert an Excalidraw Diagram","titles":["Diagrams","Excalidraw Diagrams"]},"149":{"title":"Re-Edit an Existing Diagram","titles":["Diagrams","Excalidraw Diagrams"]},"150":{"title":"Convert an Image to Excalidraw","titles":["Diagrams","Excalidraw Diagrams"]},"151":{"title":"Restore the Original Image","titles":["Diagrams","Excalidraw Diagrams"]},"152":{"title":"Draw.io Diagrams","titles":["Diagrams"]},"153":{"title":"Insert a Draw.io Diagram","titles":["Diagrams","Draw.io Diagrams"]},"154":{"title":"Import Diagrams via Drag and Drop","titles":["Diagrams","Draw.io Diagrams"]},"155":{"title":"Choosing a Diagram Tool","titles":["Diagrams"]},"156":{"title":"Focus Mode & Outline","titles":[]},"157":{"title":"Outline Panel","titles":["Focus Mode & Outline"]},"158":{"title":"Open the Outline","titles":["Focus Mode & Outline","Outline Panel"]},"159":{"title":"Using the Outline","titles":["Focus Mode & Outline","Outline Panel"]},"160":{"title":"Focus Mode","titles":["Focus Mode & Outline"]},"161":{"title":"Toggle Focus Mode","titles":["Focus Mode & Outline","Focus Mode"]},"162":{"title":"What Changes in Focus Mode","titles":["Focus Mode & Outline","Focus Mode"]},"163":{"title":"Exit Focus Mode","titles":["Focus Mode & Outline","Focus Mode"]},"164":{"title":"Tips","titles":["Focus Mode & Outline"]},"165":{"title":"Editor Overview","titles":[]},"166":{"title":"View Modes","titles":["Editor Overview"]},"167":{"title":"Status Bar","titles":["Editor Overview"]},"168":{"title":"Breadcrumbs","titles":["Editor Overview"]},"169":{"title":"Copy and Export Actions","titles":["Editor Overview"]},"170":{"title":"Copy Link Path","titles":["Editor Overview","Copy and Export Actions"]},"171":{"title":"Link Hover Preview","titles":["Editor Overview"]},"172":{"title":"Validation Indicators","titles":["Editor Overview"]},"173":{"title":"Tab Context Menu","titles":["Editor Overview","Validation Indicators"]},"174":{"title":"External Disk Change Detection","titles":["Editor Overview","Validation Indicators"]},"175":{"title":"Keyboard Shortcuts","titles":["Editor Overview"]},"176":{"title":"Markdown Guide","titles":[]},"177":{"title":"Headings","titles":["Markdown Guide"]},"178":{"title":"Text Formatting","titles":["Markdown Guide"]},"179":{"title":"Paragraphs and Line Breaks","titles":["Markdown Guide"]},"180":{"title":"Lists","titles":["Markdown Guide"]},"181":{"title":"Unordered","titles":["Markdown Guide","Lists"]},"182":{"title":"Ordered","titles":["Markdown Guide","Lists"]},"183":{"title":"Task Lists","titles":["Markdown Guide","Lists"]},"184":{"title":"Links","titles":["Markdown Guide"]},"185":{"title":"Images","titles":["Markdown Guide"]},"186":{"title":"Blockquotes & Callouts","titles":["Markdown Guide"]},"187":{"title":"GitHub-Style Callouts (Admonitions)","titles":["Markdown Guide","Blockquotes & Callouts"]},"188":{"title":"Code Blocks","titles":["Markdown Guide"]},"189":{"title":"Tables","titles":["Markdown Guide"]},"190":{"title":"Horizontal Rules","titles":["Markdown Guide"]},"191":{"title":"Footnotes","titles":["Markdown Guide"]},"192":{"title":"HTML","titles":["Markdown Guide"]},"193":{"title":"Escape Characters","titles":["Markdown Guide"]},"194":{"title":"Mermaid Diagrams","titles":["Markdown Guide"]},"195":{"title":"Toolbar Reference","titles":[]},"196":{"title":"Formatting Buttons","titles":["Toolbar Reference"]},"197":{"title":"Insert Buttons","titles":["Toolbar Reference"]},"198":{"title":"Diagram Buttons","titles":["Toolbar Reference"]},"199":{"title":"Validation and Quality","titles":["Toolbar Reference"]},"200":{"title":"Capture Button (Windows)","titles":["Toolbar Reference"]},"201":{"title":"View Mode Controls","titles":["Toolbar Reference"]},"202":{"title":"Tips","titles":["Toolbar Reference"]},"203":{"title":"Tables","titles":[]},"204":{"title":"Create a Table","titles":["Tables"]},"205":{"title":"Open the Inline Table Editor","titles":["Tables"]},"206":{"title":"Edit Cells","titles":["Tables"]},"207":{"title":"Paste Excel & Web Tables Directly","titles":["Tables"]},"208":{"title":"Add and Remove Rows","titles":["Tables"]},"209":{"title":"Column Alignment","titles":["Tables"]},"210":{"title":"Save and Cancel","titles":["Tables"]},"211":{"title":"Formatting Preservation","titles":["Tables"]},"212":{"title":"Export Table as Image or CSV","titles":["Tables"]},"213":{"title":"Tips","titles":["Tables"]},"214":{"title":"Export / Import Note Package","titles":[]},"215":{"title":"Opening the dialog","titles":["Export / Import Note Package"]},"216":{"title":"Exporting","titles":["Export / Import Note Package"]},"217":{"title":"What gets bundled","titles":["Export / Import Note Package","Exporting"]},"218":{"title":"Security","titles":["Export / Import Note Package","Exporting"]},"219":{"title":"Importing","titles":["Export / Import Note Package"]},"220":{"title":"Troubleshooting","titles":["Export / Import Note Package"]},"221":{"title":"Export & Import Reference","titles":[]},"222":{"title":"1. Single Note Export (PDF & HTML)","titles":["Export & Import Reference"]},"223":{"title":"PDF Export","titles":["Export & Import Reference","1. Single Note Export (PDF & HTML)"]},"224":{"title":"HTML Export","titles":["Export & Import Reference","1. Single Note Export (PDF & HTML)"]},"225":{"title":"Block-Level Exports (Tables & Diagrams)","titles":["Export & Import Reference","1. Single Note Export (PDF & HTML)"]},"226":{"title":"2. Downloads & Export History Manager","titles":["Export & Import Reference"]},"227":{"title":"Features & Capabilities","titles":["Export & Import Reference","2. Downloads & Export History Manager"]},"228":{"title":"2. Workspace Export (Full ZIP Bundle)","titles":["Export & Import Reference"]},"229":{"title":"Export Modes","titles":["Export & Import Reference","2. Workspace Export (Full ZIP Bundle)"]},"230":{"title":"Content Modes (for PDF & Web)","titles":["Export & Import Reference","2. Workspace Export (Full ZIP Bundle)"]},"231":{"title":"Archive Structure","titles":["Export & Import Reference","2. Workspace Export (Full ZIP Bundle)"]},"232":{"title":"3. Note Package Export & Import (.note Bundle)","titles":["Export & Import Reference"]},"233":{"title":"Exporting a Package","titles":["Export & Import Reference","3. Note Package Export & Import (.note Bundle)"]},"234":{"title":"Security","titles":["Export & Import Reference","3. Note Package Export & Import (.note Bundle)"]},"235":{"title":"Importing a Package","titles":["Export & Import Reference","3. Note Package Export & Import (.note Bundle)"]},"236":{"title":"Troubleshooting","titles":["Export & Import Reference"]},"237":{"title":"FAQ","titles":[]},"238":{"title":"What is a workspace in Notely?","titles":["FAQ"]},"239":{"title":"Where does Notely store my data?","titles":["FAQ"]},"240":{"title":"Does Notely work offline?","titles":["FAQ"]},"241":{"title":"Which features require internet?","titles":["FAQ"]},"242":{"title":"What is .notes-app?","titles":["FAQ"]},"243":{"title":"Should .notes-app be committed to Git?","titles":["FAQ"]},"244":{"title":"Can I restore deleted or changed notes?","titles":["FAQ"]},"245":{"title":"How do I reopen a workspace quickly?","titles":["FAQ"]},"246":{"title":"Does Notely have a plugin system?","titles":["FAQ"]},"247":{"title":"What happens if I configure AI?","titles":["FAQ"]},"248":{"title":"What is the easiest way to learn shortcuts?","titles":["FAQ"]},"249":{"title":"Feature Availability","titles":[]},"250":{"title":"Notely Feature Reference","titles":[]},"251":{"title":"1. Notes and Workspace","titles":["Notely Feature Reference"]},"252":{"title":"Workspace selection","titles":["Notely Feature Reference","1. Notes and Workspace"]},"253":{"title":"Opening the workspace externally","titles":["Notely Feature Reference","1. Notes and Workspace"]},"254":{"title":"Opening the website view","titles":["Notely Feature Reference","1. Notes and Workspace"]},"255":{"title":"Project-aware workspace","titles":["Notely Feature Reference","1. Notes and Workspace"]},"256":{"title":"Landing dashboard","titles":["Notely Feature Reference","1. Notes and Workspace"]},"257":{"title":"Note and folder creation","titles":["Notely Feature Reference","1. Notes and Workspace"]},"258":{"title":"Trash Recovery Bin","titles":["Notely Feature Reference","1. Notes and Workspace"]},"259":{"title":"2. Editor and Writing Experience","titles":["Notely Feature Reference"]},"260":{"title":"Multiple edit modes","titles":["Notely Feature Reference","2. Editor and Writing Experience"]},"261":{"title":"Markdown toolbar","titles":["Notely Feature Reference","2. Editor and Writing Experience"]},"262":{"title":"Inline table editor","titles":["Notely Feature Reference","2. Editor and Writing Experience"]},"263":{"title":"Code Blocks","titles":["Notely Feature Reference","2. Editor and Writing Experience"]},"264":{"title":"Find and replace","titles":["Notely Feature Reference","2. Editor and Writing Experience"]},"265":{"title":"Outline navigation","titles":["Notely Feature Reference","2. Editor and Writing Experience"]},"266":{"title":"Focus mode","titles":["Notely Feature Reference","2. Editor and Writing Experience"]},"267":{"title":"Terminal and workspace tools","titles":["Notely Feature Reference","2. Editor and Writing Experience"]},"268":{"title":"Appearance and layout","titles":["Notely Feature Reference","2. Editor and Writing Experience"]},"269":{"title":"Note statistics","titles":["Notely Feature Reference","2. Editor and Writing Experience"]},"270":{"title":"Copy and export","titles":["Notely Feature Reference","2. Editor and Writing Experience"]},"271":{"title":"Breadcrumb navigation","titles":["Notely Feature Reference","2. Editor and Writing Experience"]},"272":{"title":"3. Quality and Validation","titles":["Notely Feature Reference"]},"273":{"title":"Markdown validation","titles":["Notely Feature Reference","3. Quality and Validation"]},"274":{"title":"Typo checking & Spelling Dictionary","titles":["Notely Feature Reference","3. Quality and Validation"]},"275":{"title":"Quick problem fixing","titles":["Notely Feature Reference","3. Quality and Validation"]},"276":{"title":"4. Search and Discovery","titles":["Notely Feature Reference"]},"277":{"title":"Global search","titles":["Notely Feature Reference","4. Search and Discovery"]},"278":{"title":"Advanced search patterns","titles":["Notely Feature Reference","4. Search and Discovery","Global search"]},"279":{"title":"Code-aware search","titles":["Notely Feature Reference","4. Search and Discovery","Global search"]},"280":{"title":"Content snippets","titles":["Notely Feature Reference","4. Search and Discovery"]},"281":{"title":"Workspace graph","titles":["Notely Feature Reference","4. Search and Discovery"]},"282":{"title":"5. Tasks and Workflow","titles":["Notely Feature Reference"]},"283":{"title":"Tasks overview","titles":["Notely Feature Reference","5. Tasks and Workflow"]},"284":{"title":"Open Tasks panel","titles":["Notely Feature Reference","5. Tasks and Workflow"]},"285":{"title":"Opening the Open Tasks panel","titles":["Notely Feature Reference","5. Tasks and Workflow","Open Tasks panel"]},"286":{"title":"Using the Open Tasks panel","titles":["Notely Feature Reference","5. Tasks and Workflow","Open Tasks panel"]},"287":{"title":"All Tasks panel","titles":["Notely Feature Reference","5. Tasks and Workflow"]},"288":{"title":"Use cases","titles":["Notely Feature Reference","5. Tasks and Workflow","All Tasks panel"]},"289":{"title":"6. Git Version Control and History","titles":["Notely Feature Reference"]},"290":{"title":"Native Git Repository","titles":["Notely Feature Reference","6. Git Version Control and History"]},"291":{"title":"Compare, Restore, and Tagging","titles":["Notely Feature Reference","6. Git Version Control and History"]},"292":{"title":"Branch, Stash, and Sync Management","titles":["Notely Feature Reference","6. Git Version Control and History"]},"293":{"title":"7. Media Management","titles":["Notely Feature Reference"]},"294":{"title":"Image and file linking","titles":["Notely Feature Reference","7. Media Management"]},"295":{"title":"Media actions","titles":["Notely Feature Reference","7. Media Management"]},"296":{"title":"Screen capture (Windows)","titles":["Notely Feature Reference","7. Media Management"]},"297":{"title":"Media preview tools","titles":["Notely Feature Reference","7. Media Management"]},"298":{"title":"Workspace Health media checks","titles":["Notely Feature Reference","7. Media Management"]},"299":{"title":"Image annotation and lifecycle","titles":["Notely Feature Reference","7. Media Management"]},"300":{"title":"Original image backup and restore","titles":["Notely Feature Reference","7. Media Management"]},"301":{"title":"8. Diagram Features","titles":["Notely Feature Reference"]},"302":{"title":"Mermaid diagrams","titles":["Notely Feature Reference","8. Diagram Features"]},"303":{"title":"Excalidraw diagrams","titles":["Notely Feature Reference","8. Diagram Features"]},"304":{"title":"9. AI Assistance","titles":["Notely Feature Reference"]},"305":{"title":"AI settings","titles":["Notely Feature Reference","9. AI Assistance"]},"306":{"title":"AI chat and commands","titles":["Notely Feature Reference","9. AI Assistance"]},"307":{"title":"Semantic features","titles":["Notely Feature Reference","9. AI Assistance"]},"308":{"title":"What each AI service can do","titles":["Notely Feature Reference","9. AI Assistance"]},"309":{"title":"AI operation feedback","titles":["Notely Feature Reference","9. AI Assistance"]},"310":{"title":"How recent the AI search data is","titles":["Notely Feature Reference","9. AI Assistance"]},"311":{"title":"10. Peer-to-Peer Sync","titles":["Notely Feature Reference"]},"312":{"title":"Discovery and pairing","titles":["Notely Feature Reference","10. Peer-to-Peer Sync"]},"313":{"title":"Sync status and conflicts","titles":["Notely Feature Reference","10. Peer-to-Peer Sync"]},"314":{"title":"Security controls","titles":["Notely Feature Reference","10. Peer-to-Peer Sync"]},"315":{"title":"11. Help and Product Info","titles":["Notely Feature Reference"]},"316":{"title":"Documentation","titles":["Notely Feature Reference","11. Help and Product Info"]},"317":{"title":"Keyboard shortcuts","titles":["Notely Feature Reference","11. Help and Product Info"]},"318":{"title":"About dialog","titles":["Notely Feature Reference","11. Help and Product Info"]},"319":{"title":"12. Preview and Export","titles":["Notely Feature Reference"]},"320":{"title":"Web preview","titles":["Notely Feature Reference","12. Preview and Export"]},"321":{"title":"PDF export","titles":["Notely Feature Reference","12. Preview and Export"]},"322":{"title":"Website-style rendering","titles":["Notely Feature Reference","12. Preview and Export"]},"323":{"title":"Workspace zip export","titles":["Notely Feature Reference","12. Preview and Export"]},"324":{"title":"Your First Note","titles":[]},"325":{"title":"Step 1 — Create a Note","titles":["Your First Note"]},"326":{"title":"Step 2 — Write in Markdown","titles":["Your First Note"]},"327":{"title":"Quick Markdown Reference","titles":["Your First Note","Step 2 — Write in Markdown"]},"328":{"title":"Step 3 — Preview Your Note","titles":["Your First Note"]},"329":{"title":"Step 4 — Use the Toolbar","titles":["Your First Note"]},"330":{"title":"Step 5 — Save","titles":["Your First Note"]},"331":{"title":"What\'s Next?","titles":["Your First Note"]},"332":{"title":"Getting Started","titles":[]},"333":{"title":"Requirements","titles":["Getting Started"]},"334":{"title":"Download & Install","titles":["Getting Started"]},"335":{"title":"Release Types","titles":["Getting Started"]},"336":{"title":"1. NSIS Installer (.exe)","titles":["Getting Started","Release Types"]},"337":{"title":"2. Portable Executable (.exe)","titles":["Getting Started","Release Types"]},"338":{"title":"3. ZIP Archive (.zip)","titles":["Getting Started","Release Types"]},"339":{"title":"Cons & Limitations of Packaged Electron Applications","titles":["Getting Started"]},"340":{"title":"Open Your Workspace","titles":["Getting Started"]},"341":{"title":"Key Concepts","titles":["Getting Started"]},"342":{"title":"What to Do Next","titles":["Getting Started"]},"343":{"title":"Help at Any Time","titles":["Getting Started"]},"344":{"title":"Branches & Remote","titles":[]},"345":{"title":"1. Branch Management","titles":["Branches & Remote"]},"346":{"title":"2. Remote Synchronization (Push/Pull)","titles":["Branches & Remote"]},"347":{"title":"3. Stashing Changes","titles":["Branches & Remote"]},"348":{"title":"Commit & Stage","titles":[]},"349":{"title":"1. Staging Files","titles":["Commit & Stage"]},"350":{"title":"2. Writing a Commit","titles":["Commit & Stage"]},"351":{"title":"History & Restore","titles":[]},"352":{"title":"1. Opening Revision History","titles":["History & Restore"]},"353":{"title":"2. Comparing Diffs","titles":["History & Restore"]},"354":{"title":"3. Restoring Notes","titles":["History & Restore"]},"355":{"title":"Git Version Control","titles":[]},"356":{"title":"Why Git?","titles":["Git Version Control"]},"357":{"title":"Git Setup & Repository","titles":[]},"358":{"title":"1. Initializing a Repository","titles":["Git Setup & Repository"]},"359":{"title":"2. Cloning a Repository","titles":["Git Setup & Repository"]},"360":{"title":"3. Ignoring App Metadata (.notes-app)","titles":["Git Setup & Repository"]},"361":{"title":"Keyboard Shortcuts","titles":[]},"362":{"title":"Global & Navigation","titles":["Keyboard Shortcuts"]},"363":{"title":"Note Editor","titles":["Keyboard Shortcuts"]},"364":{"title":"Search & Find Panel","titles":["Keyboard Shortcuts"]},"365":{"title":"AI & Features","titles":["Keyboard Shortcuts"]},"366":{"title":"View, Media & Tools","titles":["Keyboard Shortcuts"]},"367":{"title":"License","titles":[]},"368":{"title":"Attribution-NonCommercial 4.0 International","titles":["License"]},"369":{"title":"Third-Party Open Source Software","titles":["License"]},"370":{"title":"Release Notes","titles":[]},"371":{"title":"2026-07-25 (latest)","titles":["Release Notes"]},"372":{"title":"AI Architecture & UI Telemetry","titles":["Release Notes","2026-07-25 (latest)"]},"373":{"title":"2026-07-17","titles":["Release Notes"]},"374":{"title":"New features","titles":["Release Notes","2026-07-17"]},"375":{"title":"2026-07-11","titles":["Release Notes"]},"376":{"title":"Refinements","titles":["Release Notes","2026-07-11"]},"377":{"title":"Fixes","titles":["Release Notes","2026-07-11"]},"378":{"title":"2026-07-03 (latest)","titles":["Release Notes"]},"379":{"title":"New features","titles":["Release Notes","2026-07-03 (latest)"]},"380":{"title":"Refinements","titles":["Release Notes","2026-07-03 (latest)"]},"381":{"title":"Fixes","titles":["Release Notes","2026-07-03 (latest)"]},"382":{"title":"2026-07-03","titles":["Release Notes"]},"383":{"title":"Documentation updates","titles":["Release Notes","2026-07-03"]},"384":{"title":"Shortcut updates","titles":["Release Notes","2026-07-03"]},"385":{"title":"Help Center updates","titles":["Release Notes","2026-07-03"]},"386":{"title":"Notes for existing users","titles":["Release Notes"]},"387":{"title":"Search","titles":[]},"388":{"title":"1. Find in Current Note","titles":["Search"]},"389":{"title":"2. Global Workspace Search","titles":["Search"]},"390":{"title":"Synonym & Term Support","titles":["Search","2. Global Workspace Search"]},"391":{"title":"3. Regular Expression Search (Regex)","titles":["Search"]},"392":{"title":"4. Code Block Search","titles":["Search"]},"393":{"title":"5. Semantic Search (AI-Powered)","titles":["Search"]},"394":{"title":"Settings Reference","titles":[]},"395":{"title":"1. Appearance","titles":["Settings Reference"]},"396":{"title":"Theme","titles":["Settings Reference","1. Appearance"]},"397":{"title":"Zoom","titles":["Settings Reference","1. Appearance"]},"398":{"title":"2. Landing View","titles":["Settings Reference"]},"399":{"title":"View Mode","titles":["Settings Reference","2. Landing View"]},"400":{"title":"Density","titles":["Settings Reference","2. Landing View"]},"401":{"title":"3. Editor and Writing","titles":["Settings Reference"]},"402":{"title":"Typo Check","titles":["Settings Reference","3. Editor and Writing"]},"403":{"title":"Outline","titles":["Settings Reference","3. Editor and Writing"]},"404":{"title":"Focus Mode","titles":["Settings Reference","3. Editor and Writing"]},"405":{"title":"4. Terminal","titles":["Settings Reference"]},"406":{"title":"Show Terminal","titles":["Settings Reference","4. Terminal"]},"407":{"title":"Terminal Shell","titles":["Settings Reference","4. Terminal"]},"408":{"title":"5. Screen Capture","titles":["Settings Reference"]},"409":{"title":"6. AI Settings","titles":["Settings Reference"]},"410":{"title":"Provider setup","titles":["Settings Reference","6. AI Settings"]},"411":{"title":"Feature toggles","titles":["Settings Reference","6. AI Settings"]},"412":{"title":"Advanced generation tuning","titles":["Settings Reference","6. AI Settings"]},"413":{"title":"Data and privacy controls","titles":["Settings Reference","6. AI Settings"]},"414":{"title":"7. Workspace Metadata and Git Safety","titles":["Settings Reference"]},"415":{"title":"8. Environment Variables","titles":["Settings Reference"]},"416":{"title":"P2P Sync","titles":[]},"417":{"title":"1. Network Discovery & Transport Security","titles":["P2P Sync"]},"418":{"title":"2. Pairing Devices & Invite Flow","titles":["P2P Sync"]},"419":{"title":"3. Delta Note Merging & Conflict Resolution","titles":["P2P Sync"]},"420":{"title":"4. Key Rotation & Security Controls","titles":["P2P Sync"]},"421":{"title":"Top Common Tasks","titles":[]},"422":{"title":"1. Open or change workspace","titles":["Top Common Tasks"]},"423":{"title":"2. Create a new note","titles":["Top Common Tasks"]},"424":{"title":"3. Create a folder","titles":["Top Common Tasks"]},"425":{"title":"4. Find text in current note","titles":["Top Common Tasks"]},"426":{"title":"5. Replace text in current note","titles":["Top Common Tasks"]},"427":{"title":"6. Switch between Edit, Split, and Preview","titles":["Top Common Tasks"]},"428":{"title":"7. Show document outline","titles":["Top Common Tasks"]},"429":{"title":"8. Enable Focus Mode","titles":["Top Common Tasks"]},"430":{"title":"9. Insert an image into a note","titles":["Top Common Tasks"]},"431":{"title":"10. Insert a Mermaid diagram","titles":["Top Common Tasks"]},"432":{"title":"11. Insert an Excalidraw diagram","titles":["Top Common Tasks"]},"433":{"title":"11b. Convert an image to Excalidraw","titles":["Top Common Tasks"]},"434":{"title":"12. View or restore note history","titles":["Top Common Tasks"]},"435":{"title":"13. Search across all notes","titles":["Top Common Tasks"]},"436":{"title":"14. Open keyboard shortcuts","titles":["Top Common Tasks"]},"437":{"title":"15. Open troubleshooting","titles":["Top Common Tasks"]},"438":{"title":"16. Run AI setup and test","titles":["Top Common Tasks"]},"439":{"title":"17. Refresh semantic graph data","titles":["Top Common Tasks"]},"440":{"title":"18. Clean unused media","titles":["Top Common Tasks"]},"441":{"title":"19. Restore original image after edits","titles":["Top Common Tasks"]},"442":{"title":"19b. Restore original image from converted Excalidraw","titles":["Top Common Tasks"]},"443":{"title":"20. Export a note to PDF","titles":["Top Common Tasks"]},"444":{"title":"21. Capture a screen area into a note","titles":["Top Common Tasks"]},"445":{"title":"22. Review open and completed tasks across workspace","titles":["Top Common Tasks"]},"446":{"title":"23. Export workspace as zip","titles":["Top Common Tasks"]},"447":{"title":"Notely Troubleshooting","titles":[]},"448":{"title":"1. Notes Are Not Showing","titles":["Notely Troubleshooting"]},"449":{"title":"2. Preview Looks Wrong","titles":["Notely Troubleshooting"]},"450":{"title":"3. A Linked File or Image Does Not Open","titles":["Notely Troubleshooting"]},"451":{"title":"4. Sync Conflicts Keep Appearing","titles":["Notely Troubleshooting"]},"452":{"title":"5. AI Features Are Disabled","titles":["Notely Troubleshooting"]},"453":{"title":"6. App Feels Slow in Large Workspaces","titles":["Notely Troubleshooting"]},"454":{"title":"7. Quick Support Details to Share","titles":["Notely Troubleshooting"]},"455":{"title":"8. Screen Capture Mode Looks Incorrect (A/R)","titles":["Notely Troubleshooting"]},"456":{"title":"9. Review Mode Save Appears Unresponsive","titles":["Notely Troubleshooting"]},"457":{"title":"10. Embedded Terminal Does Not Start","titles":["Notely Troubleshooting"]},"458":{"title":"11. Workspace Export Does Not Finish","titles":["Notely Troubleshooting"]},"459":{"title":"12. Project Website Shows Notes from an Older Workspace","titles":["Notely Troubleshooting"]},"460":{"title":"Notely User Guide","titles":[]},"461":{"title":"1. Set Up Your Workspace","titles":["Notely User Guide"]},"462":{"title":"2. Create and Organize Notes","titles":["Notely User Guide"]},"463":{"title":"3. Write and Edit Faster","titles":["Notely User Guide"]},"464":{"title":"4. Recover Changes with Git Version Control","titles":["Notely User Guide"]},"465":{"title":"5. Work with Images and Files","titles":["Notely User Guide"]},"466":{"title":"6. Capture Screen Areas into Notes (Windows)","titles":["Notely User Guide"]},"467":{"title":"7. Use Diagrams (Mermaid and Excalidraw)","titles":["Notely User Guide"]},"468":{"title":"Mermaid","titles":["Notely User Guide","7. Use Diagrams (Mermaid and Excalidraw)"]},"469":{"title":"Excalidraw","titles":["Notely User Guide","7. Use Diagrams (Mermaid and Excalidraw)"]},"470":{"title":"Convert an image to Excalidraw","titles":["Notely User Guide","7. Use Diagrams (Mermaid and Excalidraw)"]},"471":{"title":"Restore original image from converted diagram","titles":["Notely User Guide","7. Use Diagrams (Mermaid and Excalidraw)"]},"472":{"title":"8. Navigate Large Workspaces","titles":["Notely User Guide"]},"473":{"title":"9. Track Tasks Across Notes","titles":["Notely User Guide"]},"474":{"title":"10. Export Workspace as Zip","titles":["Notely User Guide"]},"475":{"title":"11. Get Help Quickly","titles":["Notely User Guide"]},"476":{"title":"UX Writing Guide","titles":[]},"477":{"title":"Core Rules","titles":["UX Writing Guide"]},"478":{"title":"Buttons and Actions","titles":["UX Writing Guide"]},"479":{"title":"Empty, Error, and Status Text","titles":["UX Writing Guide"]},"480":{"title":"Examples","titles":["UX Writing Guide"]},"481":{"title":"Website View","titles":[]},"482":{"title":"Opening the Website View","titles":["Website View"]},"483":{"title":"How It Works","titles":["Website View"]},"484":{"title":"Local HTTP Server","titles":["Website View","How It Works"]},"485":{"title":"Live Content Overrides","titles":["Website View","How It Works"]},"486":{"title":"Page Rendering Pipeline (websiteRenderer.cjs)","titles":["Website View"]},"487":{"title":"What renders in website view","titles":["Website View","Page Rendering Pipeline (websiteRenderer.cjs)"]},"488":{"title":"Project Index Page","titles":["Website View"]},"489":{"title":"Full-Text Search","titles":["Website View"]},"490":{"title":"Website Scope","titles":["Website View"]},"491":{"title":"Comparison: Website View vs Preview Pane vs PDF Export","titles":["Website View"]},"492":{"title":"Calendar & Scheduling","titles":[]},"493":{"title":"1. Task Scheduling & Due Dates","titles":["Calendar & Scheduling"]},"494":{"title":"2. Calendar Views","titles":["Calendar & Scheduling"]},"495":{"title":"Month View","titles":["Calendar & Scheduling","2. Calendar Views"]},"496":{"title":"Week View","titles":["Calendar & Scheduling","2. Calendar Views"]},"497":{"title":"Day View","titles":["Calendar & Scheduling","2. Calendar Views"]},"498":{"title":"3. Interactive Drag & Drop Scheduling","titles":["Calendar & Scheduling"]},"499":{"title":"4. Date Filtering & Overdue Tracking","titles":["Calendar & Scheduling"]},"500":{"title":"Downloads & Export History","titles":[]},"501":{"title":"1. Features & Capabilities","titles":["Downloads & Export History"]},"502":{"title":"2. Storage & Database Architecture","titles":["Downloads & Export History"]},"503":{"title":"3. Supported Export & Download Formats","titles":["Downloads & Export History"]},"504":{"title":"4. System Downloads Directory","titles":["Downloads & Export History"]},"505":{"title":"Export","titles":[]},"506":{"title":"1. Export Formats","titles":["Export"]},"507":{"title":"2. Advanced Options","titles":["Export"]},"508":{"title":"Workspace Graph","titles":[]},"509":{"title":"1. Navigating the Graph","titles":["Workspace Graph"]},"510":{"title":"2. Node Types","titles":["Workspace Graph"]},"511":{"title":"3. Semantic Clustering (AI-Powered)","titles":["Workspace Graph"]},"512":{"title":"Workspace Overview","titles":[]},"513":{"title":"1. Landing Dashboard","titles":["Workspace Overview"]},"514":{"title":"2. Note and Folder Creation","titles":["Workspace Overview"]},"515":{"title":"3. Density & Layout Views","titles":["Workspace Overview"]},"516":{"title":"4. Workspace Tools & Embedded Terminal","titles":["Workspace Overview"]},"517":{"title":"5. Workspace & Document Reloading","titles":["Workspace Overview"]},"518":{"title":"Media","titles":[]},"519":{"title":"1. Asset Storage","titles":["Media"]},"520":{"title":"2. Image Tools & Annotation","titles":["Media"]},"521":{"title":"3. Workspace Health Checks","titles":["Media"]},"522":{"title":"Tasks & Checklists","titles":[]},"523":{"title":"1. Creating Tasks in Notes","titles":["Tasks & Checklists"]},"524":{"title":"Supported Formats","titles":["Tasks & Checklists","1. Creating Tasks in Notes"]},"525":{"title":"2. Interactive Preview Toggling & Task Modal","titles":["Tasks & Checklists"]},"526":{"title":"3. Bi-Directional Markdown Synchronization","titles":["Tasks & Checklists"]},"527":{"title":"4. Smart Alignment & Deduplication Engine","titles":["Tasks & Checklists"]},"528":{"title":"5. Note-Level Task Bar & Workspace Dashboard","titles":["Tasks & Checklists"]},"529":{"title":"Note-Level Task Summary","titles":["Tasks & Checklists","5. Note-Level Task Bar & Workspace Dashboard"]},"530":{"title":"Workspace Task Page","titles":["Tasks & Checklists","5. Note-Level Task Bar & Workspace Dashboard"]},"531":{"title":"Screen Capture","titles":[]},"532":{"title":"1. How to Capture","titles":["Screen Capture"]},"533":{"title":"2. Capture Modes","titles":["Screen Capture"]},"534":{"title":"3. Toolbar Indicators","titles":["Screen Capture"]},"535":{"title":"Embedded Terminal","titles":[]},"536":{"title":"1. Opening & Toggling the Terminal","titles":["Embedded Terminal"]},"537":{"title":"2. Shell Selection & Configuration","titles":["Embedded Terminal"]},"538":{"title":"Custom Shell Path Overrides (Environment Variables)","titles":["Embedded Terminal","2. Shell Selection & Configuration"]},"539":{"title":"3. Working Directory & Lifecycle","titles":["Embedded Terminal"]},"540":{"title":"4. Security Policies & Strict Allowlist Mode","titles":["Embedded Terminal"]},"541":{"title":"Policy Modes (NOTELY_TERMINAL_POLICY)","titles":["Embedded Terminal","4. Security Policies & Strict Allowlist Mode"]},"542":{"title":"Environment Variable Security Flags","titles":["Embedded Terminal","4. Security Policies & Strict Allowlist Mode"]}},"dirtCount":0,"index":[["@alex",{"2":{"523":1}}],["@import",{"2":{"236":1}}],["❌",{"2":{"491":4}}],["x",{"2":{"374":1}}],["xml",{"2":{"153":1,"155":1}}],["xml,",{"2":{"138":1}}],["?",{"2":{"325":1}}],["✅",{"2":{"217":5,"233":5,"491":9}}],["✏️",{"2":{"212":1}}],["📥",{"2":{"500":1}}],["📄",{"2":{"212":1}}],["🖼️",{"2":{"212":1}}],["📷",{"2":{"200":2,"532":1,"534":2}}],["💻,",{"2":{"19":1,"27":1}}],["–",{"2":{"196":1}}],["|.",{"2":{"325":1}}],["|:",{"2":{"189":2,"209":2}}],["|",{"2":{"189":22,"204":15,"206":1,"209":3,"415":4,"526":8}}],["|),",{"2":{"32":1}}],["![alt",{"2":{"185":1}}],["])",{"2":{"283":1,"287":1,"525":1}}],["]+\\\\]",{"2":{"278":1,"391":1}}],["]",{"2":{"183":2,"197":1,"286":3,"326":2,"327":1,"473":1,"523":3,"524":3,"525":1,"526":1}}],["],",{"2":{"7":1,"524":3}}],["`inline`",{"2":{"327":1}}],["`inline",{"2":{"196":1}}],["`",{"2":{"196":1}}],["`hello,",{"2":{"188":1}}],["`code`",{"2":{"178":1}}],["```fenced```",{"2":{"327":1}}],["```.",{"2":{"139":1}}],["```typescript",{"2":{"139":1}}],["```",{"2":{"133":1,"143":1,"188":1,"194":1}}],["~120",{"2":{"333":1}}],["~~strikethrough~~",{"2":{"196":1}}],["~~strike~~",{"2":{"178":1}}],["~~",{"2":{"196":1}}],["~75",{"2":{"11":1,"24":1,"372":1}}],["▾",{"2":{"158":1,"205":1}}],["✓",{"2":{"155":3}}],["▶",{"2":{"137":2,"263":1}}],["✎",{"2":{"136":1,"263":1}}],["🪄",{"2":{"135":1,"263":1}}],["🧠,",{"2":{"19":1,"27":1}}],[":|",{"2":{"189":2,"209":2}}],[":",{"2":{"91":1,"325":1}}],["{path}",{"2":{"486":1}}],["{asset",{"2":{"484":1}}],["{note",{"2":{"484":2,"486":1}}],["{name}!\\"",{"2":{"133":1}}],["{workspacename}",{"2":{"231":1}}],["{workspacename}.note.",{"2":{"216":1,"233":1}}],["{workspace}",{"2":{"55":1,"66":2,"69":1,"75":1,"227":1,"233":1,"502":1}}],["{",{"2":{"85":2,"188":1}}],["\'info\',",{"2":{"69":1}}],[",",{"2":{"65":1,"231":1,"365":1,"488":2}}],["z",{"2":{"363":2}}],["z]+",{"2":{"278":1}}],["z0",{"2":{"278":1,"391":1}}],["zip:",{"2":{"506":1}}],["zip.",{"2":{"323":1,"446":2,"474":2,"506":2}}],["zip",{"0":{"228":1,"323":1,"338":1,"446":1,"474":1},"1":{"229":1,"230":1,"231":1},"2":{"65":1,"95":1,"96":1,"98":1,"108":1,"116":1,"218":1,"231":1,"234":1,"500":1,"503":1,"505":1}}],["zoom.",{"2":{"397":1}}],["zoom:",{"2":{"268":1,"397":3}}],["zoom,",{"2":{"95":1,"99":1,"103":1,"104":1,"111":1,"117":1,"281":1}}],["zoom",{"0":{"397":1},"2":{"60":1,"96":1,"106":1,"107":1,"108":1,"116":6,"268":2,"297":1,"366":2,"397":3,"509":1}}],["zero",{"0":{"11":1,"24":1,"35":1},"2":{"0":1,"1":1,"11":1,"13":1,"20":1,"75":1,"337":1,"372":1}}],["%appdata%",{"2":{"53":1,"54":1}}],["95%)",{"2":{"411":1}}],["9.",{"0":{"304":1,"430":1,"456":1,"473":1}}],["9",{"2":{"49":1,"278":1,"391":1}}],["#work",{"2":{"523":1}}],["######",{"2":{"177":1}}],["#####",{"2":{"177":1}}],["####",{"2":{"177":1}}],["###",{"2":{"177":1,"327":1}}],["##",{"2":{"177":2,"326":3,"327":1}}],["#",{"2":{"49":1,"89":2,"90":2,"177":1,"327":1}}],["→).",{"2":{"146":1}}],["→",{"2":{"37":1,"38":2,"41":1,"51":1,"65":1,"142":1,"148":1,"158":2,"161":1,"163":1,"172":1,"175":1,"188":1,"189":1,"197":1,"200":2,"202":1,"215":1,"221":2,"223":2,"226":1,"228":1,"232":1,"325":1,"327":1,"340":1,"342":4,"360":1,"368":1,"393":1,"418":1,"482":2,"491":2,"500":2,"506":1,"507":1,"509":1,"514":1,"517":2,"526":2,"533":1,"536":1,"537":1}}],["75%",{"2":{"397":1}}],["700ms).",{"2":{"223":1}}],["70b).",{"2":{"52":1}}],["70b",{"2":{"52":1}}],["72%",{"2":{"94":1}}],["7:",{"0":{"38":1}}],["7",{"2":{"37":1,"49":1,"115":1,"119":3,"130":1,"496":1,"499":1}}],["7.",{"0":{"13":1,"128":1,"293":1,"414":1,"428":1,"454":1,"467":1}}],["64kb.",{"2":{"137":1}}],["6,",{"2":{"56":1}}],["6",{"2":{"49":1,"59":1,"84":1,"119":1,"130":4,"177":1,"204":1}}],["6:",{"0":{"37":1}}],["6.",{"0":{"12":1,"28":1,"82":1,"127":1,"289":1,"409":1,"427":1,"453":1,"466":1}}],["\\\\[([^\\\\]]+)\\\\]\\\\(([^)]+)\\\\)",{"2":{"391":1}}],["\\\\[[a",{"2":{"278":1,"391":1}}],["\\\\",{"2":{"278":1,"325":1,"363":1}}],["\\\\|.",{"2":{"206":1}}],["\\\\`not",{"2":{"193":1}}],["\\\\*not",{"2":{"193":1}}],["\\\\:",{"2":{"179":1}}],["\\\\times",{"2":{"50":1}}],["\\\\text{chars}",{"2":{"36":1}}],["\\\\cup",{"2":{"39":1}}],["\\\\le",{"2":{"36":2}}],["${name}!`;",{"2":{"188":1}}],["$p(a",{"2":{"39":1}}],["$\\\\leftrightarrow$",{"2":{"38":1}}],["$\\\\rightarrow$",{"2":{"35":1}}],["$>",{"2":{"38":1}}],["$2",{"2":{"36":1}}],["$0.88",{"2":{"34":1}}],["=>",{"2":{"85":1}}],["==",{"2":{"49":1}}],["=",{"2":{"35":1,"39":1,"43":1,"55":2,"85":1,"200":2,"296":2,"366":1,"408":2,"418":1,"419":1}}],["—",{"0":{"144":1,"325":1,"326":1,"328":1,"329":1,"330":1},"1":{"327":1},"2":{"33":1,"36":5,"54":1,"136":3,"146":1,"166":1,"169":1,"172":3,"183":1,"185":1,"188":1,"189":1,"194":1,"200":2,"204":2,"205":5,"206":1,"210":1,"213":1,"214":2,"216":3,"220":1,"233":4,"234":1,"235":1,"236":1,"253":2,"254":2,"325":1,"326":1,"328":4,"329":6,"331":4,"332":1,"333":1,"334":1,"372":3,"374":12,"375":1,"376":3,"377":2,"379":4,"380":4,"381":2,"484":1,"486":3,"489":1,"490":1}}],["k).",{"2":{"445":1,"473":1}}],["k)",{"2":{"340":1}}],["kickoff",{"2":{"326":1}}],["kill",{"2":{"137":1}}],["k",{"2":{"285":1,"343":1,"362":1,"363":1,"536":1}}],["know",{"2":{"278":1,"309":1}}],["knowledgegraph",{"2":{"71":2}}],["knowledge",{"0":{"25":1,"29":1,"54":1},"1":{"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1},"2":{"4":1,"29":1,"43":1,"54":1,"56":1,"66":2,"70":1,"71":1,"75":1,"84":1,"410":1,"411":1,"516":1}}],["katex",{"2":{"84":1,"223":1}}],["kept,",{"2":{"338":1}}],["keeping",{"2":{"346":1,"374":1}}],["keeps",{"2":{"77":1,"84":1,"239":1,"247":1,"321":1,"376":1,"414":1,"459":1}}],["keep",{"0":{"78":1,"451":1},"2":{"55":1,"76":1,"125":2,"213":1,"243":1,"255":1,"262":1,"271":1,"292":1,"299":1,"314":1,"360":1,"414":1,"419":2,"446":1,"465":1,"472":1,"476":1,"477":1,"517":1,"521":1}}],["keyframes",{"2":{"374":1}}],["keyword.",{"2":{"388":1,"435":1}}],["keyword",{"2":{"143":1,"288":1,"390":1,"392":1}}],["keymap",{"2":{"116":3}}],["keymap,",{"2":{"116":1}}],["keydown",{"2":{"116":8}}],["keyboardshortcutsmodal",{"2":{"117":1}}],["keyboard",{"0":{"114":1,"129":1,"175":1,"317":1,"361":1,"436":1},"1":{"362":1,"363":1,"364":1,"365":1,"366":1},"2":{"93":1,"94":2,"95":1,"96":2,"103":2,"104":1,"105":2,"110":1,"115":1,"116":4,"117":1,"120":1,"122":1,"130":1,"131":2,"175":1,"202":3,"248":1,"317":1,"343":1,"362":1,"374":1,"379":1,"384":1,"386":1,"436":1,"456":1,"475":1,"500":1}}],["keys:",{"2":{"420":1}}],["keys",{"2":{"79":1,"106":1,"417":2,"420":1}}],["keys,",{"2":{"74":1,"379":1}}],["key.",{"2":{"52":1}}],["key)",{"2":{"48":1}}],["key",{"0":{"91":1,"115":1,"341":1,"420":1},"2":{"32":1,"52":2,"53":1,"54":1,"69":1,"95":1,"218":1,"241":1,"369":1,"410":1,"417":3,"420":1,"464":1,"475":1}}],[".png,",{"2":{"503":1}}],[".png",{"2":{"503":2}}],[".pdf",{"2":{"503":1}}],[".nly",{"2":{"503":1}}],[".note",{"2":{"65":1,"214":1,"215":2,"219":1,"220":1,"221":1,"227":1,"235":1,"236":1,"501":1,"503":1}}],[".notes",{"0":{"242":1,"243":1},"2":{"43":1,"55":1,"66":2,"69":1,"75":1,"77":1,"96":1,"99":3,"107":1,"108":1,"117":3,"217":1,"227":1,"233":1,"239":1,"242":1,"243":1,"323":1,"341":1,"360":3,"414":3,"446":1,"474":1,"486":1,"502":1,"507":1}}],[".html",{"2":{"503":1}}],[".custom",{"2":{"374":1}}],[".csv",{"2":{"212":1,"225":1}}],[".exe",{"2":{"334":1}}],[".excalidraw",{"2":{"59":1,"155":1}}],[".*",{"2":{"278":1,"391":1}}],[".zip",{"2":{"221":1,"227":1,"228":1,"491":1,"501":1,"503":1}}],[".drawio.xml",{"2":{"154":1}}],[".drawio",{"2":{"154":1,"155":1}}],[".git",{"2":{"231":1,"488":1}}],[".gitignore",{"2":{"107":1,"360":1,"414":1}}],[".gif,",{"2":{"75":1,"487":1}}],[".",{"2":{"104":1,"105":1,"126":2,"533":1}}],[".wav,",{"2":{"75":1}}],[".webp",{"2":{"503":1}}],[".webp)",{"2":{"487":1}}],[".webp).",{"2":{"75":1}}],[".webm,",{"2":{"75":1}}],[".m4a).",{"2":{"75":1}}],[".mp3,",{"2":{"75":1}}],[".md",{"2":{"8":1,"19":1,"27":2,"65":1,"75":1,"216":1,"229":1,"233":1,"332":1,"340":1,"341":1,"389":1,"448":1,"486":1,"487":1,"488":1,"489":1,"526":1}}],[".svg,",{"2":{"75":1,"487":1}}],[".jpeg,",{"2":{"75":1}}],[".jpg,",{"2":{"75":1,"487":1,"503":1}}],["...",{"2":{"32":1,"85":1}}],["*",{"2":{"286":1,"325":1,"524":1}}],["*italic*",{"2":{"178":1,"196":1,"327":1}}],["*.png.",{"2":{"153":1}}],["*.drawio",{"2":{"153":1}}],["*.md).",{"2":{"27":1,"75":1}}],["*.md),",{"2":{"19":1}}],["*.md.",{"2":{"8":1}}],["*.md",{"2":{"8":1,"233":1}}],["**3",{"2":{"326":1}}],["**monday",{"2":{"326":1}}],["***both***",{"2":{"178":1}}],["**bold**",{"2":{"178":1,"196":1,"327":1}}],["**",{"2":{"75":1,"233":1}}],["*="..."}),",{"2":{"32":1}}],["8.",{"0":{"129":1,"301":1,"415":1,"429":1,"455":1,"472":1}}],["8b",{"2":{"52":1}}],["8:",{"0":{"39":1}}],["8",{"0":{"31":1},"1":{"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1},"2":{"29":1,"30":1,"49":1,"75":1,"119":1,"212":1,"225":1}}],["80%",{"2":{"11":1,"24":1,"372":1,"397":1}}],["jaccard",{"2":{"527":1}}],["java,",{"2":{"138":1}}],["javascript):",{"2":{"137":1}}],["javascript",{"2":{"137":1,"263":1}}],["javascript,",{"2":{"134":1,"138":1,"263":1}}],["j",{"2":{"365":1,"500":1}}],["j).",{"2":{"379":1,"507":1}}],["j)",{"2":{"253":1}}],["j.",{"2":{"226":1}}],["july",{"2":{"326":1}}],["just",{"2":{"307":1}}],["jump.",{"2":{"428":1}}],["jumps",{"2":{"472":1}}],["jumps.",{"2":{"374":1}}],["jumps,",{"2":{"171":1}}],["jump",{"2":{"157":1,"171":1,"172":1,"264":1,"265":1,"275":1,"388":1,"461":1,"525":1,"529":1}}],["junction",{"2":{"48":1}}],["js,",{"2":{"188":1}}],["jsx,",{"2":{"138":1,"188":1}}],["json,",{"2":{"134":1,"138":1,"188":1}}],["json",{"2":{"20":1,"59":1,"71":1,"155":1,"372":1,"484":1,"489":2}}],["journal",{"2":{"43":1,"55":1}}],["joins,",{"2":{"9":1}}],["+",{"2":{"18":1,"24":1,"35":1,"38":2,"119":1,"136":1,"155":2,"158":2,"161":2,"163":2,"164":1,"174":2,"175":18,"178":1,"201":1,"202":1,"208":2,"210":1,"217":1,"221":1,"226":1,"233":1,"248":1,"253":4,"254":4,"257":1,"283":1,"285":1,"286":1,"291":2,"296":2,"317":1,"323":1,"325":1,"328":1,"340":1,"343":4,"349":1,"352":2,"362":16,"363":21,"364":3,"365":5,"366":15,"379":6,"388":3,"389":2,"403":2,"404":2,"418":2,"423":1,"425":1,"434":2,"444":2,"445":2,"455":2,"462":1,"463":1,"464":2,"466":2,"473":2,"474":1,"475":1,"482":4,"494":2,"500":3,"507":1,"514":1,"517":4,"524":1,"526":8,"527":2,"530":2,"532":2,"536":1}}],[">",{"2":{"11":2,"143":4,"186":2,"187":12,"194":3}}],["):",{"2":{"75":1,"84":1}}],[");",{"2":{"69":1}}],["),",{"2":{"20":1,"36":1,"65":2}}],[")",{"0":{"11":1,"24":1},"2":{"61":1,"202":1,"231":1,"475":1,"488":1}}],[").",{"2":{"1":1,"2":1,"248":1,"317":1,"539":1}}],["v2",{"2":{"143":1}}],["vs",{"0":{"491":2},"2":{"75":1,"106":1,"107":2,"116":1,"117":7,"173":1,"253":3,"356":1,"366":1,"379":3,"477":1}}],["vs.",{"2":{"49":1}}],["varied",{"2":{"412":1}}],["variable",{"0":{"542":1},"2":{"415":2,"542":1}}],["variables:",{"2":{"538":1}}],["variables)",{"0":{"538":1}}],["variables",{"0":{"415":1},"2":{"58":1,"415":1}}],["variation.",{"2":{"412":1}}],["variations",{"2":{"38":1}}],["var(",{"2":{"374":1}}],["valuable",{"2":{"104":1}}],["values",{"2":{"49":1,"54":1,"415":1}}],["value",{"0":{"123":1},"2":{"32":1}}],["validates",{"2":{"88":1}}],["validated.",{"2":{"93":1}}],["validated",{"2":{"84":1}}],["validate",{"2":{"82":1,"85":1,"146":1,"199":1,"449":1}}],["validation.",{"2":{"261":1}}],["validation,",{"2":{"95":1,"165":1}}],["validation:",{"2":{"85":1}}],["validation",{"0":{"45":1,"49":1,"172":1,"199":1,"272":1,"273":1},"1":{"46":1,"47":1,"48":1,"49":1,"273":1,"274":1,"275":1},"2":{"66":1,"85":1,"172":2,"199":1,"374":2,"449":1,"463":1}}],["valid",{"2":{"47":1,"339":1}}],["vowel;",{"2":{"36":1}}],["v1",{"2":{"35":1,"54":1,"66":1}}],["v1.5)",{"2":{"38":1,"66":1,"410":1}}],["v1.5",{"2":{"26":1,"53":1}}],["visibility.",{"2":{"499":1}}],["visibility",{"2":{"107":1,"281":1}}],["visible",{"2":{"99":1,"116":2,"321":1,"374":2}}],["visuals.",{"2":{"460":1}}],["visualizer",{"2":{"508":1}}],["visualized",{"2":{"25":1}}],["visualization.",{"2":{"516":1}}],["visualization",{"2":{"411":1}}],["visual,",{"2":{"353":1}}],["visually",{"2":{"303":1,"469":1}}],["visually.",{"2":{"145":1,"492":1}}],["visual",{"2":{"59":1,"145":1,"147":1,"155":2,"160":1,"205":1,"212":1,"266":1,"281":1,"376":1,"399":1,"492":1,"509":1,"516":1,"531":1}}],["video,",{"2":{"501":1}}],["videos,",{"2":{"281":1}}],["video",{"2":{"75":1}}],["vitepress:",{"2":{"369":1}}],["vitepress",{"2":{"89":1}}],["vite",{"2":{"87":1,"88":1}}],["vite.",{"2":{"83":1}}],["vite,",{"2":{"58":1,"84":1}}],["vitest",{"2":{"13":1,"90":1}}],["virtual",{"2":{"44":1}}],["views.",{"2":{"522":1}}],["views,",{"2":{"498":1}}],["views",{"0":{"494":1,"515":1},"1":{"495":1,"496":1,"497":1},"2":{"453":1}}],["viewport",{"2":{"380":1}}],["view:",{"2":{"353":1,"515":2,"525":1}}],["view).",{"2":{"474":1}}],["view)",{"2":{"258":1}}],["viewing,",{"2":{"518":1}}],["viewing",{"2":{"171":1,"320":1,"520":1,"525":1}}],["view,page",{"1":{"487":1}}],["view,how",{"1":{"484":1,"485":1}}],["view,",{"0":{"366":1},"2":{"59":1,"212":1}}],["view.",{"2":{"59":1,"213":1,"262":1,"424":1,"440":1,"446":1,"449":1,"489":1,"498":1}}],["viewer.",{"2":{"354":1}}],["viewer:",{"2":{"353":1}}],["viewer",{"2":{"12":1,"28":1,"95":1}}],["view",{"0":{"166":1,"201":1,"254":1,"398":1,"399":1,"434":1,"481":1,"482":1,"487":1,"491":1,"495":1,"496":1,"497":1},"1":{"399":1,"400":1,"482":1,"483":1,"486":1,"488":1,"489":1,"490":1,"491":1},"2":{"12":1,"20":2,"59":1,"75":1,"95":1,"96":4,"106":1,"107":1,"116":11,"158":2,"161":1,"163":1,"164":1,"165":1,"201":1,"205":2,"254":1,"256":1,"265":1,"266":1,"267":2,"268":4,"274":1,"286":1,"291":1,"318":1,"328":2,"356":1,"358":1,"366":5,"379":1,"381":1,"397":1,"399":3,"400":1,"403":1,"404":1,"406":1,"407":1,"427":1,"428":1,"429":1,"457":2,"463":1,"472":3,"473":1,"481":2,"482":1,"484":1,"485":1,"486":1,"491":2,"492":1,"494":1,"507":1,"514":1,"515":2,"530":1,"536":2,"537":1}}],["via:",{"2":{"500":1}}],["via",{"0":{"154":1},"2":{"10":1,"34":1,"42":1,"46":1,"48":1,"49":1,"53":1,"54":1,"57":1,"65":2,"66":1,"71":1,"96":2,"137":4,"172":1,"187":1,"223":1,"225":2,"226":1,"228":1,"232":1,"270":1,"410":1,"482":1,"487":1,"507":1,"530":1}}],["very",{"2":{"213":1,"453":1}}],["verdict",{"0":{"100":1}}],["version.",{"2":{"464":1,"484":1}}],["versioned,",{"2":{"355":1}}],["version,",{"2":{"354":1}}],["versioning",{"2":{"290":1}}],["versions",{"2":{"106":1,"116":1,"230":1,"244":2,"351":1,"366":1,"419":1}}],["version",{"0":{"63":1,"289":1,"355":1,"464":1},"1":{"290":1,"291":1,"292":1,"356":1},"2":{"77":1,"78":1,"92":1,"95":1,"96":1,"108":1,"120":1,"175":1,"243":1,"270":1,"290":1,"291":1,"292":1,"318":1,"345":1,"349":1,"350":1,"355":1,"358":1,"360":1,"390":2,"414":1,"454":1,"464":1,"475":1,"507":1}}],["versatile,",{"2":{"52":1}}],["vercel",{"2":{"52":1,"66":1}}],["verifies",{"2":{"65":1,"218":1}}],["verified",{"0":{"95":1},"2":{"65":1,"85":1,"95":1,"234":2}}],["verification.",{"2":{"93":1}}],["verification",{"0":{"13":1},"2":{"13":1,"218":1}}],["verify",{"2":{"28":1,"52":1,"219":1,"235":1,"354":1,"410":1,"439":1,"450":1,"451":1}}],["verb:",{"2":{"477":1}}],["verbs",{"2":{"36":1}}],["verb",{"2":{"36":2,"46":1}}],["verbatim,",{"2":{"24":1}}],["verbatim",{"2":{"11":1}}],["verbosity,",{"2":{"8":1,"19":1}}],["vectors",{"2":{"38":1,"417":1}}],["vectors.",{"2":{"26":1}}],["vector",{"0":{"38":1,"43":1},"1":{"44":1},"2":{"7":1,"29":1,"30":1,"38":1,"50":1,"51":1,"53":2,"66":4,"70":1,"75":1,"84":1,"223":1,"410":1}}],["y",{"2":{"363":1}}],["yyyy.zip.",{"2":{"231":1}}],["yes.",{"2":{"244":1}}],["yes,",{"2":{"120":1}}],["yes",{"2":{"96":62,"116":5,"240":1}}],["yet,",{"2":{"499":1}}],["yet",{"2":{"94":1}}],["you\'ll",{"2":{"330":1}}],["you:",{"2":{"19":1}}],["you",{"2":{"15":1,"16":1,"20":1,"77":1,"79":2,"80":2,"81":1,"134":1,"135":1,"137":2,"141":1,"150":2,"151":1,"159":1,"162":1,"164":2,"166":1,"168":1,"169":1,"172":1,"203":1,"205":1,"206":1,"207":1,"208":1,"211":1,"238":1,"239":1,"240":1,"241":1,"247":3,"255":1,"256":2,"269":1,"270":1,"271":2,"273":1,"274":1,"275":2,"278":5,"280":1,"287":1,"296":1,"298":1,"299":2,"303":2,"305":1,"308":1,"309":1,"322":1,"324":1,"328":2,"330":3,"334":1,"338":1,"347":2,"348":1,"349":1,"351":1,"356":1,"368":3,"386":2,"387":1,"389":1,"394":1,"396":2,"400":1,"407":2,"411":1,"413":1,"414":1,"416":1,"419":1,"421":1,"438":1,"446":1,"452":1,"453":1,"454":2,"461":1,"465":1,"466":1,"473":1,"484":1,"485":2,"490":1,"491":1,"504":1,"505":1,"506":1,"508":1,"513":2,"515":1,"520":1,"525":1,"531":1,"532":1,"533":1,"538":1,"539":1}}],["yourself.",{"2":{"77":1}}],["your",{"0":{"78":1,"324":1,"328":1,"340":1,"461":1},"1":{"325":1,"326":1,"327":1,"328":1,"329":1,"330":1,"331":1},"2":{"7":1,"14":1,"16":1,"17":1,"53":1,"54":1,"55":1,"76":1,"77":2,"78":1,"137":4,"142":1,"145":1,"146":1,"147":1,"148":2,"149":1,"153":1,"164":1,"170":1,"171":1,"172":2,"185":1,"205":1,"207":1,"211":1,"212":1,"223":1,"227":1,"238":1,"239":1,"243":1,"247":1,"252":1,"263":1,"274":1,"278":1,"283":1,"284":1,"290":1,"292":1,"294":1,"325":1,"326":1,"330":1,"332":2,"335":1,"336":1,"340":3,"341":1,"342":1,"345":1,"346":2,"347":1,"348":1,"354":1,"356":1,"357":1,"358":1,"360":1,"391":1,"392":2,"396":1,"397":1,"410":2,"413":1,"414":2,"418":1,"420":1,"427":1,"438":1,"450":1,"452":1,"454":1,"457":1,"461":2,"463":1,"464":1,"465":1,"466":1,"473":1,"481":2,"482":1,"491":1,"500":1,"501":2,"504":1,"505":1,"506":2,"507":1,"512":2,"515":1,"517":1,"518":1,"519":1,"520":1,"521":1,"526":1,"531":1,"532":1,"535":1,"536":1,"537":2,"539":1}}],["yaml,",{"2":{"134":1,"138":1,"188":1}}],["yaml",{"2":{"8":1,"19":1,"27":1}}],["quotes",{"2":{"135":1}}],["queue:",{"2":{"499":1}}],["queue",{"2":{"42":1,"44":1,"50":1}}],["queues.",{"2":{"55":1}}],["queues",{"2":{"26":1}}],["question,",{"2":{"17":1}}],["queries,",{"2":{"70":1}}],["queries",{"2":{"3":1,"6":1,"23":1,"502":1}}],["query.",{"2":{"6":1}}],["queryexecutor",{"2":{"2":1}}],["query",{"2":{"1":1,"2":1,"3":1,"4":1}}],["quick,",{"2":{"421":1}}],["quicker",{"2":{"376":1}}],["quickly,",{"2":{"460":1}}],["quickly:",{"2":{"256":1}}],["quickly.",{"2":{"252":1,"264":1,"275":1,"465":1,"515":1}}],["quickly?",{"0":{"245":1}}],["quickly",{"0":{"475":1},"2":{"81":1,"157":1,"361":1,"374":1,"399":1,"447":1,"495":1}}],["quick",{"0":{"275":1,"327":1,"454":1},"2":{"15":1,"82":1,"95":1,"195":1,"254":1,"258":1,"261":1,"283":1,"287":1,"288":1,"306":1,"329":1,"337":1,"374":1,"436":1,"472":1,"498":1,"499":1,"500":1,"501":1,"513":1}}],["quality:",{"2":{"94":1,"100":1}}],["quality",{"0":{"36":1,"45":1,"46":1,"119":1,"199":1,"272":1},"1":{"46":1,"47":1,"48":1,"49":1,"273":1,"274":1,"275":1},"2":{"7":1,"105":1,"107":1,"119":2,"130":1,"131":1,"274":1,"321":1}}],["[timestamp].md.",{"2":{"419":1}}],["[text](url)",{"2":{"197":1,"327":1}}],["[note",{"2":{"419":1}}],["[a",{"2":{"278":1}}],["[^1]:",{"2":{"191":1}}],["[!caution]",{"2":{"187":1}}],["[!important]",{"2":{"187":1}}],["[!todo]",{"2":{"187":1}}],["[!tip]",{"2":{"187":1}}],["[!warning]",{"2":{"187":1}}],["[!note]",{"2":{"187":2}}],["[relative",{"2":{"184":1}}],["[link",{"2":{"184":1}}],["[x]",{"2":{"183":1,"326":1,"327":1,"473":1,"523":1,"526":2}}],["[0,",{"2":{"49":1}}],["[",{"2":{"7":1,"183":2,"197":1,"283":1,"286":3,"326":2,"327":1,"473":1,"523":3,"524":6,"525":1,"526":1}}],["[\\"graph",{"2":{"6":1}}],["});",{"2":{"85":1}}],["}",{"2":{"6":1,"7":1,"85":1,"188":1}}],["\\"optional",{"2":{"185":1}}],["\\"hover",{"2":{"184":1}}],["\\"mychannel\\");",{"2":{"85":1}}],["\\"add",{"2":{"11":1}}],["\\"accepted\\":",{"2":{"7":1}}],["\\"explain",{"2":{"11":1}}],["\\"below",{"2":{"7":1}}],["\\"rejectedreason\\":",{"2":{"7":1}}],["\\"rejectedstrategies\\":",{"2":{"6":1}}],["\\"notes.extract",{"2":{"7":1}}],["\\"similarityscore\\":",{"2":{"7":1}}],["\\"sourcetype\\":",{"2":{"7":1}}],["\\"selectedstrategy\\":",{"2":{"6":1}}],["\\"task",{"2":{"6":1}}],["\\"confidence\\":",{"2":{"6":1}}],["\\"workspace",{"2":{"6":1}}],["\\"intent\\":",{"2":{"6":1}}],["urgent).",{"2":{"525":1}}],["url",{"2":{"197":1,"346":2,"359":1}}],["urls",{"2":{"66":1}}],["url.",{"2":{"52":1,"410":1}}],["udp",{"2":{"417":2}}],["uml",{"2":{"152":1}}],["ux",{"0":{"124":1,"476":1},"1":{"477":1,"478":1,"479":1,"480":1},"2":{"104":1}}],["utilities",{"2":{"516":1,"535":1}}],["utilityprocess",{"2":{"84":1}}],["utility",{"2":{"84":1,"339":1}}],["utf",{"2":{"75":1,"212":1,"225":1}}],["updating",{"2":{"526":1}}],["updated",{"2":{"103":2,"174":1,"383":1,"385":1}}],["updates",{"0":{"383":1,"384":1,"385":1},"2":{"93":1,"159":1,"168":1,"271":1,"490":1,"502":1,"526":1}}],["updates.",{"2":{"70":1,"174":1,"303":1,"375":1,"439":1}}],["updates,",{"2":{"70":1,"336":1,"522":1}}],["update",{"2":{"19":1,"94":1,"131":1,"166":1,"167":1,"269":1,"278":1,"346":1,"350":1,"389":1,"459":1,"526":1}}],["upcoming:",{"2":{"499":1}}],["upcoming",{"2":{"492":1}}],["upon",{"2":{"368":1,"502":1}}],["upload",{"2":{"346":1}}],["upstream",{"2":{"346":1}}],["up:",{"2":{"305":1}}],["up.",{"2":{"303":1}}],["up",{"0":{"461":1},"2":{"78":1,"120":1,"223":1,"243":1,"247":1,"258":1,"298":1,"305":1,"326":1,"419":1}}],["ui:",{"2":{"477":1}}],["ui?",{"2":{"120":1}}],["ui.",{"2":{"104":1,"231":1}}],["ui;",{"2":{"96":1}}],["uistatecontext.jsx:",{"2":{"60":1}}],["ui)",{"2":{"57":1}}],["ui,",{"2":{"36":1,"93":1}}],["ui",{"0":{"12":1,"71":1,"372":1},"2":{"19":1,"37":1,"67":1,"75":1,"94":1,"99":1,"100":1,"103":1,"104":1,"105":1,"116":2,"117":2,"131":1,"162":1,"369":1,"383":1,"397":1,"526":1}}],["uicontext).",{"2":{"9":1}}],["unnecessarily.",{"2":{"402":1}}],["unused",{"0":{"440":1},"2":{"298":2,"440":2,"453":1,"521":1}}],["unfinished",{"2":{"284":1}}],["unchecked",{"2":{"256":1,"283":1,"513":1}}],["unclipped",{"2":{"212":1,"225":1}}],["unpack",{"2":{"215":1}}],["unordered",{"0":{"181":1},"2":{"197":1}}],["unresponsive",{"0":{"456":1}}],["unresolved.",{"2":{"110":1}}],["unreachable",{"2":{"419":1}}],["unrelated",{"2":{"7":1}}],["undo",{"2":{"116":1,"363":1,"374":2}}],["undocumented.",{"2":{"96":13,"111":2,"112":5,"113":1,"116":16,"120":1}}],["undocumented",{"2":{"94":1,"96":2,"106":1,"110":1,"116":6}}],["underneath",{"2":{"303":1}}],["underlines",{"2":{"172":1}}],["understanding,",{"2":{"306":1}}],["understand",{"2":{"81":1,"120":2,"394":1}}],["under",{"2":{"13":1,"15":1,"17":1,"96":1,"103":1,"104":1,"106":1,"274":1,"349":1,"356":1,"367":1,"368":2,"374":1,"533":1}}],["unavailable",{"2":{"99":1,"117":1}}],["unauthorized",{"2":{"85":1}}],["unassignedcommunities",{"2":{"49":1}}],["unassigned",{"2":{"49":1}}],["unscheduled",{"2":{"499":1}}],["unsigned",{"2":{"339":1}}],["unsupported",{"2":{"236":1,"263":1}}],["unstaged",{"2":{"63":1,"292":1,"347":1,"349":1}}],["unsaved",{"2":{"60":1,"173":1,"330":2,"485":1,"526":1}}],["unlike",{"2":{"481":1}}],["unlinked",{"2":{"50":1}}],["unlocking",{"2":{"218":1}}],["unless",{"2":{"6":1,"247":1,"339":1,"446":1,"507":1}}],["unique",{"2":{"417":1}}],["unix",{"2":{"407":1}}],["unified",{"2":{"227":1,"380":1}}],["unit",{"2":{"90":1}}],["unit,",{"2":{"90":1}}],["union",{"2":{"39":1}}],["universal",{"0":{"36":1,"46":1},"2":{"36":1,"116":1}}],["usb",{"2":{"334":1,"337":1}}],["usable.",{"2":{"119":1}}],["usable",{"2":{"102":1}}],["usage:",{"2":{"104":1}}],["usage",{"2":{"96":1,"107":1,"108":2,"372":1,"384":1}}],["usually",{"2":{"77":1,"241":1,"243":1}}],["useful,",{"2":{"104":1}}],["useful",{"2":{"104":2,"119":1,"168":1,"287":1,"404":1,"406":1,"506":1}}],["used",{"2":{"93":1,"115":3,"216":1,"252":1,"298":1,"321":1,"386":1,"461":1,"480":1}}],["use.",{"2":{"80":1,"438":1}}],["uses",{"2":{"30":1,"54":1,"90":1,"96":1,"99":1,"104":1,"117":3,"118":1,"197":1,"236":1,"325":1,"346":1,"381":1,"396":2,"407":1,"527":2,"537":2}}],["use",{"0":{"80":1,"81":1,"288":1,"329":1,"467":1},"1":{"468":1,"469":1,"470":1,"471":1},"2":{"8":1,"20":1,"27":1,"80":1,"96":1,"104":1,"108":1,"120":1,"133":1,"143":1,"157":1,"159":1,"163":1,"177":2,"179":1,"192":1,"206":1,"208":1,"213":1,"215":1,"216":1,"236":1,"240":1,"244":1,"245":1,"247":1,"252":2,"263":1,"265":1,"266":1,"267":3,"278":1,"279":1,"286":1,"287":1,"296":1,"297":1,"306":1,"308":1,"320":1,"325":1,"340":1,"361":1,"368":1,"374":2,"376":1,"380":1,"386":1,"394":1,"396":1,"397":1,"400":1,"407":2,"411":1,"412":2,"414":1,"421":1,"424":1,"425":1,"430":1,"431":1,"432":1,"436":1,"439":1,"447":1,"453":1,"460":1,"461":1,"462":1,"463":2,"464":1,"465":1,"473":1,"477":2,"491":1,"517":1}}],["users,",{"2":{"131":1}}],["users:",{"2":{"100":1}}],["users.",{"2":{"96":1,"99":1,"119":1,"232":1}}],["users",{"0":{"386":1},"2":{"59":1,"105":1,"214":1,"339":1}}],["user",{"0":{"71":1,"120":1,"460":1},"1":{"461":1,"462":1,"463":1,"464":1,"465":1,"466":1,"467":1,"468":1,"469":1,"470":1,"471":1,"472":1,"473":1,"474":1,"475":1},"2":{"3":1,"8":1,"11":2,"54":1,"58":1,"65":1,"74":1,"75":1,"93":1,"94":2,"95":2,"99":4,"103":2,"104":4,"110":1,"116":2,"118":1,"120":2,"123":1,"125":1,"130":1,"131":1,"143":1,"246":1,"250":1,"336":1,"383":1,"411":1,"415":1,"541":2,"542":1}}],["using",{"0":{"159":1,"286":1},"2":{"2":1,"11":1,"26":1,"29":1,"35":1,"39":1,"43":1,"50":2,"52":1,"53":1,"56":1,"66":2,"79":1,"135":1,"137":2,"141":1,"164":1,"166":1,"187":1,"199":1,"218":1,"227":1,"263":1,"285":1,"312":1,"321":1,"326":1,"328":1,"356":1,"369":1,"374":1,"388":1,"391":1,"417":1,"419":1,"459":1,"463":1,"509":1,"511":1,"521":1,"523":1,"532":1,"538":1}}],["gcm",{"2":{"417":2}}],["g",{"2":{"362":1}}],["guidance,",{"2":{"105":1}}],["guidance",{"2":{"94":1,"96":1,"99":1,"118":2}}],["guided",{"2":{"105":1,"119":1}}],["guide.",{"2":{"104":1,"116":3,"120":1,"123":1}}],["guide.md:",{"2":{"118":1}}],["guide.md",{"2":{"104":2}}],["guide,7.",{"1":{"468":1,"469":1,"470":1,"471":1}}],["guide,blockquotes",{"1":{"187":1}}],["guide,lists",{"1":{"181":1,"182":1,"183":1}}],["guide,",{"2":{"103":1,"125":1}}],["guide",{"0":{"129":1,"176":1,"460":1,"476":1},"1":{"177":1,"178":1,"179":1,"180":1,"184":1,"185":1,"186":1,"188":1,"189":1,"190":1,"191":1,"192":1,"193":1,"194":1,"461":1,"462":1,"463":1,"464":1,"465":1,"466":1,"467":1,"472":1,"473":1,"474":1,"475":1,"477":1,"478":1,"479":1,"480":1},"2":{"76":1,"94":1,"96":1,"110":1,"115":1,"117":1,"120":2,"122":1,"130":2,"131":1,"188":1,"189":1,"194":1,"200":1,"248":1,"324":1,"327":1,"331":1,"362":1,"384":1,"386":1,"460":1}}],["guards",{"2":{"85":1,"542":1}}],["guard",{"0":{"85":1}}],["gantt",{"2":{"59":1,"143":2,"194":1}}],["gate",{"0":{"36":1,"46":1}}],["gfm",{"2":{"59":1,"487":1}}],["give",{"2":{"368":1}}],["gitlab,",{"2":{"346":1}}],["git?",{"0":{"243":1,"356":1}}],["git]",{"2":{"143":1,"194":1}}],["git,npm,node,dir,ls).",{"2":{"542":1}}],["git,npm,node).",{"2":{"415":1}}],["git,",{"2":{"75":2,"390":1}}],["git:",{"2":{"70":1,"369":1}}],["git",{"0":{"63":1,"144":1,"289":1,"290":1,"355":1,"357":1,"414":1,"464":1},"1":{"290":1,"291":1,"292":1,"356":1,"358":1,"359":1,"360":1},"2":{"63":2,"70":1,"95":1,"96":1,"99":1,"103":1,"104":1,"108":1,"111":1,"117":1,"243":1,"290":2,"333":2,"342":2,"346":2,"350":1,"355":2,"356":3,"357":1,"358":4,"359":1,"360":1,"369":1,"414":3,"415":2,"464":1,"517":1,"535":1,"537":1,"538":2}}],["github,",{"2":{"346":1}}],["github.",{"2":{"334":1}}],["github",{"0":{"187":1},"2":{"59":1,"176":1,"187":1,"356":1,"491":1,"506":1}}],["gitvc),",{"2":{"59":1}}],["gibberish,",{"2":{"46":1}}],["gpt",{"2":{"52":1,"410":1}}],["gliner2relexadapter.js",{"2":{"35":1}}],["gliner2",{"0":{"35":1},"2":{"35":1,"54":3}}],["glance",{"0":{"22":1},"1":{"23":1,"24":1,"25":1,"26":1,"27":1,"28":1}}],["global,",{"2":{"129":1,"248":1}}],["global",{"0":{"15":1,"74":1,"277":1,"362":1,"389":1},"1":{"16":1,"17":1,"390":1},"2":{"15":1,"60":1,"72":1,"74":1,"95":1,"96":2,"102":1,"108":1,"115":1,"116":8,"278":1,"362":6,"365":1,"389":1,"392":1,"417":1,"435":1,"500":1}}],["goes",{"2":{"187":1}}],["go,",{"2":{"134":1,"138":1,"188":1}}],["good:",{"2":{"480":3}}],["good",{"2":{"96":1,"100":1,"104":3}}],["google",{"2":{"52":1}}],["golden",{"2":{"91":1}}],["go",{"2":{"20":1,"215":1,"247":1,"325":1,"334":1,"446":1,"461":1,"474":1}}],["gemini,",{"2":{"410":1}}],["gemini",{"2":{"52":1,"99":1}}],["gemini:",{"2":{"52":1}}],["generally",{"2":{"105":1}}],["generating",{"2":{"92":1}}],["generation.",{"2":{"92":1}}],["generation,",{"2":{"63":1,"95":1}}],["generation:",{"2":{"54":1}}],["generation",{"0":{"6":1,"29":1,"52":1,"412":1},"1":{"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1},"2":{"29":1,"54":1,"84":1,"92":1,"107":1,"486":1}}],["generate",{"2":{"92":1,"106":1,"122":1,"393":1,"411":1,"418":1,"420":1}}],["generates",{"2":{"39":1,"47":1,"92":1,"417":1,"506":1}}],["generates,",{"2":{"34":1}}],["generated",{"2":{"11":1,"65":1,"131":1,"217":1,"233":1}}],["generic",{"2":{"37":1,"65":1,"68":1,"95":1,"218":1,"234":1}}],["getting",{"0":{"332":1},"1":{"333":1,"334":1,"335":1,"336":1,"337":1,"338":1,"339":1,"340":1,"341":1,"342":1,"343":1},"2":{"310":1}}],["gets",{"0":{"217":1},"2":{"233":1}}],["get",{"0":{"475":1},"2":{"7":1,"105":1,"288":1,"484":6,"486":1}}],["greeted",{"2":{"513":1}}],["greet(name)",{"2":{"188":1}}],["green",{"2":{"353":1}}],["grid.",{"2":{"516":1}}],["grid:",{"2":{"208":1}}],["grid",{"2":{"203":1,"205":1,"206":1,"210":1,"213":1,"262":1,"375":1,"463":1,"496":1,"515":1}}],["granular",{"2":{"497":1}}],["grained",{"2":{"356":1}}],["grade",{"2":{"131":1}}],["grammatical",{"2":{"36":1,"46":1}}],["graphics",{"2":{"59":1}}],["graphmaintenance",{"2":{"42":1}}],["graphworker",{"2":{"42":1,"50":1}}],["graph.db:",{"2":{"55":1,"75":1}}],["graph.db",{"2":{"43":1}}],["graph.db.",{"2":{"25":1,"66":1}}],["graph.",{"2":{"39":1,"439":1}}],["graphdb.js):",{"2":{"66":1}}],["graphdb.js",{"2":{"39":1}}],["graphdb",{"2":{"38":1}}],["graph:",{"2":{"36":1,"70":1,"509":1,"516":1}}],["graph:traverse).",{"2":{"5":1}}],["graphrag",{"2":{"29":1}}],["graph):",{"2":{"41":1}}],["graph)",{"2":{"6":1}}],["graph",{"0":{"25":1,"29":1,"45":1,"54":1,"81":1,"281":1,"439":1,"508":1,"509":1},"1":{"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"509":1,"510":1,"511":1},"2":{"4":1,"6":2,"7":2,"13":2,"29":2,"35":1,"43":1,"44":1,"49":1,"50":1,"54":3,"66":2,"70":2,"71":1,"75":1,"81":1,"84":1,"95":1,"96":1,"102":1,"104":1,"106":2,"116":1,"120":2,"143":3,"164":1,"194":1,"281":3,"305":1,"362":1,"410":1,"411":3,"439":1,"453":1,"472":1,"508":1,"509":1,"511":1}}],["graph,",{"2":{"4":1,"7":1,"23":1,"75":1,"95":1,"372":1}}],["groq,",{"2":{"66":1,"410":1}}],["groq",{"2":{"52":1,"99":1}}],["groq:",{"2":{"52":1}}],["groq"",{"2":{"35":1}}],["group",{"2":{"257":1,"281":1,"286":1,"462":1,"514":1}}],["grouped",{"2":{"255":1,"286":1,"287":1,"379":1}}],["groups",{"2":{"50":1}}],["grounding,",{"2":{"23":1,"372":1}}],["grounding",{"2":{"9":1}}],["groundingengine.",{"2":{"2":1}}],["grounding.spec.js:",{"2":{"13":1}}],["grounding.",{"2":{"0":1}}],["nc",{"2":{"367":1}}],["nsis",{"0":{"336":1}}],["nicely",{"2":{"270":1}}],["n).",{"2":{"257":1,"423":1,"462":1,"514":1}}],["n",{"2":{"175":1,"325":1,"362":1,"363":1}}],["nginx,",{"2":{"138":1}}],["npm",{"2":{"89":1,"90":3}}],["number",{"2":{"269":1,"286":1,"525":1,"527":1}}],["numbers)",{"2":{"491":1}}],["numbers",{"2":{"136":1,"487":1}}],["numbers,",{"2":{"36":1,"59":1}}],["numbered",{"2":{"103":1,"486":1,"523":1,"524":1}}],["null",{"2":{"69":1}}],["null,",{"2":{"69":2}}],["navigable,",{"2":{"481":1}}],["navigating",{"0":{"509":1},"2":{"374":1}}],["navigation.",{"2":{"481":1,"486":1}}],["navigation",{"0":{"126":1,"265":1,"271":1,"362":1},"2":{"59":1,"119":1,"157":1,"164":1,"171":1,"374":1,"379":1,"491":1,"494":1}}],["navigation,",{"2":{"59":1,"486":1}}],["navigate.",{"2":{"177":1}}],["navigate:",{"2":{"171":1}}],["navigate",{"0":{"472":1},"2":{"168":1,"271":1,"286":1,"347":1,"350":1,"361":1,"374":1}}],["naming.",{"2":{"104":2}}],["naming",{"2":{"93":1,"105":1,"117":2,"325":1}}],["name.",{"2":{"423":1,"424":1}}],["name].sync",{"2":{"419":1}}],["named",{"2":{"231":1}}],["name:",{"2":{"133":1}}],["name)),",{"2":{"44":1}}],["names",{"2":{"37":1,"98":1,"325":1,"386":1,"465":1}}],["name",{"2":{"34":1,"38":1,"49":1,"325":1}}],["name,",{"2":{"8":1,"44":2}}],["native,",{"2":{"355":1}}],["native",{"0":{"290":1},"2":{"43":1,"63":1,"227":1,"253":1,"290":1,"339":2,"379":1,"416":1,"464":1,"502":1,"537":1}}],["natural",{"2":{"32":1,"33":1}}],["nlp",{"2":{"11":1,"13":1,"372":1}}],["neighbors.",{"2":{"509":1}}],["netlify.",{"2":{"506":1}}],["netlify,",{"2":{"491":1}}],["network.",{"2":{"241":1}}],["network",{"0":{"417":1},"2":{"10":1,"64":1,"90":1,"152":1,"155":1,"249":1,"333":1,"417":2}}],["never",{"2":{"219":1,"235":1,"484":1}}],["nested",{"2":{"168":1,"181":2}}],["new",{"0":{"374":1,"379":1,"423":1},"2":{"105":1,"106":1,"116":1,"120":1,"175":1,"179":1,"208":1,"257":1,"325":2,"342":1,"345":1,"354":1,"363":1,"379":2,"385":1,"420":1,"423":1,"459":1,"462":1,"514":3}}],["newline",{"2":{"9":1}}],["nearly",{"2":{"103":1}}],["needing",{"2":{"485":1}}],["needed:",{"2":{"221":1}}],["needed",{"2":{"206":1}}],["needed.",{"2":{"80":1,"294":1,"334":1,"433":1,"446":1,"450":1,"465":1}}],["need",{"2":{"77":1,"120":1,"164":1,"206":1,"241":1,"287":1,"339":1,"342":1,"347":1,"396":1,"446":1,"453":1,"454":1,"473":1}}],["needs",{"2":{"5":1,"241":1}}],["neural",{"0":{"35":1},"2":{"29":1,"30":1,"32":1,"33":1,"35":1,"49":1,"66":1,"411":1}}],["next.",{"2":{"479":1}}],["next?",{"0":{"331":1}}],["next",{"0":{"342":1},"2":{"19":1,"52":1,"116":1,"175":1,"286":1,"362":1,"364":1,"388":1,"425":1,"479":1,"490":1,"499":1}}],["no.",{"2":{"120":1,"243":1}}],["now",{"2":{"103":1,"279":1,"372":1,"374":4,"375":1,"376":2,"377":1,"379":2,"380":3,"381":2}}],["nowhere.",{"2":{"96":1}}],["normalization",{"2":{"374":1}}],["normalizes",{"2":{"135":1}}],["normalize",{"2":{"131":1}}],["normal",{"2":{"55":1,"279":1}}],["notices.txt",{"2":{"369":1}}],["notice.",{"2":{"187":1}}],["notion",{"2":{"187":1,"196":1}}],["notion,",{"2":{"169":1}}],["notifications.",{"2":{"270":1}}],["notification",{"2":{"169":1,"374":1}}],["not.",{"2":{"116":2,"120":1}}],["not",{"0":{"448":1,"450":1,"457":1,"458":1},"2":{"54":1,"69":5,"77":1,"79":1,"93":2,"94":1,"95":1,"96":5,"99":2,"100":1,"104":4,"105":3,"107":1,"115":1,"116":5,"117":1,"119":1,"120":3,"129":1,"146":2,"151":1,"193":1,"218":1,"220":1,"234":1,"243":1,"246":2,"253":1,"279":1,"307":1,"308":1,"333":1,"358":1,"368":1,"402":1,"414":1,"452":2,"482":1,"521":2}}],["note\'s",{"2":{"379":1,"434":1,"485":1,"489":1}}],["notepad).",{"2":{"339":1}}],["note".",{"2":{"478":1}}],["note"",{"2":{"286":1}}],["note](.",{"2":{"184":1}}],["note]",{"2":{"143":2}}],["note).",{"2":{"279":1,"325":2}}],["note)",{"2":{"37":1}}],["note:",{"2":{"16":1,"93":1,"271":1,"286":1,"471":1,"514":1,"517":1,"530":1}}],["note.md)",{"2":{"184":1}}],["note.",{"2":{"16":2,"148":1,"157":1,"168":1,"171":1,"244":1,"283":1,"352":1,"444":1,"464":2,"521":1,"525":1,"531":1}}],["note,step",{"1":{"327":1}}],["note,",{"2":{"15":1,"127":1,"136":1,"211":1,"269":1,"387":1,"477":1,"529":1}}],["note",{"0":{"15":1,"214":1,"222":1,"232":1,"257":1,"269":1,"324":1,"325":1,"328":1,"363":1,"388":1,"419":1,"423":1,"425":1,"426":1,"430":1,"434":1,"443":1,"444":1,"514":1,"528":1,"529":1},"1":{"16":1,"17":1,"215":1,"216":1,"217":1,"218":1,"219":1,"220":1,"223":1,"224":1,"225":1,"233":1,"234":1,"235":1,"325":1,"326":1,"328":1,"329":1,"330":1,"331":1,"529":1,"530":1},"2":{"12":1,"15":2,"16":1,"26":2,"34":2,"42":1,"44":1,"49":1,"50":1,"56":1,"62":1,"64":1,"65":2,"66":1,"75":2,"77":1,"78":1,"80":1,"81":1,"91":1,"94":1,"95":2,"96":5,"99":1,"103":2,"104":1,"106":1,"108":2,"112":1,"116":7,"117":1,"120":1,"124":1,"131":1,"137":1,"164":1,"169":1,"170":1,"171":1,"173":2,"174":1,"175":3,"177":2,"187":1,"199":1,"215":1,"217":1,"221":4,"222":1,"223":1,"229":2,"230":3,"232":1,"233":1,"236":1,"239":1,"240":1,"242":1,"254":3,"256":1,"257":2,"264":1,"270":2,"271":1,"277":2,"281":2,"283":1,"286":3,"287":1,"291":2,"303":1,"306":1,"320":1,"321":1,"324":1,"325":3,"326":1,"330":2,"341":2,"342":1,"349":1,"351":1,"352":1,"354":2,"356":1,"363":6,"364":2,"366":1,"374":2,"380":3,"388":1,"389":2,"402":1,"403":1,"408":1,"411":1,"417":1,"419":2,"423":2,"443":1,"451":1,"453":1,"458":1,"462":2,"464":1,"472":1,"473":1,"481":1,"482":3,"484":2,"486":2,"487":2,"489":1,"491":3,"502":1,"503":3,"509":2,"510":1,"513":1,"514":2,"515":3,"517":4,"520":1,"522":1,"523":1,"525":1,"526":2,"527":1,"529":1,"530":1}}],["notes?",{"0":{"244":1}}],["notes]",{"2":{"194":1}}],["notes.",{"2":{"59":1,"111":1,"147":1,"164":1,"165":1,"168":1,"238":1,"256":1,"257":1,"260":1,"265":1,"271":1,"279":1,"303":1,"340":1,"390":1,"399":1,"462":1,"472":1,"510":1,"513":1,"518":1,"530":1}}],["notes,2026",{"1":{"372":1,"374":1,"376":1,"377":1,"379":1,"380":1,"381":1,"383":1,"384":1,"385":1}}],["notes,",{"2":{"29":1,"95":1,"129":1,"238":1,"240":1,"242":1,"279":1,"348":1,"349":1,"374":1,"460":1,"506":1}}],["notes:",{"2":{"11":1,"132":1,"137":1,"268":1,"346":1,"399":2,"465":1,"473":1,"489":1,"513":1}}],["notes:search,",{"2":{"5":1}}],["notes)",{"2":{"7":1}}],["notes",{"0":{"78":1,"82":1,"251":1,"354":1,"370":1,"386":1,"435":1,"448":1,"459":1,"462":1,"466":1,"473":1,"523":1},"1":{"252":1,"253":1,"254":1,"255":1,"256":1,"257":1,"258":1,"371":1,"373":1,"375":1,"378":1,"382":1,"386":1,"524":1},"2":{"0":1,"7":1,"11":1,"17":1,"65":1,"75":1,"77":1,"78":1,"79":1,"81":2,"94":1,"95":1,"96":3,"99":2,"103":1,"104":1,"116":5,"117":1,"118":5,"119":1,"120":1,"123":1,"164":2,"171":1,"196":1,"197":1,"200":1,"214":1,"215":1,"216":1,"219":2,"220":1,"221":1,"224":1,"230":1,"232":1,"233":2,"235":2,"236":1,"239":1,"244":1,"252":1,"255":1,"256":1,"257":2,"258":1,"268":1,"281":2,"283":1,"284":1,"288":2,"294":1,"299":2,"307":1,"321":2,"323":1,"325":1,"326":2,"330":1,"332":2,"340":1,"341":2,"343":1,"359":1,"361":1,"362":1,"363":3,"364":1,"365":1,"366":1,"383":1,"384":1,"385":1,"386":1,"393":1,"399":2,"400":1,"411":1,"414":1,"415":1,"416":1,"445":1,"458":1,"461":2,"462":1,"474":1,"481":1,"484":1,"488":1,"506":2,"508":1,"510":1,"511":1,"512":1,"513":1,"514":2,"517":1,"520":1,"521":1,"525":1}}],["notelyproject.zip).",{"2":{"474":1}}],["notelyproject.zip,",{"2":{"323":1}}],["notely,",{"2":{"335":1}}],["notely:",{"2":{"253":1,"460":1}}],["notely?",{"0":{"238":1},"2":{"342":1}}],["notely.",{"2":{"224":1,"250":1,"340":1,"361":1,"387":1,"394":1,"461":1,"481":1,"512":1,"514":1}}],["notely\'s",{"2":{"15":1,"238":1,"242":1,"244":1,"414":1}}],["notely",{"0":{"56":1,"77":1,"93":1,"239":1,"240":1,"246":1,"250":1,"447":1,"460":1},"1":{"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"64":1,"65":1,"66":1,"67":1,"68":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"94":1,"95":1,"96":1,"97":1,"98":1,"99":1,"100":1,"101":1,"102":1,"103":1,"104":1,"105":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"115":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1,"251":1,"252":1,"253":1,"254":1,"255":1,"256":1,"257":1,"258":1,"259":1,"260":1,"261":1,"262":1,"263":1,"264":1,"265":1,"266":1,"267":1,"268":1,"269":1,"270":1,"271":1,"272":1,"273":1,"274":1,"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1,"297":1,"298":1,"299":1,"300":1,"301":1,"302":1,"303":1,"304":1,"305":1,"306":1,"307":1,"308":1,"309":1,"310":1,"311":1,"312":1,"313":1,"314":1,"315":1,"316":1,"317":1,"318":1,"319":1,"320":1,"321":1,"322":1,"323":1,"448":1,"449":1,"450":1,"451":1,"452":1,"453":1,"454":1,"455":1,"456":1,"457":1,"458":1,"459":1,"461":1,"462":1,"463":1,"464":1,"465":1,"466":1,"467":1,"468":1,"469":1,"470":1,"471":1,"472":1,"473":1,"474":1,"475":1},"2":{"0":1,"8":1,"14":1,"21":1,"29":1,"52":1,"53":1,"54":1,"56":1,"57":1,"68":1,"72":1,"74":1,"75":1,"76":1,"77":1,"78":1,"80":1,"83":1,"90":1,"94":1,"131":1,"132":1,"134":2,"138":1,"140":1,"141":1,"152":1,"154":1,"165":1,"172":1,"174":1,"176":1,"185":1,"187":1,"192":1,"203":1,"207":1,"211":1,"214":2,"218":1,"219":1,"221":1,"223":1,"226":1,"232":1,"235":1,"236":1,"239":1,"243":1,"262":1,"263":2,"268":1,"273":1,"274":1,"275":1,"278":1,"290":1,"296":1,"298":1,"300":1,"307":1,"308":1,"310":1,"318":1,"325":1,"330":2,"332":1,"334":1,"336":1,"339":2,"340":2,"341":1,"344":1,"346":1,"351":1,"354":1,"355":1,"358":1,"360":2,"367":1,"369":1,"391":1,"392":1,"393":1,"396":1,"402":1,"406":1,"407":1,"414":1,"415":6,"416":1,"417":1,"419":1,"454":1,"464":1,"474":1,"475":1,"484":1,"485":1,"486":1,"492":1,"493":1,"500":1,"504":1,"505":1,"516":1,"517":1,"518":1,"520":1,"522":1,"527":1,"531":1,"535":1,"538":1,"540":1,"542":5}}],["noncommercial:",{"2":{"368":1}}],["noncommercial",{"0":{"368":1},"2":{"367":1}}],["non",{"2":{"46":1,"49":1,"50":1,"115":1,"116":1,"419":1}}],["node\'s",{"2":{"227":1}}],["node.js",{"2":{"84":1,"339":1}}],["node.js.",{"2":{"56":1}}],["node.",{"2":{"53":1,"66":1,"137":1,"410":1}}],["nodes:",{"2":{"510":3}}],["nodes,",{"2":{"75":1}}],["nodes",{"2":{"47":1,"49":1,"50":1,"55":1,"509":2}}],["node",{"0":{"510":1},"2":{"39":1,"49":1,"281":1,"339":1,"488":1,"502":1,"509":1,"535":1}}],["noise.",{"2":{"376":1}}],["noise",{"0":{"36":1}}],["nouns",{"2":{"477":1}}],["noun",{"0":{"33":1}}],["no",{"2":{"1":1,"15":1,"37":1,"54":1,"93":2,"94":1,"96":27,"99":5,"103":1,"105":1,"111":2,"116":36,"118":1,"120":1,"206":1,"332":2,"334":1,"374":1,"484":1,"489":1,"490":1,"510":1}}],["w",{"2":{"366":1,"482":2}}],["w)",{"2":{"254":2,"379":1}}],["wpm)",{"2":{"167":1}}],["wrong",{"0":{"449":1},"2":{"236":1}}],["wrap",{"2":{"202":1}}],["wraps",{"2":{"196":5}}],["wrapper.",{"2":{"369":1}}],["wrapper",{"2":{"87":1}}],["wrapping",{"2":{"75":1,"202":1}}],["writable.",{"2":{"458":1}}],["written",{"2":{"135":1,"137":1,"140":1,"183":1,"209":1,"522":1}}],["written.",{"2":{"93":1,"218":1,"234":1}}],["writing:",{"2":{"513":1}}],["writing,",{"2":{"324":1,"410":1}}],["writing.",{"2":{"166":1,"279":1,"423":1}}],["writing",{"0":{"259":1,"350":1,"401":1,"476":1},"1":{"260":1,"261":1,"262":1,"263":1,"264":1,"265":1,"266":1,"267":1,"268":1,"269":1,"270":1,"271":1,"402":1,"403":1,"404":1,"477":1,"478":1,"479":1,"480":1},"2":{"95":1,"96":1,"104":1,"112":1,"162":1,"165":1,"166":1,"256":1,"305":1,"306":1,"380":1,"404":1}}],["write?",{"2":{"342":1}}],["writes",{"2":{"210":1,"526":1}}],["write:",{"2":{"172":1}}],["write.",{"2":{"159":1}}],["write",{"0":{"326":1,"463":1},"1":{"327":1},"2":{"43":1,"55":1,"136":1,"142":1,"223":1,"260":1,"274":1,"302":1,"330":1,"463":2,"468":1}}],["weekly",{"2":{"496":1}}],["week",{"0":{"496":1},"2":{"498":1}}],["weeks**.",{"2":{"326":1}}],["well",{"2":{"106":1,"108":1}}],["well.",{"2":{"96":1}}],["welcome",{"2":{"105":1}}],["weak.",{"2":{"105":1}}],["weak",{"2":{"100":2}}],["were",{"2":{"93":2,"151":1,"368":1,"454":1,"471":1}}],["weight),",{"2":{"44":1}}],["web)",{"0":{"230":1},"2":{"221":1}}],["websitetemplate.cjs.",{"2":{"487":1}}],["websitetemplate.cjs",{"2":{"486":1}}],["website.",{"2":{"254":1}}],["website",{"0":{"254":1,"322":1,"459":1,"481":1,"482":1,"487":1,"490":1,"491":1},"1":{"482":1,"483":1,"484":1,"485":1,"486":1,"487":1,"488":1,"489":1,"490":1,"491":1},"2":{"106":1,"116":1,"166":1,"201":1,"254":4,"322":1,"366":1,"379":2,"381":2,"459":3,"481":3,"482":2,"484":1,"485":1,"486":1,"489":1,"490":1,"491":2,"506":1}}],["website,",{"2":{"93":1}}],["web",{"0":{"207":1,"320":1},"2":{"4":1,"95":2,"96":1,"98":1,"138":1,"166":1,"201":1,"207":1,"224":1,"229":1,"254":3,"260":1,"320":1,"323":1,"339":1,"379":2,"446":1,"458":1,"459":1,"474":1,"482":3,"491":1,"506":1}}],["would",{"2":{"131":1}}],["would,",{"2":{"36":1}}],["word,",{"2":{"207":1,"274":1}}],["word",{"2":{"37":2,"46":1,"167":1,"172":1,"269":1,"291":1,"353":1,"388":1,"527":1}}],["words.",{"2":{"307":1}}],["words,",{"2":{"46":1,"274":2}}],["words;",{"2":{"36":1}}],["words",{"2":{"9":1,"167":1,"172":1,"269":2,"393":1,"477":1}}],["workloads",{"2":{"492":1}}],["work,",{"2":{"347":1}}],["work.",{"2":{"345":1,"380":1,"410":1}}],["working",{"0":{"539":1},"2":{"132":1,"168":1,"241":1,"247":1,"253":1,"255":1,"263":1,"268":1,"413":1,"460":1,"539":1}}],["workflow:",{"2":{"335":1}}],["workflow,all",{"1":{"288":1}}],["workflow,open",{"1":{"285":1,"286":1}}],["workflow,",{"2":{"116":1}}],["workflows:",{"2":{"108":3}}],["workflows.",{"2":{"103":1,"124":1,"131":1}}],["workflows",{"2":{"96":1,"99":1,"102":1,"103":1,"104":1,"112":2,"126":1,"128":1,"384":1,"385":1}}],["workflow.",{"2":{"96":1}}],["workflow",{"0":{"86":1,"108":1,"144":1,"282":1},"1":{"87":1,"88":1,"89":1,"283":1,"284":1,"287":1},"2":{"95":1,"96":1,"104":1,"116":2}}],["work",{"0":{"240":1,"465":1},"2":{"76":1,"256":1,"287":1,"288":1,"336":1,"347":1,"456":1,"460":1,"493":1,"513":1}}],["works",{"0":{"483":1},"1":{"484":1,"485":1},"2":{"34":1,"106":1,"116":1,"159":1,"279":1}}],["workspace\'s",{"2":{"502":1}}],["workspace]",{"2":{"143":1}}],["workspaceactivitypanel,",{"2":{"105":1}}],["workspaces",{"0":{"453":1,"472":1},"2":{"96":1,"99":1,"103":1,"111":1,"137":1,"239":1,"240":1,"281":1,"288":1,"290":1,"314":1,"400":1}}],["workspaces,",{"2":{"94":1,"104":3,"117":1,"120":1,"124":1,"131":1}}],["workspaces.",{"2":{"74":1,"245":1,"502":1}}],["workspace".",{"2":{"96":1}}],["workspace"",{"2":{"94":1}}],["workspace:",{"2":{"16":1,"517":1,"526":1}}],["workspace.test.js:",{"2":{"91":1}}],["workspace.",{"2":{"15":1,"65":1,"99":1,"103":1,"117":1,"148":1,"214":1,"216":1,"228":1,"233":1,"238":1,"255":1,"256":1,"267":1,"277":1,"346":1,"422":1,"448":1,"450":1,"461":1,"490":1,"500":1,"513":1,"519":1,"535":1}}],["workspace."",{"2":{"7":1}}],["workspace,",{"2":{"14":1,"120":1,"127":1,"131":1,"387":1,"477":1,"513":1}}],["workspacecontext,",{"2":{"9":1}}],["workspace",{"0":{"72":1,"73":1,"75":1,"81":1,"228":1,"238":1,"245":1,"251":1,"252":1,"253":1,"255":1,"267":1,"281":1,"298":1,"323":1,"340":1,"389":1,"414":1,"422":1,"445":1,"446":1,"458":1,"459":1,"461":1,"474":1,"508":1,"512":1,"516":1,"517":1,"521":1,"528":1,"530":1},"1":{"73":1,"74":1,"75":1,"229":1,"230":1,"231":1,"252":1,"253":1,"254":1,"255":1,"256":1,"257":1,"258":1,"390":1,"509":1,"510":1,"511":1,"513":1,"514":1,"515":1,"516":1,"517":1,"529":1,"530":1},"2":{"4":2,"7":2,"29":1,"49":1,"55":1,"59":1,"62":2,"63":1,"69":1,"72":1,"75":3,"77":2,"78":1,"79":1,"81":2,"91":1,"94":1,"95":7,"96":6,"98":1,"99":2,"102":1,"103":2,"104":4,"106":3,"107":1,"108":3,"111":1,"112":1,"116":6,"117":2,"120":2,"124":1,"131":1,"150":2,"154":1,"165":1,"170":1,"175":1,"185":1,"197":1,"215":1,"216":1,"217":1,"219":2,"220":2,"221":3,"226":2,"227":3,"228":1,"229":1,"231":2,"235":2,"236":2,"238":1,"239":1,"243":1,"244":1,"252":2,"253":5,"256":1,"267":2,"274":1,"281":2,"292":1,"323":4,"326":1,"340":4,"341":2,"357":1,"358":1,"359":1,"360":1,"362":6,"374":3,"379":6,"381":3,"383":1,"386":1,"414":1,"415":2,"417":4,"420":1,"433":1,"439":2,"446":1,"458":1,"459":3,"461":1,"470":1,"472":2,"474":1,"481":1,"484":1,"488":1,"489":1,"490":2,"491":1,"492":1,"499":1,"500":2,"501":1,"502":1,"503":1,"505":1,"506":1,"507":3,"508":1,"509":2,"512":1,"513":1,"515":1,"516":2,"517":5,"522":2,"526":2,"530":1,"536":1,"539":2,"540":1}}],["workerprocess.cjs):",{"2":{"84":1}}],["worker",{"2":{"26":1}}],["warn",{"2":{"415":1}}],["warnings:",{"2":{"339":1}}],["warnings",{"2":{"308":1,"339":1}}],["warnings.",{"2":{"82":1,"449":1,"526":1}}],["warning,",{"2":{"196":1}}],["warning.",{"2":{"187":1}}],["warning",{"2":{"80":1,"174":1,"187":1,"391":1,"517":1}}],["way",{"0":{"248":1},"2":{"419":1}}],["ways:",{"2":{"15":1}}],["wait",{"2":{"220":1,"236":1}}],["was",{"2":{"93":2,"219":1,"220":2,"236":2,"459":1}}],["watching",{"2":{"166":1}}],["watch",{"2":{"79":1,"90":1}}],["watches",{"2":{"62":1}}],["watcher",{"2":{"62":1,"91":1,"526":1}}],["walks",{"2":{"324":1}}],["walkthroughs",{"2":{"105":1}}],["walkthrough",{"2":{"67":1}}],["wal",{"2":{"55":1}}],["wal;).",{"2":{"43":1}}],["want",{"2":{"20":1,"80":1,"81":1,"151":1,"162":1,"338":1,"394":1,"396":1,"400":1,"414":1,"421":1,"438":1,"461":1,"466":1,"532":1}}],["why",{"0":{"356":1}}],["whose",{"2":{"499":2}}],["who",{"2":{"216":1}}],["whole",{"2":{"16":1,"277":1,"388":1}}],["wheel",{"2":{"509":1}}],["whether",{"2":{"164":1,"310":1,"474":1,"507":1}}],["where",{"0":{"77":1,"239":1},"2":{"116":1,"162":1,"211":1,"217":1,"221":1,"252":1,"271":1,"275":1,"298":1,"321":1,"337":1,"338":2,"340":1,"376":1,"389":1,"413":1,"461":1,"466":1,"525":1,"532":1,"533":1}}],["whenever",{"2":{"17":1,"526":1}}],["when",{"0":{"81":1},"2":{"7":1,"10":1,"42":1,"50":1,"76":1,"78":1,"79":1,"81":1,"159":1,"167":1,"168":2,"171":1,"172":1,"192":1,"205":2,"210":1,"211":1,"216":1,"247":1,"254":1,"258":1,"262":1,"269":1,"271":1,"275":1,"281":1,"287":1,"294":1,"299":1,"307":1,"308":1,"330":1,"335":1,"346":1,"349":1,"374":3,"393":1,"394":1,"396":2,"397":1,"400":1,"402":1,"407":1,"414":1,"415":1,"421":1,"429":1,"453":1,"454":1,"461":1,"465":1,"473":1,"477":1,"480":1,"482":1,"485":1,"493":1,"511":1,"513":1,"517":1,"520":1,"525":1,"527":3,"529":1,"537":1,"540":1,"542":1}}],["whitelist.",{"2":{"418":1}}],["whitelisted",{"2":{"36":1}}],["whitespace",{"2":{"400":1}}],["white",{"2":{"212":1,"374":1}}],["whiteboard",{"2":{"59":1,"140":1,"147":1}}],["which",{"0":{"241":1},"2":{"33":1,"201":1,"249":3,"308":1,"486":1,"491":1,"513":1}}],["while",{"2":{"15":2,"19":1,"94":1,"99":1,"105":1,"164":1,"166":1,"210":2,"255":1,"262":1,"273":1,"328":1,"377":1,"403":1,"406":1,"485":1}}],["what\'s",{"0":{"331":1}}],["what",{"0":{"98":1,"99":1,"162":1,"217":1,"238":1,"242":1,"247":1,"248":1,"308":1,"342":1,"487":1},"2":{"16":1,"20":2,"104":1,"229":1,"233":1,"322":1,"328":1,"341":1,"394":1,"454":1,"479":2,"484":1}}],["wireframes",{"2":{"155":1}}],["wireframes,",{"2":{"59":1}}],["will:",{"2":{"219":1,"235":1}}],["will",{"2":{"137":2,"154":1,"219":1,"263":1,"330":1,"339":1,"352":1,"354":1,"358":1,"360":1,"390":1,"392":1}}],["wizard",{"2":{"95":1,"105":1}}],["widgets.",{"2":{"283":1}}],["wide",{"2":{"62":1,"75":1,"239":1,"496":1,"516":1,"522":2}}],["width",{"2":{"35":1,"166":1}}],["wikilinks",{"2":{"487":1}}],["wikilinks,",{"2":{"66":1,"75":1}}],["wikilink",{"2":{"59":1}}],["windows.",{"2":{"332":1}}],["windows",{"2":{"92":3,"95":1,"213":1,"296":1,"333":1,"336":1,"339":3,"377":1,"407":2,"415":2,"444":1,"466":1,"501":1,"531":1,"532":1,"537":2,"538":1}}],["windows,",{"2":{"85":1}}],["window.electronapi.",{"2":{"84":1}}],["window):",{"2":{"11":1}}],["window",{"2":{"11":1,"13":1,"74":1,"84":1,"116":4,"213":1,"223":1,"339":1,"372":1,"459":1,"491":1,"493":1,"506":1}}],["within",{"2":{"136":1,"377":1,"387":1,"498":1}}],["with:",{"2":{"136":1}}],["with,",{"2":{"34":1,"39":1}}],["without",{"2":{"3":1,"7":1,"29":1,"55":1,"63":1,"93":1,"119":1,"134":2,"139":1,"169":2,"179":1,"203":1,"224":1,"263":1,"279":1,"288":1,"337":1,"338":1,"355":1,"416":1,"419":1,"456":1,"485":1,"493":1,"498":1,"502":1,"535":1}}],["with",{"0":{"79":1,"135":1,"464":1,"465":1},"2":{"1":1,"7":1,"9":1,"12":3,"15":1,"16":1,"19":1,"24":1,"27":1,"34":1,"35":1,"36":1,"43":1,"47":1,"49":1,"54":1,"59":1,"65":1,"66":1,"75":1,"79":2,"83":1,"84":1,"94":2,"95":8,"96":3,"98":1,"116":5,"118":1,"120":1,"127":1,"131":1,"132":2,"133":1,"134":1,"146":1,"149":1,"150":2,"164":3,"166":2,"171":1,"174":1,"184":1,"188":1,"191":1,"193":1,"212":2,"214":2,"216":1,"220":1,"223":2,"224":1,"225":3,"227":1,"236":1,"238":1,"253":1,"258":1,"262":1,"263":3,"279":1,"291":1,"303":2,"313":1,"320":1,"330":1,"339":1,"346":1,"354":1,"372":1,"374":2,"379":1,"381":1,"389":1,"396":1,"399":1,"414":1,"417":1,"418":1,"433":1,"458":1,"460":1,"463":2,"464":1,"470":1,"477":1,"486":3,"487":1,"501":1,"516":2,"517":1,"522":1,"529":1}}],["365",{"2":{"417":1}}],["320ms",{"2":{"223":1}}],["3×3",{"2":{"197":1}}],["300000).",{"2":{"418":1}}],["30",{"2":{"50":1,"417":1,"499":1}}],["30s).",{"2":{"34":1}}],["384",{"2":{"38":1,"66":1,"75":1}}],["35$,",{"2":{"36":1}}],["3.1",{"2":{"52":1}}],["3.3",{"2":{"52":1}}],["3.",{"0":{"8":1,"19":1,"25":1,"54":1,"61":1,"79":1,"86":1,"124":1,"232":1,"272":1,"338":1,"347":1,"354":1,"360":1,"391":1,"401":1,"419":1,"424":1,"450":1,"463":1,"498":1,"503":1,"511":1,"515":1,"521":1,"526":1,"534":1,"539":1},"2":{"182":1}}],["3:",{"0":{"6":1,"34":1},"2":{"527":1}}],["3",{"0":{"328":1},"2":{"2":1,"20":1,"33":1,"49":1,"177":1,"204":1,"223":1,"363":1,"366":1,"372":1,"419":1}}],["09:00",{"2":{"493":1}}],["08",{"2":{"493":2}}],["0",{"2":{"116":1,"366":2}}],["03.",{"2":{"93":1}}],["03",{"0":{"378":1,"382":1},"1":{"379":1,"380":1,"381":1,"383":1,"384":1,"385":1},"2":{"93":1}}],["07",{"0":{"371":1,"373":1,"375":1,"378":1,"382":1},"1":{"372":1,"374":1,"376":1,"377":1,"379":1,"380":1,"381":1,"383":1,"384":1,"385":1},"2":{"93":2}}],["0.45–0.60).",{"2":{"54":1}}],["0.95$)",{"2":{"50":1}}],["0.92$",{"2":{"34":1}}],["0.92,",{"2":{"6":1}}],["0.1)",{"2":{"49":1}}],["0.88$",{"2":{"38":1}}],["0.85)",{"2":{"34":1}}],["0.02,",{"2":{"7":1}}],["0.25.",{"2":{"7":1}}],["0.25),",{"2":{"2":1}}],["0ms",{"2":{"2":1,"11":1,"24":1,"372":1}}],["&",{"2":{"526":1}}],["<=========================>",{"2":{"526":1}}],["<",{"2":{"192":1}}],["<summary>click",{"2":{"192":1}}],[""removed"",{"2":{"514":1}}],[""ai",{"2":{"477":2}}],[""disaster",{"2":{"393":1}}],[""documentation"",{"2":{"96":1}}],[""backup"",{"2":{"393":1}}],[""type",{"2":{"480":1}}],[""todos",",{"2":{"285":1}}],[""top",{"2":{"103":1,"118":1}}],[""tasks",",{"2":{"285":1}}],[""connect",{"2":{"480":1}}],[""code",{"2":{"279":1}}],[""cancel",",{"2":{"478":1}}],[""clear",{"2":{"478":1}}],[""clear"",{"2":{"263":1}}],[""close",",{"2":{"478":1}}],[""create",{"2":{"478":1}}],[""checkboxes").",{"2":{"285":1}}],[""customize",{"2":{"257":1}}],[""incorrect",{"2":{"220":1,"236":1}}],[""import",{"2":{"220":1,"236":1}}],[""export",",{"2":{"478":1}}],[""exporting").",{"2":{"393":1}}],[""export",{"2":{"220":1,"236":1}}],[""",{"2":{"196":1,"325":1}}],[""manage",{"2":{"172":1}}],[""search",{"2":{"480":1}}],[""show",{"2":{"478":1}}],[""save",",{"2":{"478":1}}],[""start",{"2":{"127":1}}],[""sqlite",{"2":{"38":1}}],[""file",{"2":{"96":1,"103":1}}],[""open",{"2":{"94":1,"96":1,"285":1,"286":1}}],[""help",{"2":{"94":3,"96":1,"103":1}}],[""groq").",{"2":{"35":1}}],[""gemini",",{"2":{"35":1}}],[""notes",{"2":{"94":2}}],[""no",{"2":{"7":1,"480":1}}],["<",{"2":{"7":1,"49":1,"325":1}}],[">15x",{"2":{"49":1}}],[">",{"2":{"4":2,"71":1,"79":1,"80":1,"81":1,"94":2,"96":2,"99":1,"103":3,"105":1,"116":2,"117":2,"131":1,"146":1,"196":1,"238":1,"244":1,"245":1,"247":1,"248":1,"252":2,"253":2,"254":2,"257":1,"265":1,"266":1,"267":3,"268":4,"281":1,"291":1,"296":1,"305":1,"312":1,"316":1,"317":1,"318":1,"323":1,"325":1,"339":1,"396":1,"397":1,"399":2,"400":1,"402":1,"403":1,"404":1,"406":1,"407":1,"408":1,"409":1,"422":1,"423":1,"428":1,"429":1,"436":1,"437":1,"438":1,"439":1,"444":1,"446":1,"448":1,"451":1,"452":1,"454":1,"455":1,"457":2,"459":2,"461":2,"462":1,"464":1,"466":1,"472":4,"474":1,"475":3}}],[">0.80),",{"2":{"4":1}}],[">=",{"2":{"2":1}}],["&",{"0":{"0":1,"2":1,"8":1,"12":1,"15":1,"19":1,"20":1,"23":1,"28":1,"32":1,"33":1,"36":1,"37":1,"38":1,"39":1,"43":1,"45":1,"50":1,"58":1,"60":1,"61":1,"62":1,"65":1,"66":1,"71":1,"72":1,"76":1,"84":1,"86":1,"92":1,"156":1,"186":1,"207":1,"221":1,"222":1,"225":1,"226":1,"227":1,"230":1,"232":1,"274":1,"334":1,"339":1,"344":1,"348":1,"351":1,"357":1,"362":1,"364":1,"365":1,"366":1,"372":1,"390":1,"417":1,"418":1,"419":1,"420":1,"492":1,"493":1,"498":1,"499":1,"500":1,"501":1,"502":1,"503":1,"515":1,"516":1,"517":1,"520":1,"522":1,"525":1,"527":1,"528":1,"536":1,"537":1,"539":1,"540":1},"1":{"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"16":1,"17":1,"44":1,"46":1,"47":1,"48":1,"49":1,"59":1,"60":1,"62":1,"63":1,"64":1,"65":1,"66":1,"67":2,"73":1,"74":1,"75":1,"77":1,"78":1,"79":1,"80":1,"81":1,"82":1,"87":1,"88":1,"89":1,"157":1,"158":1,"159":1,"160":1,"161":1,"162":1,"163":1,"164":1,"187":1,"222":1,"223":2,"224":2,"225":2,"226":1,"227":2,"228":1,"229":1,"230":1,"231":1,"232":1,"233":2,"234":2,"235":2,"236":1,"345":1,"346":1,"347":1,"349":1,"350":1,"352":1,"353":1,"354":1,"358":1,"359":1,"360":1,"493":1,"494":1,"495":1,"496":1,"497":1,"498":1,"499":1,"501":1,"502":1,"503":1,"504":1,"523":1,"524":1,"525":1,"526":1,"527":1,"528":1,"529":2,"530":2,"538":1,"541":1,"542":1},"2":{"2":5,"8":2,"9":1,"11":1,"12":6,"13":3,"36":4,"47":1,"61":1,"62":1,"65":1,"66":1,"71":1,"75":1,"137":1,"173":2,"212":1,"213":1,"226":1,"257":1,"365":1,"374":1,"393":1,"416":1,"417":1,"500":3,"507":1,"514":1,"516":2,"517":1,"525":2,"530":1}}],["c).",{"2":{"494":1}}],["c++",{"2":{"339":1}}],["c:\\\\users\\\\name)",{"2":{"213":1}}],["c[commit",{"2":{"194":1}}],["cms",{"2":{"169":1}}],["cmd:",{"2":{"407":1,"537":1}}],["cmd.",{"2":{"267":1}}],["cmd+p)",{"2":{"274":1}}],["cmd+0",{"2":{"116":1}}],["cmd+=",{"2":{"116":1}}],["cmd+4",{"2":{"116":1}}],["cmd+3",{"2":{"116":2}}],["cmd+2",{"2":{"116":2}}],["cmd+1",{"2":{"116":2}}],["cmd+\\\\",{"2":{"116":1}}],["cmd+y",{"2":{"116":1}}],["cmd+z",{"2":{"116":1}}],["cmd+f",{"2":{"116":1}}],["cmd+delete",{"2":{"116":1}}],["cmd+s",{"2":{"116":1}}],["cmd+shift+a",{"2":{"116":1}}],["cmd+shift+g",{"2":{"116":1}}],["cmd+shift+,",{"2":{"116":1}}],["cmd+shift+p",{"2":{"116":1}}],["cmd+shift+z",{"2":{"116":1}}],["cmd+shift+s",{"2":{"116":1}}],["cmd+shift+k",{"2":{"116":1}}],["cmd+shift+delete",{"2":{"116":1}}],["cmd+shift+r",{"2":{"116":1}}],["cmd+shift+w",{"2":{"116":1}}],["cmd+shift+o",{"2":{"116":1}}],["cmd+shift+h",{"2":{"116":1}}],["cmd+shift+e",{"2":{"116":2}}],["cmd+shift+n",{"2":{"116":1}}],["cmd+shift+l",{"2":{"115":1,"116":2,"117":1}}],["cmd+shift+f",{"2":{"115":1,"116":2,"117":1}}],["cmd+n",{"2":{"116":1}}],["cmd+",{"2":{"116":2}}],["cmd+h",{"2":{"115":1,"116":1}}],["cmd+k",{"2":{"115":1,"116":2,"117":1,"118":1}}],["cmd",{"2":{"106":1,"138":1,"226":1,"248":1,"253":2,"254":2,"257":1,"285":1,"291":1,"296":1,"317":1,"362":8,"363":15,"364":2,"365":3,"366":8,"379":3,"403":1,"404":1,"407":1,"418":1,"423":1,"425":1,"434":1,"444":1,"445":1,"455":1,"462":1,"463":1,"464":1,"466":1,"473":1,"475":1,"482":2,"500":2,"507":1,"536":1}}],["c",{"2":{"143":1,"189":1,"194":1,"204":1,"209":1}}],["c{write",{"2":{"143":1}}],["csv):",{"2":{"225":1}}],["csv",{"0":{"212":1},"2":{"212":1,"225":1}}],["csharp,",{"2":{"138":1}}],["css,",{"2":{"134":1,"138":1,"188":1}}],["css",{"2":{"58":1,"223":1,"224":1,"236":1,"374":2}}],["cpu",{"2":{"84":1}}],["certificate.",{"2":{"339":1}}],["centrally:",{"2":{"473":1}}],["centralized,",{"2":{"68":1}}],["centralized",{"0":{"68":1},"1":{"69":1,"70":1,"71":1},"2":{"374":2}}],["center.",{"2":{"103":1,"105":1,"117":1,"128":1,"131":1}}],["center,",{"2":{"95":1,"99":1,"131":1,"262":1}}],["center".",{"2":{"94":1,"96":1}}],["center",{"0":{"385":1},"2":{"93":1,"96":2,"98":1,"103":2,"104":1,"105":1,"106":1,"112":1,"116":1,"119":1,"189":2,"209":2,"316":1,"343":1,"362":1,"383":1,"385":1,"386":1,"437":1,"475":1}}],["cell,",{"2":{"206":1}}],["cells.",{"2":{"206":1,"495":1}}],["cells",{"0":{"206":1},"2":{"205":2,"206":1,"210":1,"262":1,"498":2}}],["cell",{"2":{"36":1,"204":6,"206":1,"209":1,"213":1,"375":1,"377":1,"495":1}}],["c.",{"0":{"64":1}}],["crop,",{"2":{"533":1}}],["crop:",{"2":{"520":1}}],["crop",{"2":{"465":1}}],["crops",{"2":{"300":1}}],["cross",{"2":{"34":1,"481":1,"486":1,"487":1,"491":1}}],["credit",{"2":{"368":1}}],["credible",{"2":{"131":1}}],["credentials",{"2":{"346":1,"359":1,"410":1}}],["creator",{"2":{"220":1,"236":1}}],["creative,",{"2":{"412":1}}],["creative",{"2":{"367":1}}],["creation",{"0":{"257":1,"514":1}}],["creation,",{"2":{"63":1,"84":1,"91":1,"92":1,"95":2}}],["creating,",{"2":{"324":1}}],["creating",{"0":{"523":1},"1":{"524":1},"2":{"127":1,"460":1,"502":1,"507":1}}],["creates",{"2":{"77":1,"336":1,"341":1,"419":1}}],["create",{"0":{"204":1,"325":1,"423":1,"424":1,"462":1},"2":{"69":1,"96":2,"108":1,"141":1,"240":1,"257":2,"292":1,"326":1,"342":1,"345":2,"349":1,"358":1,"363":1,"418":1,"462":2,"514":2,"523":1}}],["create,",{"2":{"42":1,"477":1}}],["created",{"2":{"19":1,"75":1,"151":2,"471":2,"500":1}}],["critical",{"0":{"110":1,"122":1}}],["crud,",{"2":{"91":1}}],["crud",{"2":{"62":1}}],["cte",{"2":{"25":1}}],["ctrl+shift+tab",{"2":{"374":1}}],["ctrl+tab",{"2":{"374":1}}],["ctrl",{"2":{"18":1,"115":4,"116":40,"117":3,"158":1,"161":1,"163":1,"174":1,"175":11,"210":1,"226":1,"285":1,"296":1,"325":1,"343":3,"352":1,"362":10,"363":15,"364":2,"365":3,"366":8,"388":2,"389":1,"403":1,"404":1,"425":1,"434":1,"444":1,"463":1,"466":1,"482":2,"500":1,"532":1,"536":1}}],["cutting",{"2":{"372":1}}],["cursor.",{"2":{"142":1,"204":1,"207":1}}],["cursor",{"2":{"16":1,"159":1,"196":1,"197":1,"205":1,"262":1,"329":1,"375":1,"444":1,"463":1,"466":1,"532":1}}],["currently.",{"2":{"246":1}}],["currently",{"2":{"94":1,"222":1,"358":1}}],["current",{"0":{"388":1,"425":1,"426":1},"2":{"16":1,"96":2,"99":2,"100":1,"104":1,"106":1,"110":1,"115":1,"116":2,"118":1,"120":2,"131":2,"157":1,"167":1,"168":1,"175":1,"196":1,"199":1,"200":1,"202":1,"215":1,"216":1,"233":1,"248":1,"254":2,"264":1,"271":2,"279":1,"283":1,"296":1,"345":1,"352":1,"363":3,"364":2,"379":1,"381":1,"383":1,"385":1,"386":1,"387":1,"403":1,"408":1,"456":1,"482":1,"485":1,"486":1,"499":1,"534":1}}],["custom)",{"2":{"19":1,"27":1}}],["customize",{"2":{"19":1,"27":1,"257":1,"504":1,"515":1}}],["customization",{"0":{"19":1},"2":{"108":1}}],["custom",{"0":{"538":1},"2":{"8":1,"19":3,"27":1,"52":3,"58":1,"59":1,"172":3,"187":1,"274":2,"339":1,"374":2,"379":2,"486":1,"525":1}}],["chronological",{"2":{"513":1}}],["chronologically",{"2":{"464":1}}],["chrome.",{"2":{"160":1}}],["chromium",{"2":{"65":1,"223":1,"339":1,"491":1}}],["choice",{"2":{"332":1}}],["choice,",{"2":{"239":1}}],["choosing",{"0":{"155":1}}],["choose.",{"2":{"239":1}}],["chooses",{"2":{"139":1}}],["choose",{"2":{"16":1,"18":1,"174":1,"216":1,"220":1,"233":2,"236":1,"252":1,"308":1,"323":1,"335":1,"407":1,"410":1,"419":1,"427":1,"433":1,"441":1,"442":1,"443":1,"455":1,"463":1,"474":2,"507":1,"517":1}}],["chose.",{"2":{"241":1}}],["chose",{"2":{"80":1,"452":1}}],["checkbox",{"2":{"525":1}}],["checkboxes",{"2":{"183":1,"283":1,"473":1,"522":1}}],["check.",{"2":{"402":1,"455":1}}],["checkmarks,",{"2":{"379":1}}],["checkpoint",{"2":{"348":1}}],["checkpoint.",{"2":{"345":1}}],["check"",{"2":{"220":1,"236":1}}],["checking",{"0":{"274":1},"2":{"172":1}}],["checking,",{"2":{"59":1,"95":1}}],["checks.",{"2":{"274":1,"463":1}}],["checks",{"0":{"298":1,"521":1},"2":{"172":1,"278":1,"391":1,"402":1,"501":1}}],["checksum",{"2":{"92":1}}],["checks,",{"2":{"70":1}}],["check:",{"2":{"82":1}}],["checklists,5.",{"1":{"529":1,"530":1}}],["checklists,1.",{"1":{"524":1}}],["checklists",{"0":{"522":1},"1":{"523":1,"525":1,"526":1,"527":1,"528":1}}],["checklists:",{"2":{"516":1}}],["checklists.",{"2":{"287":1}}],["checklist",{"2":{"75":1,"124":1,"522":1,"523":1}}],["check",{"0":{"402":1},"2":{"38":1,"107":1,"146":1,"158":1,"431":1,"448":1,"449":1,"450":1,"455":1,"468":1}}],["chunking,",{"2":{"70":1}}],["chunk",{"2":{"26":1,"55":1,"75":1}}],["chunks",{"2":{"16":1,"66":1}}],["chips,",{"2":{"380":1}}],["chips.",{"2":{"262":1,"463":1}}],["chips",{"2":{"17":1,"205":1,"208":1,"374":1,"376":1}}],["chip",{"2":{"17":1}}],["changing",{"2":{"381":1}}],["change,",{"2":{"490":1,"517":1}}],["changed",{"0":{"244":1},"2":{"256":1,"459":1}}],["changed.",{"2":{"211":1}}],["change.",{"2":{"174":1,"350":1}}],["changelog.md",{"2":{"383":1}}],["changelog.",{"2":{"123":1,"131":1}}],["changelog",{"2":{"94":1,"111":1}}],["changes,",{"2":{"149":1,"330":1,"357":1}}],["changes.",{"2":{"79":1,"355":1,"356":1,"374":1,"434":1}}],["changes",{"0":{"162":1,"347":1,"464":1},"2":{"26":1,"78":1,"136":1,"210":2,"267":1,"292":2,"330":1,"346":1,"347":1,"349":2,"350":1,"368":1,"419":1,"464":1,"485":1,"517":1,"520":1,"526":1}}],["changes)",{"2":{"5":1}}],["change",{"0":{"174":1,"422":1},"2":{"18":1,"466":1,"498":1,"517":1}}],["channel",{"0":{"85":1}}],["channels.",{"2":{"57":1}}],["charts",{"2":{"155":1}}],["charts,",{"2":{"59":1,"194":1}}],["character",{"2":{"36":1,"193":1,"206":1}}],["characters",{"0":{"193":1},"2":{"9":1,"36":1,"206":1,"325":1}}],["char",{"2":{"36":1}}],["chat,",{"2":{"80":1,"95":1}}],["chat:",{"2":{"15":1}}],["chat",{"0":{"15":1,"306":1},"1":{"16":1,"17":1},"2":{"15":2,"16":1,"19":1,"20":1,"24":1,"96":1,"305":1,"372":1}}],["citation",{"2":{"13":1}}],["closing",{"2":{"539":1}}],["closed",{"2":{"283":2,"287":1}}],["closely",{"2":{"281":1}}],["closes",{"2":{"210":1}}],["close",{"2":{"173":6,"286":1,"322":1,"330":1,"363":1,"379":1,"453":1,"463":1}}],["clone",{"2":{"359":1}}],["cloning",{"0":{"359":1}}],["cloud",{"2":{"29":1,"52":1,"53":1,"63":1,"66":1,"152":1,"332":1,"410":1,"416":1}}],["cleared",{"2":{"490":1}}],["clear,",{"2":{"325":1,"350":1,"476":1}}],["clears",{"2":{"210":1}}],["clear",{"2":{"71":4,"106":1,"210":1,"274":1,"413":1,"462":1}}],["clearing,",{"2":{"71":1}}],["cleanly",{"2":{"539":1}}],["clean,",{"2":{"207":1}}],["cleaner,",{"2":{"380":1}}],["cleaner",{"2":{"103":1}}],["cleaned",{"2":{"39":1}}],["cleanup",{"2":{"96":1,"108":1}}],["cleansed",{"2":{"33":1,"230":3}}],["cleansedcontent",{"2":{"33":1}}],["cleansing",{"0":{"32":1}}],["clean",{"0":{"440":1},"2":{"9":1,"12":1,"20":1,"32":1,"72":1,"212":2,"225":2,"298":1,"336":1,"346":1}}],["clustering,",{"2":{"102":1}}],["clustering.",{"2":{"50":1}}],["clustering",{"0":{"511":1},"2":{"39":1,"50":1,"95":1,"104":1,"511":1}}],["clusters",{"2":{"36":1,"511":1}}],["clutter",{"2":{"20":1}}],["clarity,",{"2":{"382":1}}],["claims",{"2":{"103":1}}],["class,",{"2":{"374":1}}],["classdiagram",{"2":{"143":1}}],["class",{"2":{"59":1,"143":1,"387":1}}],["classifies",{"2":{"4":1}}],["clause",{"2":{"36":2}}],["client",{"2":{"356":1,"487":1,"489":1,"506":1}}],["clients,",{"2":{"169":1}}],["clipboard,",{"2":{"170":1}}],["clipboard.",{"2":{"169":1,"171":1}}],["cli",{"2":{"63":1}}],["cli,",{"2":{"36":1}}],["click.",{"2":{"374":1}}],["clicks",{"2":{"374":1}}],["clicking",{"2":{"171":1,"257":1,"391":1,"525":2,"529":1}}],["click",{"2":{"15":1,"18":1,"19":1,"52":1,"96":1,"132":1,"135":1,"136":2,"137":1,"139":1,"142":1,"148":2,"149":2,"150":2,"151":1,"153":4,"158":1,"159":1,"168":1,"170":1,"172":2,"173":1,"174":2,"183":1,"187":1,"189":1,"196":1,"197":1,"204":1,"206":1,"212":1,"213":1,"216":3,"219":3,"233":2,"235":2,"263":2,"271":1,"274":3,"278":1,"279":1,"286":1,"291":1,"303":2,"339":1,"340":1,"347":2,"349":3,"350":1,"352":1,"353":1,"354":1,"358":1,"374":2,"379":1,"392":1,"418":3,"428":1,"433":1,"434":2,"442":1,"444":2,"446":1,"464":1,"466":2,"470":1,"471":1,"474":1,"486":1,"495":1,"498":1,"509":2,"511":1,"515":1,"517":3,"520":1,"525":1,"532":1}}],["came",{"2":{"286":1,"442":1}}],["cause",{"2":{"220":1,"236":1}}],["caution)",{"2":{"196":1}}],["caution",{"2":{"187":1}}],["casing",{"2":{"477":1}}],["casual",{"2":{"155":1}}],["case",{"2":{"388":1,"477":1,"480":2}}],["case:",{"2":{"279":1}}],["cases:",{"2":{"278":1}}],["cases",{"0":{"288":1},"2":{"120":1}}],["cased",{"2":{"37":1}}],["categorizes",{"2":{"499":1}}],["categories.",{"2":{"525":1}}],["categories",{"0":{"70":1}}],["category",{"2":{"119":1,"138":1,"227":1,"501":1,"503":1}}],["cards",{"2":{"399":1}}],["cards,",{"2":{"28":1}}],["card",{"2":{"374":1,"515":1}}],["carol",{"2":{"326":1}}],["carousel",{"2":{"105":1}}],["calendar.",{"2":{"499":1}}],["calendar",{"0":{"492":1,"494":1},"1":{"493":1,"494":1,"495":2,"496":2,"497":2,"498":1,"499":1},"2":{"492":1,"494":2,"498":3,"499":2,"516":1}}],["calculations",{"2":{"53":1}}],["calibrated",{"2":{"35":1}}],["callout",{"2":{"187":3,"196":1,"520":1}}],["callouts",{"0":{"186":1,"187":1},"1":{"187":1}}],["calls,",{"2":{"28":1,"143":1}}],["calls",{"2":{"12":1}}],["call",{"2":{"12":1,"20":1,"372":1}}],["calling.",{"2":{"52":1}}],["calling",{"2":{"9":1}}],["canvas).",{"2":{"470":1}}],["canvas.",{"2":{"369":1}}],["canvas",{"2":{"147":1,"148":1,"149":1,"150":1,"155":2}}],["canvas,",{"2":{"84":1}}],["cancel",{"0":{"210":1},"2":{"136":1,"210":1,"262":1,"463":2}}],["cannot",{"2":{"47":1,"80":1,"308":1}}],["canonical",{"2":{"38":1,"44":1,"49":1,"125":1}}],["candidate",{"2":{"35":1,"46":1,"50":1}}],["can",{"0":{"244":1,"308":1},"2":{"15":1,"16":1,"36":1,"79":1,"120":8,"135":1,"137":2,"150":2,"164":2,"166":1,"169":1,"186":1,"187":1,"205":2,"207":1,"208":1,"214":2,"216":1,"240":1,"243":1,"255":1,"256":2,"270":1,"275":1,"278":1,"280":1,"281":1,"290":1,"296":1,"298":1,"299":1,"303":2,"305":1,"307":1,"308":1,"334":1,"355":1,"356":1,"387":1,"411":1,"414":1,"465":2,"491":1,"504":1,"506":1,"525":1,"533":1,"538":1}}],["cache",{"2":{"106":1,"484":1,"490":1}}],["caches:",{"2":{"72":1}}],["caches",{"2":{"71":1,"75":2,"360":1}}],["cached):",{"2":{"9":1}}],["caching",{"0":{"9":1},"2":{"2":1}}],["captured",{"2":{"296":1,"408":1,"533":2}}],["capture:",{"2":{"296":1,"533":1}}],["capture.",{"2":{"200":1,"408":1,"444":1,"466":1}}],["capture,",{"2":{"95":1,"102":1,"531":1}}],["capture",{"0":{"200":1,"296":1,"408":1,"444":1,"455":1,"466":1,"531":1,"532":1,"533":1},"1":{"532":1,"533":1,"534":1},"2":{"95":1,"96":2,"106":1,"107":1,"108":1,"116":1,"120":1,"175":1,"200":3,"296":3,"366":1,"408":1,"444":1,"455":3,"456":1,"457":1,"466":2,"532":1,"533":1}}],["captures",{"2":{"7":1}}],["capped",{"2":{"9":1,"35":1,"137":1}}],["capabilities.",{"2":{"113":1}}],["capabilities",{"0":{"22":1,"227":1,"501":1},"2":{"5":1,"14":1,"281":1}}],["capability",{"0":{"5":1},"2":{"2":1,"4":1,"9":1,"308":1}}],["copies",{"2":{"170":1,"270":2}}],["copying:",{"2":{"419":1}}],["copy:",{"2":{"171":1}}],["copy",{"0":{"169":1,"170":1,"270":1},"2":{"12":1,"20":1,"139":3,"154":1,"169":3,"170":1,"171":1,"173":1,"207":1,"219":1,"235":1,"270":2,"368":1,"374":3,"486":1}}],["counter",{"2":{"501":1}}],["counters)",{"2":{"486":1}}],["counts",{"2":{"283":1}}],["count:",{"2":{"269":2,"286":1}}],["count",{"2":{"167":3,"227":1,"231":1,"269":1}}],["could",{"2":{"93":1}}],["could,",{"2":{"36":1}}],["colors",{"2":{"374":1}}],["colored",{"2":{"374":2}}],["color..."",{"2":{"257":1}}],["color",{"2":{"257":1}}],["color,",{"2":{"173":1}}],["colleagues\'",{"2":{"345":1}}],["collects",{"2":{"256":1,"284":1}}],["collisions",{"2":{"219":1,"235":1}}],["collaboration,",{"2":{"344":1}}],["collaborating.",{"2":{"76":1}}],["collapsible,",{"2":{"137":1}}],["col",{"2":{"208":2}}],["column",{"0":{"209":1},"2":{"8":1,"20":1,"189":3,"205":2,"208":2,"209":4,"213":1,"262":1,"372":1,"376":1,"463":1}}],["columns,",{"2":{"208":1}}],["columns",{"2":{"8":1,"225":1,"262":1,"376":1,"463":1,"539":1}}],["columns).",{"2":{"8":1}}],["coordinates",{"2":{"61":1}}],["coordinated",{"2":{"1":1}}],["cover",{"2":{"93":1,"94":1,"104":1,"385":1}}],["covers",{"2":{"93":1,"176":1}}],["coverage.",{"2":{"104":1,"382":1}}],["coverage,",{"2":{"96":1}}],["coverage",{"0":{"96":1},"2":{"49":1,"100":1,"102":1,"111":1,"117":1,"119":1}}],["covered.",{"2":{"96":1}}],["covered;",{"2":{"96":1}}],["covered,",{"2":{"96":1}}],["covered",{"2":{"13":1,"96":1,"105":1,"108":2}}],["cosine",{"2":{"38":1}}],["cosinesimilarity()",{"2":{"38":1}}],["coerce",{"2":{"37":1}}],["coercion",{"0":{"37":1},"2":{"37":1}}],["combined",{"2":{"230":1}}],["combine",{"2":{"164":1}}],["combining",{"2":{"164":1}}],["coming",{"2":{"99":1,"117":1,"342":1}}],["comfortable:",{"2":{"400":1}}],["comfortable",{"2":{"96":1,"107":1,"116":1,"268":1,"366":1,"400":1,"515":1}}],["comments:",{"2":{"525":1}}],["commercial",{"2":{"368":1}}],["comma",{"2":{"415":1,"542":1}}],["command.",{"2":{"541":1}}],["command",{"2":{"95":1,"96":4,"98":1,"115":1,"116":4,"120":1,"122":1,"137":1,"172":1,"196":1,"245":1,"274":1,"285":2,"340":1,"343":1,"362":1,"384":1,"407":2,"415":2,"436":1,"445":1,"457":1,"473":1,"477":1,"480":1,"494":1,"500":1,"516":1,"517":2,"530":1,"536":1,"537":1,"540":1,"541":2,"542":3}}],["commands,",{"2":{"535":2}}],["commands"",{"2":{"480":1}}],["commands.",{"2":{"85":1,"407":1}}],["commands",{"0":{"86":1,"306":1},"1":{"87":1,"88":1,"89":1},"2":{"63":1,"95":1,"103":1,"187":1,"406":1,"480":1}}],["commit,",{"2":{"390":1}}],["commit.",{"2":{"350":1}}],["committing.",{"2":{"349":1}}],["committed,",{"2":{"350":1}}],["committed",{"0":{"243":1},"2":{"349":1,"414":1,"526":1}}],["commit:",{"2":{"347":1}}],["commits",{"2":{"291":2,"346":1,"352":1,"464":2,"507":1}}],["commits,",{"2":{"70":1}}],["commit",{"0":{"348":1,"350":1},"1":{"349":1,"350":1},"2":{"63":2,"348":1,"350":1,"351":1,"353":1,"354":2,"434":1,"464":1}}],["communities",{"2":{"50":1}}],["communitydetector.js,",{"2":{"39":1}}],["community",{"0":{"39":1,"50":1},"2":{"39":1,"49":1,"50":1}}],["communicating",{"2":{"47":1,"57":1}}],["communicates",{"2":{"39":1,"47":1}}],["commons",{"2":{"367":1}}],["commonjs",{"2":{"88":1}}],["common",{"0":{"421":1},"1":{"422":1,"423":1,"424":1,"425":1,"426":1,"427":1,"428":1,"429":1,"430":1,"431":1,"432":1,"433":1,"434":1,"435":1,"436":1,"437":1,"438":1,"439":1,"440":1,"441":1,"442":1,"443":1,"444":1,"445":1,"446":1},"2":{"36":1,"66":1,"120":1,"195":1,"374":1,"391":1,"447":1}}],["completion",{"2":{"309":1,"479":1,"493":1,"529":1}}],["completions",{"2":{"166":1}}],["completely",{"2":{"374":1,"410":1}}],["completely.",{"2":{"274":1}}],["completed.",{"2":{"525":1,"530":1}}],["completed",{"0":{"445":1},"2":{"183":1,"287":1,"445":1,"473":2,"498":1,"523":1,"525":1,"529":1}}],["completed,",{"2":{"131":1}}],["complete",{"2":{"131":1,"176":1,"331":1}}],["completeness",{"2":{"119":1,"130":1}}],["completeness:",{"2":{"94":1}}],["compiles",{"2":{"92":1,"339":1,"506":1}}],["compiled",{"2":{"2":1,"9":1,"338":1}}],["compresses",{"2":{"104":1,"372":1}}],["compressed",{"2":{"11":1,"338":1}}],["comprehensive",{"2":{"90":1}}],["comparison:",{"0":{"491":1}}],["comparison",{"2":{"353":1}}],["comparing",{"0":{"353":1}}],["compared,",{"2":{"355":1}}],["compared",{"2":{"339":2}}],["compare",{"2":{"291":1,"351":1,"419":1,"434":1,"464":1}}],["compare,",{"0":{"291":1},"2":{"95":1}}],["compatibility",{"2":{"47":1,"225":1}}],["compatible).",{"2":{"410":1}}],["compatible:",{"2":{"52":1,"410":1}}],["compatible",{"2":{"39":1,"52":1,"410":1}}],["compact,",{"2":{"515":1}}],["compact:",{"2":{"400":1}}],["compact",{"2":{"96":1,"107":1,"116":1,"262":1,"268":1,"366":1,"376":2,"400":2,"463":1,"515":1}}],["compacts",{"2":{"24":1}}],["compaction.spec.js:",{"2":{"13":1}}],["compaction",{"0":{"11":2,"24":2},"2":{"1":2,"2":2,"12":1,"13":1,"20":2,"28":1,"372":1}}],["compaction,",{"2":{"0":1,"91":1}}],["computer",{"2":{"340":1}}],["computer.",{"2":{"336":1}}],["computes",{"2":{"62":1}}],["compute",{"2":{"38":1}}],["component.",{"2":{"379":1}}],["components",{"2":{"105":1}}],["components.",{"2":{"93":1}}],["component",{"0":{"59":1},"2":{"59":1}}],["component:",{"2":{"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1}}],["compound",{"2":{"35":1}}],["composition",{"2":{"13":1}}],["corner",{"2":{"374":1,"380":1}}],["corner.",{"2":{"139":1}}],["corporate",{"2":{"337":1}}],["corresponding",{"2":{"339":1}}],["correct.",{"2":{"448":1,"450":1}}],["correctly",{"2":{"213":1}}],["correctly.",{"2":{"82":1}}],["correctness",{"2":{"119":1}}],["correctness:",{"2":{"94":1}}],["correct",{"0":{"98":1},"2":{"94":1,"134":1,"219":1}}],["corruption.",{"2":{"419":1}}],["corrupting",{"2":{"33":1}}],["corrupted",{"2":{"220":1,"236":1}}],["core",{"0":{"84":1,"477":1},"2":{"9":1,"59":1,"61":1,"91":1,"96":3,"110":1,"240":1,"333":1}}],["codes",{"2":{"312":1}}],["code)",{"2":{"202":1,"356":1}}],["code`",{"2":{"196":1}}],["code\\\\`",{"2":{"193":1}}],["code:",{"2":{"117":1}}],["codebase:",{"2":{"95":1}}],["codeblock,",{"2":{"32":1}}],["codeexecutoripc.test.js:",{"2":{"91":1}}],["code.",{"2":{"79":1,"103":1,"253":1}}],["code,",{"2":{"75":1,"140":1,"173":1,"279":1,"379":1,"418":1}}],["codemirror:",{"2":{"369":1}}],["codemirror",{"2":{"56":1,"59":1,"84":1,"116":4}}],["code",{"0":{"132":1,"133":1,"136":1,"137":1,"188":1,"263":1,"279":1,"392":1},"1":{"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1},"2":{"11":1,"33":1,"59":1,"91":1,"93":1,"95":1,"96":1,"106":1,"107":1,"116":1,"117":7,"131":1,"132":2,"133":1,"134":2,"135":3,"136":3,"137":9,"139":2,"142":1,"172":1,"178":2,"188":2,"199":1,"253":2,"263":5,"274":1,"279":3,"291":1,"327":1,"331":2,"353":1,"366":1,"369":1,"374":1,"379":2,"392":3,"402":1,"418":1,"463":2,"486":1,"487":1}}],["converts",{"2":{"207":1,"225":1}}],["converted",{"0":{"442":1,"471":1},"2":{"151":1,"303":1}}],["convert",{"0":{"150":1,"433":1,"470":1},"2":{"150":1,"303":1}}],["conversion.",{"2":{"151":1,"442":1}}],["conversion",{"2":{"95":1,"471":1}}],["conversationstore",{"2":{"2":1}}],["conversation",{"2":{"2":1,"9":1,"12":1,"20":2,"55":1}}],["concentrated",{"2":{"404":1}}],["concepts",{"0":{"341":1},"2":{"390":1,"393":1}}],["conceptually.",{"2":{"104":1}}],["concept,",{"2":{"99":1}}],["concept.",{"2":{"37":1}}],["concept",{"0":{"38":1},"2":{"13":1,"38":1,"49":1,"341":1}}],["concise.",{"2":{"125":1}}],["conditions:",{"2":{"368":1}}],["conditions",{"2":{"116":1}}],["conflict.",{"2":{"120":1,"419":1,"451":1}}],["conflicting",{"2":{"94":1,"116":1}}],["conflicts.",{"2":{"104":1,"120":1,"129":1}}],["conflicts",{"0":{"313":1,"451":1},"2":{"79":1,"96":1,"104":1,"110":1,"115":1,"116":5,"117":1,"118":1,"122":1,"131":1,"313":1}}],["conflicts,",{"2":{"65":1,"95":1}}],["conflict",{"0":{"419":1},"2":{"78":1,"96":4,"103":1,"106":1,"108":1,"112":1,"313":1,"419":4,"451":1,"526":1}}],["confidently",{"2":{"120":1}}],["confidenceanomalies",{"2":{"49":1}}],["confidence,",{"2":{"44":1}}],["confidence.",{"2":{"34":1}}],["confidence",{"2":{"12":1,"39":1,"48":1,"49":1,"54":1,"411":2}}],["confirmed",{"2":{"440":1}}],["confirm.",{"2":{"325":1,"330":1,"422":1,"443":1}}],["confirm",{"2":{"82":1,"220":1,"236":1,"280":1,"386":1,"418":1,"430":1,"441":1,"448":1,"451":1,"452":1,"455":1,"456":1,"457":1,"458":1,"459":1,"461":1,"474":1,"479":1}}],["config",{"2":{"138":1}}],["config,",{"2":{"72":1}}],["configurable",{"2":{"394":1,"417":1}}],["configurable.",{"2":{"54":1}}],["configuration:",{"2":{"415":1}}],["configurations",{"2":{"338":1}}],["configurations.",{"2":{"55":1}}],["configuration",{"0":{"74":1,"537":1},"1":{"538":1}}],["configure",{"0":{"247":1},"2":{"51":1,"346":1,"533":1}}],["configured,",{"2":{"393":1,"457":1}}],["configured.",{"2":{"219":1}}],["configured",{"2":{"10":1,"52":1,"357":1}}],["connected",{"2":{"420":1,"451":1}}],["connect",{"2":{"52":1,"281":1,"410":1}}],["connects",{"2":{"52":1}}],["connections.",{"2":{"417":1}}],["connections",{"2":{"164":1,"410":1,"508":1}}],["connection",{"2":{"52":2,"64":1,"420":1,"438":1,"452":1,"502":1}}],["connectives,",{"2":{"36":1}}],["connecting",{"2":{"20":1}}],["continue.",{"2":{"461":1}}],["continue",{"2":{"95":1,"96":1,"112":1,"208":1,"256":1,"380":1,"469":1,"513":1}}],["continuously,",{"2":{"330":1}}],["continuous",{"2":{"20":1}}],["contrasted",{"2":{"374":1}}],["contrast",{"2":{"137":1,"263":1,"374":2}}],["contracts",{"2":{"85":1}}],["control,",{"2":{"390":1}}],["controlled",{"2":{"296":1}}],["control:",{"2":{"209":1,"360":1,"484":1}}],["control",{"0":{"63":1,"289":1,"355":1,"464":1},"1":{"290":1,"291":1,"292":1,"356":1},"2":{"201":1,"210":1,"243":1,"290":1,"291":1,"292":1,"338":1,"345":1,"349":1,"350":1,"355":1,"358":1,"379":1,"390":1,"464":1,"507":1,"516":1}}],["controls,",{"2":{"107":1,"517":1}}],["controls:",{"2":{"107":1,"262":1}}],["controls.",{"2":{"104":1,"111":1,"262":1,"425":1,"463":2}}],["controls",{"0":{"201":1,"314":1,"413":1,"420":1},"2":{"60":1,"95":2,"96":1,"99":1,"103":1,"106":1,"205":2,"213":1,"268":2,"297":1,"314":1,"376":1,"379":2,"380":1,"411":1,"412":2,"424":1,"427":1,"540":1}}],["control.",{"2":{"21":1,"414":1}}],["content.",{"2":{"174":1,"206":1,"213":1,"389":1,"451":1}}],["content}",{"2":{"143":1}}],["contents:",{"2":{"515":1}}],["contents",{"2":{"139":1,"354":1,"521":1}}],["content",{"0":{"230":1,"280":1,"485":1},"2":{"48":1,"55":1,"60":1,"78":1,"98":1,"105":2,"134":1,"167":1,"169":1,"174":2,"187":1,"192":1,"210":1,"230":4,"269":1,"270":1,"277":1,"306":1,"326":1,"354":1,"377":3,"387":1,"389":1,"402":1,"485":1,"490":1,"515":1,"517":2}}],["contextmenu",{"2":{"116":1,"366":1}}],["contextual",{"2":{"105":1,"124":1,"262":1}}],["contexts",{"0":{"60":1}}],["context,",{"2":{"23":1,"372":1}}],["context.",{"2":{"11":1,"187":1,"473":1}}],["contextorchestrator",{"2":{"2":1}}],["context",{"0":{"7":1,"11":1,"16":1,"24":1,"66":1,"173":1},"1":{"67":1},"2":{"0":1,"1":1,"2":1,"9":1,"12":1,"16":4,"20":1,"53":1,"70":1,"116":8,"129":1,"162":1,"257":1,"280":1,"366":1,"372":1,"376":1,"384":1,"482":1,"514":1}}],["contained",{"2":{"224":1,"337":1}}],["contains",{"2":{"102":1,"103":1,"104":1,"105":2,"218":1,"448":1}}],["contain",{"2":{"36":1}}],["containing",{"2":{"36":1,"338":1,"341":1,"374":1,"510":1,"512":1}}],["constraints.",{"2":{"493":1}}],["construction",{"2":{"9":1}}],["constructs",{"2":{"6":1}}],["consequence,",{"2":{"478":1}}],["consecutive",{"2":{"36":1}}],["consumes",{"2":{"339":1}}],["consumption,",{"2":{"12":1}}],["cons",{"0":{"339":1}}],["consider",{"2":{"164":1}}],["consistency",{"2":{"119":1,"130":1,"380":1}}],["consistent,",{"2":{"476":1}}],["consistently",{"2":{"116":1,"374":1}}],["consistent",{"2":{"94":1,"116":1,"135":1,"374":1,"396":1,"477":1}}],["console",{"2":{"71":1}}],["consonant",{"2":{"36":1}}],["r:",{"2":{"534":1}}],["r),",{"2":{"517":2}}],["r)",{"0":{"455":1},"2":{"200":1}}],["r",{"2":{"175":2,"200":2,"209":1,"296":1,"363":1,"408":1,"455":1,"466":1}}],["r,",{"2":{"174":1}}],["r1",{"2":{"52":1}}],["risk",{"2":{"187":1}}],["richer",{"2":{"260":1,"320":1}}],["rich",{"2":{"52":1,"132":1,"165":1,"187":1,"263":1,"291":1}}],["right)",{"2":{"262":1}}],["rightmost",{"2":{"208":1}}],["right,",{"2":{"173":1}}],["right.",{"2":{"166":1}}],["right",{"2":{"15":1,"18":1,"96":1,"139":2,"150":1,"151":1,"164":1,"166":1,"170":1,"172":1,"173":1,"174":1,"189":2,"208":1,"209":2,"257":1,"274":1,"303":2,"374":1,"433":1,"434":1,"442":1,"470":1,"471":1,"517":1,"520":1}}],["ruby",{"2":{"138":1}}],["rust,",{"2":{"134":1,"138":1,"188":1}}],["rule",{"2":{"36":5,"49":1}}],["rules:",{"2":{"47":1,"49":1}}],["rules.",{"2":{"37":1,"139":1}}],["rules",{"0":{"190":1,"477":1},"2":{"36":1,"46":1}}],["runner",{"2":{"91":1,"137":1}}],["running)",{"2":{"482":1}}],["running",{"2":{"2":1,"7":1,"54":1,"137":1,"337":1}}],["run",{"0":{"438":1},"2":{"66":1,"87":1,"88":1,"89":2,"90":5,"95":1,"105":2,"106":1,"112":1,"124":1,"127":1,"131":1,"136":1,"137":4,"199":1,"247":1,"249":1,"263":2,"274":1,"308":1,"334":2,"339":1,"358":1,"410":1,"426":1,"438":1,"440":1,"445":2,"452":1,"473":2,"517":1,"535":1}}],["runtimes",{"2":{"339":1}}],["runtime,",{"2":{"339":1}}],["runtime.",{"2":{"8":1,"54":1,"369":1}}],["runtime",{"2":{"2":1,"9":1,"26":1,"35":1,"66":1,"415":1}}],["runs",{"2":{"2":2,"26":1,"35":1,"42":1,"49":1,"50":1,"53":3,"54":1,"63":1,"137":4,"330":1,"337":1,"338":1,"481":1,"489":1}}],["random",{"2":{"484":1}}],["radius",{"2":{"374":2,"380":1}}],["rail",{"2":{"374":1}}],["rail.",{"2":{"15":1}}],["ram",{"2":{"339":1}}],["rather",{"2":{"102":1,"393":1}}],["ratio",{"2":{"49":1}}],["rate",{"2":{"10":1}}],["raw,",{"2":{"95":1,"98":1}}],["rawpayload)",{"2":{"85":1}}],["raw",{"2":{"29":1,"48":1,"75":1,"85":1,"166":1,"201":1,"203":1,"205":1,"212":1,"225":1,"229":1,"230":4,"269":1,"274":1,"291":1,"328":1,"463":1,"484":1,"486":1,"506":1}}],["room.",{"2":{"515":1}}],["root",{"2":{"49":1,"75":1,"99":1,"219":1,"220":1,"231":1,"235":1,"236":1,"415":1,"488":1,"490":1,"539":1}}],["rollback",{"2":{"356":1}}],["role:",{"2":{"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1}}],["role",{"2":{"8":1,"415":3,"541":1,"542":2}}],["routes,",{"2":{"486":1}}],["routes.",{"2":{"486":1}}],["routes:",{"2":{"278":1}}],["route",{"2":{"484":2}}],["routing,",{"2":{"13":1,"59":1}}],["rows.",{"2":{"216":1,"445":1,"502":1}}],["rows",{"0":{"208":1},"2":{"208":1,"225":1,"262":1,"376":1,"400":2,"463":1,"539":1}}],["row",{"2":{"189":2,"205":2,"208":4,"374":1,"376":1,"473":1,"515":1}}],["row.",{"2":{"50":1,"380":1}}],["roadmap",{"0":{"131":1}}],["rotation",{"0":{"420":1},"2":{"95":1}}],["rotated",{"2":{"420":1}}],["rotate",{"2":{"79":1,"106":1,"420":1}}],["reinsert",{"2":{"450":1}}],["reusing",{"2":{"381":1}}],["reuse",{"2":{"323":1}}],["reorganized",{"2":{"372":1}}],["reopen",{"0":{"245":1},"2":{"252":1,"340":1}}],["reopens",{"2":{"149":1}}],["reopening",{"2":{"95":1,"108":1}}],["rewritten",{"2":{"486":1}}],["rewriting",{"2":{"305":1,"486":2}}],["rewrite",{"2":{"18":1}}],["revoke",{"2":{"420":1}}],["revisions",{"2":{"434":1,"464":1}}],["revision:",{"2":{"354":1}}],["revision",{"0":{"352":1}}],["revision.",{"2":{"291":1}}],["review).",{"2":{"466":1}}],["review,",{"2":{"444":1}}],["reviews,",{"2":{"287":1}}],["review.",{"2":{"287":1}}],["reviewing",{"2":{"165":1,"515":1}}],["review",{"0":{"119":1,"445":1,"456":1},"2":{"82":1,"95":1,"108":2,"200":2,"240":1,"267":1,"296":4,"298":1,"345":1,"408":3,"444":1,"445":2,"455":1,"456":2,"466":1,"473":1,"533":2,"534":1}}],["reveal",{"2":{"173":1,"253":1,"379":2}}],["reveals",{"2":{"145":1,"227":1}}],["revert",{"2":{"151":1,"349":1,"374":1,"434":1,"520":1}}],["re",{"0":{"149":1},"2":{"134":1,"303":1,"417":1,"448":1,"455":1,"459":1,"469":1,"517":1}}],["red",{"2":{"499":1}}],["redistribute",{"2":{"368":1}}],["red.",{"2":{"353":1}}],["redo",{"2":{"116":2,"363":1}}],["reducing",{"2":{"160":1}}],["reduced",{"2":{"162":1}}],["reduces",{"2":{"160":1,"404":1}}],["reduce",{"2":{"125":1,"266":1,"374":1,"453":1,"472":1}}],["reduction,",{"2":{"11":1}}],["redundancy.",{"2":{"11":1}}],["redundant",{"2":{"8":1,"9":1}}],["render",{"2":{"193":1,"302":1,"491":1,"503":1}}],["render:",{"2":{"146":1}}],["renders,",{"2":{"500":1}}],["renders",{"0":{"487":1},"2":{"133":1,"134":1,"137":1,"141":1,"145":1,"153":1,"176":1,"192":1,"223":1,"226":1,"254":1,"481":1}}],["rendering.",{"2":{"223":1}}],["rendering,",{"2":{"84":1}}],["rendering",{"0":{"322":1,"486":1},"1":{"487":1},"2":{"59":1,"65":1,"166":1,"201":1,"260":1,"431":1,"468":1,"486":1,"487":1}}],["renderer,",{"2":{"339":1}}],["renderer",{"0":{"58":1},"1":{"59":1,"60":1},"2":{"57":1,"59":2,"84":1,"85":1,"93":2,"116":2}}],["rendered",{"2":{"17":1,"142":1,"145":1,"164":1,"166":2,"201":1,"212":1,"222":1,"223":1,"225":2,"229":2,"254":1,"260":1,"320":1,"328":1,"353":1,"482":1,"484":2,"491":2}}],["rename,",{"2":{"95":1,"295":1,"299":1}}],["renames,",{"2":{"62":1}}],["rename",{"2":{"42":1,"96":1,"116":1,"128":1,"257":1,"363":1,"465":1,"514":1,"533":1}}],["rebuilds.",{"2":{"70":1}}],["rebuild",{"0":{"41":1},"2":{"41":1,"49":1,"511":1}}],["requests",{"2":{"247":1,"419":1}}],["request",{"2":{"67":1,"220":1,"236":1,"489":1}}],["requested)",{"2":{"7":1}}],["requested",{"2":{"6":1,"11":2}}],["requirement",{"2":{"333":1}}],["requirements",{"0":{"333":1}}],["require(\\".",{"2":{"85":1}}],["required.",{"2":{"489":1}}],["required,",{"2":{"332":1}}],["required",{"2":{"54":1,"333":2,"411":1,"415":2,"542":2}}],["require",{"0":{"241":1},"2":{"47":1,"249":2,"339":1}}],["requires",{"2":{"37":1,"47":1,"52":2,"393":1}}],["replicate",{"2":{"416":1}}],["replace.",{"2":{"388":1}}],["replaced",{"2":{"379":1}}],["replace",{"0":{"264":1,"426":1},"2":{"94":1,"95":1,"96":1,"108":1,"115":1,"116":1,"122":1,"127":1,"131":1,"136":1,"150":1,"175":1,"354":1,"364":1,"426":3,"465":1,"470":1}}],["replace,",{"2":{"59":1,"295":1,"299":1}}],["repetition.",{"2":{"374":1}}],["repeat",{"2":{"103":1}}],["repeatedly",{"2":{"117":1}}],["repeated",{"2":{"36":1}}],["repo,",{"2":{"390":1}}],["repositories,",{"2":{"292":1}}],["repositories",{"2":{"290":1}}],["repository,",{"2":{"390":1}}],["repository:",{"2":{"358":1,"359":1}}],["repository.",{"2":{"346":1,"357":1,"358":1,"359":1,"368":1}}],["repository",{"0":{"290":1,"357":1,"358":1,"359":1},"1":{"358":1,"359":1,"360":1},"2":{"93":4,"346":2,"350":1,"358":1,"359":2,"383":1}}],["reports",{"2":{"231":1,"273":1}}],["report",{"2":{"93":1,"137":1}}],["represent",{"2":{"19":1,"510":3}}],["refinements",{"0":{"376":1,"380":1}}],["reflects",{"2":{"200":1,"381":1}}],["reflect",{"2":{"96":1}}],["refresh,",{"2":{"120":1}}],["refresh",{"0":{"439":1},"2":{"71":1,"96":1,"381":1,"439":1,"451":1,"453":1,"459":1,"491":2,"511":1}}],["refactoring",{"2":{"410":1,"527":1}}],["refactor",{"2":{"18":1}}],["referencing.",{"2":{"374":1}}],["reference.",{"2":{"436":1,"470":1,"533":1}}],["reference.md:",{"2":{"118":1}}],["reference.md",{"2":{"104":1}}],["reference,12.",{"1":{"320":1,"321":1,"322":1,"323":1}}],["reference,11.",{"1":{"316":1,"317":1,"318":1}}],["reference,10.",{"1":{"312":1,"313":1,"314":1}}],["reference,1.",{"1":{"223":1,"224":1,"225":1,"252":1,"253":1,"254":1,"255":1,"256":1,"257":1,"258":1,"396":1,"397":1}}],["reference,9.",{"1":{"305":1,"306":1,"307":1,"308":1,"309":1,"310":1}}],["reference,8.",{"1":{"302":1,"303":1}}],["reference,7.",{"1":{"294":1,"295":1,"296":1,"297":1,"298":1,"299":1,"300":1}}],["reference,6.",{"1":{"290":1,"291":1,"292":1,"410":1,"411":1,"412":1,"413":1}}],["reference,5.",{"1":{"283":1,"284":1,"285":1,"286":1,"287":1,"288":1}}],["reference,4.",{"1":{"277":1,"278":1,"279":1,"280":1,"281":1,"406":1,"407":1}}],["reference,3.",{"1":{"233":1,"234":1,"235":1,"273":1,"274":1,"275":1,"402":1,"403":1,"404":1}}],["reference,2.",{"1":{"227":1,"229":1,"230":1,"231":1,"260":1,"261":1,"262":1,"263":1,"264":1,"265":1,"266":1,"267":1,"268":1,"269":1,"270":1,"271":1,"399":1,"400":1}}],["reference,",{"2":{"103":1,"125":1}}],["reference",{"0":{"195":1,"221":1,"250":1,"327":1,"394":1},"1":{"196":1,"197":1,"198":1,"199":1,"200":1,"201":1,"202":1,"222":1,"226":1,"228":1,"232":1,"236":1,"251":1,"259":1,"272":1,"276":1,"282":1,"289":1,"293":1,"301":1,"304":1,"311":1,"315":1,"319":1,"395":1,"398":1,"401":1,"405":1,"408":1,"409":1,"414":1,"415":1},"2":{"65":1,"94":1,"95":1,"96":3,"99":2,"103":1,"104":2,"108":2,"112":1,"115":1,"116":3,"117":1,"123":1,"124":1,"126":2,"131":1,"150":1,"170":1,"331":1,"342":1,"363":2,"383":1,"491":1}}],["references.",{"2":{"224":1}}],["references",{"0":{"17":1},"2":{"49":1,"103":1,"117":1,"119":1,"128":1,"291":1}}],["referenced",{"2":{"11":1,"223":1,"510":1,"521":1}}],["refer",{"2":{"369":1,"519":1}}],["refers",{"2":{"94":1}}],["referred",{"2":{"17":1}}],["regular",{"0":{"391":1},"2":{"391":1}}],["regularly.",{"2":{"78":1}}],["regex.",{"2":{"392":1}}],["regex",{"2":{"95":1,"96":1,"102":1,"391":2}}],["regression",{"2":{"13":1}}],["registers",{"2":{"336":1}}],["registered",{"2":{"4":1}}],["registration,",{"2":{"84":1}}],["registry.",{"2":{"27":1}}],["registry",{"0":{"8":1,"27":1},"2":{"8":1}}],["rearrange",{"2":{"509":1}}],["reach",{"2":{"241":1}}],["react:",{"2":{"369":1}}],["react",{"2":{"58":1,"67":1,"84":1}}],["react,",{"2":{"56":1,"83":1}}],["real",{"2":{"59":1,"71":1,"102":1,"104":1,"115":1,"127":1,"129":1,"131":1,"159":1,"165":1,"166":1,"231":1,"274":1,"411":1,"485":1,"522":1,"526":1}}],["reasoning",{"2":{"350":1}}],["reasoning.",{"2":{"21":1}}],["reasons",{"2":{"12":1}}],["reader",{"2":{"381":1}}],["readers",{"2":{"177":1}}],["read",{"2":{"164":1,"166":1,"260":1,"328":1,"463":1}}],["read.",{"2":{"119":1}}],["reads",{"2":{"104":1,"340":1}}],["reading",{"2":{"167":2,"269":2,"489":1,"506":1}}],["reading).",{"2":{"20":1}}],["readiness",{"0":{"131":1},"2":{"100":1}}],["readme:",{"2":{"117":1}}],["readme,",{"2":{"103":1,"125":1}}],["readme.",{"2":{"96":1,"99":1}}],["readme.md:",{"2":{"118":2}}],["readme.md",{"2":{"93":1}}],["readme",{"0":{"97":1,"100":1},"2":{"94":1,"96":1,"98":1,"99":5,"117":4,"122":1,"125":1,"130":1}}],["readability",{"2":{"119":1}}],["readability).",{"2":{"18":1}}],["readable",{"2":{"59":1,"65":1,"72":1,"218":1,"234":1,"374":1}}],["ready",{"2":{"0":1,"342":1,"347":1,"349":1}}],["rejected.",{"2":{"234":1}}],["reject",{"2":{"65":1}}],["rejecting",{"2":{"46":1,"85":1}}],["rejection),",{"2":{"13":1}}],["rejection",{"2":{"12":1}}],["rejects",{"2":{"7":1,"36":4,"218":1}}],["remember",{"2":{"411":1}}],["remembered).",{"2":{"474":1}}],["remembered",{"2":{"323":1}}],["remix,",{"2":{"368":1}}],["remote,",{"2":{"419":1}}],["remote",{"0":{"344":1,"346":1},"1":{"345":1,"346":1,"347":1},"2":{"236":1,"292":1,"344":1,"346":5}}],["removing",{"2":{"208":1}}],["removes",{"2":{"208":2,"527":1}}],["remove",{"0":{"208":1},"2":{"95":1,"96":1,"108":1,"262":1,"274":1,"299":1,"420":1,"463":1}}],["removed",{"2":{"78":1,"95":1,"96":1,"106":1,"108":1,"116":2,"120":1,"244":1,"353":1,"363":1}}],["removed.",{"2":{"33":1}}],["removed).",{"2":{"12":1}}],["remains",{"2":{"374":1,"377":1}}],["remain",{"2":{"0":1,"21":1,"374":1}}],["retry.",{"2":{"457":1}}],["retrying",{"2":{"449":1}}],["retry",{"2":{"419":3,"456":1,"458":2}}],["retry,",{"2":{"220":1,"236":1}}],["retried",{"2":{"223":1}}],["retrieves",{"2":{"17":1,"20":1}}],["retrievedevidence,",{"2":{"9":1}}],["retrieval:",{"2":{"53":1}}],["retrieval.",{"2":{"29":1}}],["retrieval",{"2":{"7":2,"12":1,"13":1}}],["retrievalquality",{"2":{"2":1,"7":1,"12":1}}],["retrieval,",{"2":{"2":1}}],["retrieval):",{"2":{"2":1}}],["return",{"2":{"133":1,"188":1,"392":1}}],["returns",{"2":{"7":2,"10":1}}],["reschedule",{"2":{"498":1}}],["resume",{"2":{"256":2,"380":1,"513":1}}],["result:",{"2":{"461":1}}],["result.",{"2":{"435":1}}],["resulting",{"2":{"339":1}}],["result",{"2":{"178":1,"208":1,"212":1}}],["results",{"2":{"34":1,"49":1,"264":1,"278":1,"279":1,"280":1,"389":1,"392":1,"484":1,"489":1}}],["resize",{"2":{"433":1,"539":2}}],["resizable",{"2":{"150":1,"470":1}}],["reside",{"2":{"8":2}}],["respective",{"2":{"495":1}}],["respects",{"2":{"135":1,"415":1}}],["responsive",{"2":{"59":1}}],["responses",{"2":{"412":1,"484":1}}],["responsestructure)",{"2":{"8":1}}],["response",{"2":{"9":1,"412":1}}],["reset",{"2":{"106":1,"116":2,"268":1,"366":2,"397":1}}],["restart",{"2":{"448":1,"455":1}}],["restructuring",{"0":{"125":1}}],["restricted.",{"2":{"337":1}}],["restrict",{"2":{"216":1,"540":1}}],["restriction,",{"2":{"13":1}}],["restricts",{"2":{"6":1,"16":2,"39":1,"233":1,"541":1}}],["restoration",{"2":{"354":1}}],["restore:",{"2":{"520":1}}],["restored",{"2":{"355":1}}],["restores",{"2":{"346":1}}],["restore",{"0":{"151":1,"244":1,"300":1,"351":1,"434":1,"441":1,"442":1,"471":1},"1":{"352":1,"353":1,"354":1},"2":{"95":2,"96":1,"120":1,"151":3,"205":1,"219":1,"235":1,"244":1,"291":1,"354":2,"434":1,"441":2,"442":1,"464":1,"471":2}}],["restore,",{"0":{"291":1},"2":{"95":1}}],["restoring",{"0":{"354":1},"2":{"78":1,"258":1,"300":1}}],["resources.",{"2":{"539":1}}],["resources",{"2":{"8":1}}],["resolving,",{"2":{"451":1}}],["resolved",{"2":{"224":1,"384":1,"491":1}}],["resolved:",{"2":{"223":1}}],["resolved).",{"2":{"65":1}}],["resolve",{"2":{"79":1,"94":1,"122":1,"219":1,"235":1,"313":1,"451":1}}],["resolves",{"2":{"2":2,"5":1,"62":1,"65":1}}],["resolution,",{"2":{"59":1,"212":1,"225":1}}],["resolution",{"0":{"5":1,"419":1},"2":{"108":1,"145":1,"225":1,"419":1}}],["resolution):",{"2":{"2":1}}],["recut",{"2":{"520":1}}],["recursive",{"2":{"66":1}}],["recursively",{"2":{"62":1}}],["recognition",{"2":{"376":1}}],["recognizes",{"2":{"286":1}}],["reconnects",{"2":{"227":1}}],["reconstruct",{"2":{"4":1}}],["recover",{"0":{"464":1},"2":{"120":1,"300":1,"347":1,"464":1}}],["recovery"",{"2":{"393":1}}],["recovery.",{"2":{"127":1}}],["recovery",{"0":{"258":1},"2":{"108":2,"120":1,"258":1,"507":1}}],["recommended",{"2":{"52":1,"107":1,"360":1,"507":1}}],["recording",{"2":{"326":1}}],["recordings",{"2":{"75":1}}],["records",{"2":{"48":1,"502":1,"527":1}}],["record",{"2":{"48":1}}],["recently",{"2":{"74":1,"252":1,"256":2,"380":1,"461":1,"513":1}}],["recent",{"0":{"310":1},"2":{"5":1,"7":2,"11":1,"24":1,"94":1,"95":3,"96":3,"99":1,"103":1,"104":3,"106":1,"108":1,"111":1,"117":1,"120":2,"124":1,"131":1,"239":1,"245":2,"252":1,"256":1,"267":1,"340":2,"374":1,"461":1,"513":3}}],["relying",{"2":{"355":1}}],["reloading",{"0":{"517":1}}],["reload",{"2":{"95":1,"106":1,"116":1,"173":2,"174":3,"175":2,"219":1,"235":1,"363":1,"517":8}}],["related.",{"2":{"281":1}}],["related",{"2":{"80":1,"81":1,"128":1,"257":1,"307":1,"341":1,"390":2,"411":2,"413":1,"462":1,"511":1}}],["relatively:",{"2":{"519":1}}],["relatively",{"2":{"102":1}}],["relative",{"2":{"62":1,"104":1,"170":1,"197":1,"219":1,"235":1,"374":1,"486":1,"487":1}}],["relations.",{"2":{"47":1,"511":1}}],["relationship",{"0":{"47":1},"2":{"39":1,"48":2,"54":1,"66":1,"70":1,"75":1,"95":1,"106":1,"107":1,"516":1}}],["relationships:",{"2":{"411":1}}],["relationships.",{"2":{"54":1,"55":1,"411":1,"472":1,"508":1}}],["relationships",{"2":{"34":1,"35":1,"44":1,"48":1,"50":1,"81":1,"143":1}}],["relationships,",{"2":{"5":1}}],["relations,",{"2":{"25":1,"66":1}}],["relation",{"2":{"6":1,"66":1}}],["released",{"2":{"367":1}}],["release:",{"2":{"94":1}}],["release",{"0":{"131":1,"335":1,"370":1},"1":{"371":1,"372":1,"373":1,"374":1,"375":1,"376":1,"377":1,"378":1,"379":1,"380":1,"381":1,"382":1,"383":1,"384":1,"385":1,"386":1},"2":{"92":2,"93":1,"94":1,"95":1,"100":1,"111":1,"123":1,"131":1,"287":1,"334":1,"382":1,"383":1,"385":1}}],["releasing",{"0":{"82":1},"2":{"131":1}}],["relex)",{"2":{"410":1}}],["relex",{"2":{"54":2}}],["relevant",{"2":{"16":1,"102":1}}],["relevance",{"2":{"2":1,"7":2,"13":1,"17":1,"280":1}}],["47653.",{"2":{"418":1}}],["47653):",{"2":{"417":1}}],["4)",{"2":{"374":1}}],["4),",{"2":{"35":1}}],["4o",{"2":{"52":1,"410":1}}],["4o,",{"2":{"52":1,"410":1}}],["4+",{"2":{"36":1}}],["4,",{"2":{"33":1}}],["4,000",{"2":{"9":1}}],["429,",{"2":{"10":1}}],["4.0)",{"2":{"367":1}}],["4.0",{"0":{"368":1},"2":{"367":1}}],["4.",{"0":{"9":1,"10":1,"20":1,"26":1,"55":1,"68":1,"80":1,"90":1,"125":1,"276":1,"392":1,"405":1,"420":1,"425":1,"451":1,"464":1,"499":1,"504":1,"516":1,"527":1,"540":1}}],["4:",{"0":{"7":1,"35":1},"2":{"527":1}}],["4",{"0":{"3":1,"329":1},"1":{"4":1,"5":1,"6":1,"7":1},"2":{"2":2,"11":1,"13":1,"24":1,"36":1,"49":1,"91":1,"119":2,"130":2,"177":1,"204":1,"366":1,"417":1,"477":1,"527":1}}],["h.",{"2":{"434":1}}],["http",{"0":{"484":1},"2":{"484":1}}],["https",{"2":{"359":1}}],["html:",{"2":{"270":1}}],["html).",{"2":{"263":1}}],["html)",{"0":{"222":1},"1":{"223":1,"224":1,"225":1}}],["html,",{"2":{"134":1,"138":1,"188":1,"501":1}}],["html",{"0":{"192":1,"224":1},"2":{"32":1,"36":1,"65":1,"137":2,"169":2,"192":2,"207":1,"221":1,"223":1,"224":1,"229":2,"263":1,"486":1,"491":1,"503":1,"506":1}}],["h3",{"2":{"327":1}}],["h2,",{"2":{"327":1}}],["h2.",{"2":{"177":1}}],["h)",{"2":{"291":1,"464":1}}],["hr",{"2":{"197":1}}],["h6",{"2":{"196":1}}],["h1–h6",{"2":{"329":1}}],["h1,",{"2":{"327":1}}],["h1",{"2":{"177":1,"196":1}}],["h",{"2":{"175":2,"352":1,"364":1,"366":1,"388":1}}],["hmr",{"2":{"87":1}}],["hierarchy",{"2":{"177":1,"271":1}}],["hide.",{"2":{"477":1}}],["hides",{"2":{"404":1,"406":1}}],["hide",{"2":{"374":1}}],["hiding",{"2":{"160":1}}],["hidden",{"2":{"55":1,"75":1,"159":1,"162":1,"192":1,"231":1,"341":1,"374":1,"403":1}}],["history.",{"2":{"243":1,"290":1,"354":1,"356":1}}],["history.db.",{"2":{"502":1}}],["history.db",{"2":{"227":1}}],["history.db).",{"2":{"226":1}}],["history,",{"2":{"103":1,"120":1,"240":1,"242":1,"390":1}}],["history",{"0":{"226":1,"289":1,"351":1,"352":1,"434":1,"500":1},"1":{"227":1,"290":1,"291":1,"292":1,"352":1,"353":1,"354":1,"501":1,"502":1,"503":1,"504":1},"2":{"63":1,"77":1,"78":1,"95":2,"96":1,"175":1,"212":1,"226":1,"239":1,"291":3,"341":1,"351":1,"352":2,"353":1,"354":1,"356":1,"365":1,"366":1,"434":2,"464":3,"500":3,"502":1,"507":2}}],["high,",{"2":{"525":1}}],["highly",{"2":{"374":1}}],["highlights",{"2":{"521":1}}],["highlights,",{"2":{"520":1}}],["highlight.js",{"2":{"138":1}}],["highlighting:",{"2":{"188":1}}],["highlighting.",{"2":{"134":1,"291":1}}],["highlighting",{"2":{"133":1,"136":1,"138":1,"139":1,"166":1,"353":1,"389":1,"486":1,"487":1,"491":1}}],["highlighting,",{"2":{"59":1,"263":1}}],["highlight",{"2":{"18":1,"187":1,"509":1}}],["highlighted",{"2":{"16":1,"159":1,"499":1}}],["highest",{"2":{"94":1}}],["higher",{"2":{"54":1,"166":1,"412":1}}],["high",{"0":{"57":1,"111":1,"123":1},"2":{"26":1,"55":1,"96":2,"102":1,"104":2,"107":1,"120":1,"137":1,"145":1,"187":1,"212":1,"225":2,"263":1,"274":1,"495":1,"515":1,"523":1}}],["hunspell",{"2":{"274":2}}],["human",{"2":{"59":1,"72":1}}],["hub",{"2":{"49":1}}],["huggingface",{"2":{"26":1,"53":1,"99":1,"410":1}}],["heights",{"2":{"380":1}}],["height",{"2":{"380":1}}],["heuristics.",{"2":{"372":1}}],["heuristics:markdown[executive",{"2":{"11":1}}],["hello(name):",{"2":{"133":1}}],["helping",{"2":{"508":1}}],["helper",{"2":{"339":1,"477":1}}],["help.",{"2":{"316":1,"475":1}}],["helps",{"2":{"271":1,"298":1,"300":1,"411":1}}],["helpful",{"2":{"187":1,"263":1,"411":1,"463":1}}],["help",{"0":{"105":1,"128":1,"315":1,"343":1,"385":1,"475":1},"1":{"316":1,"317":1,"318":1},"2":{"71":1,"93":1,"94":1,"95":1,"96":2,"98":1,"99":3,"103":3,"104":4,"105":8,"110":1,"116":4,"117":3,"118":4,"119":1,"124":1,"125":1,"128":1,"130":1,"131":3,"164":1,"202":1,"243":1,"248":1,"314":1,"316":2,"317":1,"318":1,"343":1,"362":1,"382":1,"383":1,"385":1,"386":1,"414":1,"436":1,"437":2,"454":2,"475":4}}],["here.",{"2":{"187":1,"192":1}}],["here"",{"2":{"127":1}}],["here",{"2":{"105":1,"119":1,"191":1}}],["heavy",{"2":{"453":1}}],["head",{"2":{"345":1}}],["header:",{"2":{"328":1}}],["headers",{"2":{"262":1}}],["header.",{"2":{"172":1,"427":1}}],["header",{"2":{"166":1,"168":1,"187":1,"201":1,"204":3,"205":2,"209":1,"213":2,"262":1,"286":1,"330":1,"375":1,"463":1,"496":1,"529":1}}],["header;",{"2":{"96":1}}],["heading",{"2":{"159":2,"172":1,"177":7,"193":1,"196":2,"327":1,"329":1,"449":1,"486":1}}],["headings,",{"2":{"261":1,"463":1}}],["headings",{"0":{"177":1},"2":{"157":1,"403":1,"428":1,"486":1}}],["headless",{"2":{"65":1,"223":1,"491":1}}],["healing",{"2":{"50":1}}],["health:",{"2":{"513":1}}],["health",{"0":{"298":1,"521":1},"2":{"20":1,"28":1,"95":1,"96":1,"372":1,"440":1,"521":1}}],["hourly",{"2":{"496":1,"497":1,"516":1}}],["hour",{"2":{"493":1,"498":1}}],["hours,",{"2":{"492":1}}],["house",{"2":{"75":1}}],["home,",{"2":{"379":1}}],["hosts.",{"2":{"415":2}}],["hosted",{"2":{"346":1}}],["host",{"2":{"339":1,"491":1,"506":1,"537":1}}],["hood",{"2":{"274":1,"356":1}}],["hook",{"2":{"116":7}}],["holds",{"2":{"238":1}}],["horizontal",{"0":{"190":1}}],["hotkeys.",{"2":{"59":1}}],["how",{"0":{"245":1,"310":1,"483":1,"532":1},"2":{"19":1,"20":1,"76":2,"106":1,"281":1,"411":1,"412":3,"515":1}}],["hovering",{"2":{"145":1,"171":1,"212":1}}],["hover",{"0":{"171":1},"2":{"17":1,"135":1,"136":1,"137":2,"187":1,"196":1,"263":2,"349":1,"374":2,"380":1,"509":1,"520":1}}],["hydrated",{"2":{"8":1}}],["hybrid",{"2":{"2":1,"29":1}}],["halts",{"2":{"419":1}}],["halo",{"2":{"380":1}}],["happening,",{"2":{"459":1}}],["happening.",{"2":{"309":1}}],["happens",{"0":{"247":1},"2":{"330":1}}],["hanging.",{"2":{"263":1}}],["hangs",{"2":{"137":1}}],["hand.",{"2":{"374":1}}],["handoff,",{"2":{"323":1}}],["handshakes",{"2":{"420":1}}],["handshake",{"2":{"91":1}}],["hand",{"2":{"59":1}}],["handling",{"2":{"78":1,"96":1,"108":1}}],["handling:",{"2":{"7":1,"502":1}}],["handled",{"2":{"206":1,"213":1,"244":1,"487":1}}],["handles,",{"2":{"75":1}}],["handles",{"2":{"62":1,"84":1,"185":1,"484":1}}],["handle,",{"2":{"60":1}}],["handlers,",{"2":{"93":1}}],["handler",{"2":{"1":1,"84":1}}],["hasn\'t",{"2":{"211":1}}],["has",{"2":{"94":1,"115":1,"139":1,"209":1,"210":1,"215":1,"227":1,"456":1,"499":1}}],["hashes",{"2":{"218":1,"234":1}}],["hashes,",{"2":{"55":1,"75":2}}],["hashed",{"2":{"65":1,"218":1,"234":1}}],["hash",{"2":{"48":1,"216":1,"218":1,"220":1,"233":1,"236":1,"526":1,"527":1}}],["hardening",{"2":{"99":1}}],["hardcoded",{"2":{"3":1,"37":1,"94":1,"105":1,"131":1}}],["harness",{"2":{"90":1}}],["haven\'t",{"2":{"499":1}}],["have,",{"2":{"36":1}}],["have",{"0":{"246":1},"2":{"33":1,"93":1,"202":1,"303":1,"347":1,"379":1,"380":1,"501":1}}],["22",{"2":{"502":1}}],["22.",{"0":{"445":1}}],["21.",{"0":{"444":1}}],["2px",{"2":{"380":1}}],["25",{"0":{"371":1},"1":{"372":1}}],["256",{"2":{"48":1,"65":3,"216":1,"218":3,"233":1,"234":3,"417":3,"420":1}}],["20.",{"0":{"443":1}}],["2000).",{"2":{"419":1}}],["200%",{"2":{"397":1}}],["200",{"2":{"167":1,"269":1}}],["2026",{"0":{"371":1,"373":1,"375":1,"378":1,"382":1},"2":{"93":2,"493":2}}],["23.",{"0":{"446":1}}],["23",{"2":{"103":1}}],["2–3",{"2":{"36":1}}],["270",{"2":{"13":1}}],["2:",{"0":{"5":1,"33":1},"2":{"11":1,"527":1}}],["2.0",{"2":{"52":1}}],["2.",{"0":{"3":1,"18":1,"24":1,"53":1,"58":1,"78":1,"85":1,"123":1,"226":1,"228":1,"259":1,"337":1,"346":1,"350":1,"353":1,"359":1,"389":1,"398":1,"418":1,"423":1,"449":1,"462":1,"494":1,"502":1,"507":1,"510":1,"514":1,"520":1,"525":1,"533":1,"537":1},"2":{"182":1,"524":1}}],["2",{"0":{"326":1},"1":{"327":1},"2":{"2":1,"11":2,"49":1,"130":1,"177":1,"189":1,"204":2,"363":1,"366":1,"372":1,"419":1,"477":1,"529":1}}],["1)",{"2":{"526":1}}],["19.",{"0":{"441":1}}],["19b.",{"0":{"442":1},"2":{"103":1}}],["17.",{"0":{"439":1}}],["17",{"0":{"373":1},"1":{"374":1}}],["1or",{"2":{"190":1}}],["1compiles",{"2":{"88":1}}],["1launches",{"2":{"87":1}}],["18.",{"0":{"440":1}}],["18",{"2":{"84":1}}],["18,",{"2":{"58":1}}],["15).",{"2":{"493":1}}],["15.",{"0":{"437":1}}],["15"",{"2":{"103":1,"118":1}}],["15",{"2":{"49":1,"493":1}}],["14.",{"0":{"436":1}}],["14**.",{"2":{"326":1}}],["14",{"2":{"49":1}}],["127.0.0.1",{"2":{"484":1}}],["12.",{"0":{"319":1,"434":1,"459":1}}],["12quick",{"2":{"187":1}}],["12use",{"2":{"185":1}}],["12",{"2":{"49":1,"89":1,"179":1,"209":1,"417":1}}],["123inline",{"2":{"189":1}}],["123rendered",{"2":{"183":1}}],["123for",{"2":{"179":1}}],["1234",{"2":{"192":1,"204":1,"523":1,"526":1}}],["1234column",{"2":{"189":1}}],["1234notely",{"2":{"133":1}}],["12345supported",{"2":{"188":1}}],["12345",{"2":{"85":1,"181":1}}],["123456→",{"2":{"194":1}}],["123456heading",{"2":{"177":1}}],["1234567",{"2":{"143":1}}],["12345678",{"2":{"90":1}}],["1234567891011121314",{"2":{"326":1}}],["1234567891011121314151617custom",{"2":{"187":1}}],["123456789",{"2":{"69":1}}],["123456",{"2":{"6":1,"7":1}}],["123",{"2":{"11":1,"182":1,"184":1,"186":1,"191":1,"193":1}}],["11:00).",{"2":{"493":1}}],["11.",{"0":{"315":1,"432":1,"458":1,"475":1}}],["11b.",{"0":{"433":1}}],["11b",{"2":{"103":1}}],["11",{"0":{"375":1},"1":{"376":1,"377":1},"2":{"49":1,"333":1}}],["100mb+",{"2":{"339":1}}],["100%",{"2":{"66":1}}],["100%):",{"2":{"13":1}}],["10.",{"0":{"311":1,"431":1,"457":1,"474":1}}],["10)",{"2":{"119":1,"130":1}}],["10",{"2":{"49":1,"94":1,"137":1,"263":1,"333":1}}],["1]",{"2":{"49":1}}],["16.",{"0":{"438":1}}],["16",{"2":{"49":2}}],["1:",{"0":{"4":1,"32":1,"95":1},"2":{"11":1,"527":1}}],["1",{"0":{"325":1},"2":{"2":1,"11":1,"39":1,"49":1,"116":1,"177":1,"189":1,"190":1,"204":2,"212":1,"363":1,"366":2,"417":1,"519":1}}],["1.2)),",{"2":{"35":1}}],["1.",{"0":{"2":1,"15":1,"23":1,"52":1,"57":1,"77":1,"84":1,"122":1,"222":1,"251":1,"336":1,"345":1,"349":1,"352":1,"358":1,"388":1,"395":1,"417":1,"422":1,"448":1,"461":1,"493":1,"501":1,"506":1,"509":1,"513":1,"519":1,"523":1,"532":1,"536":1},"2":{"197":1,"523":1,"524":1}}],["13.",{"0":{"435":1}}],["13",{"0":{"1":1,"23":1},"2":{"0":1,"1":1,"21":1,"23":1,"49":1,"372":2}}],["(headings,",{"2":{"487":1}}],["(highlight.js)",{"2":{"486":1}}],["(html):",{"2":{"137":1}}],["(6px)",{"2":{"374":1}}],["(62",{"2":{"13":1}}],["(x64).",{"2":{"339":1}}],["(x64)",{"2":{"333":1}}],["([x]).",{"2":{"525":1}}],["([x])",{"2":{"287":1}}],["([",{"2":{"287":1,"525":1}}],["([[note]]).",{"2":{"59":1}}],["(js),",{"2":{"263":1}}],["(js,",{"2":{"137":1}}],["(\\\\ufeff)",{"2":{"225":1}}],["(~",{"2":{"223":1,"501":1,"507":1}}],["(~130mb)",{"2":{"53":1}}],["(off",{"2":{"323":1}}],["(optional)",{"2":{"216":1,"233":1,"466":1}}],["(or",{"2":{"215":1,"219":1,"235":1,"274":1,"285":1,"325":1,"488":1,"490":1,"505":1}}],["(orphaned",{"2":{"49":1}}],["(orphan",{"2":{"42":1}}],["()",{"2":{"187":1}}],["(used",{"2":{"484":1}}],["(uses,",{"2":{"34":1}}],["(updates",{"2":{"269":1}}],["(under",{"2":{"172":1}}],["(unclosed",{"2":{"172":1}}],["(⚡)",{"2":{"153":1}}],["(deduplicated",{"2":{"486":1}}],["(defaults",{"2":{"542":1}}],["(default",{"2":{"417":1,"474":2}}],["(default)",{"2":{"209":1,"415":1}}],["(document",{"2":{"365":1}}],["(download):",{"2":{"225":1}}],["(download",{"2":{"225":2}}],["(dash)",{"2":{"286":1}}],["(data",{"2":{"36":1}}],["(diagrams.net)",{"2":{"152":1}}],["(```).",{"2":{"392":1}}],["(```",{"2":{"134":1}}],["(```mermaid)",{"2":{"59":1}}],["(var(",{"2":{"374":1}}],["(validatepayload)",{"2":{"85":1}}],["(verifymodeldimensions)",{"2":{"66":1}}],["(verbatim",{"2":{"11":1}}],["({workspace}",{"2":{"75":2,"539":1}}],["({data",{"2":{"32":1}}],["(%appdata%",{"2":{"74":1}}],["(.zip)",{"0":{"338":1}}],["(.exe)",{"0":{"336":1,"337":1}}],["(.excalidraw).",{"2":{"75":1}}],["(.pdf).",{"2":{"75":1}}],["(.png,",{"2":{"75":1,"487":1}}],["(.mp4,",{"2":{"75":1}}],["(.md)",{"2":{"8":1,"19":1}}],["(.notes",{"0":{"360":1},"2":{"65":1,"226":1,"231":1,"488":1}}],["(.note",{"0":{"232":1},"1":{"233":1,"234":1,"235":1},"2":{"65":1}}],["(katex),",{"2":{"59":1}}],["(knowledgegraph,",{"2":{"59":1}}],["($w",{"2":{"50":1}}],["(next)",{"2":{"374":1}}],["(neural",{"2":{"49":1}}],["(no",{"2":{"482":1}}],["(non",{"2":{"220":1,"236":1,"364":1}}],["(not",{"2":{"65":1,"201":1}}],["(notely",{"0":{"541":1}}],["(notes",{"2":{"446":1,"474":1}}],["(note",{"2":{"379":1}}],["(notepackageipc.cjs)",{"0":{"65":1}}],["(note,",{"2":{"32":1,"47":1,"196":1}}],["(node:sqlite",{"2":{"502":1}}],["(node:sqlite).",{"2":{"227":1}}],["(node:sqlite)",{"2":{"43":1}}],["(node.js",{"2":{"57":1}}],["(f3)",{"2":{"388":1}}],["(f1).",{"2":{"437":1}}],["(f1)",{"2":{"316":1,"475":1}}],["(for",{"0":{"230":1},"2":{"453":1,"477":1}}],["(full",{"0":{"228":1},"1":{"229":1,"230":1,"231":1}}],["(file",{"2":{"49":1}}],["(flowtracker),",{"2":{"55":1}}],["(flowtracker).",{"2":{"2":1}}],["(flowtracker)",{"2":{"1":1}}],["(google",{"2":{"410":1}}],["(gliner2",{"2":{"66":1,"410":1}}],["(gitservice.cjs)",{"0":{"63":1}}],["(gfm).",{"2":{"176":1}}],["(gfm)",{"2":{"59":1}}],["(gpt",{"2":{"52":1,"410":1}}],["(gemini,",{"2":{"66":1}}],["(gemini",{"2":{"52":1}}],["(get",{"2":{"7":1}}],["(graphservice.js,",{"2":{"66":1}}],["(graphconfidence,",{"2":{"54":1}}],["(graphmaintenance.js):",{"2":{"50":1}}],["(graphvalidationengine.js)",{"0":{"49":1}}],["(graphworker)",{"0":{"42":1}}],["(graphbuilder.rebuild())",{"0":{"41":1}}],["(10%",{"2":{"411":1}}],["(120ms",{"2":{"223":1}}],["(1",{"2":{"39":1,"119":1,"130":1}}],["(raw)",{"2":{"229":1}}],["(raw,",{"2":{"221":1}}],["(right",{"2":{"209":1}}],["(rendered",{"2":{"487":1}}],["(regex)",{"0":{"391":1}}],["(release.sh):",{"2":{"92":1}}],["(react",{"0":{"58":1},"1":{"59":1,"60":1},"2":{"57":1}}],["(recommended):",{"2":{"53":1}}],["(refreshed",{"2":{"34":1}}],["(runtime",{"2":{"2":1}}],["(|",{"2":{"32":1}}],["(>0.35",{"2":{"527":1}}],["(>20%",{"2":{"49":1}}],["(>4",{"2":{"24":1}}],["("sqlite",{"2":{"38":1}}],["("gemini",{"2":{"35":1}}],["(<0.25",{"2":{"13":1}}],["(🤖,",{"2":{"19":1,"27":1}}],["(browse",{"2":{"474":1}}],["(browser",{"2":{"339":1}}],["(bold,",{"2":{"202":1}}],["(buildnotedelta",{"2":{"419":1}}],["(build",{"2":{"92":1}}],["(builtin",{"2":{"19":1,"27":1}}],["(blocks",{"2":{"39":1}}],["(bge",{"2":{"38":1,"66":1,"410":1}}],["(base",{"2":{"9":1}}],["(ttl)",{"2":{"417":1}}],["(trash",{"2":{"258":1}}],["(tag).",{"2":{"417":1}}],["(tables",{"0":{"225":1}}],["(tasks:extract,",{"2":{"5":1}}],["(the",{"2":{"177":1,"470":1}}],["(type,",{"2":{"44":1}}],["(tone,",{"2":{"19":1}}],["(technical",{"2":{"12":1,"20":1}}],["(like",{"2":{"339":2,"346":1,"356":1,"506":1}}],["(left,",{"2":{"262":1}}],["(left",{"2":{"209":1}}],["(landing",{"2":{"379":1}}],["(landingview.jsx,",{"2":{"59":1}}],["(latest)",{"0":{"371":1,"378":1},"1":{"372":1,"379":1,"380":1,"381":1}}],["(lastindexof(\'\\\\n\'))",{"2":{"9":1}}],["(low,",{"2":{"525":1}}],["(logdb.js).",{"2":{"68":1}}],["(logdb.js)",{"0":{"68":1},"1":{"69":1,"70":1,"71":1}}],["(logdb).",{"2":{"55":1}}],["(logdb),",{"2":{"20":1,"372":1}}],["(local",{"2":{"10":1,"491":1}}],["(eperm,",{"2":{"223":1}}],["(environment",{"0":{"538":1}}],["(encrypted",{"2":{"221":1}}],["(entityresolver.isvalidentityname())",{"0":{"46":1}}],["(entity",{"2":{"38":1,"44":1}}],["(edit",{"2":{"303":1}}],["(editor",{"2":{"164":1}}],["(edges",{"2":{"49":1}}],["(event,",{"2":{"85":1}}],["(evidencestore.js)",{"0":{"48":1}}],["(evidencefusionengine.js)",{"0":{"47":1}}],["(embeddingdb.js):",{"2":{"66":1}}],["(electron",{"2":{"61":1,"84":2}}],["(excalidraw,",{"2":{"501":1}}],["(excluding",{"2":{"274":1}}],["(executive",{"2":{"11":1}}],["(explore",{"2":{"6":1,"7":1}}],["(e.g.,",{"2":{"41":1,"263":1,"325":1,"339":1,"350":1}}],["(e.g.",{"2":{"10":1,"18":1,"213":1,"337":1,"393":1,"415":1,"493":2,"529":1,"537":1,"542":1}}],["(queryexecutor.js)",{"0":{"10":1}}],["(websiterenderer.cjs)",{"0":{"486":1},"1":{"487":1}}],["(webpreview.cjs)",{"2":{"484":1}}],["(web)",{"2":{"229":1}}],["(workspace",{"2":{"231":1}}],["(workspace.recent",{"2":{"7":1}}],["(workermanager.cjs",{"2":{"84":1}}],["(windows)",{"0":{"200":1,"296":1,"466":1},"2":{"227":1,"366":1}}],["(will,",{"2":{"36":1}}],["(with",{"2":{"15":1,"20":1,"263":1,"374":1,"491":1}}],["(without",{"2":{"8":1}}],["(permissive,",{"2":{"541":1}}],["(person,",{"2":{"47":1}}],["(persona,",{"2":{"9":1}}],["(personas.db)",{"2":{"8":1,"27":1}}],["(powershell.exe",{"2":{"537":1}}],["(port",{"2":{"417":1}}],["(pat).",{"2":{"346":1}}],["(push",{"0":{"346":1}}],["(plus)",{"2":{"286":1}}],["(planner.js)",{"0":{"6":1}}],["(ps1),",{"2":{"263":1}}],["(ps1,",{"2":{"137":1}}],["(py),",{"2":{"263":1}}],["(py,",{"2":{"137":1}}],["(pdf,",{"2":{"501":1}}],["(pdf)",{"2":{"229":1}}],["(pdf",{"0":{"222":1},"1":{"223":1,"224":1,"225":1}}],["(p2plive.cjs",{"2":{"416":1}}],["(p2p)",{"0":{"79":1},"2":{"416":1}}],["(p2pservice.cjs)",{"0":{"64":1}}],["(process.env.notely",{"2":{"92":1}}],["(promptpipeline.js)",{"0":{"9":1}}],["(pragma",{"2":{"43":1}}],["(previous).",{"2":{"374":1}}],["(pre",{"2":{"9":1}}],["(if",{"2":{"454":1,"482":1}}],["(iv)",{"2":{"417":1}}],["(images,",{"2":{"281":1,"484":1,"501":1,"519":1}}],["(ipcschemas.cjs):",{"2":{"85":1}}],["(id,",{"2":{"8":1}}],["(invite",{"2":{"418":1}}],["(including",{"2":{"377":1}}],["(in",{"2":{"343":1}}],["(intentanalyzer.js)",{"0":{"4":1}}],["(intent",{"2":{"2":1}}],["(index.js).",{"2":{"1":1}}],["(",{"2":{"7":1,"35":1,"69":1,"146":1,"283":1,"489":1,"526":1}}],["(auto",{"2":{"491":1}}],["(arrow",{"2":{"379":1}}],["(asterisk)",{"2":{"286":1}}],["(asserttrustedipcsender):",{"2":{"85":1}}],["(a",{"0":{"455":1},"2":{"200":1,"466":1}}],["(admonitions)",{"0":{"187":1}}],["(app.getpath("downloads")).",{"2":{"504":1}}],["(app.jsx):",{"2":{"59":1}}],["(appears",{"2":{"279":1}}],["(applogspage.jsx):",{"2":{"71":1}}],["(appdata",{"2":{"19":1,"27":1}}],["(always",{"2":{"54":1}}],["(alter",{"2":{"8":1}}],["(action",{"2":{"5":1}}],["(aicleargraphdata)",{"2":{"71":1}}],["(aiclearembeddingsdata),",{"2":{"71":1}}],["(aiservice.cjs)",{"0":{"66":1},"1":{"67":1}}],["(ai,",{"2":{"36":1}}],["(aihealthpage.jsx)",{"0":{"12":1}}],["(aiflow.js),",{"2":{"20":1}}],["(aiflow.js)",{"0":{"2":1,"23":1}}],["(ai",{"0":{"11":1,"24":1,"393":1,"511":1},"2":{"1":1,"2":1,"20":1}}],["(cwd)",{"2":{"539":1}}],["(cmd.exe).",{"2":{"537":1}}],["(client",{"2":{"491":1}}],["(cc",{"2":{"367":1}}],["(center)",{"2":{"209":1}}],["(changes",{"2":{"183":1}}],["(chokidar):",{"2":{"62":1}}],["(callout)",{"2":{"196":1}}],["(calculated",{"2":{"167":1,"269":1}}],["(capabilityresolver.js)",{"0":{"5":1}}],["(ctrl+v)",{"2":{"207":1}}],["(ctrl",{"2":{"136":1,"202":1,"248":1,"253":2,"254":2,"257":1,"274":1,"291":1,"317":1,"340":1,"379":3,"418":1,"423":1,"445":1,"455":1,"462":1,"464":1,"473":1,"475":1,"494":1,"500":1,"507":1,"514":1,"517":2,"530":1}}],["(ctes).",{"2":{"66":1}}],["(css",{"2":{"65":1}}],["(column",{"2":{"211":1}}],["(codemirroreditor.jsx,",{"2":{"59":1}}],["(communitydetector.js):",{"2":{"50":1}}],["(compaction,",{"2":{"23":1,"372":1}}],["(compactedturnscount,",{"2":{"12":1}}],["(corp,",{"2":{"37":1}}],["(copy",{"2":{"28":1}}],["(containing",{"2":{"507":1}}],["(contextorchestrator.js)",{"0":{"7":1}}],["(context",{"2":{"2":1}}],["(confidence",{"2":{"4":1,"34":1}}],["(mermaid",{"0":{"467":1},"1":{"468":1,"469":1,"470":1,"471":1}}],["(media",{"2":{"65":1}}],["(memory",{"2":{"2":1}}],["(macos).",{"2":{"227":1}}],["(maxwidth",{"2":{"35":1}}],["(markdownpreview.jsx):",{"2":{"59":1}}],["(markdown",{"0":{"27":1},"2":{"323":1,"474":1}}],["(multi",{"2":{"2":1}}],["(sync",{"2":{"419":1}}],["(system",{"2":{"2":1}}],["(spacing",{"2":{"376":1}}],["(save",{"2":{"491":1}}],["(sanitized):",{"2":{"231":1}}],["(same",{"2":{"49":1}}],["(skips",{"2":{"172":1}}],["(strict):",{"2":{"541":1}}],["(stdout",{"2":{"137":1}}],["(stage)",{"2":{"349":1}}],["(staged",{"2":{"63":1}}],["(status,",{"2":{"44":1}}],["(shift",{"2":{"388":1}}],["(sh),",{"2":{"263":1}}],["(sh,",{"2":{"137":1}}],["(sha",{"2":{"48":1}}],["(src",{"2":{"84":1}}],["(supports",{"2":{"52":1}}],["(single",{"2":{"49":1}}],["(see",{"2":{"46":1}}],["(search",{"2":{"7":1}}],["(source",{"2":{"44":2,"49":1}}],["(scripts",{"2":{"92":1}}],["(screenshot,",{"2":{"37":1}}],["(score",{"2":{"2":1}}],["5))",{"2":{"374":1}}],["5).",{"2":{"46":1}}],["54%",{"2":{"94":1}}],["5+",{"2":{"36":1}}],["5:",{"0":{"36":1}}],["5.8",{"2":{"94":1,"130":1}}],["5.",{"0":{"11":1,"27":1,"72":1,"81":1,"92":1,"126":1,"282":1,"393":1,"408":1,"426":1,"452":1,"465":1,"517":1,"528":1}}],["5",{"0":{"2":1,"330":1},"2":{"1":1,"2":2,"12":1,"13":1,"20":1,"23":1,"28":1,"35":1,"36":1,"46":1,"49":1,"55":1,"91":1,"119":2,"130":1,"177":1,"204":1,"372":1,"418":1,"419":1,"529":1}}],["b,",{"2":{"418":1}}],["b[write",{"2":{"194":1}}],["b[create",{"2":{"143":1}}],["b",{"2":{"143":1,"189":1,"194":1,"196":1,"204":1,"329":1}}],["bit",{"2":{"417":2,"420":1}}],["binaries",{"2":{"541":1}}],["binary",{"2":{"75":1,"339":1,"415":1,"538":1}}],["binds",{"2":{"484":1}}],["bindings",{"2":{"339":1}}],["bindings,",{"2":{"129":1}}],["bindings.",{"2":{"94":1,"105":1,"386":1,"475":1}}],["bin",{"0":{"258":1},"2":{"258":3}}],["bi",{"0":{"526":1},"2":{"75":1,"516":1,"522":1,"526":1}}],["b.",{"0":{"63":1}}],["b)",{"2":{"39":1}}],["banner.",{"2":{"517":1}}],["banner",{"2":{"174":1,"374":2,"517":1}}],["badge.",{"2":{"358":1}}],["badges.",{"2":{"227":1,"501":1}}],["badge",{"2":{"172":1,"200":1}}],["bad",{"2":{"172":1}}],["bars",{"2":{"374":1}}],["bar",{"0":{"167":1,"528":1},"1":{"529":1,"530":1},"2":{"162":1,"167":1,"201":1,"212":1,"269":1,"279":1,"291":1,"358":1,"393":1,"500":1}}],["bar:",{"2":{"145":1,"388":1,"391":1}}],["bar.",{"2":{"59":1,"166":1,"278":1,"352":1}}],["basic",{"2":{"204":1}}],["basics",{"2":{"108":1}}],["bash:",{"2":{"407":1,"537":1}}],["bash):",{"2":{"137":1}}],["bash,",{"2":{"134":1,"138":1,"188":1,"267":1}}],["bash",{"2":{"106":1,"137":2,"263":1,"407":2,"415":4,"537":3,"538":4}}],["bash#",{"2":{"90":1}}],["bashnpm",{"2":{"87":1,"88":1,"89":1}}],["base.css",{"2":{"374":1}}],["base",{"2":{"52":1,"410":1,"433":1}}],["baseline.",{"2":{"131":1}}],["baseline",{"2":{"34":1}}],["based",{"2":{"34":1,"53":1,"119":1,"140":1,"155":1,"159":1,"296":1,"353":1,"393":1,"403":1,"410":1,"411":1,"515":1,"537":1}}],["backslashes",{"2":{"213":1,"377":1}}],["backslash",{"2":{"193":1}}],["backtick",{"2":{"139":1}}],["backticks",{"2":{"133":1}}],["backups.",{"2":{"507":1}}],["backups",{"2":{"506":1}}],["backups,",{"2":{"323":1}}],["backup",{"0":{"300":1},"2":{"104":1,"300":1,"520":1}}],["backend",{"2":{"138":1}}],["backend)",{"2":{"57":1}}],["backed",{"2":{"78":1,"94":1,"105":1,"355":1,"464":1}}],["background",{"2":{"26":1,"50":1,"84":2,"150":1,"210":2,"212":1,"225":1,"262":1,"374":2,"377":1}}],["back",{"2":{"10":1,"26":1,"116":1,"135":1,"136":1,"183":1,"210":1,"253":1,"258":1,"303":1,"349":1,"363":1,"376":1,"379":1,"461":1,"526":1}}],["bge",{"2":{"26":1,"53":2,"66":1}}],["browsing",{"2":{"258":1}}],["browser.",{"2":{"253":1,"254":1,"379":1,"482":1}}],["browser",{"2":{"224":1,"459":1,"481":1,"489":1,"491":2}}],["browse",{"2":{"216":1,"219":1,"233":1,"235":1,"323":1,"351":1,"446":1,"515":1}}],["broadcast",{"2":{"417":1}}],["broadest",{"2":{"104":1}}],["broadly",{"2":{"96":2,"98":1,"131":1}}],["broad",{"2":{"94":1,"119":1}}],["breathing",{"2":{"515":1}}],["break",{"2":{"179":1}}],["breaks",{"0":{"179":1}}],["breakdown,",{"2":{"372":1}}],["breakdown.",{"2":{"28":1}}],["breakdown",{"2":{"12":1,"20":1}}],["breadcrumb",{"0":{"271":1},"2":{"168":2,"271":1,"380":1}}],["breadcrumbs",{"0":{"168":1}}],["breadth:",{"2":{"100":1}}],["bridge",{"2":{"84":1}}],["branches.",{"2":{"345":1}}],["branches",{"0":{"344":1},"1":{"345":1,"346":1,"347":1},"2":{"345":2,"347":1}}],["branches,",{"2":{"292":1}}],["branch,",{"0":{"292":1}}],["branch",{"0":{"345":1},"2":{"63":1,"70":1,"344":1,"345":2}}],["brainstorming",{"2":{"412":1}}],["brainstorm",{"2":{"15":1}}],["become",{"2":{"486":1}}],["behind",{"2":{"242":1,"350":1}}],["behaviour.",{"2":{"379":1}}],["behaviour",{"2":{"230":1}}],["behavior:",{"2":{"539":1}}],["behavior,",{"2":{"96":1,"480":1}}],["behavior.",{"2":{"96":1,"455":1}}],["behavior",{"2":{"9":1,"96":1,"115":1,"116":1,"118":1,"296":1,"377":1,"413":1,"533":1}}],["being",{"2":{"220":1,"258":1,"330":1,"486":1}}],["below",{"2":{"208":1,"249":1}}],["beneath",{"2":{"137":1}}],["benefits:",{"2":{"11":1}}],["better",{"2":{"120":1,"139":1}}],["between",{"0":{"427":1},"2":{"57":1,"72":1,"79":1,"157":1,"164":1,"167":1,"179":1,"232":1,"265":1,"267":1,"291":1,"374":1,"411":1,"416":1,"525":2,"526":1,"530":1}}],["beyond",{"2":{"95":1,"99":1}}],["best",{"2":{"78":1,"155":1,"336":1,"337":1,"338":1}}],["be",{"0":{"243":1},"2":{"36":1,"93":1,"103":2,"104":1,"137":1,"164":1,"187":1,"205":1,"214":1,"290":1,"355":1,"357":1,"393":1,"411":1,"412":1}}],["before",{"0":{"82":1},"2":{"36":1,"46":1,"85":1,"94":1,"95":1,"131":1,"200":1,"218":1,"223":1,"234":1,"280":1,"296":2,"300":1,"323":1,"357":1,"380":1,"408":3,"419":1,"449":1,"455":1,"466":1,"486":1,"520":1,"526":1,"533":2,"534":1,"542":1}}],["been",{"2":{"33":1,"93":1,"227":1,"379":1,"380":1,"499":1,"501":1}}],["bulk",{"2":{"440":1,"521":1}}],["bullet",{"2":{"11":1,"524":1}}],["buffers.",{"2":{"173":1}}],["buffers,",{"2":{"60":1}}],["buffer",{"2":{"137":1,"485":1,"526":2}}],["bundle)",{"0":{"228":1,"232":1},"1":{"229":1,"230":1,"231":1,"233":1,"234":1,"235":1},"2":{"221":1}}],["bundle.",{"2":{"219":1}}],["bundled:",{"2":{"233":1}}],["bundled",{"0":{"217":1},"2":{"65":1}}],["bundles,",{"2":{"500":1}}],["bundles",{"2":{"65":1,"92":1,"506":1}}],["bundle",{"0":{"88":1},"2":{"65":3,"215":1,"217":1,"218":2,"233":2,"234":2,"235":1,"323":1,"339":1,"505":1}}],["but",{"2":{"54":1,"94":2,"96":6,"99":3,"104":1,"105":2,"107":1,"116":4,"117":1,"119":2,"120":2,"347":1,"414":1}}],["button,",{"2":{"374":1}}],["button).",{"2":{"263":1}}],["buttons.",{"2":{"529":1}}],["buttons,",{"2":{"477":1}}],["buttons",{"0":{"196":1,"197":1,"198":1,"478":1},"2":{"166":1,"201":1,"202":1,"205":1,"213":1,"328":1,"463":1}}],["buttons:",{"2":{"71":1,"212":1,"410":1}}],["button.",{"2":{"136":1,"174":1,"354":1}}],["button",{"0":{"200":1},"2":{"52":1,"71":2,"133":1,"135":1,"136":1,"137":2,"139":2,"149":1,"185":1,"196":1,"197":1,"198":1,"199":1,"200":1,"201":1,"204":1,"209":1,"221":1,"227":1,"263":4,"278":1,"279":1,"291":1,"349":1,"352":1,"381":1,"391":1,"408":1,"434":1,"464":1,"478":2,"486":1,"500":1,"501":1,"517":1,"532":1}}],["built",{"0":{"105":1},"2":{"56":1,"59":1,"78":1,"83":1,"105":1,"236":1,"313":1,"369":1,"502":1}}],["builtin",{"2":{"8":1}}],["builds",{"2":{"339":1,"489":1}}],["building",{"2":{"335":1}}],["build,",{"2":{"98":1}}],["build.",{"2":{"54":1}}],["build",{"0":{"49":1,"88":1,"92":1},"2":{"88":1,"89":1,"92":1,"106":1,"153":1,"368":1,"459":1,"535":1}}],["bubble.",{"2":{"17":1}}],["blank",{"2":{"179":1}}],["blur",{"2":{"103":1}}],["blueprint",{"0":{"1":1}}],["blobs.",{"2":{"75":1}}],["blocked",{"2":{"542":1}}],["blocked:",{"2":{"456":1}}],["blocking.",{"2":{"496":1}}],["blockquote",{"2":{"187":1,"196":1}}],["blockquote.",{"2":{"186":1}}],["blockquotes,",{"2":{"487":1}}],["blockquotes",{"0":{"186":1}}],["block\'s",{"2":{"136":1}}],["block.",{"2":{"135":1,"137":1,"142":1,"154":1,"486":1}}],["blocks"",{"2":{"279":1}}],["blocks).",{"2":{"172":1}}],["blocks",{"0":{"132":1,"188":1,"263":1},"1":{"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1},"2":{"59":1,"188":2,"274":1,"279":2,"302":1,"331":1,"392":2,"463":1,"487":1}}],["blocks.",{"2":{"55":1,"497":1}}],["blocks:",{"2":{"9":1}}],["block:",{"2":{"9":1,"16":1}}],["block",{"0":{"133":1,"142":1,"225":1,"392":1},"2":{"9":1,"59":1,"95":1,"96":1,"133":1,"134":2,"136":1,"137":2,"139":1,"142":1,"148":1,"198":2,"199":1,"263":1,"329":1,"419":1,"420":1,"449":1,"468":1,"487":1}}],["bookmark",{"2":{"464":1}}],["border",{"2":{"380":1}}],["borders",{"2":{"374":1}}],["bob",{"2":{"326":1}}],["box",{"2":{"196":1}}],["boxes",{"2":{"12":1,"20":1,"187":1}}],["bold",{"2":{"178":4,"327":1,"329":1}}],["bottom",{"2":{"167":1,"208":1,"536":2}}],["both",{"2":{"8":1,"33":1,"115":3,"146":1,"169":1,"178":1,"241":1,"270":1,"287":1,"339":1,"418":1,"482":1,"493":1}}],["body",{"2":{"8":3,"105":1,"187":1}}],["body:",{"2":{"8":1}}],["bounds",{"2":{"49":1}}],["boundary",{"2":{"36":1}}],["bound",{"2":{"5":1}}],["byte",{"2":{"9":1,"225":1,"417":1}}],["by",{"0":{"109":1},"1":{"110":1,"111":1,"112":1,"113":1},"2":{"1":1,"6":1,"13":1,"16":1,"24":1,"52":1,"58":1,"65":1,"68":1,"93":1,"105":1,"133":1,"160":1,"174":1,"176":1,"206":1,"218":2,"227":1,"234":1,"239":1,"244":1,"255":1,"257":1,"260":1,"274":1,"277":1,"286":3,"288":1,"296":1,"307":1,"323":1,"326":1,"328":1,"351":1,"356":1,"367":1,"372":2,"388":1,"391":1,"410":1,"419":1,"440":1,"463":3,"481":1,"484":1,"487":1,"489":1,"504":1,"510":1,"513":1,"514":1,"517":1,"521":1,"530":2,"535":1,"542":1}}],["elsewhere.",{"2":{"480":1}}],["element",{"2":{"162":1,"327":1}}],["element.",{"2":{"150":1}}],["elements.",{"2":{"195":1}}],["elements",{"2":{"145":1}}],["electron:",{"2":{"369":1}}],["electron,",{"2":{"56":1,"83":1}}],["electron",{"0":{"339":1},"2":{"1":1,"42":1,"61":2,"87":1,"88":1,"91":2,"93":2,"116":1,"339":1,"491":1}}],["e",{"2":{"366":1}}],["ebusy",{"2":{"223":1}}],["eperm"",{"2":{"220":1,"236":1}}],["erased",{"2":{"258":1}}],["erdiagram",{"2":{"143":1}}],["er",{"2":{"143":1}}],["error,",{"0":{"479":1}}],["error:",{"2":{"278":1,"391":1}}],["errors",{"2":{"146":1,"172":1}}],["errors,",{"2":{"9":1}}],["error.",{"2":{"137":1}}],["error):",{"2":{"10":1}}],["error",{"2":{"9":1,"10":1,"146":1,"270":1,"274":1,"278":1,"330":1,"415":1,"454":1,"457":1,"479":1}}],["e[commit",{"2":{"143":1}}],["easily",{"2":{"530":1}}],["easier",{"2":{"462":1}}],["easiest",{"0":{"248":1}}],["easy",{"2":{"119":1,"120":1,"170":1,"336":1,"338":1,"499":1}}],["earlier",{"2":{"244":1}}],["each",{"0":{"308":1},"2":{"50":1,"65":1,"67":2,"135":1,"209":1,"218":1,"229":2,"241":1,"281":1,"339":1,"394":1,"451":1,"486":1}}],["esc.",{"2":{"463":1}}],["escape),",{"2":{"379":1}}],["escaped",{"2":{"206":1,"213":1,"377":2}}],["escape",{"0":{"193":1}}],["esc",{"2":{"116":1,"210":1,"363":1}}],["estimated",{"2":{"94":2,"167":1,"269":1}}],["e.g.",{"2":{"478":3}}],["e.",{"0":{"66":1}}],["equations",{"2":{"59":1,"223":1}}],["etc.).",{"2":{"27":1,"37":1}}],["etc.)",{"2":{"19":1,"36":2,"172":1}}],["edges.",{"2":{"75":1}}],["edges)",{"2":{"49":1}}],["edges",{"2":{"49":2}}],["edge",{"2":{"15":1,"39":1,"42":1,"50":1}}],["edits.",{"2":{"300":1,"456":1}}],["edits",{"0":{"441":1},"2":{"296":1,"347":1,"376":1,"377":1,"419":2,"526":1}}],["edits,",{"2":{"62":1}}],["edit.",{"2":{"273":1}}],["editable",{"2":{"205":2,"323":1}}],["edited",{"2":{"205":1,"210":1,"256":1,"380":1,"441":1,"513":1,"527":1}}],["edit:",{"2":{"145":1,"260":1,"463":1}}],["edit,",{"0":{"427":1},"2":{"95":1,"159":1,"300":1,"520":1}}],["edit",{"0":{"149":1,"206":1,"260":1,"463":1},"2":{"19":1,"59":1,"77":1,"96":1,"108":1,"116":3,"133":1,"136":1,"142":1,"149":1,"150":1,"166":2,"167":1,"201":1,"203":1,"205":1,"206":1,"211":1,"212":1,"240":1,"262":1,"263":1,"303":1,"326":1,"328":1,"331":1,"361":1,"363":1,"376":1,"402":1,"432":1,"433":1,"463":1,"469":1,"470":1,"474":1}}],["editing.",{"2":{"208":1,"210":1,"469":1}}],["editing,",{"2":{"127":1,"485":1}}],["editing",{"2":{"15":1,"75":1,"95":1,"120":1,"136":1,"155":1,"189":1,"206":1,"262":1,"269":2,"299":1,"328":1,"369":1,"376":1,"377":1,"460":1,"513":1,"529":1}}],["editors",{"2":{"339":1}}],["editor,",{"2":{"129":1,"248":1}}],["editorpane.jsx,",{"2":{"59":1}}],["editor.",{"2":{"18":1,"132":1,"135":1,"146":1,"153":1,"154":1,"176":1,"206":1,"207":1,"262":1,"296":1,"376":1}}],["editor:",{"2":{"18":1,"59":1,"263":1}}],["editor",{"0":{"58":1,"136":1,"165":1,"205":1,"259":1,"262":1,"363":1,"401":1},"1":{"59":1,"60":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"260":1,"261":1,"262":1,"263":1,"264":1,"265":1,"266":1,"267":1,"268":1,"269":1,"270":1,"271":1,"402":1,"403":1,"404":1},"2":{"14":1,"33":1,"36":1,"46":1,"59":1,"84":1,"105":1,"116":9,"117":1,"136":2,"137":1,"145":1,"159":2,"165":1,"166":3,"167":1,"168":1,"169":1,"172":1,"173":1,"187":1,"189":3,"195":1,"196":1,"197":1,"201":3,"203":1,"204":1,"205":6,"208":1,"210":2,"212":1,"213":1,"262":1,"263":3,"271":1,"274":1,"296":1,"325":1,"326":1,"328":2,"329":1,"331":1,"342":1,"360":1,"362":2,"363":15,"364":2,"366":4,"374":1,"375":2,"377":1,"408":1,"427":1,"441":1,"463":1,"481":1,"485":1,"506":1,"526":2,"532":1,"533":1}}],["emphasis,",{"2":{"261":1}}],["empties,",{"2":{"42":1}}],["emptying",{"2":{"258":1}}],["emptygraph",{"2":{"49":1}}],["empty,",{"0":{"479":1},"2":{"7":2,"448":1}}],["empty",{"2":{"7":1,"49":1,"105":3,"113":1,"131":1,"134":1,"479":1}}],["email",{"2":{"169":1}}],["embed",{"2":{"148":1,"154":1,"194":1}}],["embedded",{"0":{"457":1,"516":1,"535":1},"1":{"536":1,"537":1,"538":1,"539":1,"540":1,"541":1,"542":1},"2":{"59":2,"71":1,"95":1,"96":1,"99":1,"147":1,"223":1,"267":1,"339":1,"406":1,"415":1,"487":2,"516":1,"535":1}}],["embedder",{"2":{"38":1}}],["embedding,",{"2":{"75":1}}],["embeddingspage",{"2":{"71":2}}],["embeddingspage,",{"2":{"59":1}}],["embeddings:",{"2":{"70":1,"411":1}}],["embeddings",{"2":{"38":2,"53":2,"66":2,"71":1,"106":1,"393":3,"410":2}}],["embeddings.db.",{"2":{"66":1}}],["embeddings.db:",{"2":{"55":1,"75":1}}],["embeddings.db",{"2":{"26":1}}],["embeddings,",{"2":{"23":1,"26":1,"107":1,"372":1}}],["embedding",{"0":{"26":1,"38":1,"53":1},"2":{"30":1,"66":1,"84":1,"95":1}}],["emoji",{"2":{"19":1}}],["emits",{"2":{"6":1,"10":1}}],["ensuring",{"2":{"374":1}}],["ensures:",{"2":{"356":1}}],["ensure",{"2":{"85":1,"139":1,"456":1}}],["encryption:",{"2":{"417":1}}],["encrypted",{"2":{"65":1,"91":1,"216":1,"218":1,"234":1,"417":2}}],["encoded",{"2":{"212":1,"225":1}}],["enhancements",{"0":{"127":1}}],["enough",{"2":{"119":1,"164":1}}],["enough:",{"2":{"106":1}}],["environments:",{"2":{"540":1}}],["environments",{"2":{"337":1}}],["environment.",{"2":{"137":1}}],["environment",{"0":{"415":1,"542":1},"2":{"99":1,"415":2,"538":1}}],["enforcement",{"2":{"542":1}}],["enforce",{"2":{"85":1,"542":1}}],["enforces",{"2":{"4":1,"36":1,"39":1,"47":1,"85":1,"415":1,"541":1}}],["enabling",{"2":{"75":1,"486":2}}],["enabled,",{"2":{"402":1}}],["enabled.",{"2":{"192":1,"486":1}}],["enabled",{"2":{"55":1,"393":1}}],["enable",{"0":{"429":1},"2":{"53":1,"205":1,"360":1,"391":1,"402":1}}],["enables,",{"2":{"34":1}}],["end:",{"2":{"493":1}}],["endpoint",{"2":{"410":2}}],["endpoints",{"2":{"52":1,"85":1}}],["end,",{"2":{"379":1}}],["end",{"0":{"120":1},"2":{"49":1,"94":1,"95":1,"96":1,"99":3,"104":1,"120":1,"123":1,"131":2,"179":1,"243":1,"417":2,"493":1,"498":1,"525":1}}],["ending",{"2":{"36":1}}],["engage",{"2":{"47":1}}],["engine)",{"2":{"339":1}}],["engine:",{"2":{"274":1,"419":1}}],["engineering",{"2":{"152":1,"155":1}}],["engine,graph",{"1":{"46":1,"47":1,"48":1,"49":1}}],["engine,database",{"1":{"44":1}}],["engine,ingestion",{"1":{"41":1,"42":1}}],["engine,",{"0":{"39":1}}],["engine,the",{"1":{"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1}}],["engine.",{"2":{"29":1}}],["engine",{"0":{"11":1,"29":1,"54":1,"64":1,"66":1,"527":1},"1":{"30":1,"31":1,"40":1,"43":1,"45":1,"50":1,"67":1},"2":{"59":1,"66":1,"372":1}}],["en",{"2":{"26":1,"38":1,"53":1,"66":1,"410":1}}],["entries",{"2":{"385":1}}],["entries.",{"2":{"75":1}}],["entropy",{"2":{"36":1}}],["entry",{"2":{"1":1,"245":1,"372":1}}],["enterprise",{"2":{"540":1}}],["enter,",{"2":{"379":1}}],["enters",{"2":{"137":1}}],["enter",{"2":{"36":1,"116":1,"210":1,"219":1,"235":1,"285":1,"325":2,"350":1,"364":2,"392":1,"418":1,"423":1,"424":1,"425":1,"426":1,"435":1,"456":1}}],["entities.",{"2":{"50":1}}],["entities",{"2":{"32":1,"35":1,"44":1,"49":4,"411":1}}],["entityresolver",{"2":{"38":1}}],["entityresolver.",{"2":{"38":1}}],["entityresolver.resolvementionvector()",{"2":{"38":1}}],["entityresolver.sanitizeentitytype()",{"2":{"37":1}}],["entityresolver.isvalidentityname()",{"2":{"36":1}}],["entity",{"0":{"37":1},"2":{"5":1,"35":1,"36":1,"37":1,"38":1,"39":1,"44":3,"47":1,"49":1,"50":2,"54":1,"55":1,"66":1,"70":1,"75":1,"516":1}}],["entirely",{"2":{"26":1,"53":1,"54":1,"96":1,"249":1}}],["entire",{"2":{"15":1,"16":1,"221":1,"228":1,"356":1,"387":1,"493":1,"495":1,"505":1}}],["even",{"2":{"390":1,"456":1}}],["event",{"2":{"231":1}}],["event,",{"2":{"85":1}}],["events",{"2":{"85":1}}],["events.",{"2":{"71":1}}],["everyday",{"2":{"460":1}}],["every",{"2":{"2":1,"34":1,"48":1,"49":1,"103":1,"139":1,"216":1,"218":1,"234":1,"250":1,"308":2,"355":1,"417":1,"486":1,"501":1}}],["evaluation",{"2":{"59":1}}],["evidencecoverageratio",{"2":{"49":1}}],["evidencelessedges",{"2":{"49":1}}],["evidenceless",{"2":{"49":1}}],["evidencefusionengine.js,",{"2":{"39":1}}],["evidencefusionengine.fusetriple().",{"2":{"34":1}}],["evidence",{"0":{"39":1,"48":1},"2":{"0":1,"7":2,"9":3,"30":1,"44":2,"48":3,"49":1}}],["excerpt,",{"2":{"489":1}}],["excel,",{"2":{"207":1}}],["excel",{"0":{"207":1},"2":{"225":1}}],["excluded",{"2":{"231":1,"488":1}}],["excali",{"2":{"65":1,"217":1,"233":1,"486":1}}],["excalidraw)",{"0":{"467":1},"1":{"468":1,"469":1,"470":1,"471":1}}],["excalidraw).",{"2":{"303":1}}],["excalidraw.",{"2":{"150":1,"432":1,"433":1,"470":1}}],["excalidraw",{"0":{"147":1,"148":1,"150":1,"303":1,"432":1,"433":1,"442":1,"469":1,"470":1},"2":{"59":1,"65":1,"75":1,"95":2,"96":1,"108":1,"140":1,"147":1,"148":3,"149":1,"150":3,"151":3,"155":1,"198":2,"217":1,"227":1,"233":1,"303":3,"329":1,"331":1,"442":1,"469":1,"471":1,"484":1,"486":1,"487":1,"501":1,"503":1}}],["exit",{"0":{"163":1},"2":{"263":1}}],["exist.",{"2":{"120":1,"521":1}}],["exist",{"2":{"115":1,"117":1,"119":1,"501":1}}],["existence",{"2":{"93":1}}],["exists.",{"2":{"202":1}}],["exists;",{"2":{"96":1}}],["exists,",{"2":{"96":2,"116":2,"119":1}}],["exists",{"2":{"69":2,"98":1,"211":1,"450":1}}],["existing",{"0":{"149":1,"386":1},"2":{"38":1,"95":1,"149":1,"154":1,"219":1,"235":1,"303":1,"359":1,"465":1}}],["example,",{"2":{"453":1,"477":1}}],["example.com",{"2":{"184":1}}],["example.com)",{"2":{"184":1}}],["example",{"0":{"144":1},"2":{"278":1,"279":1}}],["example:",{"2":{"139":1}}],["examples",{"0":{"480":1},"2":{"138":1}}],["examples:",{"2":{"105":1,"391":1}}],["exactly.",{"2":{"131":1}}],["exact",{"2":{"48":1,"307":1,"390":1,"393":1,"419":1,"454":1,"457":1,"501":1,"525":1,"527":1}}],["exe.sh):",{"2":{"92":1}}],["execute,",{"2":{"526":1}}],["execute",{"2":{"137":3,"263":1,"417":1}}],["executes",{"2":{"2":2,"7":1,"39":1,"66":1}}],["executables",{"2":{"415":1,"542":1}}],["executable.",{"2":{"92":1,"334":1,"538":2}}],["executable",{"0":{"337":1},"2":{"92":1,"415":1}}],["executor,",{"2":{"23":1,"372":1}}],["executive",{"0":{"94":1},"2":{"24":1,"372":1}}],["executing",{"2":{"23":1}}],["execution:",{"2":{"63":1,"263":1}}],["execution",{"0":{"2":1,"90":1,"137":1},"1":{"91":1},"2":{"2":1,"3":1,"6":1,"9":1,"10":2,"12":1,"20":2,"55":1,"57":1,"91":1,"137":4,"263":1,"372":1,"415":1,"516":1,"540":1,"541":1,"542":1}}],["executions",{"2":{"1":1}}],["extracted",{"2":{"55":1,"75":1,"374":1,"411":1}}],["extractor",{"2":{"48":1,"49":1}}],["extractor,",{"2":{"44":1}}],["extracts",{"2":{"32":1,"35":1}}],["extractions,",{"2":{"70":1}}],["extraction.",{"2":{"32":1}}],["extraction,",{"2":{"30":1}}],["extraction",{"0":{"35":1},"2":{"11":1,"13":1,"54":1,"66":1,"410":1}}],["extended",{"2":{"162":1,"525":1}}],["extends",{"2":{"16":1}}],["extension",{"2":{"95":1,"246":1,"503":1}}],["extensions",{"2":{"59":1}}],["externally",{"0":{"253":1},"2":{"174":1,"517":1}}],["externalurl,",{"2":{"32":1}}],["external",{"0":{"174":1},"2":{"1":1,"4":1,"62":1,"63":1,"66":1,"75":1,"85":1,"93":1,"100":1,"125":1,"174":2,"236":1,"355":1,"489":1,"517":2}}],["expired",{"2":{"417":1}}],["expiration",{"2":{"417":1}}],["expression",{"0":{"391":1},"2":{"391":1}}],["expressions",{"2":{"66":1}}],["expected",{"2":{"220":1,"236":1}}],["expectations",{"2":{"108":1}}],["expectations,",{"2":{"104":1}}],["experience,",{"2":{"336":1}}],["experience.",{"2":{"189":1}}],["experience:",{"2":{"136":1}}],["experience",{"0":{"259":1},"1":{"260":1,"261":1,"262":1,"263":1,"264":1,"265":1,"266":1,"267":1,"268":1,"269":1,"270":1,"271":1},"2":{"132":1,"263":1}}],["experimentation.",{"2":{"120":1}}],["export:progress)",{"2":{"231":1}}],["exportmanager.",{"2":{"225":2}}],["exporting",{"0":{"216":1,"233":1},"2":{"502":1}}],["export,",{"2":{"102":1,"104":1,"116":1,"120":1,"501":1}}],["exports.",{"2":{"231":1}}],["exports,",{"2":{"227":1,"500":1}}],["exports",{"0":{"225":1},"2":{"65":1,"145":1,"212":2,"222":1,"225":2,"226":1,"228":1,"374":1,"501":1,"504":1,"507":1}}],["exporters:",{"2":{"65":1}}],["exported.",{"2":{"217":1,"233":1}}],["exported",{"2":{"59":1,"212":1,"220":1,"227":3,"229":1,"236":1,"501":3,"503":1,"507":1}}],["export",{"0":{"65":1,"169":1,"212":1,"214":1,"221":1,"222":1,"223":1,"224":1,"226":1,"228":1,"229":1,"232":1,"270":1,"319":1,"321":1,"323":1,"443":1,"446":1,"458":1,"474":1,"491":1,"500":1,"503":1,"505":1,"506":1},"1":{"170":1,"215":1,"216":1,"217":1,"218":1,"219":1,"220":1,"222":1,"223":2,"224":2,"225":2,"226":1,"227":2,"228":1,"229":2,"230":2,"231":2,"232":1,"233":2,"234":2,"235":2,"236":1,"320":1,"321":1,"322":1,"323":1,"501":1,"502":1,"503":1,"504":1,"506":1,"507":1},"2":{"65":2,"95":1,"96":4,"98":1,"107":1,"108":2,"112":1,"116":3,"120":1,"169":1,"212":2,"215":2,"216":2,"217":1,"220":1,"221":5,"225":3,"226":2,"227":1,"228":1,"232":1,"233":2,"236":2,"240":1,"247":1,"270":1,"321":2,"323":4,"365":1,"366":1,"374":1,"446":2,"458":3,"474":3,"491":3,"500":3,"502":2,"503":1,"504":1,"505":1,"506":2,"507":1}}],["export.",{"2":{"20":1,"70":1,"71":1,"126":1,"372":1,"443":2}}],["exposed",{"2":{"98":1,"99":1}}],["exposes.",{"2":{"103":1}}],["exposes",{"2":{"84":1,"94":1,"99":1,"107":1,"115":1,"253":1}}],["expose",{"2":{"1":1,"246":1}}],["expanded",{"2":{"384":1}}],["expand<",{"2":{"192":1}}],["expand),",{"2":{"20":1,"28":1}}],["expandable",{"2":{"20":1,"372":1}}],["expand",{"2":{"12":1,"205":1,"213":1}}],["explaining",{"2":{"350":1}}],["explain",{"2":{"107":1,"120":1}}],["explained.",{"2":{"96":1}}],["explains",{"2":{"76":1,"250":1}}],["explicit",{"2":{"37":1,"415":1,"478":1}}],["explicitly",{"2":{"6":1,"41":1,"247":1,"262":1}}],["exploration.",{"2":{"4":1}}],["explorer",{"2":{"227":1,"253":1,"379":2,"501":1}}],["explorer.",{"2":{"173":1}}],["explore",{"2":{"4":1,"472":1}}],["ignoring",{"0":{"360":1}}],["ignored",{"2":{"414":1}}],["ignore",{"2":{"79":1,"96":1,"107":1,"172":1,"274":2,"360":1,"414":3}}],["i",{"0":{"244":1,"245":1,"247":1},"2":{"70":1,"84":1,"196":1,"329":1,"365":1}}],["ipcsecurity.cjs\\");",{"2":{"85":1}}],["ipcmain.handle(\\"mychannel\\",",{"2":{"85":1}}],["ipcmain.handle",{"2":{"85":1}}],["ipc",{"0":{"85":1},"2":{"57":1,"84":2,"85":2,"90":1,"91":1,"526":1,"542":1}}],["ipc:",{"2":{"42":1}}],["ids:",{"2":{"391":1}}],["identify",{"2":{"458":1,"465":1}}],["identity",{"2":{"318":1,"527":2}}],["identity,",{"2":{"48":1}}],["ideal",{"2":{"162":1}}],["idx",{"2":{"69":1}}],["id)",{"2":{"49":2}}],["id),",{"2":{"44":1}}],["id",{"2":{"49":2,"50":1,"69":1,"486":1}}],["id,",{"2":{"44":4}}],["itself,",{"2":{"299":1}}],["itself",{"2":{"217":1}}],["its",{"2":{"206":1,"210":1,"227":1,"247":1,"310":1,"340":1,"414":1,"464":1,"525":1,"539":2}}],["italic,",{"2":{"202":1}}],["italic\\\\*",{"2":{"193":1}}],["italic",{"2":{"178":4,"327":1,"329":1}}],["item",{"2":{"170":1,"181":5,"187":1,"197":2,"226":1,"227":1,"374":1,"500":1,"501":1}}],["items:",{"2":{"106":1}}],["items:json{",{"2":{"7":1}}],["items.",{"2":{"104":1,"298":1}}],["items",{"2":{"7":1,"131":1,"258":1,"288":1,"326":1,"374":3,"499":1}}],["items,",{"2":{"5":1,"103":1}}],["it:",{"2":{"150":1}}],["it?",{"2":{"120":1}}],["it.",{"2":{"116":1,"148":1,"159":1,"247":1,"452":1,"453":1}}],["it",{"0":{"483":1},"1":{"484":1,"485":1},"2":{"20":1,"29":1,"54":1,"77":1,"93":2,"94":1,"103":1,"116":1,"131":1,"139":1,"154":2,"157":1,"164":1,"165":1,"170":1,"172":3,"186":1,"193":1,"217":1,"218":1,"238":1,"257":1,"263":1,"274":1,"275":2,"278":1,"300":1,"303":1,"328":1,"334":2,"339":2,"341":1,"349":1,"360":1,"380":1,"402":2,"411":1,"436":1,"484":1,"486":1,"512":1,"515":1}}],["icon,",{"2":{"466":1}}],["icon.cjs):",{"2":{"92":1}}],["icons,",{"2":{"374":1}}],["icons).",{"2":{"374":1}}],["icons.",{"2":{"84":1}}],["icons",{"2":{"27":1,"92":1}}],["icon",{"2":{"15":1,"92":2,"153":1,"173":1,"187":1,"212":1,"213":1,"257":2,"296":2,"444":1,"455":1,"466":1,"500":1,"534":1}}],["image](.",{"2":{"519":1}}],["image,",{"2":{"303":1}}],["image):",{"2":{"225":1}}],["image.png)",{"2":{"519":1}}],["image.",{"2":{"150":1,"151":1,"299":1,"433":1,"441":1,"442":1,"470":1,"471":2,"520":1}}],["images,",{"2":{"66":1,"510":1}}],["images",{"0":{"185":1,"465":1},"2":{"65":1,"75":1,"217":2,"223":1,"233":2,"294":1,"465":1,"487":1}}],["image",{"0":{"150":1,"151":1,"212":1,"294":1,"299":1,"300":1,"430":1,"433":1,"441":1,"442":1,"450":1,"470":1,"471":1,"520":1},"2":{"29":1,"32":1,"77":1,"92":1,"95":2,"116":6,"120":1,"145":1,"150":3,"151":3,"153":1,"185":1,"197":2,"212":2,"225":3,"242":1,"296":1,"299":1,"300":1,"303":4,"321":2,"329":2,"366":1,"408":1,"430":1,"433":1,"441":1,"442":1,"456":1,"465":2,"466":1,"470":3,"471":1,"486":1,"520":2,"532":1,"533":2}}],["immediately",{"2":{"274":1,"337":1,"346":1,"374":1,"381":1,"408":1,"533":1}}],["immediately.",{"2":{"219":1,"235":1,"256":1,"258":1,"296":1,"325":1,"515":1}}],["immediate",{"2":{"11":1,"225":1,"513":1}}],["impact,",{"2":{"107":1}}],["implies",{"2":{"116":1}}],["imply",{"2":{"103":1}}],["implement",{"2":{"117":1}}],["implemented:",{"2":{"105":1}}],["implemented,",{"2":{"96":1}}],["implemented",{"2":{"94":2,"95":2,"96":10,"99":1,"105":1,"119":1}}],["implementation.",{"2":{"93":1,"94":1,"115":1,"122":1}}],["implementation",{"2":{"93":1,"94":1,"99":1,"105":1,"115":1,"131":1}}],["implements,",{"2":{"34":1,"39":1}}],["implements",{"2":{"0":1,"47":1}}],["imposes",{"2":{"75":1}}],["import\\\\s+\\\\{[\\\\w\\\\s,]+\\\\}",{"2":{"278":1}}],["imports:",{"2":{"278":1}}],["import.",{"2":{"233":1,"234":1}}],["importing",{"0":{"219":1,"235":1}}],["import,",{"2":{"218":1}}],["imported",{"2":{"214":1,"219":1,"235":1}}],["important,",{"2":{"196":1}}],["important",{"2":{"82":1,"119":1,"139":1,"187":1}}],["import:",{"2":{"65":1}}],["import",{"0":{"65":1,"154":1,"214":1,"221":1,"232":1},"1":{"215":1,"216":1,"217":1,"218":1,"219":1,"220":1,"222":1,"223":1,"224":1,"225":1,"226":1,"227":1,"228":1,"229":1,"230":1,"231":1,"232":1,"233":2,"234":2,"235":2,"236":1},"2":{"1":1,"65":3,"70":1,"95":1,"215":2,"216":1,"218":1,"219":3,"220":1,"221":1,"232":1,"235":2,"236":1,"359":1}}],["improved",{"2":{"374":1,"381":1}}],["improvements",{"0":{"121":1,"124":1,"126":1,"128":1,"129":1},"1":{"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1}}],["improve",{"2":{"18":1}}],["if",{"0":{"247":1},"2":{"7":2,"10":1,"16":1,"20":1,"69":2,"79":2,"80":1,"131":1,"134":1,"137":2,"146":1,"151":1,"164":1,"174":1,"196":1,"202":1,"206":1,"216":1,"218":1,"219":2,"227":1,"235":1,"243":1,"253":1,"278":2,"303":1,"330":2,"347":1,"358":1,"359":1,"368":1,"386":2,"390":1,"391":1,"407":2,"414":1,"419":1,"444":1,"446":1,"448":1,"450":1,"452":1,"454":1,"455":1,"456":1,"457":2,"458":1,"459":2,"466":2,"490":1,"501":1,"511":1}}],["is:",{"2":{"506":1}}],["issue",{"2":{"391":1,"454":1}}],["issues?",{"2":{"120":1}}],["issues",{"0":{"103":1},"2":{"94":1,"172":2,"273":1,"463":1}}],["issues.",{"2":{"82":1,"374":1,"402":1,"447":1,"458":1}}],["is.",{"2":{"296":1}}],["is,",{"2":{"229":1,"446":1}}],["isolate",{"2":{"458":1}}],["isolated",{"2":{"84":1}}],["isolator",{"0":{"33":1}}],["iscompacted)",{"2":{"12":1}}],["is",{"0":{"98":1,"99":1,"238":1,"242":1,"248":1,"310":1},"2":{"1":1,"6":1,"17":1,"33":1,"43":1,"50":1,"54":2,"56":1,"58":1,"65":1,"68":1,"78":1,"83":1,"93":1,"94":4,"96":4,"98":1,"99":4,"103":2,"104":2,"105":6,"110":3,"112":1,"113":1,"115":5,"119":2,"120":2,"135":1,"137":1,"142":1,"146":1,"148":2,"150":1,"152":1,"159":3,"162":1,"164":1,"165":1,"166":1,"171":1,"174":1,"186":1,"191":2,"192":1,"196":1,"201":1,"204":1,"205":1,"206":1,"209":1,"210":3,"216":2,"217":1,"218":3,"219":1,"220":1,"229":1,"231":1,"233":1,"234":2,"238":1,"242":1,"243":1,"253":1,"254":1,"262":2,"263":2,"275":1,"278":1,"281":1,"296":2,"307":1,"309":1,"310":1,"322":1,"323":2,"326":1,"330":1,"332":1,"334":1,"339":2,"340":1,"341":1,"356":1,"358":1,"359":1,"360":1,"367":1,"369":1,"374":1,"377":2,"387":1,"391":1,"403":1,"413":1,"414":1,"417":1,"419":1,"444":1,"448":1,"450":1,"456":1,"457":2,"458":2,"459":1,"466":3,"470":1,"474":4,"480":1,"482":1,"484":1,"486":1,"487":1,"490":2,"493":1,"501":1,"508":1,"512":1,"517":1,"526":1,"527":1,"533":1,"539":1,"542":2}}],["initial",{"2":{"539":1}}],["initialize",{"2":{"358":1}}],["initialized",{"2":{"290":1}}],["initializing",{"0":{"358":1}}],["initialization",{"2":{"417":1}}],["initialization,",{"2":{"63":1}}],["initialization.",{"2":{"28":1}}],["init",{"2":{"358":1}}],["inherits",{"2":{"339":1}}],["in.",{"2":{"332":1}}],["inaccessible",{"2":{"217":1,"233":1}}],["inaccurate",{"0":{"99":1}}],["inaccurate.",{"2":{"96":1,"110":1}}],["inline",{"0":{"205":1,"262":1},"2":{"105":2,"178":1,"189":1,"192":1,"197":1,"203":1,"205":1,"212":1,"224":1,"262":1,"331":1,"374":1,"375":1,"463":1,"487":1}}],["injection",{"2":{"486":1}}],["injection.",{"2":{"9":1}}],["injects",{"2":{"346":1}}],["injected",{"2":{"85":1,"487":1}}],["in,",{"2":{"75":1,"397":1}}],["indicate",{"2":{"368":1}}],["indicator",{"2":{"330":1,"439":1,"501":1,"529":2}}],["indicators",{"0":{"172":1,"534":1},"1":{"173":1,"174":1},"2":{"380":1}}],["indices",{"2":{"75":1}}],["individual",{"2":{"65":1,"216":1,"274":1,"288":1,"356":1,"484":1,"525":1}}],["indent",{"2":{"263":1}}],["indentation",{"2":{"135":1}}],["independently",{"2":{"71":1,"167":1,"269":1}}],["index,",{"2":{"481":1}}],["indexing.",{"2":{"84":1}}],["indexing",{"0":{"42":1},"2":{"55":1,"70":1,"84":1,"489":1}}],["indexing:",{"2":{"8":1}}],["indexes",{"0":{"44":1},"2":{"44":1}}],["indexer",{"0":{"26":1}}],["indexed",{"2":{"0":1,"21":1}}],["index.json)",{"2":{"489":1}}],["index.json",{"2":{"484":1}}],["index.md:",{"2":{"118":1}}],["index.md",{"2":{"104":1,"105":1}}],["index.md,",{"2":{"103":1}}],["index.",{"2":{"19":1,"393":1,"527":1}}],["index",{"0":{"53":1,"488":1},"2":{"8":1,"26":1,"27":1,"34":1,"51":1,"69":1,"484":2,"489":1,"491":1}}],["increasing",{"2":{"223":1}}],["incrementally",{"2":{"419":1}}],["incremental",{"0":{"42":1}}],["incorrect",{"0":{"455":1}}],["incorrectly",{"2":{"116":1}}],["inconsistencies",{"0":{"117":1}}],["inconsistent.",{"2":{"96":1,"105":1}}],["incomplete:",{"2":{"107":1}}],["incomplete",{"0":{"99":1},"2":{"96":1,"99":1,"111":1,"118":1,"120":1}}],["incomplete.",{"2":{"94":1,"115":1,"119":1}}],["include:",{"2":{"137":1,"188":1,"281":1,"369":1}}],["include",{"2":{"129":1,"134":1,"323":1,"374":1,"384":1,"474":1,"478":1,"479":1,"484":1,"489":1,"507":1}}],["included",{"2":{"104":1,"217":1,"233":1}}],["includes:",{"2":{"323":1}}],["includes",{"2":{"78":1,"127":1,"203":1,"256":1,"268":1,"287":1,"292":1,"339":1,"379":2,"416":1,"459":1,"481":1,"492":1,"500":1,"516":1,"518":1,"540":1}}],["including:",{"2":{"138":1}}],["including",{"2":{"95":1,"103":1,"334":1}}],["inc,",{"2":{"37":1}}],["ingestion",{"0":{"40":1}}],["info",{"0":{"315":1},"1":{"316":1,"317":1,"318":1},"2":{"196":1,"339":1,"415":1}}],["information.",{"2":{"318":1}}],["informational",{"2":{"187":1}}],["information",{"2":{"5":1,"374":1,"460":1}}],["infinite",{"2":{"137":1}}],["infrastructure",{"0":{"68":1},"1":{"69":1,"70":1,"71":1}}],["inference",{"2":{"33":1,"35":1,"67":1}}],["invalid.",{"2":{"278":1,"391":1}}],["invariant",{"2":{"2":1}}],["inventory",{"0":{"95":1},"2":{"96":1,"110":1}}],["invites",{"2":{"96":1}}],["invites,",{"2":{"95":1}}],["invite",{"0":{"418":1},"2":{"79":1,"312":1,"418":3}}],["invocation",{"2":{"84":1,"85":1,"96":1}}],["invocations,",{"2":{"70":1}}],["invokes:",{"2":{"20":1}}],["insufficient.",{"2":{"107":1}}],["insert,",{"2":{"466":2}}],["insert.",{"2":{"296":1,"455":1}}],["insert:",{"2":{"296":2,"408":2,"533":2}}],["inserts",{"2":{"196":1,"408":1,"533":1}}],["inserted.",{"2":{"466":1}}],["inserted",{"2":{"142":1,"148":1,"204":1,"296":1,"466":1,"519":1}}],["insertion.",{"2":{"430":1}}],["insertions",{"2":{"353":1}}],["insertion",{"2":{"96":1,"112":1}}],["insertion,",{"2":{"95":1}}],["inserting",{"2":{"95":1,"408":1}}],["insert",{"0":{"133":1,"142":1,"148":1,"153":1,"197":1,"430":1,"431":1,"432":1},"2":{"95":2,"99":1,"108":1,"115":1,"116":2,"153":1,"187":1,"195":1,"196":1,"197":7,"198":2,"200":3,"261":1,"296":3,"302":1,"303":1,"329":6,"363":1,"408":3,"455":1,"465":1,"468":1,"469":1,"534":2}}],["instantly.",{"2":{"340":1,"420":1,"513":1}}],["instantly",{"2":{"263":1,"389":1,"531":1}}],["instant",{"2":{"227":1}}],["instant,",{"2":{"52":1}}],["installs",{"2":{"336":1}}],["installed",{"2":{"537":1}}],["installed.",{"2":{"253":1}}],["installer",{"0":{"336":1},"2":{"334":1,"336":1}}],["install",{"0":{"334":1},"2":{"99":1,"100":1,"118":1,"120":1,"131":1,"337":2}}],["installation.",{"2":{"337":1,"338":1}}],["installations",{"2":{"336":1}}],["installation",{"2":{"99":1,"120":1,"123":1}}],["instead.",{"2":{"386":1}}],["instead",{"2":{"96":1,"139":1,"220":1,"258":1,"376":1,"380":1,"381":1}}],["instructions",{"2":{"130":1}}],["instructions,",{"2":{"27":1}}],["instructions.",{"2":{"8":1,"19":1,"99":1}}],["inspection.",{"2":{"63":1}}],["inspects",{"2":{"46":1,"134":1}}],["inspector",{"2":{"20":2,"96":1}}],["inspect",{"2":{"20":1,"244":1,"297":1,"338":1,"464":1,"495":1}}],["inside",{"2":{"15":1,"16":1,"18":1,"51":1,"53":1,"55":1,"59":1,"69":1,"71":1,"132":1,"135":1,"137":2,"142":1,"189":1,"205":1,"206":2,"216":1,"217":1,"220":1,"223":1,"229":1,"233":1,"236":1,"255":1,"262":1,"263":2,"264":1,"279":1,"321":1,"341":1,"375":1,"392":1,"463":1,"472":1,"481":1,"495":1,"502":1,"506":2,"514":1,"518":1,"519":1,"522":1,"523":1,"526":1}}],["inputs,",{"2":{"380":1}}],["input",{"2":{"11":1,"12":1,"24":1,"33":1,"286":1,"359":2,"372":1}}],["in",{"0":{"105":1,"162":1,"238":1,"326":1,"388":1,"425":1,"426":1,"453":1,"487":1,"523":1},"1":{"327":1,"524":1},"2":{"4":1,"6":1,"7":1,"8":2,"9":1,"10":2,"14":1,"15":1,"18":1,"19":2,"25":1,"38":1,"43":1,"47":1,"52":1,"54":1,"65":1,"66":2,"75":1,"77":1,"78":1,"80":2,"82":1,"90":1,"93":7,"94":1,"95":2,"96":13,"98":2,"99":1,"104":1,"105":4,"106":2,"107":1,"110":1,"115":3,"116":11,"117":1,"122":2,"124":1,"125":1,"126":2,"131":1,"133":2,"135":1,"137":5,"139":2,"140":1,"141":1,"142":2,"145":1,"147":1,"148":4,"149":1,"150":1,"151":1,"153":1,"157":2,"159":3,"166":2,"167":2,"168":2,"171":2,"172":2,"173":2,"175":1,"183":1,"187":2,"189":1,"192":1,"196":2,"201":1,"203":1,"204":1,"205":5,"206":2,"210":1,"211":1,"212":2,"213":3,"216":1,"217":1,"218":3,"220":2,"224":1,"227":4,"233":1,"234":3,"236":3,"239":1,"243":1,"247":1,"248":1,"250":1,"253":4,"254":1,"257":1,"262":1,"263":4,"265":1,"268":1,"269":3,"270":1,"274":2,"278":2,"279":2,"283":2,"287":1,"288":1,"291":1,"295":1,"296":1,"299":1,"302":2,"303":1,"305":2,"308":2,"313":1,"316":1,"322":1,"325":1,"326":2,"328":1,"330":1,"332":1,"339":1,"345":1,"350":2,"352":1,"353":3,"354":3,"356":3,"360":2,"364":2,"366":3,"368":2,"369":1,"374":4,"377":1,"379":6,"382":1,"384":1,"387":1,"388":1,"391":1,"392":1,"393":1,"394":1,"406":1,"411":1,"414":2,"415":2,"417":1,"424":1,"427":1,"431":1,"433":1,"434":1,"437":1,"438":1,"444":4,"450":2,"452":1,"456":1,"457":1,"460":1,"461":1,"464":1,"465":1,"466":2,"468":1,"470":1,"473":1,"475":1,"479":1,"481":1,"482":1,"484":1,"488":2,"489":2,"491":1,"493":1,"498":1,"499":1,"500":2,"501":3,"504":1,"512":1,"515":1,"517":2,"519":1,"520":2,"521":2,"522":1,"525":3,"530":1,"532":1,"533":1,"540":1}}],["intended",{"2":{"323":1}}],["intentionally",{"2":{"446":1}}],["intent,",{"2":{"102":1}}],["intents",{"2":{"4":1}}],["intent",{"0":{"4":1},"2":{"4":1,"11":1,"13":2,"372":1}}],["integer",{"2":{"69":1}}],["integrity.",{"2":{"235":1}}],["integrity",{"2":{"91":1,"219":1,"220":1,"236":1}}],["integrity,",{"2":{"65":1}}],["integration?",{"2":{"342":1}}],["integration",{"2":{"90":2,"369":1,"499":1}}],["integration,",{"2":{"90":1}}],["integrations.",{"2":{"84":1}}],["integration:",{"2":{"59":1}}],["integrates",{"2":{"34":1,"66":1,"290":1}}],["integrated,",{"2":{"535":1}}],["integrated",{"2":{"14":1,"152":1,"263":1,"492":1,"516":1,"518":1}}],["interval",{"2":{"419":1}}],["intervals",{"2":{"419":1}}],["interrupted",{"2":{"419":1}}],["international",{"0":{"368":1},"2":{"367":1}}],["internally",{"2":{"94":1}}],["internal",{"2":{"1":1,"75":1,"85":1,"93":1,"104":1,"131":1,"360":1}}],["internet",{"2":{"241":1,"249":1}}],["internet?",{"0":{"241":1}}],["interaction",{"2":{"159":1,"262":1,"376":1}}],["interactions",{"2":{"143":1}}],["interactively",{"2":{"25":1}}],["interactive",{"0":{"145":1,"498":1,"525":1},"2":{"12":1,"59":1,"137":1,"154":1,"183":1,"281":1,"508":1,"516":1,"525":1,"541":1}}],["interface)",{"2":{"339":1}}],["interface\\\\s+\\\\w+",{"2":{"279":1}}],["interface",{"2":{"58":1}}],["interconnected",{"2":{"29":1}}],["into",{"0":{"430":1,"444":1,"466":1},"2":{"0":1,"3":1,"5":1,"9":1,"11":1,"21":1,"24":1,"25":1,"29":1,"50":1,"53":1,"65":2,"134":1,"150":1,"152":1,"154":2,"164":1,"169":1,"207":2,"214":2,"215":2,"219":1,"225":1,"230":1,"235":1,"270":1,"284":1,"346":1,"372":2,"374":1,"408":1,"461":1,"486":1,"492":1,"499":1,"501":1,"506":1,"522":1,"526":1,"531":1}}],["pwsh).",{"2":{"537":1}}],["pwsh.",{"2":{"137":1}}],["pty.",{"2":{"535":1}}],["pty",{"2":{"516":1,"539":2}}],["pty):",{"2":{"339":1}}],["p)",{"2":{"418":1,"500":1}}],["p",{"2":{"362":1}}],["pngs)",{"2":{"484":1}}],["png",{"2":{"145":1,"155":1,"212":1,"225":2,"374":1,"487":1}}],["pinned,",{"2":{"459":1}}],["picture",{"2":{"299":1}}],["picker",{"2":{"196":1,"197":1,"340":1,"450":1}}],["pick",{"2":{"185":1,"219":1,"329":1,"430":1}}],["pipes",{"2":{"377":1}}],["pipe",{"2":{"206":1}}],["pipeline,",{"2":{"70":1}}],["pipeline:",{"2":{"38":1}}],["pipelineregression.spec.js:",{"2":{"13":1}}],["pipeline\\",",{"2":{"6":1}}],["pipeline",{"0":{"2":1,"31":1,"486":1},"1":{"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"487":1},"2":{"1":1,"23":1,"30":1,"486":1}}],["pie",{"2":{"143":2}}],["python3.",{"2":{"137":1}}],["python):",{"2":{"137":1}}],["python",{"2":{"137":2,"263":1}}],["python,",{"2":{"134":1,"138":1,"188":1,"263":1}}],["pull:",{"2":{"346":1}}],["pull)",{"0":{"346":1}}],["pull",{"2":{"292":1}}],["pushed",{"2":{"420":1}}],["push:",{"2":{"346":1}}],["push",{"2":{"292":1}}],["publishing",{"2":{"224":1}}],["publish",{"2":{"131":1,"491":1}}],["purpose:",{"2":{"476":1}}],["purposes.",{"2":{"368":1}}],["purpose",{"2":{"98":1,"215":1,"415":1}}],["purging:",{"2":{"50":1,"527":1}}],["purging,",{"2":{"42":1}}],["purely",{"2":{"8":1}}],["pdfs,",{"2":{"281":1,"484":1,"510":1,"519":1}}],["pdf.",{"2":{"223":1}}],["pdf,",{"2":{"95":1,"98":1,"221":2}}],["pdf",{"0":{"223":1,"230":1,"321":1,"443":1,"491":1},"2":{"65":1,"96":1,"108":1,"116":2,"223":1,"227":1,"229":2,"236":1,"321":2,"323":1,"366":1,"443":1,"446":1,"458":2,"474":1,"484":2,"487":1,"491":1,"501":1,"503":1,"506":2}}],["pending",{"2":{"187":1,"288":1,"445":1,"473":1}}],["peer,",{"2":{"418":1}}],["peers:",{"2":{"420":1}}],["peers.",{"2":{"417":1,"420":1}}],["peers,",{"2":{"95":1}}],["peers",{"0":{"79":1},"2":{"64":1,"96":1,"312":1,"418":2,"420":1,"451":1}}],["peer",{"0":{"311":2},"1":{"312":2,"313":2,"314":2},"2":{"64":2,"79":1,"91":2,"416":2,"417":2,"418":1}}],["perfect",{"2":{"496":1,"506":1}}],["performing",{"2":{"346":1}}],["performs",{"2":{"34":1}}],["performance",{"2":{"26":1,"44":1,"55":1}}],["periodic",{"2":{"417":1}}],["permanent",{"2":{"348":1}}],["permanently",{"2":{"258":2,"527":1}}],["permissive",{"2":{"415":1,"541":1}}],["permissions",{"2":{"337":1}}],["permission",{"2":{"9":1}}],["permitted",{"2":{"1":1}}],["percentages.",{"2":{"17":1}}],["per",{"0":{"104":1},"2":{"12":1,"177":1,"205":1,"227":1,"230":2,"262":1,"269":1,"339":1,"502":1}}],["perspective",{"0":{"120":1}}],["person.",{"2":{"37":1}}],["personal",{"2":{"336":1,"346":1}}],["personalization",{"2":{"96":1,"173":1}}],["personas,",{"2":{"19":1,"23":1,"372":1}}],["personas.",{"2":{"19":1}}],["personas",{"2":{"8":6,"19":3,"27":3}}],["personas:",{"2":{"8":1}}],["persona,",{"2":{"2":1}}],["persona",{"0":{"8":1,"19":1,"27":1},"2":{"2":1,"8":1,"12":1,"55":1}}],["persist",{"2":{"27":1,"539":1}}],["persistent",{"2":{"20":1,"346":1,"372":1}}],["persistence:",{"2":{"227":1}}],["persistence,",{"2":{"46":1}}],["persistence",{"2":{"2":1}}],["persisted",{"2":{"19":1,"59":1,"69":1,"502":1}}],["persists",{"2":{"2":1}}],["p2psyncengine.cjs),",{"2":{"416":1}}],["p2pstatuspanel,",{"2":{"105":1}}],["p2p,",{"2":{"120":1,"126":1}}],["p2plive.test.js:",{"2":{"91":1}}],["p2p",{"0":{"64":1,"416":1},"1":{"417":1,"418":1,"419":1,"420":1},"2":{"74":1,"79":2,"90":1,"91":1,"95":1,"96":1,"104":1,"106":1,"108":1,"116":2,"312":2,"362":1,"418":2,"419":1,"420":1,"451":2}}],["plugin",{"0":{"246":1},"2":{"95":1,"246":1}}],["plus",{"2":{"44":1,"95":1,"116":1}}],["placing",{"2":{"354":1,"375":1,"463":1,"506":1}}],["placement:",{"2":{"498":1}}],["place.",{"2":{"287":1}}],["place",{"2":{"159":1,"444":1,"466":1}}],["placed.",{"2":{"532":1}}],["placed",{"2":{"150":1,"303":1}}],["placeholder",{"2":{"102":1,"153":1}}],["places:",{"2":{"283":1}}],["places",{"2":{"65":1}}],["plausibility",{"0":{"39":1,"47":1},"2":{"39":1}}],["plain",{"2":{"34":1,"75":1,"155":1,"169":2,"229":1,"270":2,"332":1,"346":1,"377":1}}],["platform",{"2":{"21":1,"104":1,"115":1,"120":1,"123":1,"129":1,"333":1}}],["plan",{"0":{"6":1},"2":{"6":1}}],["planned",{"2":{"493":1}}],["planner,",{"2":{"23":1,"372":1}}],["plannerdecision",{"2":{"2":1,"6":1,"12":1}}],["planning,",{"2":{"91":1}}],["planning",{"0":{"3":1},"1":{"4":1,"5":1,"6":1,"7":1},"2":{"2":2,"3":1,"9":1,"13":1,"496":1}}],["p(b))$.",{"2":{"39":1}}],["p(a))(1",{"2":{"39":1}}],["php,",{"2":{"138":1}}],["phase",{"0":{"95":1}}],["physical",{"2":{"66":1}}],["phonetic",{"2":{"36":1}}],["phrase",{"0":{"33":1},"2":{"477":1}}],["packets",{"2":{"417":1}}],["packaging",{"0":{"92":1},"2":{"92":1,"98":1}}],["packaged",{"0":{"339":1},"2":{"339":1,"506":1}}],["packages),",{"2":{"501":1}}],["packages",{"2":{"234":1,"369":1,"491":1}}],["packages,",{"2":{"227":1}}],["packages:",{"2":{"92":1}}],["packages.",{"2":{"65":1,"218":1}}],["package.json.",{"2":{"98":1}}],["package.",{"2":{"65":1,"216":2,"219":1,"232":1,"233":1,"235":1,"339":1}}],["package",{"0":{"214":1,"232":1,"233":1,"235":1},"1":{"215":1,"216":1,"219":1,"220":1,"233":1,"234":1,"235":1},"2":{"65":1,"70":1,"92":1,"214":1,"215":3,"217":1,"219":3,"220":3,"221":2,"233":1,"235":1,"236":3,"323":1,"335":1,"339":1,"369":1,"503":1}}],["package,exporting",{"1":{"217":1,"218":1}}],["package,",{"0":{"65":1},"2":{"501":1}}],["pan",{"2":{"509":1}}],["pan,",{"2":{"281":1}}],["pane,",{"2":{"481":1}}],["pane",{"0":{"491":1},"2":{"59":1,"171":1,"173":1,"491":1}}],["pane:",{"2":{"20":1}}],["panel"",{"2":{"285":1}}],["panel:",{"2":{"283":2,"349":1,"389":1,"536":1}}],["panel;",{"2":{"96":1}}],["panels.",{"2":{"128":1}}],["panels",{"2":{"71":1,"102":1,"256":1,"374":1,"397":1}}],["panels,",{"2":{"60":1}}],["panel.",{"2":{"19":1,"205":1,"286":1,"290":1,"350":1,"377":1,"392":1,"426":1,"457":1}}],["panel,",{"2":{"16":1}}],["panel",{"0":{"15":1,"157":1,"284":1,"285":1,"286":1,"287":1,"364":1},"1":{"16":1,"17":1,"158":1,"159":1,"285":1,"286":1,"288":1},"2":{"14":1,"15":1,"28":1,"95":1,"96":2,"99":1,"116":2,"157":1,"159":2,"160":1,"162":1,"164":1,"177":1,"210":1,"284":1,"285":1,"363":1,"364":2,"380":1,"403":1,"406":1,"419":2,"445":1,"473":1,"499":1,"539":2}}],["padding",{"2":{"162":1,"212":1,"225":1}}],["pairing",{"0":{"312":1,"418":1},"2":{"108":1,"417":1}}],["pair",{"2":{"79":2,"312":1,"418":1}}],["pairs,",{"2":{"74":1}}],["pat,",{"2":{"346":1}}],["path:",{"2":{"538":2}}],["path}",{"2":{"484":3,"486":1}}],["path.",{"2":{"170":1,"173":1,"233":1,"415":1}}],["path",{"0":{"170":1,"538":1},"2":{"49":1,"62":1,"65":1,"67":1,"96":1,"127":1,"168":1,"171":1,"185":1,"197":1,"216":1,"220":1,"223":1,"233":1,"236":1,"374":2,"415":7,"450":1,"474":1,"486":1,"502":1,"504":1,"538":2}}],["path,",{"2":{"44":1}}],["paths).",{"2":{"377":1}}],["paths)",{"2":{"223":1}}],["paths.",{"2":{"219":1,"235":1,"258":1}}],["paths,",{"2":{"62":1}}],["paths",{"2":{"17":1,"85":1,"120":1,"213":2,"223":1,"486":2,"538":1}}],["pattern.",{"2":{"278":1}}],["patterns.",{"2":{"391":1}}],["patterns:",{"2":{"278":1,"411":1}}],["patterns,",{"2":{"278":1}}],["patterns",{"0":{"278":1},"2":{"36":1,"106":1,"279":1}}],["pattern",{"0":{"34":1,"85":1},"2":{"29":1,"33":1,"34":1,"95":1,"107":1,"278":1,"391":1}}],["palette:",{"2":{"285":1,"536":1}}],["palette.",{"2":{"115":1,"116":1,"285":1,"477":1}}],["palette;",{"2":{"96":1}}],["palette,",{"2":{"95":1,"120":1,"384":2}}],["palette",{"0":{"18":1},"2":{"18":1,"95":1,"96":2,"115":1,"116":5,"118":1,"172":1,"245":1,"274":1,"340":1,"343":1,"362":1,"365":1,"445":1,"473":1,"494":1,"500":1,"517":2,"530":1}}],["page)",{"2":{"484":1}}],["page:",{"2":{"345":1}}],["pages",{"2":{"119":1,"207":1,"506":1}}],["pages.",{"2":{"103":1}}],["pages,",{"2":{"60":1,"491":1}}],["page.",{"2":{"20":1,"103":1,"104":1,"123":1}}],["page",{"0":{"486":1,"488":1,"530":1},"2":{"15":1,"59":1,"126":3,"176":1,"210":1,"229":1,"250":1,"262":1,"292":1,"372":1,"383":3,"394":1,"421":1,"447":1,"482":1,"484":3,"488":1,"489":2,"490":1}}],["pass",{"2":{"527":5}}],["passed.",{"2":{"499":1}}],["passes",{"2":{"485":1}}],["passthrough",{"2":{"484":1}}],["password"",{"2":{"220":1,"236":1}}],["password,",{"2":{"218":1}}],["password",{"2":{"65":1,"216":3,"218":1,"219":6,"220":2,"233":2,"234":2,"235":2,"236":2}}],["passing",{"2":{"13":1}}],["paste",{"0":{"207":1},"2":{"134":2,"169":1,"207":1,"263":1,"270":1,"531":1}}],["past",{"2":{"11":1,"507":1}}],["payloads",{"2":{"9":1,"12":1,"55":1,"85":1,"417":1}}],["payload",{"2":{"2":1,"10":1,"85":2,"417":1}}],["party",{"0":{"369":1},"2":{"369":1,"416":1}}],["part",{"2":{"104":1}}],["partly",{"2":{"99":1}}],["partially.",{"2":{"120":2}}],["partially",{"2":{"103":1,"108":1,"118":2}}],["partial",{"2":{"96":21,"116":8}}],["paragraph",{"2":{"524":1}}],["paragraph,",{"2":{"179":1}}],["paragraphs.",{"2":{"186":1}}],["paragraphs:",{"2":{"179":1}}],["paragraphs",{"0":{"179":1}}],["paragraph.",{"2":{"16":1,"179":2}}],["parallel",{"2":{"2":1}}],["parsing",{"2":{"7":1,"30":1,"377":1}}],["parse",{"2":{"154":1}}],["parser",{"0":{"32":1},"2":{"7":1,"13":1,"486":1}}],["parsed",{"2":{"0":1,"21":1}}],["pool",{"2":{"514":1}}],["poorly",{"2":{"374":1}}],["port.",{"2":{"484":1}}],["port",{"2":{"418":1}}],["portability:",{"2":{"356":1}}],["portable",{"0":{"337":1},"2":{"65":1,"214":1,"323":1,"334":3,"338":1}}],["portable:",{"2":{"55":1}}],["portal.",{"2":{"93":1}}],["pop",{"2":{"374":1}}],["popover,",{"2":{"529":1}}],["popover",{"2":{"374":1,"380":2}}],["popup.",{"2":{"463":1}}],["popup",{"2":{"171":1,"263":2,"463":1}}],["possible.",{"2":{"321":1,"376":1,"477":1}}],["position",{"2":{"210":1,"532":1}}],["position.",{"2":{"159":1}}],["post",{"0":{"49":1}}],["powershell:",{"2":{"537":1}}],["powershell,",{"2":{"138":1}}],["powershell):",{"2":{"137":1}}],["powershell",{"2":{"137":2,"263":1,"537":1}}],["powered)",{"0":{"393":1,"511":1}}],["powered",{"2":{"29":1,"58":1,"274":1,"535":1}}],["policies.",{"2":{"516":1,"541":1}}],["policies",{"0":{"540":1},"1":{"541":1,"542":1},"2":{"9":1}}],["policy=strict",{"2":{"542":1}}],["policy:",{"2":{"419":1}}],["policy.",{"2":{"415":1}}],["policy.md.",{"2":{"9":1}}],["policy)",{"0":{"541":1},"2":{"9":1}}],["policy,",{"2":{"9":6}}],["policy",{"0":{"541":1},"2":{"2":1,"415":2,"457":1,"542":2}}],["pointing",{"2":{"521":1}}],["points",{"2":{"11":1}}],["point",{"2":{"1":1,"93":1,"356":1,"372":1}}],["practice:",{"2":{"78":1}}],["pragma",{"2":{"55":1}}],["privileged",{"2":{"57":1}}],["privacy",{"0":{"413":1}}],["privacy,",{"2":{"0":1}}],["private.",{"2":{"359":1}}],["private",{"2":{"1":1,"21":1,"243":1,"414":1}}],["priorities,",{"2":{"75":1}}],["priority,",{"2":{"530":1}}],["priority",{"2":{"7":1,"26":1,"44":1,"94":1,"187":1,"523":1,"525":1}}],["priority:",{"2":{"4":1,"525":1}}],["prior",{"2":{"9":1}}],["primary",{"2":{"7":1,"59":1,"69":1,"165":1,"478":1}}],["pros:",{"2":{"336":1,"337":1,"338":1}}],["prose",{"0":{"33":1},"2":{"32":1,"33":1,"34":1,"172":1}}],["protected,",{"2":{"219":1}}],["protected",{"2":{"218":1}}],["protection",{"2":{"65":1,"219":1,"234":1}}],["prominent",{"2":{"104":1}}],["prompting.",{"2":{"419":1}}],["prompted.",{"2":{"79":1,"235":1}}],["prompt)",{"2":{"8":1}}],["prompts.",{"2":{"504":1}}],["prompts:",{"2":{"219":1}}],["prompts,",{"2":{"23":1,"372":1}}],["prompts",{"2":{"8":2,"9":1,"20":1,"374":1}}],["promptpipeline",{"2":{"2":1,"9":1}}],["prompt",{"0":{"9":1,"20":1},"2":{"2":2,"8":2,"9":2,"12":1,"13":1,"19":1,"20":1,"28":1,"55":1,"70":1,"220":1,"330":1,"407":1,"537":1}}],["proceed.",{"2":{"219":1}}],["procedurally,",{"2":{"116":1}}],["procedural",{"2":{"104":1}}],["processor,",{"2":{"339":1}}],["processes",{"2":{"339":1}}],["processes,",{"2":{"143":1}}],["processed",{"2":{"230":1,"419":1,"486":1}}],["process,",{"2":{"105":1,"517":1}}],["process",{"0":{"61":1,"84":1},"1":{"62":1,"63":1,"64":1,"65":1,"66":1,"67":1},"2":{"57":2,"61":1,"84":3,"137":1,"516":1}}],["processing",{"2":{"26":1,"85":1}}],["problematic",{"2":{"458":1}}],["problem,",{"2":{"275":1}}],["problem.",{"2":{"172":1}}],["problem",{"0":{"275":1},"2":{"94":2}}],["probabilistic",{"2":{"39":1}}],["productivity:",{"2":{"516":1}}],["productivity,",{"2":{"164":1}}],["productive",{"2":{"166":1}}],["production",{"0":{"88":1},"2":{"89":1}}],["product",{"0":{"315":1},"1":{"316":1,"317":1,"318":1},"2":{"94":1,"98":1,"103":1,"105":1}}],["produces",{"2":{"33":1,"224":1}}],["produce",{"2":{"32":1,"54":1}}],["progress,",{"2":{"525":1,"530":1}}],["progress",{"2":{"231":2,"309":1,"313":1,"529":1}}],["progress.",{"2":{"64":1}}],["programmatically",{"2":{"11":1}}],["providing",{"2":{"522":1}}],["provides",{"2":{"132":1,"147":1,"195":1,"221":1,"254":1,"263":1,"329":1,"379":1,"489":1,"495":1,"513":1}}],["provide",{"2":{"105":1}}],["provider:",{"2":{"410":1}}],["providers,",{"2":{"480":1}}],["providers",{"0":{"52":1},"2":{"10":1,"52":1,"117":1,"118":1}}],["provider",{"0":{"10":1,"410":1},"2":{"2":1,"10":2,"51":1,"52":2,"54":1,"96":1,"99":4,"103":1,"117":1,"118":1,"308":1}}],["provenance",{"0":{"45":1,"48":1},"1":{"46":1,"47":1,"48":1,"49":1}}],["proportions",{"2":{"143":1}}],["proprietary",{"2":{"75":1}}],["propagation",{"2":{"39":1,"50":2}}],["proper",{"2":{"37":1}}],["property",{"2":{"29":1}}],["professional",{"2":{"28":1,"152":1,"380":1}}],["project",{"0":{"255":1,"459":1,"488":1},"2":{"4":1,"143":1,"243":1,"254":2,"255":1,"288":1,"326":3,"379":1,"381":1,"406":1,"459":1,"481":1,"482":1,"484":1,"486":1,"488":1,"490":3,"491":1,"492":1,"516":2,"530":1,"535":1,"539":1}}],["predictable",{"2":{"412":1}}],["predictable,",{"2":{"412":1}}],["predicate",{"2":{"47":1}}],["predicates",{"2":{"39":1}}],["precision:",{"2":{"356":1}}],["precise,",{"2":{"152":1}}],["precise",{"2":{"54":1}}],["prepends",{"2":{"196":1}}],["prepositions,",{"2":{"36":1,"46":1}}],["preferred",{"2":{"537":1}}],["prefer",{"2":{"407":2,"477":1}}],["prefers",{"2":{"407":1,"537":1}}],["preference",{"2":{"107":2}}],["preferences.",{"2":{"75":1}}],["preferences,",{"2":{"60":1,"74":1,"239":1}}],["prefix",{"2":{"193":1}}],["prettier.",{"2":{"263":1}}],["prettier:",{"2":{"135":1}}],["prettier",{"0":{"135":1},"2":{"136":1,"199":1}}],["prettier,",{"2":{"132":1}}],["prerequisites",{"2":{"99":1}}],["preload.cjs):",{"2":{"84":1}}],["preload",{"2":{"84":1,"93":1}}],["previously",{"2":{"441":1}}],["previous",{"2":{"78":1,"116":1,"175":1,"354":1,"356":1,"362":1,"364":1,"381":1,"388":1,"425":1,"490":1}}],["previewing",{"2":{"324":1}}],["previews).",{"2":{"453":1}}],["previews.",{"2":{"374":1,"515":1}}],["previews",{"2":{"303":1,"374":1,"399":1,"487":1}}],["preview:",{"2":{"260":2,"463":1}}],["preview)",{"2":{"164":1}}],["preview,",{"2":{"95":2,"129":1,"433":1,"470":1}}],["preview.",{"2":{"82":1,"149":1,"151":1,"322":1,"431":1,"449":1,"468":1}}],["preview",{"0":{"171":1,"297":1,"319":1,"320":1,"328":1,"427":1,"449":1,"491":1,"525":1},"1":{"320":1,"321":1,"322":1,"323":1},"2":{"59":3,"89":1,"96":2,"99":1,"108":1,"112":1,"116":11,"133":1,"135":1,"136":1,"137":3,"139":1,"141":1,"142":1,"145":1,"148":1,"149":1,"150":1,"151":1,"153":2,"155":2,"159":1,"166":3,"171":2,"183":1,"192":1,"201":2,"212":1,"240":1,"248":1,"254":1,"260":1,"263":3,"291":1,"297":1,"298":1,"302":1,"303":1,"320":1,"321":1,"328":2,"353":1,"363":2,"366":3,"374":1,"442":1,"456":1,"463":1,"469":1,"471":1,"472":1,"481":1,"482":1,"491":1,"520":1,"525":1}}],["prevents",{"2":{"210":1}}],["preventing",{"2":{"33":1,"374":2,"526":1}}],["prevent",{"2":{"9":1,"66":1,"171":1,"174":1,"263":1,"374":1,"419":1,"517":1}}],["present",{"2":{"93":2,"96":1}}],["preserve",{"2":{"376":1}}],["preserves",{"2":{"211":1,"377":1,"527":1}}],["preserved",{"2":{"11":1,"213":1}}],["preservation",{"0":{"211":1},"2":{"376":1}}],["preserving",{"2":{"48":1,"229":1}}],["preset",{"2":{"19":1,"27":1}}],["press",{"2":{"18":1,"163":1,"174":1,"226":1,"285":2,"325":2,"352":1,"388":2,"389":1,"425":1,"434":1,"444":1,"466":1,"532":1,"536":1}}],["pre",{"0":{"32":1},"2":{"2":1,"12":1,"526":1,"541":1}}],["s)",{"2":{"455":1}}],["s.",{"2":{"296":1,"444":1,"466":1,"532":1}}],["skips",{"2":{"402":1}}],["skipped",{"2":{"233":1}}],["skipped;",{"2":{"217":1}}],["skeleton",{"2":{"197":1,"204":1,"329":1}}],["sketching,",{"2":{"155":1}}],["sketch",{"2":{"59":1}}],["s",{"2":{"175":1,"363":1,"366":1}}],["switch",{"0":{"427":1},"2":{"136":2,"142":1,"146":1,"166":1,"168":1,"175":2,"219":1,"235":1,"267":1,"271":1,"292":1,"303":1,"328":1,"345":2,"347":1,"362":2,"363":3,"374":1,"381":1,"449":1,"457":1,"459":1,"530":1}}],["switching,",{"2":{"344":1}}],["switching.",{"2":{"162":1,"227":1}}],["switching",{"2":{"96":1,"108":1,"167":1,"374":1,"490":1,"502":1}}],["src",{"2":{"118":1}}],["smart",{"0":{"527":1},"2":{"499":1}}],["smartscreen",{"2":{"339":2}}],["smarter",{"2":{"80":1,"305":1}}],["smaller",{"2":{"458":1}}],["small",{"2":{"26":1,"38":1,"53":1,"66":2,"104":1,"397":1,"410":1,"419":1}}],["snip",{"2":{"296":1,"444":1,"466":1,"531":1,"532":1}}],["snippets:",{"2":{"263":1}}],["snippets",{"0":{"280":1},"2":{"137":1,"263":1,"389":1,"392":1}}],["snippet",{"2":{"11":1,"134":1,"263":1}}],["snapshots,",{"2":{"323":1}}],["snapshots:",{"2":{"64":1}}],["snapshot",{"2":{"93":1,"283":1,"419":1}}],["svg",{"2":{"59":2,"155":1,"223":1,"225":1}}],["sdk.",{"2":{"66":1}}],["sdk:",{"2":{"52":1}}],["sdk,",{"2":{"36":1}}],["shifts:",{"2":{"527":1}}],["shifts",{"2":{"374":1}}],["shift",{"2":{"174":1,"175":4,"253":2,"254":2,"291":1,"296":1,"343":1,"352":1,"362":6,"363":4,"364":1,"365":2,"366":6,"379":3,"389":1,"418":1,"434":1,"444":1,"455":1,"464":1,"466":1,"482":2,"494":1,"500":1,"517":1,"530":1,"532":1}}],["shift+f10",{"2":{"116":1}}],["shift+enter",{"2":{"116":1}}],["sh.",{"2":{"137":1}}],["shelf.",{"2":{"347":1}}],["shell.",{"2":{"407":1}}],["shell:",{"2":{"106":1,"537":1}}],["shell,",{"2":{"95":1,"99":1,"103":1,"111":1}}],["shell",{"0":{"407":1,"537":1,"538":1},"1":{"538":1},"2":{"59":1,"95":1,"96":1,"107":1,"108":1,"137":1,"138":1,"267":1,"407":1,"457":2,"535":1,"537":2,"538":1,"541":1}}],["sheet",{"2":{"124":1}}],["sha1(filepath",{"2":{"527":1}}],["shape",{"2":{"211":1,"376":1}}],["shapes,",{"2":{"147":1}}],["shareable",{"2":{"491":1}}],["share:",{"2":{"368":1,"454":1}}],["shared",{"2":{"214":1,"218":1,"314":1,"326":1,"380":1}}],["share",{"0":{"454":1},"2":{"79":1,"326":1}}],["sharing.",{"2":{"323":1}}],["sharing",{"0":{"82":1},"2":{"49":1,"232":1}}],["sha",{"2":{"65":2,"216":1,"218":2,"233":1,"234":2}}],["short:",{"2":{"477":1}}],["short",{"2":{"418":1,"479":1}}],["shortcut:",{"2":{"158":1,"161":1,"403":1,"404":1}}],["shortcut,",{"2":{"116":1}}],["shortcut.",{"2":{"116":12}}],["shortcuts?",{"0":{"248":1},"2":{"120":1}}],["shortcuts.",{"2":{"104":1,"105":1,"115":1,"116":1,"117":1,"129":1,"131":1,"248":1,"436":1}}],["shortcuts,",{"2":{"94":2,"336":1,"386":1}}],["shortcuts",{"0":{"175":1,"317":1,"361":1,"436":1},"1":{"362":1,"363":1,"364":1,"365":1,"366":1},"2":{"93":1,"96":2,"105":1,"116":1,"120":1,"175":1,"202":1,"248":1,"253":1,"317":1,"343":1,"361":1,"362":1,"384":2,"475":1}}],["shortcut",{"0":{"114":1,"116":1,"384":1},"1":{"115":1,"116":1},"2":{"93":1,"94":2,"96":6,"104":1,"110":2,"116":3,"117":1,"119":2,"120":1,"122":1,"126":1,"131":1,"175":1,"187":1,"210":1,"227":1,"328":1,"336":1,"343":1,"362":1,"363":1,"364":1,"365":1,"366":1,"382":1,"384":1,"482":1,"500":1}}],["show,",{"2":{"477":1}}],["shown)",{"2":{"454":1}}],["shown",{"2":{"389":1,"457":1,"463":1}}],["shown:",{"2":{"201":1}}],["showing",{"0":{"448":1},"2":{"271":1,"380":1,"496":1,"515":1}}],["show",{"0":{"406":1,"428":1},"2":{"106":1,"115":1,"116":2,"129":1,"151":1,"158":1,"169":1,"175":1,"227":1,"265":1,"267":1,"270":1,"280":1,"309":1,"403":1,"406":1,"428":1,"457":1,"472":1,"501":1,"536":2}}],["shows:",{"2":{"205":1}}],["shows",{"0":{"459":1},"2":{"67":1,"80":1,"115":1,"117":1,"157":1,"167":1,"168":1,"216":1,"256":2,"275":1,"286":1,"296":1,"308":1,"310":1,"328":1,"353":1,"380":1,"391":1,"403":1,"408":1,"413":1,"466":1,"513":1,"534":1}}],["should",{"0":{"243":1},"2":{"103":2,"104":1,"164":1,"456":1,"461":1,"479":3}}],["should,",{"2":{"36":1}}],["shot",{"0":{"35":1},"2":{"491":1}}],["schedule",{"2":{"492":1,"497":1,"516":1}}],["scheduled",{"2":{"492":1,"493":3,"495":1,"496":1,"498":1,"499":1}}],["scheduling:",{"2":{"516":1,"525":1}}],["scheduling,2.",{"1":{"495":1,"496":1,"497":1}}],["scheduling",{"0":{"492":1,"493":1,"498":1},"1":{"493":1,"494":1,"498":1,"499":1}}],["schematics,",{"2":{"152":1,"155":1}}],["schematics.",{"2":{"59":1}}],["schemas",{"2":{"140":1,"143":1}}],["schema",{"0":{"43":1,"69":1},"1":{"44":1},"2":{"85":2}}],["scan",{"2":{"418":1,"517":1}}],["scanning",{"2":{"399":1,"515":1}}],["scale",{"2":{"268":1,"374":1}}],["scattered",{"2":{"99":1}}],["scenes",{"2":{"242":1}}],["scrollbar.",{"2":{"380":1}}],["scrolls",{"2":{"216":1}}],["scrolling",{"2":{"210":1,"262":1,"377":2}}],["scroll",{"2":{"159":2,"210":2,"377":1}}],["scratch.",{"2":{"324":1}}],["scratch",{"2":{"151":1}}],["script",{"2":{"92":2,"137":1,"487":1}}],["scripts,",{"2":{"535":1}}],["scripts",{"0":{"92":1},"2":{"137":2}}],["scripts.",{"2":{"88":1}}],["screen.",{"2":{"458":1,"459":1}}],["screen)",{"2":{"379":1}}],["screen).",{"2":{"215":1,"379":1}}],["screens)",{"2":{"365":1}}],["screenshot.png",{"2":{"185":1}}],["screenshot.png)",{"2":{"185":1}}],["screenshot",{"2":{"93":1,"466":1}}],["screenshots).",{"2":{"350":1}}],["screenshots.",{"2":{"99":1}}],["screenshots",{"2":{"93":1,"217":1,"233":1}}],["screen;",{"2":{"254":1}}],["screen,",{"2":{"253":1,"323":1}}],["screen",{"0":{"296":1,"408":1,"444":1,"455":1,"466":1,"531":1},"1":{"532":1,"533":1,"534":1},"2":{"59":1,"60":1,"95":2,"96":2,"102":1,"105":2,"106":1,"107":1,"108":1,"116":2,"120":1,"132":1,"175":1,"177":1,"200":4,"205":1,"213":1,"296":3,"366":1,"381":1,"408":1,"444":1,"455":1,"466":2,"474":1,"482":1,"531":1,"533":1}}],["scoring",{"2":{"35":1}}],["scorecard",{"0":{"130":1}}],["score.",{"2":{"48":1}}],["scores",{"2":{"12":1,"39":1}}],["score",{"2":{"7":1,"12":1,"119":1,"130":1,"411":1}}],["scope),",{"2":{"488":1}}],["scope,",{"2":{"129":1}}],["scope",{"0":{"16":1,"490":1},"2":{"98":1,"116":1,"221":2,"362":1,"363":1,"364":1,"365":1,"366":1,"381":1,"459":1,"489":1,"490":4}}],["scoped:",{"2":{"15":1}}],["scoped",{"0":{"15":1},"1":{"16":1,"17":1},"2":{"55":1,"262":1}}],["sql",{"2":{"138":1}}],["sqlcreate",{"2":{"69":1}}],["sql,",{"2":{"36":1,"134":1,"188":1}}],["sqlite",{"0":{"25":1,"44":1,"55":1},"2":{"0":1,"8":2,"19":1,"27":1,"29":1,"38":1,"43":1,"66":1,"68":1,"75":1,"227":1,"502":2,"522":1,"526":1}}],["sort:",{"2":{"530":1}}],["sorted",{"2":{"488":1}}],["softened",{"2":{"380":1}}],["software",{"0":{"369":1}}],["solid",{"2":{"225":1,"374":2}}],["sole",{"2":{"33":1}}],["sound.",{"2":{"105":1}}],["source:",{"2":{"286":1}}],["source.",{"2":{"260":1}}],["source).",{"2":{"92":1,"183":1}}],["sources.",{"2":{"137":1}}],["sources",{"2":{"47":1,"93":1,"94":1}}],["sourced",{"0":{"17":1}}],["source",{"0":{"8":1,"19":1,"27":1,"369":1},"2":{"0":1,"8":1,"19":1,"21":1,"27":1,"48":1,"49":1,"75":1,"92":1,"94":1,"135":1,"146":1,"153":1,"166":1,"210":1,"230":1,"233":1,"260":1,"286":2,"328":1,"369":1,"445":1,"472":1,"473":1,"512":1,"525":2}}],["soon.",{"2":{"99":1,"117":1}}],["so",{"2":{"93":1,"150":1,"208":1,"218":1,"219":2,"235":1,"243":1,"256":2,"275":1,"280":1,"299":1,"303":1,"309":1,"330":1,"402":1,"411":1,"462":1,"465":1,"484":1,"485":1,"490":1}}],["something",{"2":{"309":1}}],["something,",{"2":{"80":1}}],["some",{"2":{"93":1,"96":2,"103":2,"104":1,"113":1,"120":1,"239":1}}],["slot",{"2":{"498":1}}],["slots",{"2":{"496":1,"498":1}}],["slow",{"0":{"453":1}}],["slug",{"2":{"486":1}}],["slash",{"2":{"187":2,"196":1}}],["slashing",{"2":{"24":1}}],["slider",{"2":{"411":1}}],["slide",{"2":{"352":1}}],["sliding",{"2":{"11":1,"13":1,"372":1}}],["slicing",{"2":{"9":1}}],["sprint",{"2":{"496":1}}],["spreadsheet",{"2":{"189":1,"203":1,"225":1}}],["spread",{"2":{"103":1}}],["spin",{"2":{"374":1}}],["spikes",{"2":{"84":1}}],["splash",{"2":{"105":1,"119":1}}],["split:",{"2":{"260":1,"463":1}}],["split,",{"0":{"427":1},"2":{"95":1,"159":1}}],["split",{"2":{"59":3,"94":1,"96":1,"103":1,"116":2,"129":1,"133":1,"141":1,"142":1,"145":1,"146":1,"164":3,"166":3,"171":1,"201":1,"212":1,"328":2,"363":2,"449":1,"468":1,"472":1,"525":1}}],["splitting",{"2":{"35":1}}],["splits",{"2":{"9":1}}],["special",{"2":{"325":1}}],["specifying",{"2":{"410":1}}],["specify",{"2":{"139":1}}],["specifically",{"2":{"339":1}}],["specific",{"2":{"116":7,"232":1,"384":1,"387":1,"419":1,"493":2,"498":1,"505":1,"538":1}}],["specifics,",{"2":{"104":1}}],["spelling",{"0":{"274":1},"2":{"172":5,"274":5,"402":1}}],["spell",{"2":{"59":1}}],["spot",{"2":{"81":1}}],["spawning.",{"2":{"542":1}}],["spawns",{"2":{"84":1,"137":1}}],["spacing",{"2":{"211":1,"374":1}}],["space.",{"2":{"258":1}}],["spaces",{"2":{"179":1}}],["space",{"2":{"18":1,"374":3}}],["sparingly.",{"2":{"192":1}}],["sparkles",{"2":{"15":1}}],["span),",{"2":{"44":1}}],["span",{"2":{"35":1,"186":1}}],["saving.",{"2":{"533":1}}],["saving",{"2":{"408":1}}],["saves",{"2":{"153":1,"330":1,"374":1}}],["save.",{"2":{"149":1,"303":1,"424":1,"432":1,"466":1,"469":1}}],["save",{"0":{"210":1,"330":1,"456":1},"2":{"116":1,"136":1,"148":1,"150":1,"153":1,"210":1,"216":1,"233":1,"262":1,"296":2,"330":1,"347":1,"348":1,"363":1,"380":1,"433":1,"444":1,"456":2,"463":1,"470":1,"485":1,"504":1,"521":1,"526":1}}],["saved.",{"2":{"330":1,"452":1,"526":1}}],["saved",{"2":{"75":1,"145":1,"173":1,"212":1,"216":1,"230":1,"299":1,"410":1,"413":1,"484":1,"533":1}}],["save,",{"2":{"42":1,"463":1,"477":1}}],["same",{"2":{"103":1,"241":1,"321":1,"376":1,"419":1,"448":1,"477":1,"502":1,"527":1}}],["says",{"2":{"99":1,"105":1}}],["say",{"2":{"96":1,"105":1,"116":1,"117":2}}],["salted",{"2":{"65":1,"216":1,"218":1,"233":1,"234":1}}],["safer.",{"2":{"314":1}}],["safely",{"2":{"137":1,"213":1,"514":1}}],["safely,",{"2":{"62":1,"460":1}}],["safe,",{"2":{"84":1}}],["safe",{"0":{"78":1},"2":{"76":1,"192":1,"412":1}}],["safety,",{"2":{"360":1}}],["safety:",{"2":{"356":1,"526":1}}],["safety",{"0":{"414":1},"2":{"2":2,"9":1,"78":1,"85":1,"104":1,"377":1}}],["sandboxed",{"2":{"57":1}}],["sanitization",{"0":{"37":1}}],["sanitation:",{"2":{"9":1}}],["symptom",{"2":{"220":1,"236":1}}],["synonym",{"0":{"390":1}}],["sync.",{"2":{"516":1}}],["syncs",{"2":{"490":1}}],["syncing.",{"2":{"344":1}}],["syncing",{"2":{"236":1}}],["sync,",{"2":{"91":1}}],["synced",{"2":{"78":1,"220":2,"334":1}}],["synchronized",{"2":{"517":1}}],["synchronization",{"0":{"346":1,"526":1},"2":{"416":1}}],["synchronization.",{"2":{"64":1,"75":1}}],["synchronously",{"2":{"63":1}}],["synchronous",{"2":{"55":1}}],["sync",{"0":{"64":1,"76":1,"79":1,"292":1,"311":1,"313":1,"416":1,"451":1},"1":{"77":1,"78":1,"79":1,"80":1,"81":1,"82":1,"312":1,"313":1,"314":1,"417":1,"418":1,"419":1,"420":1},"2":{"49":1,"64":1,"74":1,"79":1,"95":1,"96":1,"104":1,"106":2,"108":1,"112":1,"241":1,"299":1,"313":1,"346":1,"362":1,"419":2,"522":1,"526":2}}],["syntax).",{"2":{"274":1}}],["syntax:",{"2":{"187":1,"286":1,"523":1}}],["syntax.",{"2":{"141":1,"203":1,"431":1,"468":1}}],["syntax,",{"2":{"33":1}}],["syntax",{"2":{"7":2,"36":1,"46":1,"59":1,"133":1,"136":1,"142":1,"146":1,"155":1,"166":1,"169":1,"176":1,"178":1,"188":1,"207":1,"263":1,"302":1,"327":1,"331":1,"391":1,"449":2,"486":1,"487":1,"491":1}}],["system.",{"2":{"522":1,"537":1}}],["system\'s",{"2":{"501":2,"504":1}}],["system:",{"2":{"396":1,"464":1}}],["system?",{"0":{"246":1}}],["systems,",{"2":{"531":1,"538":1}}],["systems",{"2":{"169":1,"221":1}}],["systemic",{"0":{"103":1}}],["system,",{"2":{"9":1,"47":1,"268":1,"336":1}}],["system",{"0":{"62":1,"68":1,"128":1,"504":1},"1":{"69":1,"70":1,"71":1},"2":{"2":1,"3":1,"8":1,"9":1,"12":1,"20":2,"28":1,"30":1,"65":1,"70":1,"71":2,"75":1,"84":1,"95":1,"106":1,"130":1,"137":2,"140":1,"145":1,"173":1,"212":1,"221":1,"223":1,"227":2,"253":2,"321":1,"337":1,"339":2,"355":1,"369":1,"374":1,"379":2,"396":2,"415":2,"507":1,"539":1}}],["segment",{"2":{"168":1,"271":1}}],["semicolons",{"2":{"135":1}}],["semantics",{"2":{"381":2}}],["semantic",{"0":{"47":1,"307":1,"393":1,"439":1,"511":1},"2":{"7":1,"30":1,"39":1,"47":1,"50":1,"53":1,"95":1,"374":1,"511":2}}],["seven",{"2":{"105":1,"117":1}}],["several",{"2":{"94":2,"99":1,"103":1,"104":1,"119":1,"120":1,"283":1}}],["severity",{"0":{"109":1},"1":{"110":1,"111":1,"112":1,"113":1},"2":{"71":1}}],["sequencing.",{"2":{"104":1}}],["sequencediagram",{"2":{"143":1}}],["sequence:",{"2":{"131":1}}],["sequence",{"2":{"59":1,"143":1,"194":1,"218":1}}],["sequence)",{"2":{"2":1}}],["serious",{"2":{"94":1}}],["serves",{"2":{"484":1}}],["served:",{"2":{"486":1}}],["served",{"2":{"481":1}}],["server.",{"2":{"491":1}}],["server)",{"2":{"346":1}}],["servers",{"2":{"224":1,"416":1}}],["server",{"0":{"87":1,"484":1},"2":{"87":1,"89":1,"482":1,"484":3,"486":2,"489":1,"490":1}}],["services",{"2":{"305":1,"506":1}}],["service",{"0":{"62":1,"308":1},"2":{"80":2,"90":1,"241":1,"247":1,"305":2,"308":1,"410":1,"438":1,"452":1,"489":1}}],["service,",{"2":{"47":1}}],["seamlessly",{"2":{"159":1}}],["seamless",{"2":{"75":1,"486":1}}],["searches",{"2":{"389":1}}],["search:",{"2":{"278":1,"393":1}}],["searchable",{"2":{"283":1,"284":1}}],["searchable.",{"2":{"119":1}}],["searchability",{"2":{"119":1}}],["search,2.",{"1":{"390":1}}],["search,",{"2":{"71":1,"80":1,"263":1,"481":1}}],["searching,",{"2":{"127":1}}],["searching",{"2":{"16":1,"390":1,"393":1}}],["search.",{"2":{"7":1,"96":1,"435":1}}],["search\\"]",{"2":{"6":1}}],["search",{"0":{"276":1,"277":1,"278":1,"279":1,"310":1,"364":1,"387":1,"389":1,"391":1,"392":1,"393":1,"435":1,"489":1},"1":{"277":1,"278":2,"279":2,"280":1,"281":1,"388":1,"389":1,"390":1,"391":1,"392":1,"393":1},"2":{"4":1,"6":1,"7":1,"38":1,"53":1,"59":1,"95":1,"96":1,"102":1,"108":1,"115":1,"116":1,"264":1,"274":1,"277":1,"278":3,"279":5,"280":1,"281":1,"285":1,"286":1,"305":1,"307":1,"310":1,"343":1,"362":1,"387":2,"388":2,"389":1,"390":1,"391":2,"392":2,"393":1,"411":1,"453":1,"484":5,"489":6,"491":1,"500":1,"530":1}}],["sets",{"2":{"415":1,"539":1}}],["set",{"0":{"461":1},"2":{"173":1,"216":1,"238":1,"247":1,"262":1,"305":2,"326":1,"444":1,"525":1,"542":1}}],["set.",{"2":{"125":1}}],["set,",{"2":{"93":1,"94":1,"216":1}}],["set:",{"2":{"63":1}}],["setting",{"2":{"52":1,"96":1,"200":1}}],["settings?",{"2":{"120":1}}],["settings,",{"2":{"95":1,"99":1,"107":1,"111":1,"131":1,"249":1,"385":1}}],["settings",{"0":{"107":1,"305":1,"394":1,"409":1},"1":{"395":1,"396":1,"397":1,"398":1,"399":1,"400":1,"401":1,"402":1,"403":1,"404":1,"405":1,"406":1,"407":1,"408":1,"409":1,"410":2,"411":2,"412":2,"413":2,"414":1,"415":1},"2":{"19":1,"41":1,"51":1,"52":1,"54":1,"70":1,"77":1,"93":2,"94":1,"96":2,"104":2,"106":1,"107":1,"111":1,"116":1,"120":3,"123":1,"126":1,"172":2,"200":1,"268":1,"274":1,"296":1,"308":1,"360":1,"365":1,"383":1,"396":1,"408":1,"444":1,"455":1,"466":1,"533":1}}],["settings.json.",{"2":{"117":1}}],["settings.json",{"2":{"99":1}}],["settings.",{"2":{"14":1,"51":1,"80":2,"94":1,"247":1,"305":1,"308":1,"346":1,"393":1,"409":1,"420":1,"438":1,"452":1}}],["setup",{"0":{"51":1,"53":1,"357":1,"410":1,"438":1},"1":{"52":1,"53":1,"54":1,"55":1,"358":1,"359":1,"360":1},"2":{"99":1,"100":1,"102":1,"104":1,"108":1,"118":1,"124":1,"130":1,"131":1,"393":1}}],["selfloops",{"2":{"49":1}}],["self",{"2":{"49":1,"50":1,"95":1,"106":1,"112":1,"224":1,"337":1,"346":1}}],["selecting",{"2":{"257":1}}],["selections)",{"2":{"505":1}}],["selections",{"2":{"202":1}}],["selection",{"0":{"252":1,"537":1},"1":{"538":1},"2":{"18":1,"95":2,"96":2,"196":5,"202":1,"329":1}}],["selection.",{"2":{"16":1,"263":1}}],["selection:",{"2":{"16":1}}],["selector",{"2":{"136":1}}],["selected",{"2":{"65":1,"77":1,"173":1,"196":1,"215":1,"221":1,"260":1,"308":1,"354":1,"379":1,"448":1}}],["select",{"2":{"18":1,"19":2,"20":1,"150":1,"151":1,"170":1,"202":1,"216":2,"233":1,"235":1,"279":1,"296":1,"340":1,"345":1,"354":1,"358":1,"359":1,"379":1,"422":1,"431":1,"432":1,"434":1,"437":1,"443":1,"444":1,"446":1,"461":1,"464":1,"466":1,"470":1,"471":1,"474":1,"517":2,"532":1,"536":1,"537":1}}],["selects,",{"2":{"380":1}}],["selects",{"2":{"16":1,"537":1}}],["seconds",{"2":{"263":1,"417":1}}],["seconds.",{"2":{"137":1}}],["second",{"2":{"94":1,"179":1,"182":1,"419":1}}],["secondary",{"2":{"10":1,"478":1}}],["security.md",{"2":{"104":1}}],["security",{"0":{"85":1,"218":1,"234":1,"314":1,"417":1,"420":1,"540":1,"542":1},"1":{"541":1,"542":1},"2":{"85":1,"137":1,"516":1,"540":1,"542":1}}],["security:",{"2":{"65":1}}],["securely",{"2":{"216":1,"218":1,"420":1}}],["secure",{"2":{"57":1}}],["sections",{"2":{"157":1,"177":1,"265":1,"279":1}}],["sections.",{"2":{"99":1}}],["section",{"2":{"95":1,"96":1,"99":1,"104":1,"107":1,"112":1,"159":1,"349":1,"350":1,"428":1}}],["section.",{"2":{"79":1,"99":1,"120":1}}],["section)",{"2":{"47":1}}],["section,",{"2":{"32":1}}],["separators:",{"2":{"209":1}}],["separation",{"2":{"72":1}}],["separating",{"2":{"30":1}}],["separately",{"2":{"239":1,"299":1}}],["separates",{"2":{"57":1}}],["separate",{"2":{"54":1,"164":1,"230":2,"305":1,"339":1}}],["separated",{"2":{"20":1,"415":1,"542":1}}],["sessions,",{"2":{"55":1}}],["sessions",{"2":{"24":1,"162":1,"372":1,"404":1,"539":1}}],["session",{"2":{"20":2,"372":1,"539":1}}],["see",{"2":{"17":1,"65":1,"67":1,"142":1,"146":1,"164":1,"281":1,"322":1,"328":1,"330":1,"368":1,"400":1,"484":1,"485":1,"490":1,"491":1}}],["sensitive",{"2":{"540":1}}],["sensitivity",{"2":{"388":1}}],["sentence",{"2":{"36":1,"48":1,"191":1,"477":1,"480":1}}],["sentences",{"2":{"34":1}}],["sentence.",{"2":{"9":1,"479":1}}],["sender",{"2":{"85":1,"220":1,"236":1}}],["sends",{"2":{"16":1}}],["send",{"2":{"16":1}}],["suitable",{"2":{"224":1}}],["suite",{"0":{"90":1},"1":{"91":1}}],["suites",{"2":{"13":1}}],["supplied",{"2":{"220":1}}],["supportive",{"2":{"478":1}}],["supporting",{"2":{"58":1,"59":2}}],["support.",{"2":{"320":1}}],["supports:",{"2":{"258":1}}],["supports",{"2":{"138":1,"140":1,"165":1,"187":1,"287":1,"296":1,"308":1,"344":1,"379":1,"393":1,"494":1,"531":1}}],["support",{"0":{"390":1,"454":1},"2":{"105":1,"120":1,"166":1,"238":1,"239":1,"242":1,"341":1,"414":2,"452":1,"493":1,"507":1}}],["supported.",{"2":{"388":1}}],["supported",{"0":{"138":1,"503":1,"524":1},"2":{"99":1,"123":1,"134":1,"137":2,"176":1,"286":1}}],["support,",{"2":{"95":1,"306":1}}],["suggestion.",{"2":{"187":1}}],["suggested",{"0":{"121":1}}],["suspected",{"2":{"172":1}}],["successfully.",{"2":{"459":1}}],["success",{"2":{"169":1,"270":1,"479":1}}],["such",{"2":{"4":1,"77":1,"383":1,"386":1}}],["sufficient",{"2":{"100":1}}],["suffixes",{"2":{"37":1}}],["surrounding",{"2":{"160":1,"162":1,"404":1}}],["surface.",{"2":{"117":1}}],["surface",{"2":{"95":1,"96":1,"103":1,"116":1,"117":1,"128":1,"130":1,"390":1}}],["surfaces.",{"2":{"94":1,"104":1}}],["surfaces",{"2":{"93":1,"94":1,"95":1,"103":1,"105":1,"112":1,"119":1,"256":1}}],["surfaces:",{"2":{"93":1,"94":1,"95":1,"105":1}}],["sure",{"2":{"78":1}}],["summarizes",{"2":{"513":1}}],["summarize,",{"2":{"18":1}}],["summarizing,",{"2":{"410":1}}],["summaries,",{"2":{"372":1}}],["summaries:",{"2":{"283":1}}],["summary,",{"2":{"380":1}}],["summary:",{"2":{"283":1}}],["summary>",{"2":{"192":1}}],["summary):",{"2":{"11":1}}],["summary\\",",{"2":{"6":1}}],["summary",{"0":{"94":1,"529":1},"2":{"4":1,"11":1,"24":1,"350":1,"380":1,"381":2,"399":1,"529":1}}],["subnet",{"2":{"417":1,"418":1}}],["subtle",{"2":{"380":1}}],["subdirectory.",{"2":{"360":1}}],["subdirectories",{"2":{"75":1}}],["subprocess",{"2":{"137":1,"539":1}}],["subsequent",{"2":{"93":1,"340":1}}],["subsystems,e.",{"1":{"67":1}}],["subsystems:",{"2":{"61":1}}],["subsystems",{"0":{"61":1},"1":{"62":1,"63":1,"64":1,"65":1,"66":1}}],["subsystem",{"0":{"0":1,"21":1,"63":1,"65":1,"66":1,"70":1},"1":{"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"67":1},"2":{"28":1,"66":1,"67":1,"69":2,"71":4,"75":1,"231":1,"372":1,"416":1,"503":1}}],["subfolders",{"2":{"514":1}}],["subfolders,",{"2":{"374":1}}],["subfolders.",{"2":{"340":1,"512":1}}],["subfolder).",{"2":{"219":1,"235":1}}],["subfolder",{"2":{"62":1,"220":1,"341":1,"519":1}}],["sub",{"2":{"1":1,"44":1}}],["since",{"2":{"339":1}}],["single",{"0":{"222":1},"1":{"223":1,"224":1,"225":1},"2":{"0":1,"1":1,"8":1,"65":1,"104":1,"159":1,"177":1,"214":1,"221":1,"256":1,"336":1,"337":1,"341":1,"372":1,"380":1,"491":2,"497":1,"503":2,"512":1,"513":1}}],["silently",{"2":{"217":1,"233":1}}],["size",{"2":{"339":1}}],["size:",{"2":{"339":1}}],["size.",{"2":{"213":1}}],["sizes",{"2":{"137":1,"380":1}}],["sits",{"2":{"195":1}}],["site,",{"2":{"491":1}}],["site",{"0":{"89":1},"2":{"89":1}}],["six",{"2":{"131":1}}],["sibling",{"2":{"95":1}}],["simultaneous",{"2":{"419":1}}],["simultaneously.",{"2":{"87":1,"527":1}}],["simple",{"2":{"141":1,"369":1}}],["simplified",{"2":{"104":1,"162":1}}],["similarity.",{"2":{"50":1,"511":1}}],["similarity",{"2":{"7":1,"12":1,"38":1,"527":2}}],["signed",{"2":{"339":1}}],["signing",{"2":{"339":1}}],["signing,",{"2":{"99":1}}],["sign",{"2":{"80":1,"305":1,"438":1,"452":1}}],["signature.",{"2":{"218":1,"235":1}}],["signature",{"2":{"65":1,"234":1}}],["signatures.",{"2":{"3":1}}],["sigmoid(val",{"2":{"35":1}}],["sigmoid",{"2":{"35":1}}],["side)",{"2":{"491":1}}],["side.",{"2":{"260":1,"351":1,"463":1}}],["sidebar,",{"2":{"486":1}}],["sidebar.",{"2":{"25":1,"434":1}}],["sidebar",{"2":{"15":1,"60":1,"352":1,"374":1,"494":1,"514":1,"530":1}}],["side",{"2":{"15":1,"260":1,"328":2,"351":1,"403":1,"419":2,"463":1,"487":1,"489":1,"499":1}}],["styling",{"2":{"225":1,"374":1,"380":1}}],["styled",{"2":{"481":1}}],["stylesheet.",{"2":{"486":1}}],["styles",{"2":{"380":1}}],["styles:",{"2":{"268":1}}],["style)",{"2":{"211":1,"376":1}}],["style",{"0":{"187":1,"322":1},"2":{"104":1,"135":1,"140":1,"166":1,"187":2,"189":1,"196":1,"201":1,"203":1,"211":1,"322":1,"376":1,"377":1,"399":1,"407":1,"515":1}}],["stderr)",{"2":{"137":1}}],["stop",{"2":{"46":1}}],["store",{"0":{"239":1},"2":{"68":1,"93":1,"484":1}}],["stores",{"0":{"77":1},"2":{"55":4,"65":1,"66":1,"75":4,"76":1,"99":1,"233":1,"234":1,"300":1,"360":1,"414":1,"520":1}}],["stored.",{"2":{"252":1}}],["stored",{"2":{"38":1,"43":1,"50":1,"55":1,"148":1,"218":1,"227":1,"239":1,"356":1,"413":1,"417":1,"519":1}}],["storage.",{"2":{"99":1,"416":1,"521":1}}],["storage",{"0":{"43":1,"72":1,"73":1,"502":1,"519":1},"1":{"44":1,"73":1,"74":1,"75":1},"2":{"94":1,"96":1,"99":1,"103":1,"104":1,"117":2,"118":1,"131":1,"155":1,"333":1}}],["storage,",{"2":{"29":1}}],["storage:",{"2":{"8":1,"67":1}}],["storing",{"2":{"26":1}}],["still",{"2":{"7":1,"82":1,"94":1,"105":1,"116":2,"217":1,"233":1,"255":1,"448":1,"450":1,"452":1,"456":1,"457":1,"501":1}}],["step.",{"2":{"479":1}}],["steps.",{"2":{"421":1}}],["steps,",{"2":{"12":1}}],["steps",{"2":{"6":1}}],["step",{"0":{"325":1,"326":1,"328":1,"329":1,"330":1},"2":{"2":1,"182":3}}],["straight",{"2":{"207":1}}],["strategy.",{"2":{"105":1}}],["strategy",{"2":{"2":2,"113":1}}],["stronger",{"2":{"120":1}}],["strong.",{"2":{"102":1}}],["strong",{"0":{"102":1}}],["structural",{"0":{"32":1},"2":{"32":1,"33":1,"37":1,"39":1,"47":1,"49":1,"172":1,"372":1}}],["structures,",{"2":{"517":1}}],["structures.",{"2":{"168":1}}],["structure.",{"2":{"358":1}}],["structure,",{"2":{"33":1}}],["structure",{"0":{"59":1,"72":1,"75":1,"231":1},"1":{"73":1,"74":1,"75":1},"2":{"30":1,"93":1,"119":1,"177":1,"229":1,"453":1}}],["structure),",{"2":{"19":1}}],["structured",{"2":{"1":1,"6":1,"10":1,"11":1,"140":1,"230":2,"506":1}}],["stream",{"2":{"20":1,"231":1,"372":2}}],["strike",{"2":{"178":1}}],["strikethrough",{"2":{"178":1}}],["strict",{"0":{"540":1},"1":{"541":1,"542":1},"2":{"37":1,"85":1,"146":1,"415":4,"457":1,"541":1,"542":2}}],["strictly",{"2":{"19":1,"27":1,"85":1}}],["strips",{"2":{"32":1}}],["stripped",{"2":{"9":1,"33":1}}],["string",{"2":{"8":1,"50":1}}],["strings",{"2":{"3":1,"9":1,"415":1}}],["stash.",{"2":{"347":1}}],["stashed",{"2":{"347":1}}],["stashing",{"0":{"347":1}}],["stash",{"2":{"292":1,"347":2}}],["stash,",{"0":{"292":1}}],["staying",{"2":{"406":1}}],["stay",{"2":{"239":1,"286":1,"299":1,"396":1}}],["stays",{"2":{"208":1,"220":1}}],["standardization",{"2":{"374":1}}],["standard",{"2":{"186":1,"206":1,"336":2,"353":1,"356":1,"374":1,"391":1,"407":1,"487":1,"522":1,"523":1,"537":1,"541":1}}],["standalone",{"2":{"92":2,"222":1,"229":1,"524":2}}],["stamping,",{"2":{"92":1}}],["staging",{"0":{"349":1}}],["staging,",{"2":{"70":1}}],["stage:",{"2":{"349":1}}],["stages",{"0":{"31":1},"1":{"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1},"2":{"33":1}}],["stage",{"0":{"2":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"348":1},"1":{"349":1,"350":1},"2":{"1":1,"2":6,"12":2,"13":1,"20":1,"23":1,"28":1,"29":1,"30":1,"46":1,"55":1,"91":1,"348":1,"349":3,"372":1}}],["starred",{"2":{"256":1,"513":1}}],["star",{"2":{"49":1}}],["starts",{"2":{"326":2,"484":1}}],["started,release",{"1":{"336":1,"337":1,"338":1}}],["started",{"0":{"332":1},"1":{"333":1,"334":1,"335":1,"339":1,"340":1,"341":1,"342":1,"343":1},"2":{"303":1,"454":1}}],["start",{"0":{"457":1},"2":{"79":1,"105":1,"119":1,"177":1,"336":1,"418":1,"423":1,"477":1,"482":1,"493":2,"498":1,"525":1}}],["startup,",{"2":{"70":1}}],["startup.",{"2":{"8":1}}],["startopology",{"2":{"49":1}}],["starting",{"2":{"36":1,"470":1}}],["stale;",{"2":{"118":2}}],["stale.",{"2":{"96":1,"99":2,"113":1}}],["staleentities",{"2":{"49":1}}],["stale",{"2":{"42":1,"49":1,"50":1,"94":2,"96":1,"99":1,"104":4,"110":1,"118":7,"119":1,"122":1,"381":1,"490":1}}],["stat",{"2":{"167":1}}],["statistics",{"0":{"269":1},"2":{"167":1,"269":1}}],["statistics:",{"2":{"167":1}}],["statistics.",{"2":{"62":1,"165":1}}],["static",{"0":{"9":1},"2":{"2":1,"9":2,"89":1,"224":1,"323":1,"481":1,"484":1,"491":2,"506":2}}],["state.",{"2":{"349":1}}],["state.json",{"2":{"99":1,"117":1}}],["state.json:",{"2":{"75":1}}],["statediagram",{"2":{"143":1}}],["statement",{"2":{"93":1}}],["states",{"2":{"64":1,"105":2,"113":1,"479":3}}],["states,",{"2":{"60":1,"105":1,"360":1}}],["state",{"0":{"60":1},"2":{"95":1,"103":1,"131":1,"143":2,"162":1,"183":1,"379":1,"381":1,"393":1}}],["state,",{"2":{"2":1,"75":1,"517":1}}],["stats,",{"2":{"28":1}}],["stats",{"2":{"12":1,"20":1}}],["statuses",{"2":{"526":1}}],["status:",{"2":{"227":1,"525":1}}],["status,",{"2":{"95":1,"117":1,"380":1}}],["status.",{"2":{"52":1,"79":1,"312":1,"451":1,"517":1}}],["status",{"0":{"167":1,"313":1,"479":1},"2":{"7":1,"59":1,"63":1,"64":1,"70":1,"79":1,"93":1,"96":1,"106":1,"116":1,"162":1,"167":1,"263":1,"269":1,"287":1,"330":1,"358":1,"362":1,"393":1,"418":1,"419":1,"498":1,"501":1,"522":1,"525":1,"526":1,"530":1}}],["t):",{"2":{"530":1}}],["tweaked",{"2":{"527":1}}],["two",{"2":{"15":1,"171":1,"179":2,"181":1,"215":1,"253":1,"419":1}}],["ttl",{"2":{"418":1}}],["ttl:",{"2":{"417":1}}],["tcp",{"2":{"417":2}}],["tls",{"2":{"417":1}}],["ts,",{"2":{"188":1}}],["tsx,",{"2":{"188":1}}],["tsx",{"2":{"138":1}}],["td",{"2":{"143":2,"194":1}}],["tune",{"2":{"480":1}}],["tuning",{"0":{"412":1}}],["tuning,",{"2":{"120":1}}],["tutorial",{"2":{"95":1,"105":1}}],["turned",{"2":{"279":1,"307":1}}],["turns]",{"2":{"11":1}}],["turns",{"2":{"11":1,"24":1,"411":1,"492":1,"522":1}}],["turn",{"2":{"2":1,"11":2,"278":1}}],["typographer",{"2":{"486":1}}],["typo",{"0":{"274":1,"402":1},"2":{"82":1,"95":1,"107":1,"172":2,"402":2,"463":1}}],["typing)",{"2":{"491":1}}],["typing",{"2":{"37":1}}],["type.",{"2":{"278":1,"328":1,"330":1,"389":1}}],["typeoverloading",{"2":{"49":1}}],["type).",{"2":{"269":1}}],["type)",{"2":{"49":2}}],["types:",{"2":{"484":1}}],["types.",{"2":{"387":1}}],["typescript",{"2":{"279":1}}],["typescript,",{"2":{"134":1,"138":1}}],["types",{"0":{"143":1,"335":1,"510":1},"1":{"336":1,"337":1,"338":1},"2":{"47":1}}],["types).",{"2":{"39":1}}],["type,",{"2":{"44":1}}],["type",{"0":{"37":1},"2":{"37":1,"49":1,"85":1,"133":1,"143":1,"187":1,"196":1,"204":1,"217":1,"278":2,"285":1,"326":1,"503":1}}],["tidy",{"2":{"521":1}}],["tidy.",{"2":{"292":1}}],["tint",{"2":{"380":1}}],["tip:",{"2":{"461":1,"465":1,"466":1}}],["tip,",{"2":{"196":1}}],["tip",{"2":{"187":1}}],["tips",{"0":{"139":1,"164":1,"202":1,"213":1},"2":{"105":1}}],["tips:",{"2":{"79":1}}],["tile",{"2":{"95":1,"96":1,"107":1,"116":1,"268":1,"366":1,"399":2,"515":1}}],["title.",{"2":{"286":1,"325":1}}],["title,",{"2":{"277":1,"489":1,"530":1}}],["title\\")",{"2":{"184":1,"185":1}}],["title](https:",{"2":{"184":1}}],["title).",{"2":{"177":1}}],["title:",{"2":{"118":1}}],["titles,",{"2":{"389":1}}],["titles",{"2":{"105":1,"187":1,"462":1,"527":1}}],["title",{"2":{"37":1,"103":1,"104":1,"113":1,"187":1,"480":1,"500":1,"527":2}}],["time.",{"2":{"356":1,"411":1,"489":1}}],["time:",{"2":{"269":1}}],["times,",{"2":{"525":1}}],["times.",{"2":{"498":1}}],["times:",{"2":{"493":1}}],["times",{"2":{"223":1,"263":1,"419":1}}],["timestamped",{"2":{"419":1}}],["timestamps.",{"2":{"258":1}}],["timestamp",{"2":{"69":1,"502":1}}],["timeout",{"2":{"137":1}}],["timeout,",{"2":{"10":1}}],["time",{"0":{"343":1},"2":{"59":1,"71":1,"93":1,"119":1,"159":1,"165":1,"166":1,"167":2,"205":1,"217":1,"231":1,"233":1,"269":1,"274":1,"420":1,"485":1,"493":1,"496":2,"498":1,"499":1,"522":1,"526":1}}],["timeline.",{"2":{"291":1,"350":1,"354":1,"492":1}}],["timelines",{"2":{"143":1,"155":1}}],["timeline",{"2":{"12":1,"20":1,"28":1,"326":1,"352":1,"353":1,"372":2,"434":1,"464":1,"497":1}}],["timeline,",{"2":{"4":1,"516":1}}],["tier",{"0":{"10":1},"2":{"11":3,"372":1}}],["tampered",{"2":{"65":1,"218":1,"234":1}}],["taking",{"2":{"56":1,"240":1}}],["tagging",{"0":{"291":1}}],["tag",{"2":{"139":1,"263":1,"291":1,"344":1,"487":1,"525":1}}],["tags:",{"2":{"525":1}}],["tags",{"2":{"139":1,"417":1,"462":1,"464":1}}],["tags,",{"2":{"25":1,"32":1,"66":1,"75":1,"292":1}}],["tag.",{"2":{"134":1}}],["tag,",{"2":{"32":1,"47":1,"134":1}}],["talks",{"2":{"19":1}}],["targets.",{"2":{"47":1}}],["target",{"2":{"18":1,"44":1,"49":2,"171":1,"339":1,"354":1,"493":1,"532":1}}],["tab.",{"2":{"219":1,"235":1}}],["tabular",{"2":{"207":1,"212":1}}],["tab,",{"2":{"173":1}}],["tabs:",{"2":{"215":1,"227":1,"530":1}}],["tabs.",{"2":{"173":1,"257":1}}],["tabs,",{"2":{"173":2,"517":1}}],["tabs",{"2":{"96":1,"173":1,"292":1,"374":2,"501":1}}],["tab",{"0":{"173":1},"2":{"20":1,"28":1,"170":1,"173":2,"174":1,"175":4,"215":1,"269":1,"345":1,"362":4,"374":2,"459":2,"517":1}}],["tab:",{"2":{"12":2}}],["table,",{"2":{"262":1}}],["table.",{"2":{"48":1}}],["table).",{"2":{"38":1}}],["tables,",{"2":{"172":1,"213":1,"261":1,"463":1,"487":1}}],["tables",{"0":{"189":1,"203":1,"207":1},"1":{"204":1,"205":1,"206":1,"207":1,"208":1,"209":1,"210":1,"211":1,"212":1,"213":1},"2":{"32":1,"189":1,"203":1,"205":2,"207":1,"212":1,"213":1,"331":1,"350":1,"463":1}}],["table",{"0":{"116":1,"204":1,"205":1,"212":1,"262":1},"2":{"8":1,"36":1,"38":1,"44":1,"49":1,"66":1,"69":1,"95":1,"96":1,"107":1,"116":1,"189":3,"197":3,"203":1,"204":2,"205":6,"206":1,"207":1,"208":1,"210":5,"211":2,"212":3,"213":1,"225":4,"262":2,"268":1,"329":2,"331":1,"366":1,"374":1,"375":2,"376":5,"377":4,"399":2,"449":1,"463":1,"515":2}}],["task:",{"2":{"463":1,"473":2}}],["task.",{"2":{"187":1,"427":1}}],["task,",{"2":{"32":1}}],["tasks:",{"2":{"286":1,"493":1,"498":1,"513":1,"524":1}}],["tasks.",{"2":{"125":1,"286":1,"287":1,"445":1,"473":2,"525":1}}],["tasks.md:",{"2":{"118":1}}],["tasks.md",{"2":{"104":1,"118":1}}],["taskspanel,",{"2":{"105":1}}],["tasks\\",",{"2":{"7":1}}],["tasks",{"0":{"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"421":1,"445":1,"473":1,"522":1,"523":1},"1":{"283":1,"284":1,"285":2,"286":2,"287":1,"288":2,"422":1,"423":1,"424":1,"425":1,"426":1,"427":1,"428":1,"429":1,"430":1,"431":1,"432":1,"433":1,"434":1,"435":1,"436":1,"437":1,"438":1,"439":1,"440":1,"441":1,"442":1,"443":1,"444":1,"445":1,"446":1,"523":1,"524":2,"525":1,"526":1,"527":1,"528":1,"529":1,"530":1},"2":{"7":1,"103":1,"113":1,"256":2,"283":4,"284":2,"285":1,"286":1,"287":1,"288":1,"374":1,"445":3,"473":3,"492":2,"493":2,"495":2,"496":1,"498":2,"499":5,"513":1,"516":1,"522":1,"523":1,"527":2,"529":1,"530":3}}],["tasks()",{"2":{"7":1}}],["tasks).",{"2":{"529":1}}],["tasks)",{"2":{"7":1}}],["tasks,",{"2":{"5":1,"75":1,"103":1}}],["task",{"0":{"183":1,"493":1,"525":1,"528":1,"529":1,"530":1},"1":{"529":1,"530":1},"2":{"4":2,"6":2,"7":3,"13":2,"59":1,"75":2,"91":1,"95":1,"102":1,"108":1,"183":4,"197":2,"283":3,"286":8,"327":1,"380":3,"381":2,"385":1,"445":1,"473":2,"487":1,"493":1,"498":1,"516":1,"522":3,"523":4,"524":1,"525":4,"526":12,"527":3,"529":2,"530":1}}],["tells",{"2":{"278":1}}],["telemetry\\"",{"2":{"11":1}}],["telemetry.",{"2":{"10":1}}],["telemetry:",{"2":{"7":1,"20":1}}],["telemetry:json{",{"2":{"6":1}}],["telemetry",{"0":{"12":1,"20":1,"28":1,"372":1},"2":{"1":1,"2":1,"12":1,"13":1,"28":1,"55":1,"104":1,"372":1}}],["temporary",{"2":{"258":1,"347":1}}],["temporarily",{"2":{"174":1,"346":1,"517":1}}],["template",{"2":{"197":1,"329":1}}],["temperature:",{"2":{"412":1}}],["temperature",{"2":{"107":1,"412":2}}],["term",{"0":{"390":1},"2":{"336":1,"389":1}}],["terminates",{"2":{"137":1,"539":1}}],["terminal:",{"2":{"516":1}}],["terminal.",{"2":{"267":1,"406":1,"415":1,"536":2}}],["terminal",{"0":{"267":1,"405":1,"406":1,"407":1,"457":1,"516":1,"535":1,"536":1,"541":1},"1":{"406":1,"407":1,"536":1,"537":1,"539":1,"540":1},"2":{"95":2,"96":3,"99":3,"103":2,"104":1,"106":2,"107":1,"108":1,"111":2,"137":1,"263":1,"267":2,"339":1,"406":1,"407":1,"415":5,"457":5,"535":1,"536":1,"537":1,"539":4,"540":1,"542":5}}],["terminal,4.",{"1":{"541":1,"542":1}}],["terminal,2.",{"1":{"538":1}}],["terminal,",{"2":{"94":1,"104":3,"117":1,"120":3,"124":1,"126":1,"131":1,"240":1}}],["terminology:",{"2":{"131":1}}],["terminology.",{"2":{"99":1,"104":1}}],["terminology",{"2":{"94":1,"96":1,"103":1,"110":1,"118":7,"119":1}}],["terms,",{"2":{"368":2}}],["terms",{"2":{"4":1,"36":2,"37":2,"46":1}}],["teammates",{"2":{"465":1}}],["team,",{"2":{"454":1}}],["team",{"2":{"79":1,"288":1,"414":1,"525":1}}],["technology).",{"2":{"47":1}}],["technologies,",{"2":{"37":1}}],["technical",{"2":{"34":1,"47":1,"140":1,"402":1}}],["test.",{"2":{"438":1,"452":1}}],["test,",{"2":{"95":1,"98":1}}],["test:p2p",{"2":{"90":1}}],["test:watch",{"2":{"90":1}}],["testing)",{"2":{"372":1}}],["testing).",{"2":{"23":1}}],["testing,",{"2":{"337":1}}],["testing:",{"2":{"90":1}}],["tests.",{"2":{"13":5,"91":4}}],["tests",{"2":{"13":7,"90":2,"91":2}}],["test",{"0":{"13":1,"90":1,"91":1,"438":1},"1":{"91":1},"2":{"13":2,"52":1,"90":2,"106":1,"112":1,"345":1,"410":1}}],["textareas",{"2":{"380":1}}],["text:",{"2":{"270":1,"463":1,"478":2}}],["text.",{"2":{"191":1,"205":1,"425":1,"426":1,"477":1}}],["text](.",{"2":{"185":2}}],["text](https:",{"2":{"184":1}}],["text,",{"2":{"48":1,"55":1,"69":1,"75":1,"374":1}}],["text",{"0":{"52":1,"178":1,"425":1,"426":1,"479":1,"489":1},"2":{"11":1,"16":2,"18":2,"32":1,"33":1,"34":1,"44":1,"54":1,"69":4,"75":1,"99":1,"140":1,"141":1,"155":3,"169":2,"196":1,"202":2,"206":1,"270":1,"286":4,"339":1,"346":1,"353":1,"397":1,"402":2,"410":2,"454":1,"457":1,"481":1,"484":1,"489":1,"491":1,"520":1,"525":1,"526":1,"527":1}}],["trim",{"2":{"520":1}}],["trigger",{"2":{"135":1,"196":2,"296":1,"339":1,"381":1,"417":1,"455":1}}],["triggered",{"2":{"41":1,"42":1}}],["try",{"2":{"328":1,"456":1,"458":1}}],["troubleshoot",{"2":{"120":1}}],["troubleshooting.md:",{"2":{"118":1}}],["troubleshooting.md",{"2":{"104":1}}],["troubleshooting",{"0":{"146":1,"220":1,"236":1,"437":1,"447":1},"1":{"448":1,"449":1,"450":1,"451":1,"452":1,"453":1,"454":1,"455":1,"456":1,"457":1,"458":1,"459":1},"2":{"102":1,"104":1,"119":1,"130":1,"385":1,"437":1}}],["treated",{"2":{"104":1}}],["treats",{"2":{"8":1}}],["tree",{"2":{"62":1,"157":1}}],["trust",{"2":{"314":1}}],["trustworthy.",{"2":{"105":1}}],["trusted.",{"2":{"451":1}}],["trusted",{"2":{"79":2,"95":1,"137":1,"312":1,"418":1,"420":2}}],["true.",{"2":{"103":1}}],["true",{"2":{"10":1}}],["truncation",{"2":{"9":1}}],["truncation:",{"2":{"9":1}}],["truth.",{"2":{"27":1}}],["truth)",{"0":{"27":1}}],["truth:",{"2":{"19":1}}],["truth",{"0":{"8":1,"19":1},"2":{"8":1,"93":1,"512":1}}],["truth,",{"2":{"0":1,"21":1}}],["tradeoffs",{"2":{"339":1}}],["trash",{"0":{"258":1},"2":{"258":3}}],["trail",{"2":{"168":1,"271":1}}],["transfers",{"2":{"417":1}}],["transform,",{"2":{"368":1}}],["transforming",{"2":{"29":1}}],["transport:",{"2":{"417":1}}],["transport",{"0":{"417":1}}],["transit",{"2":{"220":1,"236":1}}],["transient",{"2":{"171":1}}],["transcripts",{"2":{"369":1}}],["transcript",{"2":{"12":1,"20":1}}],["tracing",{"2":{"93":1}}],["track",{"0":{"473":1},"2":{"271":1,"288":1,"290":1,"355":1,"464":1,"492":1,"527":1}}],["tracks",{"2":{"60":1,"64":1,"226":1,"227":1,"464":1,"490":1,"500":1}}],["tracking:",{"2":{"227":1,"507":1}}],["tracking",{"0":{"499":1},"2":{"55":1,"63":1,"357":1,"501":1,"516":1}}],["tracker",{"0":{"20":1}}],["traces,",{"2":{"55":1}}],["trace",{"0":{"28":1},"2":{"2":1,"12":2,"20":1,"303":1,"372":1,"508":1}}],["traversal:",{"2":{"62":1}}],["traversals",{"2":{"25":1,"66":1}}],["traversal",{"2":{"6":1,"7":1}}],["thumbnails)",{"2":{"487":1}}],["thumbnails",{"2":{"217":1,"233":1}}],["things",{"2":{"242":1}}],["third",{"0":{"369":1},"2":{"182":1,"369":1,"416":1}}],["this",{"2":{"15":1,"33":1,"54":1,"76":1,"79":1,"82":1,"84":1,"93":3,"131":1,"151":1,"170":1,"176":1,"186":1,"206":1,"210":1,"250":1,"300":1,"323":1,"324":1,"330":1,"339":1,"340":1,"360":1,"382":1,"383":1,"394":1,"396":1,"411":1,"414":1,"421":1,"447":1,"459":1,"460":1,"464":1,"489":1,"506":1,"529":1}}],["that",{"2":{"85":1,"94":1,"103":1,"104":2,"118":1,"127":1,"151":1,"159":1,"168":1,"203":1,"211":1,"214":1,"217":1,"233":1,"238":1,"271":1,"281":1,"286":1,"335":1,"336":1,"337":1,"347":1,"410":1,"419":1,"427":1,"442":1,"448":1,"450":1,"459":1,"463":1,"464":1,"471":1,"492":1,"495":1,"499":1,"500":1,"508":1,"509":1,"521":1,"529":1}}],["than",{"2":{"50":1,"102":1,"103":1,"104":1,"120":1,"393":1}}],["those",{"2":{"77":1,"105":1,"131":1,"299":1}}],["threads",{"2":{"525":1}}],["threads.",{"2":{"339":1}}],["thread.",{"2":{"84":1}}],["three",{"2":{"115":1,"122":1,"133":1,"140":1,"181":1,"221":1,"335":1,"494":1}}],["threshold)",{"2":{"527":1}}],["threshold:",{"2":{"54":1,"411":1}}],["threshold",{"2":{"38":1,"415":1}}],["threshold\\"",{"2":{"7":1}}],["through",{"2":{"1":1,"2":1,"23":1,"67":1,"223":1,"264":1,"324":1,"388":1,"486":1}}],["then",{"2":{"148":1,"149":1,"296":1,"473":1}}],["they",{"2":{"120":7,"247":1,"258":1,"286":1,"349":1}}],["there",{"2":{"99":1,"120":1,"239":1,"275":1,"374":1}}],["their",{"2":{"27":1,"214":1,"219":1,"223":1,"235":1,"258":2,"303":1,"349":1,"495":1,"498":1,"509":1}}],["them,",{"2":{"240":2,"274":1}}],["them.",{"2":{"107":1,"348":1,"414":1}}],["theme.",{"2":{"396":2}}],["themed",{"2":{"229":1}}],["theme:",{"2":{"106":1,"268":1}}],["theme,",{"2":{"95":1,"99":1,"103":1,"104":1,"111":1,"117":1}}],["themes;",{"2":{"236":1}}],["themes,",{"2":{"74":1}}],["themes.",{"2":{"58":1}}],["theme",{"0":{"396":1},"2":{"60":1,"65":1,"96":1,"107":1,"108":1,"223":1,"239":1,"374":1,"396":3}}],["them",{"2":{"19":1,"141":1,"207":1,"294":1,"299":1,"498":1,"506":1,"519":1,"531":1}}],["these",{"2":{"17":1,"339":1,"350":1,"368":1}}],["the",{"0":{"31":1,"151":1,"158":1,"159":1,"205":1,"215":1,"248":1,"253":1,"254":1,"285":1,"286":1,"310":1,"329":1,"482":1,"509":1,"536":1},"2":{"0":1,"1":1,"2":1,"3":1,"6":1,"8":1,"15":10,"16":4,"17":2,"18":3,"19":4,"20":3,"21":1,"25":1,"30":1,"33":1,"36":1,"38":2,"39":2,"42":1,"48":1,"49":1,"52":2,"54":1,"55":1,"58":1,"60":1,"61":1,"65":2,"66":1,"67":3,"69":1,"80":3,"84":1,"93":5,"94":8,"95":1,"99":4,"103":4,"104":3,"105":4,"107":3,"110":1,"115":5,"116":2,"120":7,"122":3,"125":1,"131":3,"133":2,"134":4,"135":6,"136":6,"137":10,"139":5,"142":4,"145":3,"146":3,"148":4,"149":3,"150":4,"151":3,"153":5,"154":3,"157":2,"159":7,"160":1,"164":6,"165":2,"166":8,"167":5,"168":4,"169":3,"171":3,"172":4,"173":4,"174":3,"176":2,"177":1,"179":2,"183":1,"185":2,"187":5,"189":2,"191":1,"195":2,"199":2,"200":2,"201":3,"202":2,"203":1,"204":3,"205":7,"206":3,"207":1,"208":7,"209":3,"210":6,"211":2,"212":4,"213":4,"215":4,"216":9,"217":2,"218":5,"219":9,"220":8,"221":1,"222":1,"223":3,"227":2,"228":1,"229":1,"230":1,"231":3,"233":3,"234":4,"235":6,"236":3,"238":1,"239":2,"240":1,"241":2,"242":1,"244":1,"245":1,"246":1,"247":2,"248":1,"249":1,"252":1,"253":7,"254":6,"256":3,"257":3,"258":3,"262":2,"263":8,"264":1,"267":2,"269":3,"270":2,"271":4,"274":6,"277":1,"278":3,"279":2,"281":1,"283":1,"284":1,"285":3,"286":6,"290":1,"291":4,"292":1,"296":3,"299":1,"302":1,"303":3,"321":2,"323":3,"325":4,"326":3,"328":2,"329":2,"330":2,"333":1,"334":2,"335":1,"338":2,"339":5,"340":2,"341":1,"345":2,"346":6,"347":1,"349":3,"350":5,"351":1,"352":4,"353":3,"354":8,"356":3,"358":2,"359":3,"360":1,"367":1,"368":6,"369":1,"374":5,"375":1,"376":2,"377":1,"379":10,"380":3,"381":3,"384":2,"386":2,"387":2,"388":1,"389":2,"390":1,"391":3,"392":2,"393":4,"396":3,"403":1,"404":1,"406":1,"407":1,"408":5,"410":1,"411":4,"412":1,"417":1,"418":3,"419":4,"422":1,"424":1,"427":2,"433":1,"434":3,"437":1,"438":2,"446":1,"448":4,"449":1,"450":3,"451":1,"452":1,"457":3,"458":2,"459":2,"461":2,"463":4,"464":3,"465":1,"466":2,"468":1,"470":2,"473":1,"474":1,"477":1,"481":3,"482":3,"484":4,"485":2,"486":2,"488":2,"489":6,"490":6,"491":2,"494":3,"495":1,"498":1,"499":4,"500":2,"501":2,"502":3,"504":1,"506":2,"507":1,"508":1,"509":3,"511":3,"512":1,"513":3,"514":3,"517":7,"519":1,"520":3,"521":1,"525":5,"526":6,"527":1,"529":2,"530":3,"532":5,"533":3,"534":2,"536":2,"537":1,"539":6,"542":1}}],["today:",{"2":{"499":1}}],["todo,",{"2":{"7":1,"196":1}}],["toast",{"2":{"374":1}}],["toasts",{"2":{"374":2}}],["touching",{"2":{"203":1,"352":1}}],["toggling",{"0":{"525":1,"536":1}}],["toggles",{"0":{"411":1},"2":{"388":1,"525":1}}],["toggles:",{"2":{"107":1}}],["toggle:",{"2":{"323":1,"498":1,"507":1,"525":1}}],["toggle,",{"2":{"71":1}}],["toggle",{"0":{"161":1},"2":{"15":1,"107":1,"116":1,"159":1,"163":1,"183":1,"205":1,"291":1,"363":3,"393":1,"429":1,"446":1,"525":1,"536":1}}],["together",{"2":{"214":1}}],["together.",{"2":{"170":1,"445":1}}],["total",{"2":{"167":1,"269":1,"286":1}}],["toml,",{"2":{"138":1}}],["too",{"2":{"103":1,"104":3,"119":1,"397":2}}],["toolchain.",{"2":{"369":1}}],["tool?",{"2":{"342":1}}],["tool,",{"2":{"174":1}}],["tooling",{"2":{"131":1}}],["tooltip.",{"2":{"263":1}}],["tooltip",{"2":{"113":1,"116":2}}],["tooltips,",{"2":{"116":2}}],["tooltips",{"2":{"105":1}}],["tools:",{"2":{"339":1,"520":1}}],["tools.",{"2":{"218":1,"225":1,"234":1,"313":1,"355":1}}],["tools).",{"2":{"65":1}}],["tools):",{"2":{"2":1}}],["tools,",{"2":{"23":1,"372":1}}],["tools",{"0":{"267":1,"297":1,"366":1,"516":1,"520":1},"2":{"20":1,"78":1,"451":1,"465":1}}],["toolbar)",{"2":{"201":1}}],["toolbar,",{"2":{"165":1}}],["toolbar:",{"2":{"158":1,"204":1,"270":1}}],["toolbar.",{"2":{"137":1,"142":1,"148":1,"153":1,"187":1,"204":1,"205":1,"302":1,"456":1,"468":1}}],["toolbar;",{"2":{"96":1}}],["toolbar",{"0":{"195":1,"261":1,"329":1,"534":1},"1":{"196":1,"197":1,"198":1,"199":1,"200":1,"201":1,"202":1},"2":{"15":2,"116":3,"133":1,"135":1,"136":1,"137":1,"169":1,"185":1,"195":1,"202":1,"221":1,"263":2,"296":2,"329":1,"408":1,"430":1,"431":1,"432":1,"434":1,"444":1,"450":1,"455":1,"463":1,"466":1,"532":1,"534":1}}],["toolname.",{"2":{"6":1}}],["tool",{"0":{"7":1,"155":1},"2":{"0":1,"2":2,"3":1,"4":1,"5":1,"7":1,"9":2,"12":2,"20":2,"28":1,"52":1,"66":1,"70":1,"372":1,"517":1}}],["to:",{"2":{"81":1,"291":1,"368":1}}],["topbar",{"2":{"380":1,"381":1}}],["top.",{"2":{"150":1}}],["top",{"0":{"421":1},"1":{"422":1,"423":1,"424":1,"425":1,"426":1,"427":1,"428":1,"429":1,"430":1,"431":1,"432":1,"433":1,"434":1,"435":1,"436":1,"437":1,"438":1,"439":1,"440":1,"441":1,"442":1,"443":1,"444":1,"445":1,"446":1},"2":{"103":2,"104":1,"113":1,"118":2,"125":1,"137":1,"139":1,"145":1,"150":1,"173":1,"205":1,"226":1,"262":1,"291":1,"352":1,"374":1,"379":1,"434":1,"464":1,"470":1,"482":1,"500":1,"520":1,"529":1}}],["topology",{"2":{"49":1}}],["topics",{"2":{"104":1}}],["topic",{"2":{"6":1,"7":1,"119":1}}],["token:",{"2":{"410":1}}],["token.",{"2":{"53":1}}],["tokens:",{"2":{"412":1}}],["tokens,",{"2":{"51":1}}],["tokens",{"2":{"20":1,"24":1,"33":1,"107":1,"346":1,"372":1,"374":1}}],["token",{"2":{"11":1,"12":1,"346":1,"372":1,"374":1,"410":1}}],["tone,",{"2":{"8":1,"18":1}}],["to",{"0":{"81":1,"150":1,"243":1,"248":1,"311":1,"342":1,"433":1,"443":1,"454":1,"470":1,"532":1},"1":{"312":1,"313":1,"314":1},"2":{"1":2,"2":2,"9":3,"10":1,"15":2,"16":3,"17":2,"19":4,"20":2,"21":1,"26":1,"27":1,"28":1,"32":1,"33":1,"37":1,"38":2,"39":1,"48":2,"49":1,"50":1,"52":4,"54":1,"55":1,"59":1,"64":1,"65":2,"66":1,"67":1,"71":1,"75":1,"76":1,"77":1,"80":1,"81":1,"84":1,"85":1,"91":1,"93":1,"94":2,"95":2,"96":1,"103":2,"104":1,"106":1,"108":1,"116":3,"119":1,"120":1,"128":1,"131":4,"134":1,"135":2,"136":4,"137":1,"139":2,"142":2,"143":1,"145":2,"146":2,"148":1,"150":1,"151":3,"153":3,"157":1,"159":3,"163":1,"164":1,"168":3,"169":1,"170":3,"171":3,"172":4,"173":2,"174":2,"175":2,"177":1,"183":2,"184":1,"185":1,"187":2,"189":1,"192":1,"193":1,"194":1,"196":2,"205":1,"206":1,"210":1,"212":1,"213":3,"215":1,"216":3,"219":3,"221":1,"223":2,"224":1,"226":1,"227":1,"229":2,"231":1,"233":2,"235":2,"241":2,"244":1,"247":1,"252":2,"253":1,"254":1,"257":1,"258":3,"262":2,"263":4,"265":1,"266":1,"267":3,"271":3,"274":6,"279":1,"281":3,"285":2,"286":4,"290":1,"291":2,"292":3,"294":2,"296":2,"297":1,"303":2,"308":1,"318":1,"321":1,"322":2,"325":2,"330":1,"334":1,"338":1,"339":4,"340":1,"342":2,"345":1,"346":3,"347":6,"348":1,"349":4,"350":1,"353":1,"354":2,"355":1,"356":2,"359":1,"360":2,"361":1,"362":2,"363":5,"369":1,"374":7,"376":1,"379":2,"380":3,"383":1,"384":1,"385":1,"386":1,"388":2,"389":1,"392":1,"393":1,"394":1,"396":1,"400":1,"410":1,"411":1,"412":1,"414":1,"415":1,"416":2,"417":4,"418":3,"419":4,"420":2,"428":1,"434":1,"438":1,"445":2,"446":1,"447":1,"449":1,"453":1,"455":1,"458":2,"459":1,"461":2,"462":2,"464":5,"469":1,"470":1,"472":3,"473":1,"474":2,"477":1,"479":1,"484":1,"485":1,"486":2,"489":1,"491":1,"495":1,"498":3,"499":1,"501":1,"502":1,"504":1,"505":1,"506":1,"507":3,"509":3,"511":1,"512":1,"513":2,"514":2,"515":1,"517":3,"519":1,"520":1,"521":2,"525":3,"526":2,"527":2,"531":1,"538":2,"539":2,"540":1,"541":1,"542":3}}],["occurrenceindex).",{"2":{"527":1}}],["occurring",{"2":{"499":1}}],["occurs.",{"2":{"330":1}}],["occurs",{"2":{"218":1}}],["o",{"2":{"366":1}}],["old.",{"2":{"310":1}}],["older",{"0":{"459":1},"2":{"11":1,"50":1,"291":1,"386":2,"464":1}}],["o).",{"2":{"379":1}}],["o)",{"2":{"253":1}}],["own",{"2":{"210":1,"242":1,"303":1,"414":1}}],["ownership",{"2":{"117":1}}],["object",{"2":{"143":1,"478":1}}],["obsidian).",{"2":{"506":1}}],["obsidian.",{"2":{"75":1}}],["obsolete.",{"2":{"103":1,"104":1}}],["obsolete",{"0":{"118":1},"2":{"8":1}}],["os",{"2":{"99":1,"227":1}}],["omits",{"2":{"104":3}}],["omit",{"2":{"96":2}}],["omitted.",{"2":{"96":1,"488":1}}],["other.",{"2":{"281":1}}],["other",{"0":{"79":1},"2":{"120":1,"167":1,"173":1,"184":1,"214":1,"239":1,"241":1,"242":1,"270":1,"294":1,"484":1}}],["otherwise",{"2":{"16":1}}],["o,",{"2":{"70":1,"84":1}}],["overdue:",{"2":{"499":1}}],["overdue",{"0":{"499":1},"2":{"499":1}}],["overrides",{"0":{"485":1,"538":1},"2":{"490":1}}],["override",{"2":{"415":1,"485":1,"490":1,"538":1}}],["overwritten.",{"2":{"219":1,"235":1}}],["overwriting",{"2":{"174":1,"517":1}}],["overstates",{"2":{"118":1}}],["overstate",{"2":{"113":1,"117":1}}],["overall",{"2":{"94":1,"98":1,"130":1}}],["overlay.",{"2":{"444":1,"466":1,"532":1}}],["overlay",{"2":{"189":1,"205":1,"262":1,"296":1,"374":1}}],["overlays.",{"2":{"374":1}}],["overlays",{"2":{"59":1}}],["overlapping",{"2":{"103":1,"384":1,"386":1,"419":1}}],["overlap",{"2":{"78":1}}],["overloading",{"2":{"49":1}}],["overhead.",{"2":{"24":1}}],["overview,validation",{"1":{"173":1,"174":1}}],["overview,copy",{"1":{"170":1}}],["overview,capabilities",{"1":{"23":1,"24":1,"25":1,"26":1,"27":1,"28":1}}],["overview",{"0":{"21":1,"30":1,"57":1,"165":1,"283":1,"512":1},"1":{"22":1,"166":1,"167":1,"168":1,"169":1,"171":1,"172":1,"175":1,"513":1,"514":1,"515":1,"516":1,"517":1},"2":{"256":1,"288":1,"342":2,"495":1}}],["over",{"2":{"17":1,"39":1,"104":1,"136":1,"137":1,"145":1,"171":1,"202":1,"212":1,"338":1,"339":1,"349":1,"374":1,"417":1,"499":1,"509":1,"520":1}}],["operating",{"2":{"339":1,"396":1,"415":1,"537":1,"540":1}}],["operation",{"0":{"309":1},"2":{"346":1}}],["operations.",{"2":{"70":1}}],["operations",{"2":{"62":1}}],["operates",{"2":{"29":1}}],["open):",{"2":{"490":1}}],["open)",{"2":{"482":1}}],["open),",{"2":{"15":1}}],["open;",{"2":{"254":1}}],["open:",{"2":{"227":1}}],["open,",{"2":{"210":1,"327":1,"477":1,"525":1,"530":1}}],["open.",{"2":{"164":1,"285":1,"539":1}}],["opening.",{"2":{"280":1}}],["opening",{"0":{"215":1,"253":1,"254":1,"285":1,"352":1,"482":1,"536":1},"2":{"95":1,"127":1,"224":1,"288":1,"381":1}}],["opened",{"2":{"74":1,"75":1,"358":1,"459":1}}],["openai)",{"2":{"66":1}}],["openai",{"2":{"52":3,"99":1,"117":1,"410":4}}],["open",{"0":{"158":1,"205":1,"284":1,"285":1,"286":1,"340":1,"369":1,"422":1,"436":1,"437":1,"445":1,"450":1},"2":{"19":1,"60":1,"77":1,"79":1,"80":1,"81":1,"82":2,"96":1,"99":1,"103":1,"106":3,"115":1,"116":14,"117":1,"131":1,"153":1,"171":1,"173":1,"174":1,"183":2,"187":1,"189":1,"197":1,"202":1,"227":1,"238":2,"245":1,"248":1,"252":2,"253":1,"254":2,"256":1,"257":1,"263":1,"267":1,"274":1,"281":1,"283":3,"284":1,"285":2,"286":2,"287":2,"291":1,"295":1,"296":1,"303":2,"316":1,"317":1,"318":1,"339":1,"340":3,"343":3,"353":1,"356":1,"358":1,"359":1,"362":9,"363":1,"365":3,"366":4,"369":1,"374":5,"379":2,"383":1,"386":2,"388":2,"389":1,"396":1,"397":1,"399":1,"400":1,"402":1,"403":1,"404":1,"406":1,"407":1,"408":1,"409":1,"418":1,"419":1,"422":2,"423":1,"426":1,"427":1,"428":1,"429":1,"435":2,"436":1,"437":1,"438":1,"439":1,"440":1,"441":1,"443":1,"445":5,"446":1,"448":3,"451":2,"452":1,"455":1,"457":1,"459":4,"461":3,"464":2,"465":1,"469":1,"473":6,"474":1,"482":3,"485":1,"499":2,"500":1,"501":2,"506":1,"509":2,"513":2,"515":1,"517":1,"523":1,"525":1,"529":1,"536":1}}],["opens.",{"2":{"148":1}}],["opens",{"2":{"15":1,"136":1,"145":1,"196":1,"197":1,"205":1,"212":1,"253":2,"254":1,"262":1,"325":1,"375":1,"379":2,"406":1,"408":1,"501":1,"502":1,"525":1,"529":1,"533":1}}],["optimised",{"2":{"484":1}}],["optimize",{"2":{"9":1}}],["option)",{"2":{"274":1}}],["option.",{"2":{"151":1}}],["option",{"2":{"151":1,"204":2,"394":1}}],["optionally",{"2":{"350":1}}],["optional;",{"2":{"296":1}}],["optional",{"2":{"65":1,"333":1,"410":1,"462":1}}],["options,",{"2":{"379":1}}],["options.",{"2":{"96":1}}],["options",{"0":{"16":1,"507":1},"2":{"95":1,"96":1,"112":1,"120":1,"321":1,"374":1}}],["out,",{"2":{"352":1,"397":1}}],["outside",{"2":{"253":1,"542":1}}],["outline,",{"2":{"164":1}}],["outline,focus",{"1":{"161":1,"162":1,"163":1}}],["outline,outline",{"1":{"158":1,"159":1}}],["outline.",{"2":{"116":1,"159":1,"403":1,"428":1}}],["outline",{"0":{"156":1,"157":1,"158":1,"159":1,"265":1,"403":1,"428":1},"1":{"157":1,"160":1,"164":1},"2":{"95":1,"96":1,"115":1,"116":1,"157":1,"158":2,"159":3,"160":1,"162":1,"164":2,"175":1,"177":1,"265":1,"363":1,"384":1,"404":1,"472":1}}],["out",{"2":{"49":1,"106":1,"116":2,"243":1,"244":1,"263":1,"268":1,"346":1,"360":1,"366":2,"414":1,"511":1}}],["outbound",{"2":{"25":1}}],["output,",{"2":{"372":1}}],["output:",{"2":{"254":1}}],["outputs",{"2":{"137":1}}],["outputs,",{"2":{"20":1}}],["output.",{"2":{"137":1,"260":1,"412":1,"463":1}}],["output",{"2":{"12":1,"98":1,"137":2,"164":1,"166":2,"169":1,"201":1,"223":1,"263":2,"322":1,"328":2,"472":1,"491":2}}],["outcome,",{"2":{"478":1}}],["outcome",{"2":{"11":1}}],["onto",{"2":{"498":1,"499":1}}],["on:",{"2":{"414":1}}],["once",{"2":{"350":1,"386":1,"418":1,"455":1}}],["once.",{"2":{"349":1,"400":1,"456":1,"459":1,"515":1}}],["on.",{"2":{"279":1}}],["onboarding",{"0":{"127":1},"2":{"112":1,"119":1,"124":1,"131":1}}],["onboarding.",{"2":{"105":1}}],["onedrive)",{"2":{"220":1,"236":1}}],["onedrive",{"2":{"220":1,"223":1,"236":1}}],["ones.",{"2":{"129":1}}],["one",{"2":{"36":1,"116":1,"132":1,"179":1,"181":1,"202":1,"214":1,"221":1,"230":1,"255":1,"283":1,"284":1,"287":1,"335":1,"379":1,"479":1,"486":1,"491":1}}],["on)",{"2":{"34":1}}],["on,",{"2":{"34":1,"307":1}}],["on",{"2":{"15":2,"42":1,"44":1,"50":1,"54":1,"59":1,"65":1,"66":1,"69":1,"93":1,"104":1,"115":1,"135":1,"137":1,"149":1,"150":4,"153":2,"159":1,"164":2,"166":4,"174":1,"197":2,"199":1,"205":1,"218":1,"221":1,"223":1,"227":1,"234":1,"236":1,"241":1,"247":1,"253":1,"254":1,"258":1,"263":1,"274":1,"278":1,"334":1,"336":2,"337":1,"339":2,"340":1,"353":1,"355":1,"359":1,"374":3,"382":1,"397":1,"402":1,"410":1,"411":1,"413":1,"415":2,"418":4,"419":1,"470":2,"484":1,"486":1,"490":2,"491":2,"501":1,"502":1,"506":1,"512":1,"517":1,"520":1,"527":1,"530":1,"531":1,"537":3,"538":1}}],["onnx)",{"2":{"66":1}}],["onnx).",{"2":{"10":1}}],["onnxruntime",{"2":{"53":1,"66":1,"410":1}}],["onnx.",{"2":{"35":1}}],["onnx",{"0":{"35":1,"38":1},"2":{"10":1,"26":1,"29":1,"35":1,"38":1,"53":1,"54":3,"66":1,"410":1}}],["only)",{"2":{"491":1}}],["only,",{"2":{"446":1}}],["only:",{"2":{"279":2,"392":1,"506":1}}],["only;",{"2":{"96":1}}],["only.",{"2":{"93":1,"116":2,"283":1}}],["only",{"2":{"7":1,"79":1,"103":1,"105":1,"115":1,"116":6,"117":1,"120":3,"129":1,"137":1,"151":1,"166":1,"201":1,"230":4,"241":1,"247":1,"260":1,"279":1,"323":1,"328":1,"330":1,"333":1,"380":1,"392":1,"453":1,"458":1,"471":1,"474":1,"484":1,"491":2}}],["order",{"2":{"225":1}}],["ordered",{"0":{"182":1},"2":{"197":1}}],["ordering:",{"2":{"7":1}}],["oriented.",{"2":{"476":1}}],["oriented",{"2":{"116":1}}],["original.",{"2":{"441":1}}],["original:",{"2":{"151":1}}],["original",{"0":{"151":1,"300":1,"441":1,"442":1,"471":1},"2":{"95":2,"151":2,"211":1,"219":1,"220":1,"229":1,"235":1,"236":1,"258":1,"300":1,"303":2,"346":1,"376":1,"442":1,"471":1,"520":2}}],["originate",{"2":{"85":1}}],["orphans",{"2":{"49":1}}],["orphan",{"2":{"49":1,"50":1,"510":1,"527":1}}],["organize",{"0":{"462":1}}],["organizing",{"2":{"341":1}}],["organization",{"2":{"37":1}}],["org",{"2":{"37":1}}],["orchestrated",{"2":{"372":1}}],["orchestrates",{"2":{"38":1}}],["orchestration:",{"2":{"66":1}}],["orchestration",{"0":{"7":1},"2":{"13":1}}],["orchestration,",{"2":{"0":1,"91":1}}],["orchestrator",{"0":{"2":1,"23":1},"2":{"1":1}}],["or",{"0":{"82":1,"99":1,"212":1,"244":1,"422":1,"434":1,"450":1},"2":{"1":1,"3":1,"7":1,"15":1,"18":2,"19":1,"20":1,"26":1,"33":1,"35":1,"36":2,"42":1,"52":1,"59":1,"63":1,"75":2,"77":1,"85":2,"93":1,"94":1,"95":2,"99":1,"103":1,"104":2,"106":1,"107":2,"111":1,"113":1,"116":3,"119":1,"120":2,"124":1,"133":1,"136":1,"137":4,"142":1,"150":2,"154":1,"163":1,"169":1,"170":1,"171":1,"172":2,"174":1,"178":2,"179":1,"187":7,"200":1,"205":1,"207":1,"208":1,"214":1,"216":1,"217":1,"220":3,"221":2,"224":1,"226":1,"227":3,"233":1,"236":3,"241":1,"245":1,"246":1,"247":1,"257":2,"258":1,"263":2,"268":1,"270":1,"274":2,"279":1,"286":1,"291":1,"296":1,"299":1,"300":1,"303":1,"310":1,"327":1,"329":2,"334":1,"335":1,"336":1,"337":1,"338":1,"339":1,"340":1,"345":2,"346":1,"349":1,"352":1,"356":2,"358":1,"363":1,"366":1,"368":1,"374":1,"379":2,"386":1,"387":1,"392":1,"393":1,"396":2,"397":3,"399":1,"400":1,"406":1,"410":3,"412":2,"416":1,"419":2,"426":1,"434":2,"444":1,"446":1,"453":1,"458":2,"463":2,"464":2,"465":1,"466":1,"468":1,"474":1,"480":1,"490":1,"491":1,"492":1,"494":1,"495":1,"498":2,"501":3,"502":1,"506":3,"517":3,"520":1,"525":2,"526":3,"530":3,"532":1,"533":1,"537":2}}],["offers",{"2":{"521":1}}],["off).",{"2":{"474":1}}],["off:",{"2":{"414":1}}],["off.",{"2":{"163":1}}],["off",{"2":{"84":1,"159":1,"429":1,"446":1}}],["offsets,",{"2":{"48":1,"75":1}}],["offline.",{"2":{"240":1}}],["offline?",{"0":{"240":1}}],["offline,",{"2":{"29":1,"249":1}}],["offline",{"2":{"0":2,"21":1,"26":1,"53":1,"54":1,"56":1,"66":1,"155":1,"338":1,"410":1,"506":1}}],["of",{"0":{"8":1,"19":1,"27":1,"339":1},"2":{"0":1,"1":1,"8":1,"11":1,"19":1,"21":1,"27":1,"49":2,"59":1,"67":1,"71":1,"93":2,"96":1,"104":1,"107":2,"116":1,"120":1,"139":1,"150":1,"157":1,"167":2,"173":1,"179":1,"216":1,"219":1,"220":1,"236":1,"238":1,"243":1,"244":2,"257":1,"258":1,"269":2,"271":1,"284":1,"286":1,"288":1,"332":1,"339":1,"345":1,"346":1,"348":1,"349":1,"351":1,"352":1,"353":1,"356":1,"360":1,"369":1,"374":2,"376":1,"380":1,"381":1,"393":1,"414":1,"464":2,"470":1,"477":1,"484":1,"495":1,"511":1,"512":1,"513":1,"520":2,"536":1,"541":1,"542":1}}],["ms",{"2":{"418":1,"419":1}}],["m",{"2":{"362":1}}],["mb",{"2":{"333":1}}],["my",{"0":{"239":1},"2":{"325":1}}],["mm",{"2":{"231":1}}],["month.",{"2":{"495":1}}],["month",{"0":{"495":1}}],["monitor",{"2":{"313":1}}],["moment",{"2":{"220":1,"236":1}}],["mouse",{"2":{"202":1,"509":1}}],["moved",{"2":{"227":1,"244":1,"258":1,"501":1,"514":1}}],["move",{"2":{"106":1,"116":2,"131":1,"247":1,"363":1,"527":1}}],["mostly",{"2":{"96":7}}],["most",{"2":{"94":1,"104":2,"107":1,"119":1,"120":1,"166":1,"202":2,"256":1,"380":1,"513":1}}],["more)",{"2":{"281":1}}],["more:",{"2":{"194":1}}],["more.",{"2":{"115":1,"117":1,"134":1,"188":1}}],["more",{"2":{"54":1,"104":1,"105":1,"214":1,"339":2,"380":1,"385":1,"400":2,"411":1}}],["modification",{"2":{"355":1}}],["modified",{"2":{"174":1,"220":1,"236":1,"349":2,"517":1}}],["modify",{"2":{"19":1,"145":1,"349":1,"419":1}}],["modal:",{"2":{"525":1}}],["modal,",{"2":{"103":1,"116":1}}],["modal",{"0":{"525":1},"2":{"93":1,"95":1,"96":1,"105":3,"115":1,"116":1,"131":1,"137":1,"145":1,"205":1,"212":1,"374":3,"525":1,"526":1}}],["mode:",{"2":{"296":1,"353":1,"408":1,"534":1}}],["mode.",{"2":{"115":1,"116":1,"136":1,"137":1,"326":1,"404":1,"429":1}}],["modes:",{"2":{"494":1}}],["modes,",{"2":{"145":1,"165":1,"171":1}}],["modes.",{"2":{"98":1,"133":1,"141":1,"159":1,"167":1,"269":1,"302":1}}],["modes",{"0":{"166":1,"229":1,"230":1,"260":1,"533":1,"541":1},"2":{"95":4,"96":2,"107":1,"166":1,"328":1}}],["mode,",{"2":{"59":3,"95":1,"133":1,"135":1,"142":1,"148":1,"149":1,"150":1,"151":1,"153":1,"205":1,"296":1,"384":1,"520":1}}],["mode",{"0":{"156":1,"160":1,"161":1,"162":1,"163":1,"201":1,"266":1,"399":1,"404":1,"429":1,"455":1,"456":1,"540":1},"1":{"157":1,"158":1,"159":1,"160":1,"161":2,"162":2,"163":2,"164":1,"541":1,"542":1},"2":{"43":1,"55":1,"58":1,"90":1,"95":3,"96":3,"107":2,"112":1,"116":4,"139":1,"146":1,"159":3,"160":1,"161":1,"162":1,"163":1,"164":2,"166":5,"175":1,"183":1,"192":1,"200":4,"201":2,"212":1,"213":1,"229":1,"230":1,"263":1,"266":1,"291":1,"328":2,"363":4,"403":1,"415":1,"427":2,"444":2,"455":1,"456":1,"463":1,"466":4,"472":1,"525":1,"534":2,"541":2}}],["model,",{"2":{"99":1,"120":1}}],["models:",{"2":{"66":1,"410":1}}],["models",{"2":{"52":1,"54":1,"117":1}}],["models,",{"2":{"29":1,"51":1}}],["model",{"0":{"84":1},"2":{"10":1,"30":1,"53":3,"54":2,"70":1,"96":1,"99":2,"308":1}}],["modular,",{"2":{"21":1}}],["modules",{"2":{"372":1,"488":1}}],["module.",{"2":{"1":1}}],["module",{"0":{"1":1},"2":{"1":1,"23":1}}],["must",{"2":{"36":2,"85":1,"348":1,"357":1,"368":1}}],["multiple",{"0":{"260":1},"2":{"94":1,"105":1,"186":1}}],["multitenant",{"2":{"75":1}}],["multi",{"0":{"7":1,"10":1},"2":{"0":1,"35":1,"37":1,"54":1,"66":1}}],["members",{"2":{"525":1}}],["memory.db:",{"2":{"55":1}}],["memory,",{"2":{"23":1,"372":1}}],["memory",{"2":{"11":2,"24":1,"173":1,"218":1,"234":1,"339":1,"372":1}}],["means",{"2":{"455":2}}],["meaningful",{"2":{"465":1}}],["meaning",{"2":{"356":1,"393":1,"411":1}}],["meaning,",{"2":{"307":1}}],["meeting",{"2":{"326":2}}],["mechanism.",{"2":{"246":1}}],["medium,",{"2":{"525":1}}],["medium",{"0":{"112":1},"2":{"368":1}}],["media:",{"2":{"521":2}}],["media.",{"2":{"120":1,"440":1,"465":1}}],["mediatab.",{"2":{"105":1}}],["media",{"0":{"293":1,"295":1,"297":1,"298":1,"366":1,"440":1,"518":1},"1":{"294":1,"295":1,"296":1,"297":1,"298":1,"299":1,"300":1,"519":1,"520":1,"521":1},"2":{"37":1,"59":1,"65":2,"75":4,"81":1,"95":2,"96":1,"108":1,"116":3,"129":1,"153":2,"154":1,"166":1,"217":2,"219":1,"223":1,"224":1,"227":2,"233":2,"235":1,"281":1,"295":1,"297":1,"298":2,"320":1,"366":2,"440":1,"453":1,"465":2,"472":1,"484":1,"486":1,"491":1,"500":1,"501":2,"503":2,"508":1,"510":1,"518":1,"521":2}}],["media,",{"2":{"32":1,"240":1}}],["menu:",{"2":{"158":1,"161":1,"482":1,"536":1}}],["menu,",{"2":{"116":2,"187":1}}],["menu.",{"2":{"115":1,"437":1,"514":1}}],["menu;",{"2":{"96":2}}],["menu",{"0":{"106":1,"173":1},"2":{"84":1,"93":2,"96":7,"99":1,"104":1,"105":1,"106":1,"110":1,"116":34,"117":4,"120":1,"122":1,"129":1,"172":1,"187":1,"196":2,"205":2,"215":1,"221":1,"226":1,"253":1,"254":1,"257":1,"274":1,"303":1,"336":1,"364":1,"366":1,"379":4,"386":1,"455":1,"464":1,"500":1}}],["mentioned,",{"2":{"96":2}}],["mentioned",{"2":{"96":1}}],["mentions,",{"2":{"66":1}}],["mentions",{"2":{"50":1}}],["mention",{"2":{"34":1,"104":1,"116":1}}],["merging",{"0":{"419":1}}],["merged",{"2":{"230":1}}],["merges",{"2":{"39":1,"50":1}}],["merge",{"2":{"38":1,"346":1,"419":2}}],["mermaid.",{"2":{"431":1}}],["mermaid.js",{"2":{"59":1,"487":1}}],["mermaid",{"0":{"141":1,"142":1,"146":1,"194":1,"302":1,"431":1,"468":1},"2":{"95":1,"96":1,"108":1,"140":1,"141":1,"142":3,"145":3,"146":2,"155":1,"198":2,"223":1,"225":2,"302":2,"329":1,"331":1,"431":1,"449":2,"468":2,"487":1}}],["message.",{"2":{"146":1,"187":1}}],["message",{"2":{"17":1,"55":1,"69":1,"454":1}}],["message:",{"2":{"16":1}}],["messages)",{"2":{"24":1}}],["messages:javascriptconst",{"2":{"85":1}}],["messages:",{"2":{"20":1}}],["messages",{"2":{"11":1,"12":1,"309":1,"476":1}}],["messages,",{"2":{"9":1}}],["method:",{"2":{"93":1}}],["methods",{"2":{"84":1}}],["metric",{"2":{"49":1}}],["metrics,",{"2":{"20":1,"372":1}}],["metrics.",{"2":{"2":1}}],["metadata).",{"2":{"507":1}}],["metadata.json",{"2":{"217":1,"233":1}}],["metadata.json.",{"2":{"65":1,"218":1}}],["metadata.",{"2":{"60":1,"216":1}}],["metadata,",{"2":{"27":1,"75":1,"103":1,"389":1}}],["metadata",{"0":{"360":1,"414":1},"2":{"4":1,"8":3,"19":1,"29":1,"32":2,"69":1,"72":1,"95":1,"99":2,"103":1,"104":1,"105":1,"108":1,"111":1,"117":2,"153":1,"217":1,"233":1,"502":1}}],["migrating",{"2":{"506":1}}],["migrations",{"2":{"8":1}}],["migration:",{"2":{"8":1}}],["migrated",{"2":{"486":1}}],["mixed",{"2":{"477":1}}],["mixes",{"2":{"99":1}}],["milestones.",{"2":{"464":1}}],["milestone",{"2":{"326":1}}],["millisecond",{"2":{"44":1}}],["mirrors",{"2":{"220":1,"236":1}}],["microsoft",{"2":{"207":1,"339":1}}],["microcopy",{"2":{"93":1,"105":1}}],["mismatches,",{"2":{"526":1}}],["mismatches.",{"2":{"66":1,"119":1}}],["mistakes",{"2":{"274":1}}],["mistakes?",{"2":{"120":1}}],["miss.",{"2":{"120":1}}],["missing,",{"2":{"217":1,"233":1}}],["missing.",{"2":{"119":1}}],["missingworkspace",{"2":{"49":1}}],["missing",{"0":{"109":1},"2":{"9":1,"49":1,"94":1,"99":1,"104":1,"107":1,"108":1,"110":1,"128":1,"131":1,"298":1,"521":1}}],["minute",{"2":{"418":1}}],["minute).",{"2":{"269":1}}],["minutes",{"2":{"269":1}}],["minus",{"2":{"116":1}}],["mindmaps",{"2":{"59":1}}],["minimum",{"2":{"397":1,"411":1}}],["minimal",{"2":{"112":1,"162":1}}],["mini",{"2":{"281":1}}],["mini)",{"2":{"52":1,"410":1}}],["mining",{"0":{"34":1},"2":{"34":1}}],["mining,",{"2":{"29":1}}],["mines",{"2":{"34":1}}],["mid",{"2":{"9":1}}],["margins",{"2":{"515":1}}],["marking",{"2":{"353":1}}],["markers",{"2":{"495":1,"498":1}}],["markers,",{"2":{"344":1}}],["marker",{"2":{"455":1,"466":1}}],["marker.",{"2":{"455":1}}],["marked",{"2":{"99":1}}],["mark",{"2":{"225":1,"303":1,"349":1,"498":1}}],["marks",{"2":{"117":1}}],["markups",{"2":{"299":1}}],["markup,",{"2":{"36":1}}],["markup",{"2":{"36":1,"138":1,"207":1}}],["markdown![my",{"2":{"519":1}}],["markdown![alt",{"2":{"185":1}}],["markdown:",{"2":{"326":1,"526":1}}],["markdown.",{"2":{"302":1,"463":1}}],["markdown\\\\#",{"2":{"193":1}}],["markdown<details>",{"2":{"192":1}}],["markdownthis",{"2":{"191":1}}],["markdown***",{"2":{"190":1}}],["markdown|",{"2":{"189":2,"204":1,"209":1}}],["markdown>",{"2":{"186":1,"187":2}}],["markdown[link",{"2":{"184":1}}],["markdown1.",{"2":{"182":1}}],["markdownline",{"2":{"179":1}}],["markdownfirst",{"2":{"179":1}}],["markdown#",{"2":{"177":1,"326":1}}],["markdown```javascript",{"2":{"188":1}}],["markdown```mermaid",{"2":{"143":1,"194":1}}],["markdown```python",{"2":{"133":1}}],["markdown,",{"2":{"138":1,"188":1}}],["markdowneditor.jsx):",{"2":{"59":1}}],["markdownastparser.cleanse()",{"2":{"33":1}}],["markdownastparser.js",{"2":{"32":1}}],["markdown",{"0":{"8":1,"19":1,"176":1,"261":1,"273":1,"326":1,"327":1,"526":1},"1":{"177":1,"178":1,"179":1,"180":1,"181":1,"182":1,"183":1,"184":1,"185":1,"186":1,"187":1,"188":1,"189":1,"190":1,"191":1,"192":1,"193":1,"194":1,"327":1},"2":{"0":1,"7":2,"8":3,"18":1,"19":2,"21":1,"29":1,"32":1,"33":1,"56":1,"59":1,"65":2,"75":1,"82":1,"95":2,"96":1,"105":1,"108":1,"116":1,"132":1,"135":1,"154":1,"155":1,"164":1,"165":1,"166":2,"169":1,"172":2,"176":1,"181":1,"183":2,"187":1,"190":1,"193":1,"195":2,"199":1,"201":1,"203":2,"204":1,"205":2,"206":1,"207":1,"209":1,"210":1,"211":1,"212":1,"217":1,"222":1,"225":1,"230":1,"233":1,"260":1,"262":1,"273":1,"274":1,"286":1,"291":1,"327":1,"328":1,"331":1,"332":1,"341":1,"350":1,"353":1,"362":1,"369":1,"374":1,"375":2,"391":1,"430":1,"449":1,"450":1,"463":2,"466":1,"470":1,"473":1,"481":1,"486":2,"487":1,"492":1,"506":2,"510":1,"512":1,"516":1,"519":1,"522":1,"523":2,"526":3,"527":1,"533":1}}],["made.",{"2":{"368":1}}],["making",{"2":{"170":1,"380":1,"456":1}}],["makefile",{"2":{"138":1}}],["make",{"2":{"78":1,"149":1}}],["machine.",{"2":{"339":1}}],["machines",{"2":{"143":1}}],["machine",{"2":{"137":1}}],["macos",{"2":{"115":1,"116":1,"364":1,"501":1,"537":1}}],["mac",{"2":{"96":1}}],["major",{"2":{"94":2,"95":1,"103":1,"120":1,"250":1}}],["may",{"2":{"93":1,"339":1,"368":1,"452":1}}],["maintain",{"2":{"288":1,"527":1}}],["maintains",{"2":{"72":1}}],["maintenance",{"0":{"50":1},"2":{"50":1}}],["main.cjs):",{"2":{"84":1}}],["main.cjs",{"2":{"61":1}}],["main",{"0":{"61":1},"1":{"62":1,"63":1,"64":1,"65":1,"66":1,"67":1},"2":{"57":1,"61":1,"84":2,"88":1,"105":1,"244":1,"339":1,"376":1,"461":1,"494":1}}],["material.",{"2":{"368":1}}],["material",{"2":{"368":2}}],["materially",{"2":{"96":1,"120":1}}],["matrix.",{"2":{"99":1}}],["matrix",{"0":{"39":1,"47":1,"96":1},"2":{"39":1,"249":1}}],["match:",{"2":{"527":3}}],["matching",{"2":{"278":1,"279":1,"388":1,"391":1,"435":1,"480":1,"489":2}}],["matching.",{"2":{"33":1}}],["match",{"2":{"17":1,"94":1,"96":1,"98":1,"99":1,"116":2,"131":1,"220":1,"236":1,"280":1,"364":2,"374":1,"383":1}}],["matches",{"2":{"4":1,"279":2,"388":1,"389":1,"390":1,"392":1,"393":1,"499":1,"527":1}}],["maximize",{"2":{"205":1,"213":1}}],["maximum",{"2":{"164":1,"397":1}}],["max",{"2":{"36":1,"107":1,"412":1}}],["map",{"2":{"281":1}}],["map.",{"2":{"94":1,"122":1}}],["mapping",{"2":{"281":1}}],["mappings,",{"2":{"55":1}}],["mapped",{"2":{"25":1}}],["maps",{"2":{"3":1,"66":1,"508":1,"512":1}}],["managing",{"2":{"518":1}}],["manage:",{"2":{"298":1}}],["manager:",{"2":{"274":1}}],["manager",{"0":{"226":1},"1":{"227":1},"2":{"347":1,"500":2}}],["manager.",{"2":{"212":1}}],["managed",{"2":{"68":1,"77":1,"78":1,"514":1}}],["manages",{"2":{"59":1,"74":1}}],["management,",{"2":{"63":1,"522":1}}],["management",{"0":{"60":1,"71":1,"292":1,"293":1,"345":1},"1":{"294":1,"295":1,"296":1,"297":1,"298":1,"299":1,"300":1},"2":{"56":1,"414":1,"440":1,"497":1,"522":1}}],["manage",{"2":{"19":1,"172":1,"240":1,"274":1,"465":1,"480":1,"507":1,"525":1}}],["manual",{"2":{"491":1}}],["manually.",{"2":{"419":1}}],["manifest",{"2":{"218":1,"233":1,"235":1}}],["manifest.",{"2":{"65":1,"233":1,"234":1}}],["many",{"2":{"94":1,"103":1,"105":1,"115":1,"117":1,"119":1,"188":1,"399":1,"515":1}}],["mandatory",{"2":{"1":1}}],["master",{"0":{"0":1,"2":1,"23":1},"1":{"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1},"2":{"1":1,"13":1}}],["lg",{"2":{"374":1}}],["l",{"2":{"158":1,"175":1,"209":1,"363":2,"403":1}}],["lr",{"2":{"143":1}}],["lucide",{"2":{"84":1}}],["llama",{"2":{"52":3}}],["llms",{"2":{"66":1}}],["llmfallbacktriggered",{"2":{"12":1}}],["llmfallbacktriggered:",{"2":{"10":1}}],["llmregistry.",{"2":{"10":1}}],["llm",{"0":{"10":1},"2":{"2":1,"10":2,"11":1,"23":1,"24":1,"51":1,"52":1,"70":1,"99":1,"372":1,"410":1}}],["ltd,",{"2":{"37":1}}],["letting",{"2":{"520":1}}],["lets",{"2":{"141":1,"203":1,"351":1,"407":1,"411":1,"413":1}}],["legacy",{"2":{"486":1}}],["less",{"2":{"376":1}}],["leading",{"2":{"271":1}}],["leaves",{"2":{"414":1}}],["leave",{"2":{"179":1,"507":1}}],["leaving",{"2":{"169":1,"498":1,"535":1}}],["learned",{"2":{"386":1,"413":1}}],["learn",{"0":{"248":1},"2":{"120":1,"411":1}}],["learning,",{"2":{"107":1}}],["least",{"2":{"36":1}}],["levels",{"2":{"525":1}}],["levels,",{"2":{"172":1}}],["level.",{"2":{"96":1,"102":1,"120":1}}],["level",{"0":{"57":1,"225":1,"528":1,"529":1},"1":{"529":1,"530":1},"2":{"69":1,"96":1,"99":1,"104":2,"107":1,"116":4,"196":1,"218":1,"283":1,"291":1,"353":1,"379":1,"380":1,"415":1,"419":1,"482":1,"495":1}}],["leverages",{"2":{"38":1}}],["length",{"2":{"36":1}}],["left,",{"2":{"166":1}}],["left.",{"2":{"164":1}}],["left",{"2":{"14":1,"15":1,"166":1,"189":2,"209":2,"437":1,"494":1,"530":1}}],["license.",{"2":{"367":1}}],["license",{"0":{"367":1},"1":{"368":1,"369":1},"2":{"368":1,"369":1}}],["literal",{"2":{"206":1}}],["literally:",{"2":{"193":1}}],["libraries.",{"2":{"369":1}}],["library",{"2":{"96":1,"518":1}}],["library,",{"2":{"95":1}}],["library.",{"2":{"16":1}}],["lib",{"2":{"61":1,"91":1}}],["light:",{"2":{"396":1}}],["light,",{"2":{"268":1}}],["light",{"2":{"58":1,"104":1,"106":1,"339":1,"396":2}}],["lightweight",{"2":{"53":1,"131":1,"256":1}}],["likely",{"2":{"220":1,"236":1,"274":1}}],["like.",{"2":{"104":1}}],["like",{"2":{"52":1,"239":1,"242":1,"325":1,"374":1,"465":1,"480":1,"506":1}}],["lifecycle:",{"2":{"539":1}}],["lifecycle,",{"2":{"84":1}}],["lifecycle",{"0":{"40":1,"299":1,"539":1},"1":{"41":1,"42":1}}],["lived,",{"2":{"418":1}}],["live.",{"2":{"340":1,"461":1}}],["lives.",{"2":{"271":1}}],["lives",{"2":{"217":1}}],["live",{"0":{"485":1},"2":{"34":1,"59":1,"64":1,"71":2,"89":1,"137":1,"141":1,"146":1,"166":1,"167":2,"201":1,"227":2,"263":1,"269":1,"328":1,"332":1,"391":1,"487":1,"491":1,"501":1,"529":1}}],["linux).",{"2":{"537":1}}],["lint,",{"2":{"98":1}}],["line.",{"2":{"407":1}}],["line:",{"2":{"187":1}}],["lines.",{"2":{"353":1}}],["lines",{"2":{"167":1,"269":1,"486":1,"527":1}}],["lines,",{"2":{"32":1,"520":1}}],["line",{"0":{"179":1},"2":{"55":1,"59":1,"75":2,"120":1,"136":1,"167":1,"179":4,"196":1,"269":1,"291":1,"356":2,"419":3,"487":1,"491":1,"525":1,"527":3,"529":1}}],["linguistic",{"0":{"33":1}}],["link:",{"2":{"525":1}}],["linkify",{"2":{"486":1}}],["linking",{"0":{"294":1}}],["linking:",{"2":{"173":1}}],["linking,",{"2":{"70":1,"518":1}}],["link,",{"2":{"202":1}}],["link.",{"2":{"115":1,"116":1}}],["linked",{"0":{"450":1},"2":{"48":1,"65":1,"82":1,"164":1,"171":1,"214":1,"298":1,"465":1}}],["links:",{"2":{"391":1}}],["links.",{"2":{"164":1,"486":1,"510":1}}],["links,",{"2":{"75":1,"261":1,"463":1,"491":1}}],["links",{"0":{"184":1},"2":{"48":1,"411":1,"486":1,"487":1,"519":1,"521":1}}],["link",{"0":{"170":1,"171":1},"2":{"13":1,"96":2,"99":1,"108":1,"112":1,"116":1,"131":1,"170":3,"171":3,"173":1,"184":1,"197":1,"281":1,"286":1,"294":1,"327":1,"329":2,"363":1,"374":4,"450":1,"486":1,"489":1,"532":1}}],["listing",{"2":{"484":1,"499":1,"529":1}}],["listing,",{"2":{"93":1}}],["listbox",{"2":{"379":1}}],["list,",{"2":{"60":1,"380":1}}],["lists:",{"2":{"524":2}}],["lists)",{"2":{"487":1}}],["lists",{"0":{"180":1,"183":1},"2":{"99":2,"248":1,"488":1,"515":1,"521":1}}],["lists,",{"2":{"59":1,"261":1,"463":1,"487":1}}],["lists.",{"2":{"37":1,"453":1}}],["list.",{"2":{"20":1,"202":1,"283":1,"284":1,"461":1}}],["list",{"2":{"12":1,"17":1,"95":1,"96":2,"170":1,"197":4,"216":2,"219":1,"235":1,"257":1,"268":2,"374":2,"399":1,"420":1,"424":1,"449":1,"451":1,"464":1,"474":1,"513":1,"514":1,"515":1,"517":1,"523":1,"541":1,"542":1}}],["limits",{"2":{"137":1}}],["limitations",{"0":{"339":1}}],["limitations:",{"2":{"93":1}}],["limitation.",{"2":{"96":1}}],["limit",{"2":{"10":1,"279":1}}],["laptops)",{"2":{"337":1}}],["larger",{"2":{"255":1,"400":1}}],["large.",{"2":{"210":1,"216":1}}],["large",{"0":{"453":1,"472":1},"2":{"205":1,"213":2,"281":1,"339":1,"397":1,"400":1,"453":1,"515":1}}],["launch:",{"2":{"340":1}}],["launch.",{"2":{"339":1,"359":1}}],["launches:",{"2":{"340":1}}],["launches",{"2":{"227":1,"339":1,"501":1}}],["launch",{"2":{"89":1,"339":1}}],["last",{"2":{"75":1,"208":1,"216":1,"349":1,"474":1}}],["latest",{"2":{"334":1,"459":1,"484":1,"517":1}}],["later.",{"2":{"299":1,"300":1,"303":1,"462":1,"520":1}}],["later",{"2":{"99":1,"411":1}}],["latex",{"2":{"59":1,"138":1,"223":1}}],["latency",{"0":{"11":1,"24":1},"2":{"0":1,"1":1,"9":1,"12":1,"13":1,"20":2,"28":1,"372":2}}],["latency,",{"2":{"0":1,"11":1}}],["layout.",{"2":{"486":1,"509":1,"536":1}}],["layouts",{"2":{"374":1}}],["layout",{"0":{"268":1,"515":1},"2":{"59":2,"205":1,"220":1,"236":1,"268":1,"374":1,"484":1,"515":1}}],["layer,",{"2":{"67":1}}],["layer",{"0":{"3":1,"4":1,"5":1,"6":1,"7":1,"58":1,"67":1},"1":{"4":1,"5":1,"6":1,"7":1,"59":1,"60":1},"2":{"2":1,"13":1,"67":1,"91":1}}],["labeled",{"2":{"376":1}}],["labels",{"2":{"119":1,"120":1,"122":1,"150":1,"383":1,"476":1,"477":1}}],["labels:",{"2":{"100":1}}],["labels.",{"2":{"94":1,"104":1}}],["labels,",{"2":{"94":1,"477":1}}],["label",{"2":{"39":1,"50":2,"96":1,"99":1,"104":1}}],["labs,",{"2":{"37":1}}],["lands",{"2":{"197":1}}],["landing,",{"2":{"248":1}}],["landing",{"0":{"256":1,"398":1,"513":1},"1":{"399":1,"400":1},"2":{"15":1,"96":1,"99":1,"116":17,"131":1,"215":1,"253":1,"254":1,"256":1,"258":1,"268":2,"283":1,"323":1,"366":4,"379":2,"446":1,"458":1,"459":1,"474":1,"482":1,"513":1,"517":1}}],["language,",{"2":{"137":1}}],["languages,",{"2":{"138":1,"263":1}}],["languages",{"0":{"138":1},"2":{"134":1,"137":1,"188":1}}],["language).",{"2":{"134":1}}],["language",{"0":{"134":1},"2":{"33":1,"132":1,"133":1,"134":3,"135":1,"136":3,"139":2,"263":2}}],["loss,",{"2":{"526":1}}],["locked",{"2":{"262":1,"337":1}}],["locked,",{"2":{"217":1,"233":1}}],["locked.",{"2":{"210":1}}],["lock",{"2":{"75":1,"210":1,"332":1}}],["locate",{"2":{"417":1}}],["located",{"2":{"75":1}}],["location",{"2":{"216":1,"233":1,"323":1,"501":1}}],["location:",{"2":{"54":1,"507":1}}],["local,",{"2":{"419":1}}],["locality",{"0":{"55":1}}],["local):",{"2":{"54":1}}],["locally.",{"2":{"263":1}}],["locally",{"2":{"43":1,"53":1,"54":1,"137":3,"481":1,"502":1}}],["local",{"0":{"26":1,"64":1,"484":1},"2":{"0":1,"10":1,"21":1,"26":1,"29":2,"38":1,"51":1,"53":1,"55":1,"56":1,"59":1,"63":1,"64":1,"66":3,"72":1,"99":1,"117":1,"137":2,"220":1,"223":1,"226":1,"236":1,"249":1,"345":1,"346":2,"350":1,"358":1,"369":1,"406":1,"410":1,"416":1,"417":1,"418":1,"480":1,"482":1,"484":1,"512":1,"516":1,"535":1}}],["looks",{"0":{"449":1,"455":1},"2":{"236":1}}],["look",{"2":{"104":1,"322":1}}],["lookup.",{"2":{"44":1}}],["lookup",{"2":{"38":1}}],["loosely;",{"2":{"96":1}}],["loops",{"2":{"49":1,"137":1}}],["loop,",{"2":{"2":1,"137":1}}],["longer",{"2":{"94":1,"103":1,"118":1,"309":1}}],["long",{"2":{"24":1,"157":1,"164":2,"265":1,"336":1,"412":1,"472":1,"539":1}}],["load.",{"2":{"490":1}}],["load",{"2":{"174":1,"517":1}}],["loaded.",{"2":{"456":1}}],["loaded",{"2":{"98":1,"105":1}}],["loading,",{"2":{"70":1}}],["loading...",{"2":{"1":1,"3":1,"30":1,"41":1,"42":1,"43":1,"57":1,"67":1,"73":1,"84":1,"144":1,"355":1}}],["loads",{"2":{"2":1,"340":1}}],["logically.",{"2":{"514":1}}],["logic",{"2":{"61":1}}],["logged",{"2":{"49":1,"212":1,"350":1,"501":1}}],["logging):",{"2":{"2":1}}],["logging",{"0":{"68":1},"1":{"69":1,"70":1,"71":1},"2":{"1":1,"2":1,"43":1,"68":1,"415":1}}],["log",{"0":{"20":1,"70":1},"2":{"68":1,"71":4,"75":1,"415":1}}],["logs.",{"2":{"71":2}}],["logs.db:",{"2":{"55":1,"69":1,"75":1}}],["logs.db",{"2":{"49":1}}],["logs(subsystem);",{"2":{"69":1}}],["logs,",{"2":{"55":1}}],["logs",{"0":{"28":1},"2":{"2":1,"55":1,"69":3,"71":1,"226":1}}],["logdb.",{"2":{"49":1,"415":1}}],["logdb",{"2":{"1":1,"2":1}}],["lower",{"2":{"412":1}}],["lower(canonical",{"2":{"44":1}}],["lowdensity",{"2":{"49":1}}],["low",{"0":{"113":1},"2":{"0":1,"49":1}}],["dd",{"2":{"231":1}}],["d[done]",{"2":{"194":1}}],["d[save",{"2":{"143":1}}],["d",{"2":{"143":1}}],["d.",{"0":{"65":1}}],["drive,",{"2":{"337":1}}],["drive",{"2":{"334":1}}],["drill",{"2":{"283":1}}],["drift",{"2":{"96":1,"103":1}}],["drift:",{"2":{"94":1}}],["drag.",{"2":{"509":1}}],["drag",{"0":{"154":1,"498":1},"2":{"281":1,"498":2,"499":1,"509":1}}],["drawer",{"2":{"258":1,"263":1,"536":1,"539":1}}],["drawer.",{"2":{"137":1,"539":1}}],["draw",{"2":{"148":1,"150":2,"433":1,"470":1,"520":1}}],["draw.io),",{"2":{"501":1}}],["draw.io.",{"2":{"153":1}}],["draw.io",{"0":{"152":1,"153":1},"2":{"65":2,"140":1,"152":1,"153":3,"155":1,"217":2,"227":1,"233":2,"374":2,"501":1,"503":1}}],["drawn",{"2":{"59":1}}],["drawing.",{"2":{"149":1}}],["drawing,",{"2":{"140":1,"147":1}}],["drawings",{"2":{"59":1}}],["drawing",{"2":{"59":1,"75":1}}],["drains:",{"2":{"50":1}}],["dropping",{"2":{"376":1}}],["dropdown",{"2":{"71":1,"158":1,"205":1,"379":2}}],["drop",{"0":{"154":1,"498":1},"2":{"8":2,"154":1,"499":1}}],["don\'t",{"2":{"490":1}}],["done.",{"2":{"429":1}}],["done",{"2":{"327":1}}],["doing",{"2":{"454":1}}],["double",{"2":{"374":2,"515":1}}],["down",{"2":{"283":1,"337":1}}],["downloading",{"2":{"335":1}}],["download",{"0":{"334":1,"503":1},"2":{"212":2,"334":1,"339":1,"500":1}}],["download:",{"2":{"145":1}}],["downloaded",{"2":{"54":1}}],["downloads).",{"2":{"223":1,"501":1,"507":1}}],["downloads",{"0":{"226":1,"500":1,"504":1},"1":{"227":1,"501":1,"502":1,"503":1,"504":1},"2":{"53":1,"145":1,"212":2,"223":1,"226":1,"227":2,"365":1,"500":4,"501":2,"504":2,"507":2}}],["dom",{"2":{"137":1}}],["domains",{"2":{"1":1}}],["domain",{"0":{"1":1,"23":1,"34":1},"2":{"0":1,"21":1,"23":1,"29":1,"34":1,"39":1,"47":1,"372":2}}],["doesn\'t",{"2":{"236":1,"337":1}}],["does",{"0":{"239":1,"240":1,"246":1,"450":1,"457":1,"458":1},"2":{"93":1,"94":1,"104":2,"105":1,"120":1,"146":1,"220":1,"246":1,"394":1,"402":1,"414":1,"452":1}}],["dockerfile,",{"2":{"138":1}}],["doc",{"2":{"128":1}}],["doc.",{"2":{"103":1,"104":1}}],["docs.",{"2":{"94":1,"96":2,"110":1,"116":1,"120":2,"122":1}}],["docs",{"0":{"101":1},"2":{"89":1,"93":2,"94":2,"96":6,"98":1,"99":1,"103":3,"104":9,"105":4,"107":1,"113":1,"116":4,"117":2,"118":6,"119":3,"120":1,"125":1,"126":2,"130":1,"131":1,"229":1,"231":1,"383":1}}],["docs:",{"2":{"117":4}}],["docs:build",{"2":{"89":1}}],["docs:dev",{"2":{"89":1}}],["document,",{"2":{"353":1}}],["documentlist,",{"2":{"105":1}}],["documented,",{"2":{"116":3}}],["documented?",{"2":{"116":1}}],["documented:",{"2":{"107":1}}],["documented;",{"2":{"96":4}}],["documented.",{"2":{"96":3,"115":1,"117":1}}],["documented",{"2":{"96":5,"103":1,"106":2,"116":4}}],["documentation"",{"2":{"94":2,"103":1}}],["documentation,",{"2":{"386":1}}],["documentation,4.",{"1":{"91":1}}],["documentation,3.",{"1":{"87":1,"88":1,"89":1}}],["documentation",{"0":{"83":1,"89":1,"93":1,"96":1,"106":1,"107":1,"108":1,"109":1,"118":1,"119":1,"125":1,"316":1,"383":1},"1":{"84":1,"85":1,"86":1,"90":1,"92":1,"94":1,"95":1,"96":1,"97":1,"98":1,"99":1,"100":1,"101":1,"102":1,"103":1,"104":1,"105":1,"106":1,"107":1,"108":1,"109":1,"110":2,"111":2,"112":2,"113":2,"114":1,"115":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1},"2":{"93":4,"94":3,"99":1,"103":1,"104":1,"105":1,"107":1,"118":4,"120":1,"130":1,"131":3,"369":1,"382":1,"385":1,"390":1}}],["documentation.",{"2":{"65":1,"99":1,"105":1,"116":1,"117":1}}],["documentcontext.jsx:",{"2":{"60":1}}],["documentdetail.jsx):",{"2":{"59":1}}],["document).",{"2":{"32":1}}],["document",{"0":{"62":1,"104":1,"428":1,"517":1},"2":{"30":1,"60":3,"62":1,"65":1,"75":1,"94":1,"95":1,"96":1,"116":36,"158":1,"167":2,"170":1,"219":1,"235":1,"290":1,"355":1,"374":3,"464":1,"500":1}}],["documents)",{"2":{"519":1}}],["documents,",{"2":{"66":1,"227":1,"506":1,"517":1}}],["documents.",{"2":{"59":1,"157":1,"256":1}}],["documents",{"2":{"17":1,"104":1,"170":1,"487":1,"501":1,"503":4,"512":1,"515":1}}],["document.",{"2":{"15":1,"222":1,"269":1}}],["do",{"0":{"245":1,"308":1,"342":1},"2":{"77":1,"79":1,"80":1,"82":1,"96":1,"99":1,"107":1,"116":1,"120":1,"151":1,"243":1,"479":1,"521":1}}],["dictionary:",{"2":{"274":1}}],["dictionary").",{"2":{"172":1}}],["dictionary",{"0":{"274":1},"2":{"172":2,"274":5}}],["dictionary.",{"2":{"172":1,"274":1}}],["dimensions,",{"2":{"74":1}}],["dimension",{"2":{"66":2}}],["dimensional",{"2":{"38":1,"66":1,"75":1}}],["differ,",{"2":{"455":1}}],["differs.",{"2":{"390":1}}],["differences,",{"2":{"353":1}}],["differences.",{"2":{"104":1,"291":1}}],["difference",{"2":{"291":1}}],["different",{"2":{"216":1,"233":1,"268":1,"270":1}}],["diffs",{"0":{"353":1},"2":{"356":1,"419":1}}],["diffs,",{"2":{"70":1}}],["diff",{"2":{"63":1,"353":1,"354":1,"390":1}}],["direction",{"2":{"146":1}}],["directionally",{"2":{"526":1}}],["directional",{"0":{"526":1},"2":{"75":1,"516":1,"522":1}}],["directories",{"0":{"91":1},"2":{"231":1,"488":1}}],["directory.",{"2":{"227":1,"506":1}}],["directory,",{"2":{"154":1}}],["directory",{"0":{"72":1,"504":1,"539":1},"1":{"73":1,"74":1,"75":1},"2":{"62":1,"69":1,"75":1,"415":1,"501":2,"507":1,"539":1}}],["direct",{"2":{"64":1,"212":1,"227":1,"374":1,"375":1,"421":1,"489":1,"509":1,"529":1,"531":1}}],["directly.",{"2":{"466":1,"509":1}}],["directly;",{"2":{"338":1}}],["directly:",{"2":{"204":1}}],["directly",{"0":{"207":1},"2":{"34":1,"75":1,"128":1,"137":1,"145":1,"147":1,"154":1,"159":1,"171":1,"205":1,"207":1,"212":1,"214":1,"223":1,"227":1,"253":1,"270":1,"290":1,"291":1,"296":1,"356":1,"379":1,"416":1,"445":1,"464":1,"465":1,"473":1,"498":1,"501":1,"504":1,"507":1,"525":2,"526":1}}],["dirty",{"2":{"60":1}}],["dialog.",{"2":{"444":1}}],["dialogs",{"2":{"363":1}}],["dialogs,",{"2":{"60":1}}],["dialogue",{"2":{"359":1}}],["dialog",{"0":{"215":1,"318":1},"2":{"105":1,"215":1,"323":1,"363":1,"374":1,"456":1}}],["dialog;",{"2":{"96":1}}],["dialog,",{"2":{"95":1}}],["diagram.",{"2":{"142":1,"150":1,"153":1,"433":1,"469":1}}],["diagram",{"0":{"73":1,"143":1,"145":1,"148":1,"149":1,"153":1,"155":1,"198":1,"301":1,"431":1,"432":1,"471":1},"1":{"302":1,"303":1},"2":{"67":1,"140":1,"142":1,"145":3,"146":1,"148":2,"150":1,"153":3,"154":1,"198":1,"225":1,"226":1,"303":2,"320":1,"329":1,"402":1,"431":1,"432":1,"470":1,"486":1,"487":2,"500":1,"502":1,"503":2}}],["diagrams.",{"2":{"463":1}}],["diagrams)",{"0":{"225":1}}],["diagrams",{"0":{"140":1,"141":1,"147":1,"152":1,"154":1,"194":1,"302":1,"303":1,"467":1},"1":{"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"468":1,"469":1,"470":1,"471":1},"2":{"65":3,"82":1,"140":1,"141":1,"147":1,"151":2,"194":1,"217":3,"223":2,"225":1,"233":3,"303":3,"331":1,"374":1,"471":1,"486":1,"501":1,"503":2}}],["diagrams,draw.io",{"1":{"153":1,"154":1}}],["diagrams,excalidraw",{"1":{"148":1,"149":1,"150":1,"151":1}}],["diagrams,mermaid",{"1":{"142":1,"143":1,"144":1,"145":1,"146":1}}],["diagrams,",{"2":{"59":3,"194":1,"227":3,"261":1,"449":1}}],["diagram,",{"2":{"37":1,"148":1,"501":2}}],["diagnostics:",{"2":{"52":1}}],["diagnostics,",{"0":{"20":1,"28":1}}],["diagnostics",{"0":{"12":1,"71":1},"2":{"20":1}}],["dismiss",{"2":{"374":1}}],["dismissible",{"2":{"374":1}}],["disabled",{"0":{"452":1},"2":{"263":1,"374":1,"377":1,"507":1}}],["disabled,",{"2":{"205":1}}],["disabled.",{"2":{"171":1}}],["disable",{"2":{"205":1}}],["disables",{"2":{"174":1,"517":1}}],["display.",{"2":{"397":1}}],["displays:",{"2":{"269":1}}],["displays",{"2":{"171":1,"174":1,"212":1,"271":1,"393":1,"513":1,"517":1,"521":1,"529":1}}],["displayed",{"2":{"137":1,"263":1}}],["display",{"2":{"71":1,"219":1,"268":1,"515":1}}],["displaying",{"2":{"28":1,"352":1,"372":1}}],["displaying:",{"2":{"12":1}}],["distractions.",{"2":{"266":1,"472":1}}],["distractions",{"2":{"160":1,"404":1}}],["distraction",{"2":{"136":1,"263":1}}],["distribution.",{"2":{"338":1}}],["distribution",{"2":{"92":1}}],["distinct",{"2":{"221":1}}],["distinctions",{"2":{"104":1}}],["distill",{"2":{"52":1}}],["distance",{"2":{"50":1}}],["disjunctive",{"2":{"35":1}}],["disk.",{"2":{"227":1,"517":1}}],["disk,",{"2":{"173":1,"174":1,"517":2}}],["disk:",{"2":{"173":1,"517":1}}],["disk",{"0":{"174":1},"2":{"19":1,"27":1,"95":1,"106":1,"116":1,"174":3,"175":2,"258":1,"363":1,"501":2,"517":3,"526":2}}],["discard",{"2":{"349":1}}],["discard:",{"2":{"349":1}}],["discards",{"2":{"210":1}}],["discarding",{"2":{"173":1}}],["discard.",{"2":{"136":1}}],["discussion",{"2":{"525":1}}],["discussing",{"2":{"393":1}}],["discuss",{"2":{"99":1}}],["disconnected",{"2":{"81":1,"510":1}}],["discover",{"2":{"120":1,"411":1,"508":1}}],["discoverability",{"2":{"119":1}}],["discovers",{"2":{"64":1}}],["discovery",{"0":{"276":1,"312":1,"417":1},"1":{"277":1,"280":1,"281":1},"2":{"91":1,"107":1,"417":2,"418":1}}],["discovery.",{"2":{"79":1,"119":1}}],["discovery:",{"2":{"64":1}}],["discovery,global",{"1":{"278":1,"279":1}}],["discovery,",{"2":{"2":1}}],["discrepancy",{"2":{"49":1}}],["discipline",{"2":{"9":1}}],["duplication",{"2":{"125":1}}],["duplicateentities",{"2":{"49":1}}],["duplicateedges",{"2":{"49":1}}],["duplicate",{"2":{"9":1,"49":2,"50":1,"113":1,"298":1,"502":1,"521":2}}],["due",{"0":{"493":1},"2":{"75":1,"326":1,"492":1,"493":2,"495":1,"498":1,"499":4,"516":1,"525":2,"530":1}}],["dual",{"2":{"20":1}}],["duration",{"2":{"12":1}}],["during",{"2":{"8":1,"218":1,"377":1,"504":1}}],["db:",{"2":{"526":1}}],["db.sqlite:",{"2":{"75":1}}],["db"",{"2":{"38":1}}],["db,",{"2":{"36":1}}],["db",{"2":{"8":1,"526":2}}],["day.",{"2":{"495":1,"499":1}}],["day",{"0":{"497":1},"2":{"493":2,"496":3,"497":1,"498":1,"525":1}}],["days).",{"2":{"417":1}}],["days",{"2":{"417":1,"492":1,"498":1}}],["days.",{"2":{"50":1,"499":1}}],["dashboard:",{"2":{"521":1}}],["dashboardpanels,",{"2":{"105":1}}],["dashboard",{"0":{"256":1,"513":1,"528":1},"1":{"529":1,"530":1},"2":{"95":1,"96":3,"99":1,"103":1,"108":1,"131":1,"283":1,"374":5}}],["dashboard,",{"2":{"94":1,"95":1,"104":1,"112":1,"513":1}}],["dashboards,",{"2":{"14":1}}],["daily",{"0":{"80":1},"2":{"104":1}}],["date,",{"2":{"511":1,"530":1}}],["date",{"0":{"499":1},"2":{"495":3,"498":1,"499":3,"525":1}}],["dates",{"0":{"493":1},"2":{"492":1,"493":1,"498":1}}],["dates,",{"2":{"75":1,"516":1,"525":1}}],["date:",{"2":{"93":1,"493":1}}],["data".",{"2":{"478":1}}],["data").",{"2":{"477":1}}],["data"",{"2":{"477":1}}],["data?",{"0":{"239":1}}],["data",{"0":{"72":1,"76":1,"77":1,"310":1,"413":1,"439":1},"1":{"73":1,"74":1,"75":1,"77":1,"78":1,"79":1,"80":1,"81":1,"82":1},"2":{"21":1,"43":1,"55":1,"71":4,"76":1,"77":1,"104":1,"138":1,"143":1,"189":4,"205":1,"210":1,"212":1,"238":1,"247":1,"281":1,"307":1,"310":1,"323":1,"341":1,"413":2,"417":1,"419":1,"446":1,"453":1,"474":1,"507":1,"526":1}}],["data,",{"2":{"20":1}}],["database,",{"2":{"522":1}}],["database").",{"2":{"38":1}}],["databasesync).",{"2":{"502":1}}],["databasesync",{"2":{"227":1}}],["databases",{"2":{"21":1,"55":2}}],["databases.",{"2":{"0":1}}],["database",{"0":{"43":1,"55":1,"69":1,"502":1},"2":{"7":1,"70":1,"74":1,"75":1,"91":1,"143":1,"226":1,"502":1,"526":1,"527":1}}],["data."",{"2":{"480":1}}],["data.",{"2":{"4":1,"131":1,"239":1,"242":1,"446":1}}],["dark:",{"2":{"396":1}}],["dark",{"2":{"58":1,"106":1,"137":1,"263":1,"268":1,"374":1,"396":2}}],["danglingaliases",{"2":{"49":1}}],["dangling",{"2":{"49":1}}],["dag",{"0":{"6":1}}],["dags",{"2":{"3":1}}],["dynamically",{"2":{"4":1,"8":1,"227":1,"271":1,"374":1,"411":1,"539":1}}],["dynamic",{"2":{"2":1,"3":1,"9":2,"58":1,"95":1,"374":1,"502":1}}],["deadlines.",{"2":{"496":1}}],["deadlines,",{"2":{"492":1}}],["deadline",{"2":{"493":1}}],["debug",{"2":{"415":1}}],["debounced.",{"2":{"26":1}}],["deeply",{"2":{"168":1}}],["deepseek",{"2":{"52":1}}],["delta",{"0":{"419":1},"2":{"419":2}}],["deltas",{"2":{"417":1}}],["delays",{"2":{"223":1}}],["deliverables.",{"2":{"506":1}}],["delivery",{"2":{"105":1}}],["delimiter",{"2":{"211":1,"376":1}}],["deleting",{"2":{"376":1}}],["deletion.",{"2":{"521":1}}],["deletions",{"2":{"353":1}}],["deletions.",{"2":{"62":1}}],["deletion",{"2":{"258":1}}],["delete:",{"2":{"514":1}}],["delete",{"2":{"257":1,"363":1,"440":1}}],["deleted.",{"2":{"501":1}}],["deleted,",{"2":{"258":1}}],["deleted",{"0":{"244":1},"2":{"227":1,"258":1,"514":1,"527":1}}],["deleted)",{"2":{"49":1}}],["delete,",{"2":{"95":1,"477":1}}],["deletes",{"2":{"50":1}}],["dev",{"2":{"87":1}}],["development",{"0":{"86":1,"87":1},"1":{"87":1,"88":1,"89":1}}],["developer).",{"2":{"542":1}}],["developer",{"0":{"83":1},"1":{"84":1,"85":1,"86":1,"87":1,"88":1,"89":1,"90":1,"91":1,"92":1},"2":{"93":1,"94":1,"113":1,"130":1,"339":1,"415":1}}],["devices",{"0":{"418":1},"2":{"241":1,"416":1,"417":1,"419":1}}],["devices,",{"2":{"79":1}}],["devices.",{"2":{"79":1,"418":1,"484":1}}],["device",{"2":{"64":2,"66":1,"241":2,"247":1,"410":1,"413":1,"418":2,"420":1}}],["detail",{"2":{"380":1,"522":1,"525":1,"526":1}}],["details".",{"2":{"478":1}}],["details.",{"2":{"464":1,"475":1,"491":1}}],["details,",{"2":{"277":1}}],["details>",{"2":{"192":1}}],["details",{"0":{"454":1},"2":{"80":1,"94":1,"96":2,"99":1,"117":1,"118":2,"249":1,"305":1,"333":1,"399":1,"438":1,"452":1}}],["detailed",{"2":{"67":1,"350":1,"497":1}}],["detect,",{"2":{"331":1}}],["detects",{"2":{"174":1,"227":1,"517":1}}],["detected",{"2":{"134":1}}],["detect",{"0":{"134":1},"2":{"106":1,"134":1,"263":1,"298":1}}],["detection:",{"2":{"263":1}}],["detection,",{"2":{"132":1}}],["detection",{"0":{"39":1,"50":1,"174":1},"2":{"95":1}}],["deterministicsemanticminer.js",{"2":{"34":1}}],["deterministic",{"0":{"34":1},"2":{"0":1,"29":1,"37":1,"46":1,"486":1}}],["dedicated",{"0":{"136":1},"2":{"54":1,"75":1,"95":1,"96":1,"126":1,"132":1,"135":1,"136":1,"137":1,"263":1,"383":1,"463":1,"500":1}}],["dedup",{"2":{"38":1}}],["deduplication:",{"2":{"50":1,"502":1}}],["deduplication).",{"2":{"42":1}}],["deduplication",{"0":{"38":1,"527":1}}],["deduplication,",{"2":{"30":1}}],["deduplicated",{"2":{"6":1}}],["defender",{"2":{"339":1}}],["def",{"2":{"133":1}}],["default,",{"2":{"504":1}}],["default:",{"2":{"396":1,"402":1,"408":1}}],["default):",{"2":{"541":1}}],["default)",{"2":{"323":1}}],["defaults",{"2":{"216":1,"223":1,"233":1}}],["defaults,",{"2":{"107":1}}],["default",{"2":{"52":1,"54":1,"69":1,"227":1,"253":1,"254":1,"295":1,"323":1,"379":1,"397":1,"415":1,"465":1,"482":1,"501":2,"507":2,"537":1,"538":1}}],["definitions:",{"2":{"278":1}}],["definitions",{"2":{"8":1,"384":1}}],["density.",{"2":{"400":1}}],["density:",{"2":{"268":1,"515":2}}],["density,",{"2":{"95":1,"99":1,"103":1,"104":1,"111":1,"117":1}}],["density",{"0":{"400":1,"515":1},"2":{"49":1,"95":1,"96":1,"106":1,"107":1,"108":1,"116":2,"268":2,"366":1,"400":2,"515":1}}],["denser",{"2":{"399":1,"400":1}}],["dense",{"2":{"38":1,"50":1}}],["degree)",{"2":{"49":1}}],["decrypt",{"2":{"219":1,"235":1}}],["decrypts",{"2":{"65":1}}],["decisions,",{"2":{"143":1}}],["decimal",{"2":{"36":1}}],["decent.",{"2":{"105":1}}],["decay",{"2":{"50":1}}],["decay:",{"2":{"50":1}}],["decay,",{"2":{"42":1}}],["decoupledplanning.spec.js:",{"2":{"13":1}}],["decoupled",{"0":{"1":1,"3":1},"1":{"4":1,"5":1,"6":1,"7":1},"2":{"13":1,"23":1,"372":1}}],["depending",{"2":{"221":1}}],["dependencies",{"2":{"339":1}}],["dependencies.",{"2":{"63":1,"338":1,"369":1}}],["dependencies,",{"2":{"29":1}}],["depends",{"2":{"34":1}}],["destructive",{"2":{"478":1}}],["destination:",{"2":{"323":1}}],["destination",{"2":{"220":1,"236":1,"359":1,"443":1,"446":1,"458":1,"474":1,"504":1}}],["destination.",{"2":{"216":1}}],["desktop",{"2":{"332":1,"336":1,"339":1,"356":1,"380":1,"396":1}}],["deselect",{"2":{"216":1}}],["design",{"2":{"374":1}}],["designs,",{"2":{"152":1}}],["designed",{"2":{"0":1,"21":1,"322":1}}],["descriptive",{"2":{"325":1,"350":1}}],["description",{"2":{"166":1,"167":1,"350":1,"501":1,"542":1}}],["descriptions:",{"2":{"107":1}}],["descriptions",{"2":{"103":1}}],["descriptions,",{"2":{"27":1,"94":1}}],["describe",{"2":{"103":1,"116":2,"479":1}}],["described",{"2":{"102":1}}],["described,",{"2":{"96":1}}],["described.",{"2":{"96":1}}],["desc),",{"2":{"44":1}}],["f.",{"2":{"425":1}}],["f3).",{"2":{"388":1}}],["f",{"2":{"161":1,"163":1,"175":2,"343":1,"362":1,"363":1,"364":1,"388":1,"389":1,"404":1,"463":1}}],["f)",{"2":{"136":1}}],["f\\"hello,",{"2":{"133":1}}],["f2",{"2":{"116":1,"363":1}}],["f10",{"2":{"366":1}}],["f1",{"2":{"116":1,"343":1,"362":1}}],["fts",{"2":{"44":1}}],["fts5syncdiscrepancy",{"2":{"49":1}}],["fts5",{"2":{"38":1,"44":1,"49":1}}],["fp16",{"2":{"29":1}}],["friday",{"2":{"326":1}}],["fresh",{"2":{"220":1,"236":1,"310":1,"455":1}}],["freshness,",{"2":{"104":1,"120":1}}],["freshness",{"2":{"95":1,"96":1,"393":1,"439":1}}],["freehand",{"2":{"140":1,"147":1}}],["free",{"2":{"20":1,"136":1,"258":1,"263":1,"368":1,"539":1}}],["framing.",{"2":{"104":1}}],["framework.",{"2":{"369":1}}],["frame",{"2":{"85":1,"137":1}}],["fragmented.",{"2":{"96":1,"119":1}}],["fragments,",{"2":{"46":1}}],["fragments",{"2":{"36":2,"480":1}}],["frontend",{"2":{"84":1,"88":1,"369":1}}],["frontmatter.",{"2":{"19":1}}],["frontmatter",{"2":{"8":3,"19":1,"27":1,"32":1}}],["from.",{"2":{"286":1}}],["from",{"0":{"442":1,"459":1,"471":1},"2":{"8":1,"15":1,"18":1,"20":1,"30":1,"33":2,"34":1,"41":1,"54":1,"67":1,"85":1,"92":1,"94":1,"95":1,"96":1,"98":1,"99":1,"104":1,"105":1,"106":1,"116":1,"120":2,"122":1,"128":1,"131":2,"135":1,"136":1,"137":3,"151":2,"169":1,"173":2,"174":3,"175":2,"185":1,"200":1,"205":1,"207":1,"215":1,"220":2,"227":1,"231":1,"233":1,"236":2,"257":3,"262":3,"270":1,"283":2,"284":1,"290":1,"291":1,"296":2,"299":1,"300":1,"302":1,"303":3,"312":1,"323":1,"324":1,"334":1,"337":1,"340":1,"342":1,"345":2,"346":1,"363":1,"381":1,"417":1,"420":2,"434":1,"442":1,"445":1,"450":1,"454":2,"456":1,"457":1,"458":1,"459":2,"462":1,"463":2,"464":1,"465":1,"468":1,"469":1,"471":2,"473":1,"474":1,"484":1,"490":1,"494":1,"506":2,"509":1,"514":2,"517":5,"526":1,"527":1,"530":1,"537":1}}],["feels",{"0":{"453":1},"2":{"412":1}}],["feel",{"2":{"397":1}}],["feel.",{"2":{"380":1}}],["feedback",{"0":{"309":1},"2":{"270":1}}],["feeds:",{"2":{"71":1}}],["fences.",{"2":{"139":1}}],["fenced",{"2":{"134":1,"188":1,"198":1,"392":1,"487":1}}],["few",{"2":{"116":1,"339":1}}],["fewer",{"2":{"54":1}}],["featured",{"2":{"535":1}}],["feature.",{"2":{"247":1,"308":2}}],["feature",{"0":{"95":1,"249":1,"250":1,"411":1},"1":{"251":1,"252":1,"253":1,"254":1,"255":1,"256":1,"257":1,"258":1,"259":1,"260":1,"261":1,"262":1,"263":1,"264":1,"265":1,"266":1,"267":1,"268":1,"269":1,"270":1,"271":1,"272":1,"273":1,"274":1,"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1,"297":1,"298":1,"299":1,"300":1,"301":1,"302":1,"303":1,"304":1,"305":1,"306":1,"307":1,"308":1,"309":1,"310":1,"311":1,"312":1,"313":1,"314":1,"315":1,"316":1,"317":1,"318":1,"319":1,"320":1,"321":1,"322":1,"323":1},"2":{"63":1,"93":1,"96":2,"103":1,"104":2,"107":1,"111":1,"118":1,"119":1,"125":1,"155":1,"250":1,"342":1,"387":1,"452":1,"491":1,"501":1}}],["features?",{"2":{"120":1}}],["features.",{"2":{"104":1,"240":1}}],["features,",{"2":{"94":1}}],["features,1.",{"1":{"16":1,"17":1}}],["features:",{"2":{"75":1,"78":1}}],["features",{"0":{"14":1,"80":1,"227":1,"241":1,"301":1,"307":1,"365":1,"374":1,"379":1,"452":1,"501":1},"1":{"15":1,"18":1,"19":1,"20":1,"302":1,"303":1},"2":{"21":1,"29":1,"66":1,"71":3,"80":1,"99":1,"119":1,"241":1,"249":1,"305":1,"333":2,"345":1,"355":1,"372":1,"411":2,"511":1,"535":1}}],["fetches",{"2":{"489":1}}],["fetch",{"2":{"4":1,"346":1}}],["flat",{"2":{"220":1,"236":1,"453":1}}],["flavored",{"2":{"59":1,"176":1}}],["flash),",{"2":{"52":1}}],["flagged",{"2":{"172":1,"274":1}}],["flags.",{"2":{"525":1}}],["flags",{"0":{"542":1},"2":{"172":1,"274":1}}],["flag",{"2":{"12":1,"402":1}}],["flow.",{"2":{"244":1,"471":1}}],["flow.spec.js:",{"2":{"13":1}}],["flowchart",{"2":{"143":1}}],["flowcharts,",{"2":{"59":1,"194":1}}],["flow,",{"2":{"120":1,"456":1}}],["flows,",{"2":{"155":1}}],["flows",{"2":{"108":1,"117":1,"143":1}}],["flow",{"0":{"0":1,"2":1,"12":1,"20":1,"23":1,"28":1,"41":1,"42":1,"418":1},"1":{"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1},"2":{"12":1,"20":2,"23":1,"28":1,"55":1,"95":1,"96":3,"244":1,"323":1,"372":2,"376":1}}],["fonts",{"2":{"236":2}}],["footprint:",{"2":{"339":1}}],["footprint;",{"2":{"337":1}}],["footnote",{"2":{"191":1}}],["footnote.[^1]",{"2":{"191":1}}],["footnotes",{"0":{"191":1}}],["footer",{"2":{"59":1}}],["four",{"2":{"165":1}}],["found,",{"2":{"172":1}}],["foundational",{"2":{"9":1,"103":1}}],["found",{"2":{"7":1,"392":1}}],["focuses",{"2":{"382":1}}],["focused.",{"2":{"456":1}}],["focused",{"2":{"199":1,"262":1,"375":1}}],["focus",{"0":{"156":1,"160":1,"161":1,"162":1,"163":1,"266":1,"404":1,"429":1},"1":{"157":1,"158":1,"159":1,"160":1,"161":1,"162":1,"163":1,"164":1},"2":{"95":1,"96":2,"115":1,"116":2,"159":3,"160":1,"161":1,"162":1,"163":1,"175":1,"266":1,"363":1,"379":1,"380":2,"384":1,"403":1,"404":1,"429":1,"472":1,"497":1,"530":1}}],["follows",{"2":{"396":1}}],["followed",{"2":{"133":1}}],["following",{"2":{"67":1,"368":1}}],["folding,",{"2":{"59":1}}],["folder,",{"2":{"95":1,"243":1,"277":1,"334":1,"414":1,"477":1}}],["folder";",{"2":{"96":1}}],["folder"",{"2":{"94":2,"103":1}}],["folders,",{"2":{"279":1,"389":1}}],["folders",{"2":{"78":1,"244":1,"257":1,"258":2,"356":1,"461":1,"462":1}}],["folder.",{"2":{"77":1,"116":1,"117":1,"145":1,"168":1,"271":1,"334":1,"340":1,"359":1,"381":1,"422":1,"448":1}}],["folder:",{"2":{"75":1,"227":2,"514":1}}],["folder",{"0":{"101":1,"257":1,"424":1,"514":1},"1":{"102":1,"103":1,"104":1},"2":{"55":1,"75":1,"77":1,"78":1,"95":1,"96":2,"99":1,"104":1,"106":1,"108":1,"116":1,"118":5,"120":1,"168":2,"212":1,"220":2,"223":1,"229":1,"231":1,"236":1,"238":1,"239":2,"242":1,"244":1,"252":1,"253":3,"257":1,"271":1,"323":2,"332":1,"338":1,"340":2,"341":3,"356":1,"357":1,"358":1,"379":2,"386":1,"424":2,"448":2,"453":1,"458":1,"461":1,"474":1,"501":1,"504":1,"506":1,"507":1,"512":1,"514":1,"517":1}}],["for:",{"2":{"336":1,"337":1,"338":1,"390":1}}],["force",{"2":{"173":1,"517":1}}],["formal",{"2":{"269":1}}],["format).",{"2":{"446":1}}],["format):",{"2":{"65":1}}],["format,",{"2":{"331":1,"356":1}}],["format:",{"2":{"323":1,"474":1,"506":1}}],["format",{"0":{"135":1},"2":{"135":2,"136":1,"178":1,"199":2,"221":2,"263":2,"323":1,"446":1,"463":1,"474":1,"491":1}}],["format.",{"2":{"104":1,"368":1}}],["formats:",{"2":{"140":1,"286":1}}],["formats",{"0":{"503":1,"506":1,"524":1},"2":{"65":1,"96":1,"270":1,"335":1}}],["formatter",{"2":{"139":1}}],["formatter,",{"2":{"23":1,"372":1}}],["formatted",{"2":{"19":1,"27":1,"166":1,"169":1,"207":1,"270":1,"328":1,"506":1}}],["formatting:",{"2":{"263":1}}],["formatting.",{"2":{"202":1}}],["formatting",{"0":{"178":1,"196":1,"211":1},"2":{"9":1,"132":1,"135":2,"202":1,"211":1,"376":1}}],["form",{"2":{"206":1,"380":1}}],["formula,",{"2":{"32":1}}],["for",{"0":{"80":1,"386":1},"2":{"0":1,"6":1,"8":3,"11":1,"20":1,"26":1,"32":1,"44":1,"52":1,"55":1,"59":2,"62":1,"64":1,"65":1,"67":1,"75":2,"77":1,"78":2,"80":1,"84":1,"90":1,"92":1,"93":1,"95":1,"96":1,"99":3,"100":1,"104":2,"107":1,"108":1,"111":1,"115":3,"119":1,"120":1,"124":1,"126":1,"131":1,"132":1,"136":2,"138":1,"139":1,"140":3,"143":1,"146":1,"147":1,"151":1,"152":1,"155":1,"162":1,"164":2,"165":1,"166":2,"189":1,"195":1,"202":2,"205":1,"213":1,"224":1,"225":1,"232":1,"238":1,"239":1,"240":1,"241":1,"242":1,"245":1,"253":1,"260":1,"261":1,"263":2,"268":1,"269":1,"274":1,"279":2,"281":1,"283":1,"285":1,"287":1,"291":1,"303":1,"305":2,"306":1,"316":1,"320":1,"323":1,"325":1,"332":1,"333":3,"338":1,"339":2,"341":2,"344":1,"346":1,"349":1,"368":2,"369":1,"374":2,"375":1,"376":1,"380":2,"381":1,"384":1,"385":1,"387":1,"399":1,"400":1,"402":1,"403":1,"404":1,"406":1,"410":2,"411":1,"412":2,"415":4,"418":1,"419":1,"438":1,"440":1,"441":1,"443":1,"449":2,"460":1,"463":1,"471":1,"472":1,"473":1,"475":3,"477":1,"484":1,"491":1,"493":2,"495":1,"496":3,"497":1,"499":1,"500":1,"506":2,"512":1,"513":1,"515":2,"516":1,"518":1,"529":1}}],["fuzzy",{"2":{"527":1}}],["future",{"2":{"420":1}}],["fusion",{"0":{"38":1,"39":1}}],["fusion.",{"2":{"30":1}}],["fused",{"2":{"34":1}}],["fuel",{"2":{"21":1}}],["functions:",{"2":{"391":1}}],["function\\\\s+\\\\w+\\\\s*\\\\(",{"2":{"278":1,"391":1}}],["functionality?",{"2":{"120":1}}],["function",{"2":{"3":1,"188":1,"278":1}}],["fully",{"2":{"96":2,"379":1,"481":1}}],["full",{"0":{"41":1,"489":1},"2":{"2":1,"20":1,"38":1,"44":1,"49":1,"59":2,"60":1,"65":1,"67":1,"110":1,"132":1,"166":2,"168":1,"175":1,"188":1,"189":1,"194":1,"202":1,"205":1,"213":2,"271":1,"292":1,"327":1,"338":1,"351":1,"368":1,"369":1,"372":1,"481":1,"484":1,"489":1,"491":2,"507":1,"530":1,"535":1}}],["faq,",{"2":{"385":1}}],["faq.",{"2":{"111":1,"123":1}}],["faq",{"0":{"237":1},"1":{"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1,"245":1,"246":1,"247":1,"248":1},"2":{"94":1,"95":1,"383":1}}],["favorites:",{"2":{"513":1}}],["favorites,",{"2":{"95":1,"104":1,"112":1,"120":1,"131":1,"374":1}}],["favorites",{"2":{"94":1,"96":1,"99":1,"103":1,"104":1,"108":1,"256":1}}],["facing",{"2":{"65":1,"93":2,"95":1,"99":1,"104":1,"125":1,"250":1}}],["factors.",{"2":{"60":1}}],["factor",{"2":{"50":1,"107":1}}],["facades",{"2":{"23":1,"372":1}}],["facade",{"0":{"1":1},"2":{"1":1,"91":1,"372":1}}],["failed",{"2":{"479":1}}],["failed:",{"2":{"220":2,"236":2}}],["failures",{"2":{"223":1,"298":1}}],["fail.",{"2":{"10":1}}],["fails,",{"2":{"457":1,"458":1}}],["fails",{"2":{"10":1}}],["faster.",{"2":{"461":1}}],["faster",{"0":{"463":1},"2":{"11":1,"202":1,"380":1}}],["fast",{"2":{"8":1,"50":1,"155":1}}],["falls",{"2":{"10":1,"26":1,"253":1,"379":1,"511":1}}],["fallback.",{"2":{"410":1}}],["fallback,",{"2":{"13":1}}],["fallback",{"0":{"10":1},"2":{"2":1,"415":1,"538":1}}],["false,",{"2":{"7":1}}],["fabricating",{"2":{"7":1}}],["five",{"2":{"484":1}}],["fits",{"2":{"335":1,"427":1,"463":1}}],["fidelity",{"2":{"166":1}}],["finish",{"0":{"458":1}}],["fine",{"2":{"356":1}}],["final",{"0":{"130":1},"2":{"451":1,"463":1}}],["finding",{"2":{"460":1}}],["findings:",{"2":{"105":1}}],["findings",{"0":{"104":1,"115":1},"2":{"93":1}}],["finds",{"2":{"275":1,"393":1}}],["finder.",{"2":{"501":1}}],["finder",{"2":{"227":1}}],["find,",{"2":{"95":1}}],["find",{"0":{"264":1,"364":1,"388":1,"425":1},"2":{"81":1,"95":1,"96":2,"108":1,"115":1,"116":8,"136":1,"175":2,"221":1,"278":4,"288":1,"307":1,"364":6,"388":1,"391":3,"411":1,"426":2,"462":1,"463":1}}],["fixed",{"2":{"396":1}}],["fixes.",{"2":{"459":1}}],["fixes",{"0":{"122":1,"377":1,"381":1},"2":{"374":1}}],["fixes,",{"2":{"95":1}}],["fixing",{"0":{"275":1}}],["fix",{"2":{"131":1,"220":1,"236":1,"447":1,"449":1,"463":1}}],["fixme,",{"2":{"7":1}}],["field.",{"2":{"219":1}}],["field",{"2":{"19":1}}],["fields)",{"2":{"7":1}}],["filters:",{"2":{"499":1}}],["filters",{"2":{"411":1}}],["filters,",{"2":{"71":1,"95":1,"96":1}}],["filter,",{"2":{"279":1}}],["filter",{"2":{"227":1,"279":1,"286":2,"387":1,"392":2,"440":1,"501":1,"530":2}}],["filtered",{"2":{"71":1}}],["filtering:",{"2":{"7":1}}],["filtering",{"0":{"36":1,"499":1},"2":{"2":1,"13":1,"95":1,"96":1,"287":1}}],["file)",{"2":{"491":1}}],["file:",{"2":{"223":1,"419":1}}],["file.",{"2":{"219":1,"235":1,"334":1,"360":1,"430":1,"526":1,"527":1}}],["filename:",{"2":{"323":1}}],["filename",{"2":{"216":1,"219":1,"235":1,"325":1,"446":1,"474":1}}],["file,",{"2":{"154":1}}],["file",{"0":{"62":1,"75":1,"294":1,"450":1},"2":{"17":1,"60":1,"62":3,"65":3,"70":1,"84":1,"85":1,"91":1,"96":1,"116":15,"117":1,"148":1,"154":1,"173":1,"174":1,"185":1,"197":1,"212":1,"213":1,"214":1,"215":3,"216":1,"218":1,"220":1,"221":3,"224":1,"225":1,"226":1,"227":5,"228":1,"229":1,"230":1,"231":1,"232":1,"234":1,"236":1,"238":1,"244":1,"245":1,"252":2,"253":5,"257":1,"323":1,"325":1,"330":1,"336":1,"337":1,"340":1,"341":1,"349":1,"368":1,"379":5,"415":2,"422":1,"423":1,"446":1,"448":1,"450":2,"459":1,"461":2,"462":1,"474":1,"484":1,"491":1,"501":5,"502":1,"503":1,"506":1,"514":1,"517":2,"521":1,"526":1,"533":1}}],["filesystem",{"2":{"512":1}}],["files.",{"2":{"103":1,"227":1,"337":1,"440":1,"448":1,"465":1,"510":1}}],["files:",{"2":{"75":2}}],["files,",{"2":{"65":1,"72":1,"238":1,"374":1,"508":1}}],["files),",{"2":{"63":1}}],["files",{"0":{"349":1,"465":1},"2":{"1":1,"8":2,"13":1,"19":2,"21":1,"27":2,"59":1,"65":2,"75":2,"77":1,"82":1,"217":1,"218":1,"219":1,"225":1,"229":1,"230":1,"233":1,"234":1,"235":1,"243":1,"258":1,"281":1,"294":1,"298":2,"332":1,"338":3,"340":1,"349":1,"356":1,"414":2,"488":1,"489":1,"500":1,"501":1,"506":1,"514":1,"518":1,"519":1,"521":2,"526":1}}],["first.",{"2":{"449":1,"485":1}}],["first",{"0":{"324":1},"1":{"325":1,"326":1,"327":1,"328":1,"329":1,"330":1,"331":1},"2":{"0":1,"21":2,"54":1,"56":1,"93":1,"95":1,"105":2,"112":1,"119":1,"124":1,"127":1,"131":1,"172":1,"182":1,"187":1,"202":1,"300":1,"325":1,"326":1,"340":1,"342":1,"387":1,"458":1,"520":1}}],["first,",{"2":{"0":1,"29":1,"56":1,"296":1}}],["a:",{"2":{"534":1}}],["a,",{"2":{"418":1}}],["a[start]",{"2":{"194":1}}],["a[open",{"2":{"143":1}}],["afterwards,",{"2":{"346":1}}],["after",{"0":{"441":1},"2":{"93":1,"120":1,"137":1,"208":1,"231":1,"263":1,"381":1,"451":1}}],["aes",{"2":{"65":1,"218":1,"234":1,"417":2}}],["a.",{"0":{"62":1}}],["adjusts",{"2":{"539":1}}],["adjust",{"2":{"446":1,"463":1,"466":1}}],["adjusting",{"2":{"411":1}}],["adjustable",{"2":{"54":1}}],["adapt:",{"2":{"368":1}}],["administrator",{"2":{"337":1}}],["advanced",{"0":{"278":1,"412":1,"507":1},"2":{"107":1,"111":1,"120":1,"126":1,"278":2,"279":1,"344":1,"391":1,"415":1}}],["advice.",{"2":{"102":1}}],["added",{"2":{"274":1,"353":1,"383":3,"385":1,"515":1}}],["adding",{"2":{"208":1}}],["additions",{"0":{"123":1}}],["additions,",{"2":{"62":1}}],["adds",{"2":{"134":1,"208":2,"486":1}}],["add",{"0":{"208":1},"2":{"80":1,"94":1,"123":4,"124":2,"126":3,"131":2,"172":1,"179":1,"262":1,"274":3,"291":1,"294":1,"350":2,"418":1,"431":1,"438":1,"463":1,"464":1,"465":1,"495":1,"525":2}}],["addressed",{"2":{"48":1,"93":1}}],["ahead",{"2":{"43":1}}],["aggressive",{"2":{"300":1}}],["again.",{"2":{"455":1,"457":1}}],["again",{"2":{"163":1,"219":1}}],["against",{"2":{"4":1,"34":1,"85":1,"100":1,"235":1}}],["agent",{"2":{"66":1}}],["agnostic",{"2":{"30":1}}],["average",{"2":{"120":1}}],["availability",{"0":{"249":1},"2":{"151":1}}],["availability.",{"2":{"116":1}}],["availability.md",{"2":{"104":1}}],["available.",{"2":{"335":1}}],["available,",{"2":{"281":1}}],["available",{"2":{"117":1,"118":1,"254":2,"380":1,"407":1,"474":1,"484":1,"514":1}}],["avatar",{"2":{"19":2,"27":1}}],["avg",{"2":{"49":1}}],["avoid:",{"2":{"480":1}}],["avoid",{"2":{"9":1,"236":1,"325":1,"477":1}}],["above",{"2":{"135":1,"195":1,"329":1}}],["about",{"0":{"318":1},"2":{"15":1,"95":1,"96":1,"105":1,"146":1,"318":1,"454":1,"475":1}}],["absent.",{"2":{"103":1}}],["absent",{"2":{"96":1}}],["absolute",{"2":{"21":1,"223":1,"538":1}}],["abstract",{"2":{"5":1}}],["accounts",{"2":{"332":1}}],["accountability",{"2":{"288":1}}],["account",{"2":{"241":1}}],["accidental",{"2":{"171":1,"210":1,"300":1,"374":1}}],["accurately",{"2":{"385":1}}],["accurately.",{"2":{"96":1}}],["accurate,",{"2":{"274":1}}],["accurate.",{"2":{"98":1,"116":3}}],["accurate",{"2":{"96":2,"104":1}}],["accuracy,",{"2":{"382":1}}],["accuracy",{"2":{"93":1,"100":1}}],["accelerator)",{"2":{"364":1}}],["accelerator.",{"2":{"116":1}}],["accelerator",{"2":{"115":1,"116":4,"122":1}}],["accelerators",{"2":{"93":1}}],["accepted,",{"2":{"418":1}}],["accepted",{"2":{"93":1}}],["acceptance",{"2":{"12":1}}],["access.",{"2":{"249":1,"336":1,"513":1}}],["accessed",{"2":{"228":1,"232":1}}],["accessibility.",{"2":{"381":1}}],["accessibility",{"2":{"116":1,"381":1}}],["accessible",{"2":{"71":1,"484":1}}],["access",{"2":{"79":1,"173":1,"226":1,"241":1,"254":1,"314":1,"346":1,"379":1,"482":1,"494":1,"500":1,"513":1,"520":1,"530":1,"541":1}}],["acronyms",{"2":{"36":1}}],["acronym",{"2":{"36":1}}],["across",{"0":{"435":1,"445":1,"473":1},"2":{"14":1,"16":1,"23":1,"49":1,"55":1,"59":1,"61":1,"68":1,"94":1,"103":3,"105":1,"110":1,"125":1,"256":1,"267":1,"277":1,"288":1,"361":1,"379":1,"380":1,"387":1,"417":1,"477":1,"489":1,"492":1,"498":1,"513":1,"527":1,"530":1}}],["actually",{"2":{"453":1}}],["actual",{"2":{"94":1,"96":2,"99":1,"103":2,"104":1,"110":1,"120":1,"122":1}}],["action"",{"2":{"480":1}}],["action,",{"2":{"478":1}}],["action.",{"2":{"430":1,"431":1,"432":1,"439":1,"441":1}}],["actions"",{"2":{"480":1}}],["actions:",{"2":{"171":1,"173":3,"227":1,"329":1,"463":1,"478":1}}],["actions;",{"2":{"96":2}}],["actions,",{"2":{"39":1,"93":1}}],["actions.",{"2":{"18":1,"257":1,"262":1,"303":1,"306":1}}],["actions",{"0":{"18":1,"145":1,"169":1,"295":1,"478":1},"1":{"170":1},"2":{"15":1,"169":1,"195":1,"202":1,"261":1,"270":1,"309":1,"346":1,"374":1,"376":1,"443":1,"477":1,"482":1}}],["action",{"2":{"11":1,"18":1,"93":1,"116":1,"145":1,"169":1,"175":1,"187":2,"197":1,"198":1,"199":1,"200":1,"205":1,"208":2,"210":1,"212":2,"258":1,"262":1,"288":1,"326":1,"343":1,"362":1,"363":1,"364":1,"365":1,"366":1,"374":1,"376":1,"380":1,"463":1,"476":1,"482":1,"501":1}}],["activity,",{"2":{"94":1,"104":1,"117":1,"120":1,"124":1,"131":1}}],["activity.",{"2":{"7":1}}],["activity)",{"2":{"7":1}}],["activity",{"2":{"7":1,"95":1,"96":1,"99":1,"103":1,"106":1,"108":1,"111":1,"116":1,"267":1,"362":1}}],["active;",{"2":{"377":1}}],["actively",{"2":{"220":1,"236":1}}],["active.",{"2":{"137":1,"159":1,"534":2}}],["active,",{"2":{"16":1,"511":1,"542":1}}],["active",{"2":{"2":1,"10":1,"12":1,"15":1,"16":2,"60":2,"65":1,"69":1,"74":1,"159":1,"208":1,"222":1,"223":1,"228":1,"253":1,"267":1,"269":1,"291":1,"354":1,"374":1,"376":1,"379":1,"403":1,"417":1,"466":1,"482":1,"488":1,"490":1,"500":1,"502":1,"517":2,"526":1,"530":1,"531":1,"539":1}}],["acts",{"2":{"8":1,"19":1,"27":1}}],["alphabetically.",{"2":{"488":1}}],["alerts",{"2":{"419":1}}],["alongside",{"2":{"279":1,"496":1}}],["already",{"2":{"211":1,"303":1,"482":1}}],["alter",{"2":{"337":1}}],["alternatives.",{"2":{"202":1}}],["alt",{"2":{"158":1,"161":1,"163":1,"175":3,"363":2,"403":1,"404":1,"517":1}}],["always",{"2":{"139":1,"374":1,"396":2,"484":1}}],["alice",{"2":{"326":1}}],["aligned.",{"2":{"472":1}}],["aligned",{"2":{"380":1}}],["align",{"2":{"209":3}}],["alignments.",{"2":{"374":1}}],["alignment:",{"2":{"189":1,"539":1}}],["alignment",{"0":{"209":1,"527":1},"2":{"93":1,"205":2,"209":3,"213":1,"262":1,"463":1,"527":1}}],["aliases",{"2":{"44":1,"49":1}}],["alias",{"0":{"38":1},"2":{"38":1,"42":1,"50":1}}],["algorithm",{"2":{"372":1,"527":1}}],["algorithmic",{"0":{"37":1}}],["algorithm:",{"2":{"11":1}}],["also",{"2":{"34":1,"77":1,"135":1,"137":1,"187":1,"239":1,"244":1,"281":1,"308":1,"414":1}}],["all.",{"2":{"426":1}}],["all:",{"2":{"349":1}}],["allowlisting.",{"2":{"542":1}}],["allowlist",{"0":{"540":1},"1":{"541":1,"542":1},"2":{"415":1,"542":2}}],["allowlists.",{"2":{"415":1}}],["allowed.",{"2":{"457":1}}],["allowed",{"2":{"412":1,"415":1,"542":1}}],["allows",{"2":{"300":1,"505":1}}],["allowing",{"2":{"59":1,"416":1,"499":1,"531":1,"541":1}}],["all,",{"2":{"227":1,"279":1,"501":1,"530":1}}],["all",{"0":{"287":1,"435":1},"2":{"1":2,"10":1,"19":1,"23":1,"27":1,"33":1,"55":2,"65":2,"85":1,"90":1,"94":1,"103":1,"120":1,"122":1,"128":1,"131":1,"138":1,"157":1,"173":1,"210":1,"214":1,"216":2,"219":1,"226":1,"231":1,"235":1,"274":1,"283":1,"284":1,"286":1,"287":1,"288":1,"343":1,"349":2,"352":1,"369":1,"379":1,"380":1,"389":1,"390":1,"445":1,"473":1,"484":2,"486":1,"488":1,"489":2,"493":1,"496":1,"500":1,"504":1,"506":1,"507":2,"517":1,"519":1,"525":1,"529":1,"530":1}}],["api\\\\",{"2":{"278":1}}],["apis,",{"2":{"93":1}}],["apis.",{"2":{"26":1}}],["api:",{"2":{"53":1}}],["api,",{"2":{"36":1}}],["api",{"2":{"10":1,"51":1,"52":3,"53":1,"54":1,"74":1,"130":1,"143":1,"278":1,"410":2}}],["approved",{"2":{"541":1}}],["appropriate",{"2":{"134":1,"135":1,"219":1,"235":1,"368":1}}],["app)",{"0":{"360":1},"2":{"343":1}}],["apps.",{"2":{"295":1}}],["apps",{"2":{"270":1,"339":1}}],["app?",{"0":{"242":1}}],["append",{"2":{"360":1}}],["appended",{"2":{"187":1}}],["appear,",{"2":{"452":1}}],["appearing",{"0":{"451":1}}],["appeared.",{"2":{"389":1}}],["appearance",{"0":{"268":1,"395":1},"1":{"396":1,"397":1},"2":{"268":1}}],["appear",{"2":{"219":1,"220":1,"235":1,"236":1,"279":1,"283":1,"349":1,"461":1,"495":1}}],["appears.",{"2":{"136":1}}],["appears",{"0":{"456":1},"2":{"135":1,"151":1,"172":1,"340":1,"456":1,"471":1}}],["app:",{"2":{"70":1,"169":1,"414":2}}],["applynotedelta).",{"2":{"419":1}}],["applying",{"2":{"374":1}}],["apply",{"2":{"347":1}}],["applogspage,",{"2":{"59":1}}],["applied:",{"2":{"419":1}}],["applied.",{"2":{"223":1,"374":1}}],["applied,",{"2":{"65":1}}],["applies",{"2":{"2":1,"37":1,"50":1,"135":1,"206":1}}],["applications",{"0":{"339":1}}],["application.",{"2":{"227":1,"501":1}}],["application,",{"2":{"75":1,"339":1}}],["application",{"0":{"56":1,"61":1},"1":{"57":1,"58":1,"59":1,"60":1,"61":1,"62":2,"63":2,"64":2,"65":2,"66":2,"67":2,"68":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1},"2":{"56":1,"61":1,"70":1,"71":1,"72":1,"85":1,"94":1,"333":1,"337":1,"338":2,"339":1}}],["applicationtoolregistry.",{"2":{"4":1}}],["app.sqlite.",{"2":{"117":1,"417":1}}],["app.sqlite",{"2":{"99":1}}],["app.sqlite):",{"2":{"74":1}}],["app.",{"2":{"53":1,"98":1,"124":1,"239":1,"321":1,"360":1,"379":1,"465":1,"520":1}}],["app",{"0":{"77":1,"243":1,"360":1,"453":1},"2":{"43":1,"55":1,"59":1,"65":1,"66":2,"69":1,"74":1,"75":2,"77":2,"92":1,"93":3,"96":3,"99":5,"103":1,"107":1,"108":1,"110":1,"115":2,"117":5,"118":1,"125":1,"215":1,"217":1,"218":1,"219":1,"226":1,"227":1,"231":1,"233":1,"239":2,"242":2,"243":2,"246":1,"247":1,"248":1,"253":1,"268":1,"316":1,"318":1,"323":2,"332":1,"334":1,"341":1,"360":2,"369":1,"379":1,"382":1,"384":1,"411":1,"413":1,"414":1,"446":2,"448":1,"454":1,"455":1,"474":2,"475":2,"486":1,"488":1,"491":1,"502":1,"507":2}}],["appdata",{"2":{"8":1}}],["aware",{"0":{"255":1,"279":1},"2":{"9":1,"297":1,"379":1}}],["audio)",{"2":{"501":1}}],["audio",{"2":{"75":1}}],["audits,",{"2":{"287":1}}],["audit,suggested",{"1":{"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1}}],["audit,keyboard",{"1":{"115":1,"116":1}}],["audit,missing",{"1":{"110":1,"111":1,"112":1,"113":1}}],["audit,docs",{"1":{"102":1,"103":1,"104":1}}],["audit,readme",{"1":{"98":1,"99":1,"100":1}}],["audited",{"2":{"93":2}}],["audit",{"0":{"93":1,"97":1,"101":1,"105":1,"106":1,"107":1,"108":1,"114":1},"1":{"94":1,"95":1,"96":1,"97":1,"98":1,"99":1,"100":1,"101":1,"102":1,"103":1,"104":1,"105":1,"106":1,"107":1,"108":1,"109":1,"114":1,"115":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"130":1,"131":1},"2":{"93":3}}],["audit.",{"2":{"2":1}}],["audit):",{"2":{"2":1}}],["auxiliary",{"2":{"36":1}}],["aux",{"2":{"36":1}}],["auth",{"2":{"417":1}}],["authenticate",{"2":{"219":1,"235":1}}],["authentication.",{"2":{"417":1}}],["authentication",{"2":{"85":1,"346":1}}],["authorization.",{"2":{"418":1}}],["authoritative",{"2":{"27":1}}],["authored",{"2":{"19":1}}],["auth\\"",{"2":{"11":1}}],["auto,",{"2":{"267":1,"466":1}}],["autosave",{"2":{"174":1,"517":1}}],["autoincrement,",{"2":{"69":1}}],["auto",{"0":{"134":1,"135":1},"2":{"65":1,"71":1,"95":1,"96":1,"106":1,"107":1,"134":1,"135":1,"139":1,"199":1,"200":2,"217":1,"233":1,"263":3,"296":2,"330":1,"331":1,"374":1,"408":3,"455":1,"466":1,"527":1,"533":1,"534":1}}],["auto:",{"2":{"16":1,"407":1,"537":1}}],["automates",{"2":{"92":1}}],["automated",{"0":{"13":1},"2":{"419":1}}],["automatically.",{"2":{"135":1,"185":1,"340":1,"498":1,"501":1}}],["automatically:",{"2":{"134":1,"174":1}}],["automatically",{"2":{"8":1,"24":1,"38":1,"42":1,"49":1,"50":1,"54":1,"137":1,"159":1,"168":1,"205":1,"206":1,"207":1,"212":1,"219":1,"223":1,"226":1,"227":1,"235":1,"263":2,"330":1,"360":1,"403":1,"414":1,"417":1,"419":2,"463":1,"486":1,"499":1,"500":1,"501":1,"502":1,"522":1,"526":1,"533":1,"537":1,"539":2}}],["automatic",{"2":{"8":1,"132":1,"419":1,"501":1}}],["attribution:",{"2":{"368":1}}],["attribution",{"0":{"368":1},"2":{"367":1}}],["attributes:",{"2":{"525":1}}],["attributes",{"2":{"32":1,"36":1,"381":1,"486":1}}],["attempt",{"2":{"542":1}}],["attempts",{"2":{"10":1,"134":1}}],["attendees",{"2":{"326":1}}],["attachments",{"2":{"75":1}}],["attached",{"2":{"75":1}}],["at",{"0":{"22":1,"343":1},"1":{"23":1,"24":1,"25":1,"26":1,"27":1,"28":1},"2":{"8":1,"9":1,"36":1,"38":1,"49":1,"69":1,"75":1,"96":1,"102":1,"107":1,"120":1,"137":1,"142":1,"159":1,"167":2,"173":1,"177":1,"179":1,"196":1,"204":1,"205":1,"207":1,"208":2,"217":1,"233":1,"269":1,"329":1,"349":1,"374":2,"400":1,"419":1,"420":1,"489":1,"515":1,"536":1}}],["aspirational",{"2":{"129":1}}],["async",{"2":{"85":1}}],["asynchronous",{"2":{"84":1}}],["asynchronously",{"2":{"63":1}}],["as:",{"2":{"77":1}}],["ast",{"0":{"32":1},"2":{"32":1}}],["associations.",{"2":{"336":1}}],["assigned",{"2":{"499":1}}],["assignee.",{"2":{"530":1}}],["assignees",{"2":{"525":1}}],["assignee",{"2":{"75":1}}],["assign",{"2":{"498":1,"525":1}}],["assistance",{"0":{"304":1},"1":{"305":1,"306":1,"307":1,"308":1,"309":1,"310":1}}],["assistant",{"2":{"15":2,"17":2,"21":1,"305":1}}],["asserttrustedipcsender(browserwindow,",{"2":{"85":1}}],["asserttrustedipcsender",{"2":{"85":1}}],["asset.",{"2":{"458":1}}],["asset",{"0":{"519":1},"2":{"65":1,"95":1,"217":1,"233":1,"486":1,"512":1,"518":1,"520":1}}],["assets)",{"2":{"323":1,"474":1}}],["assets.",{"2":{"297":1}}],["assets:",{"2":{"65":1,"521":1}}],["assets",{"2":{"65":1,"75":2,"88":1,"92":1,"95":1,"185":2,"214":1,"217":1,"219":1,"221":1,"233":1,"235":1,"465":1,"484":1,"506":1,"510":1,"519":2,"521":2,"533":1}}],["assembled,",{"2":{"20":1}}],["assembles",{"2":{"2":1}}],["assembly.",{"2":{"70":1}}],["assembly",{"0":{"9":1},"2":{"2":1}}],["as",{"0":{"212":1,"446":1,"474":1},"2":{"4":1,"8":2,"19":3,"27":3,"59":1,"75":1,"80":1,"95":1,"99":2,"104":1,"116":3,"117":1,"125":1,"145":1,"148":1,"150":1,"154":1,"159":1,"169":2,"172":1,"205":2,"209":1,"212":2,"222":1,"223":1,"225":2,"228":1,"229":1,"230":1,"254":1,"269":1,"270":2,"274":1,"278":2,"290":1,"296":1,"323":2,"325":1,"328":1,"330":1,"332":1,"339":1,"357":1,"383":1,"386":1,"389":1,"433":1,"436":1,"446":2,"458":1,"474":2,"481":1,"484":1,"485":1,"491":3,"498":1,"505":1,"506":2,"533":1,"539":3}}],["arrow)",{"2":{"209":2}}],["arrows,",{"2":{"150":1,"520":1}}],["arrow",{"2":{"146":1}}],["arrays.",{"2":{"99":1}}],["archival",{"2":{"323":1}}],["archives",{"2":{"507":1}}],["archives,",{"2":{"227":1}}],["archive,",{"2":{"501":1}}],["archive.",{"2":{"228":1,"505":1}}],["archive",{"0":{"231":1,"338":1},"2":{"92":1,"229":1,"491":1,"503":1}}],["architectural",{"2":{"59":1}}],["architectures",{"2":{"339":1}}],["architectures.",{"2":{"140":1,"152":1}}],["architecture.",{"2":{"67":1}}],["architecture)",{"0":{"58":1},"1":{"59":1,"60":1}}],["architecture,5.",{"1":{"73":1,"74":1,"75":1}}],["architecture,4.",{"1":{"69":1,"70":1,"71":1}}],["architecture,3.",{"1":{"62":1,"63":1,"64":1,"65":1,"66":1,"67":1}}],["architecture,2.",{"1":{"4":1,"5":1,"6":1,"7":1,"59":1,"60":1}}],["architecture,",{"2":{"2":1}}],["architecture",{"0":{"0":1,"3":1,"23":1,"30":1,"56":1,"57":1,"67":1,"84":1,"372":1,"502":1},"1":{"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"57":1,"58":1,"61":1,"68":1,"72":1},"2":{"0":1,"11":1,"13":1,"105":1}}],["artifact",{"2":{"36":1}}],["artifacts",{"2":{"33":1,"46":1}}],["articles,",{"2":{"36":1}}],["around",{"2":{"21":1}}],["arguments",{"2":{"12":1,"20":1,"372":1}}],["aren\'t",{"2":{"347":1}}],["area.",{"2":{"296":1}}],["area",{"0":{"444":1},"2":{"116":1,"200":2,"296":1,"366":1,"444":1,"466":1,"532":1}}],["areas",{"0":{"102":1,"466":1},"2":{"531":1}}],["are",{"0":{"448":1,"452":1},"2":{"1":1,"8":1,"9":2,"14":1,"19":2,"20":1,"34":1,"48":1,"49":1,"55":2,"59":1,"69":1,"75":1,"94":1,"96":7,"98":1,"99":4,"102":2,"103":4,"104":2,"105":2,"110":1,"113":1,"117":1,"119":4,"120":2,"131":1,"137":2,"139":1,"172":1,"183":2,"212":1,"213":2,"217":2,"218":2,"219":1,"223":3,"231":1,"233":2,"234":3,"235":1,"239":1,"244":1,"252":1,"258":2,"281":1,"296":1,"298":1,"299":1,"335":1,"337":1,"338":1,"350":1,"368":1,"374":4,"388":1,"389":1,"393":1,"412":1,"417":1,"419":1,"420":1,"451":1,"452":1,"462":1,"486":2,"488":1,"499":1,"502":1,"511":1,"513":1,"514":1,"519":1,"526":1,"527":2}}],["anchor",{"2":{"486":1}}],["animations",{"2":{"374":1}}],["annotate:",{"2":{"520":1}}],["annotate,",{"2":{"295":1,"533":1}}],["annotate",{"2":{"150":1}}],["annotated",{"2":{"147":1}}],["annotation",{"0":{"299":1,"520":1},"2":{"465":1}}],["annotation,",{"2":{"95":1}}],["annotations",{"2":{"77":1,"108":1}}],["annotations,",{"2":{"29":1,"150":1,"360":1}}],["anytime",{"2":{"500":1,"507":1}}],["anyway",{"2":{"339":1}}],["anywhere",{"2":{"187":1,"217":1}}],["any",{"0":{"343":1},"2":{"29":1,"36":1,"52":1,"93":1,"136":1,"145":1,"150":2,"154":1,"159":1,"168":1,"170":1,"171":1,"172":1,"173":1,"189":1,"193":1,"205":1,"206":1,"212":1,"214":1,"224":1,"225":1,"233":1,"234":1,"257":1,"263":1,"271":1,"286":1,"334":1,"351":1,"353":1,"356":1,"368":1,"374":1,"410":1,"420":2,"464":1,"491":1,"495":1,"515":1,"521":1,"522":1,"523":1,"529":1,"541":1,"542":1}}],["answer",{"2":{"17":1}}],["an",{"0":{"148":1,"149":1,"150":1,"430":1,"432":1,"433":1,"459":1,"470":1},"2":{"10":1,"18":1,"19":1,"24":1,"27":1,"29":2,"30":1,"48":1,"52":1,"53":1,"56":1,"84":1,"94":1,"95":1,"99":1,"126":1,"134":1,"137":2,"148":1,"150":1,"151":2,"154":1,"164":1,"174":1,"203":1,"205":1,"209":1,"220":1,"227":1,"236":1,"247":1,"262":1,"263":1,"291":1,"296":1,"299":1,"300":1,"303":3,"329":1,"339":1,"346":1,"359":1,"374":2,"383":1,"442":1,"464":1,"469":1,"471":3,"492":1,"493":1,"496":1,"508":1,"517":1,"518":1,"520":1,"535":1}}],["analysis",{"0":{"4":1}}],["another",{"2":{"1":1,"174":1,"181":1,"183":1,"184":1,"342":1,"506":1,"517":1}}],["and",{"0":{"154":1,"169":1,"179":1,"199":1,"208":1,"210":1,"251":1,"257":1,"259":1,"264":1,"267":1,"268":1,"270":1,"272":1,"276":1,"282":1,"289":1,"291":1,"292":1,"294":1,"299":1,"300":1,"306":1,"312":1,"313":1,"315":1,"319":1,"401":1,"413":1,"414":1,"427":1,"438":1,"445":1,"462":1,"463":1,"465":1,"467":1,"478":1,"479":1,"514":1},"1":{"170":1,"252":1,"253":1,"254":1,"255":1,"256":1,"257":1,"258":1,"260":1,"261":1,"262":1,"263":1,"264":1,"265":1,"266":1,"267":1,"268":1,"269":1,"270":1,"271":1,"273":1,"274":1,"275":1,"277":1,"278":1,"279":1,"280":1,"281":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"290":1,"291":1,"292":1,"316":1,"317":1,"318":1,"320":1,"321":1,"322":1,"323":1,"402":1,"403":1,"404":1,"468":1,"469":1,"470":1,"471":1},"2":{"0":2,"1":1,"2":6,"4":1,"7":1,"8":4,"9":4,"12":1,"13":1,"14":1,"17":1,"18":1,"19":3,"20":1,"21":1,"25":1,"27":2,"28":1,"29":2,"30":1,"32":1,"33":2,"35":2,"36":2,"37":1,"46":1,"47":1,"48":2,"50":1,"51":1,"52":2,"53":2,"54":2,"55":7,"56":2,"57":1,"58":1,"59":8,"60":2,"62":2,"63":1,"64":1,"65":5,"66":4,"67":1,"71":3,"72":1,"74":1,"75":7,"76":1,"79":1,"80":1,"83":1,"84":3,"85":1,"87":1,"88":1,"90":2,"91":3,"92":2,"93":8,"94":10,"95":18,"96":20,"98":4,"99":8,"102":2,"103":4,"104":8,"105":4,"107":2,"108":7,"110":2,"111":2,"112":3,"113":1,"115":4,"116":17,"117":6,"118":5,"119":3,"120":7,"122":1,"123":1,"124":1,"125":2,"126":1,"127":1,"129":2,"131":6,"132":1,"133":1,"134":2,"135":1,"136":1,"137":2,"139":1,"140":2,"141":1,"145":2,"146":1,"147":1,"151":1,"152":1,"153":2,"154":1,"159":2,"160":1,"165":2,"166":1,"167":1,"169":1,"171":1,"172":1,"174":1,"175":1,"177":1,"188":1,"194":1,"195":1,"205":1,"207":1,"210":1,"211":1,"212":3,"214":1,"218":2,"219":3,"220":1,"221":1,"223":3,"224":1,"225":3,"226":2,"227":1,"230":2,"234":1,"235":2,"236":1,"238":1,"239":2,"240":1,"241":1,"242":1,"244":2,"248":1,"249":1,"257":3,"258":1,"260":1,"261":1,"262":3,"263":5,"264":1,"267":1,"268":1,"269":1,"274":2,"277":1,"278":1,"281":3,"283":1,"286":1,"287":4,"291":1,"292":1,"294":2,"295":1,"297":1,"298":2,"299":1,"300":1,"303":1,"305":3,"306":1,"309":1,"313":1,"314":1,"318":1,"320":1,"321":1,"323":2,"324":1,"329":1,"331":2,"336":1,"338":1,"339":2,"340":2,"341":1,"344":1,"346":2,"347":1,"348":1,"349":1,"350":1,"351":1,"353":2,"355":1,"358":1,"359":1,"360":1,"361":1,"364":1,"368":3,"369":1,"372":1,"374":10,"376":2,"377":1,"379":1,"380":4,"382":1,"383":2,"384":2,"385":2,"386":1,"388":3,"389":1,"390":1,"391":1,"399":1,"400":1,"402":2,"404":1,"408":1,"410":4,"411":3,"412":2,"413":1,"415":1,"417":2,"418":1,"419":1,"426":1,"432":1,"433":1,"443":1,"446":1,"448":1,"451":3,"455":4,"457":1,"459":1,"460":1,"461":2,"462":1,"463":6,"464":1,"465":3,"466":1,"469":1,"472":2,"474":1,"476":2,"477":1,"478":1,"479":1,"480":2,"481":2,"482":1,"484":1,"486":3,"487":3,"489":3,"492":2,"493":1,"495":1,"496":1,"497":1,"498":1,"499":1,"500":1,"501":1,"502":2,"504":1,"505":1,"506":1,"507":2,"508":2,"509":2,"510":1,"512":1,"513":1,"515":1,"516":3,"517":4,"518":1,"520":2,"522":1,"525":3,"526":1,"527":2,"529":1,"530":1,"531":1,"535":1,"536":1,"539":1,"541":1}}],["a",{"0":{"22":1,"133":1,"142":1,"153":1,"155":1,"204":1,"233":1,"235":1,"238":1,"245":1,"246":1,"325":1,"350":1,"358":1,"359":1,"423":1,"424":1,"430":1,"431":1,"443":1,"444":2,"450":1},"1":{"23":1,"24":1,"25":1,"26":1,"27":1,"28":1},"2":{"0":1,"1":2,"8":1,"15":1,"17":1,"19":1,"20":2,"21":1,"23":1,"26":1,"34":1,"52":2,"53":1,"54":1,"57":2,"65":2,"66":1,"67":1,"68":1,"71":2,"72":1,"75":1,"77":1,"79":1,"80":1,"92":1,"93":1,"94":1,"99":1,"102":1,"103":2,"104":1,"105":1,"107":1,"115":1,"120":2,"124":1,"126":2,"127":3,"131":3,"132":2,"133":1,"134":3,"135":1,"136":2,"137":5,"139":2,"141":1,"142":1,"145":1,"147":1,"148":1,"150":1,"153":1,"157":1,"159":1,"165":1,"169":1,"170":1,"171":2,"172":1,"174":2,"177":1,"179":3,"185":1,"186":1,"189":2,"191":2,"193":2,"200":2,"203":1,"204":2,"205":2,"206":2,"208":2,"211":1,"212":2,"214":1,"215":2,"216":3,"218":3,"219":2,"220":5,"222":1,"223":1,"224":1,"225":3,"226":1,"228":1,"229":2,"231":1,"233":2,"234":1,"235":1,"236":4,"238":1,"239":1,"241":1,"243":1,"244":1,"246":1,"252":1,"254":2,"258":1,"262":2,"263":6,"269":1,"270":1,"271":1,"274":1,"275":1,"288":1,"296":1,"305":2,"308":2,"324":1,"325":1,"329":1,"330":3,"332":2,"334":3,"336":2,"337":2,"338":1,"339":3,"340":4,"341":4,"345":1,"346":2,"347":1,"348":1,"349":1,"350":2,"352":1,"353":1,"354":2,"355":1,"356":1,"357":1,"358":2,"362":1,"372":1,"374":3,"375":2,"379":2,"380":5,"383":2,"387":1,"391":1,"396":1,"403":1,"407":1,"408":1,"414":1,"416":1,"417":1,"418":1,"419":2,"420":1,"433":1,"434":1,"436":1,"441":1,"452":1,"455":2,"458":2,"459":1,"461":1,"462":1,"463":1,"464":3,"468":1,"470":1,"473":1,"477":1,"479":1,"480":1,"481":2,"482":1,"484":4,"485":1,"486":2,"487":1,"489":2,"490":1,"491":2,"492":1,"493":1,"495":1,"496":1,"497":1,"499":2,"500":1,"502":1,"505":1,"506":3,"509":1,"512":2,"513":2,"517":1,"520":2,"522":2,"527":2,"529":1,"533":2,"538":1,"541":1}}],["ai?",{"0":{"247":1}}],["aisettings",{"2":{"99":1,"117":1}}],["ai,",{"2":{"75":1,"99":1,"126":1}}],["ai:",{"2":{"70":1}}],["aihealthpage,",{"2":{"59":1}}],["aipersonasmanager,",{"2":{"59":1}}],["aiflow,",{"2":{"91":1}}],["aiflow",{"2":{"13":1}}],["aiflow.js.",{"2":{"372":1}}],["aiflow.js,",{"2":{"23":1}}],["aiflow.js:",{"2":{"2":1}}],["aiflow.js",{"2":{"1":1}}],["ai",{"0":{"0":1,"14":1,"18":1,"21":1,"51":1,"66":1,"67":1,"80":1,"304":1,"305":1,"306":1,"308":1,"309":1,"310":1,"365":1,"372":1,"409":1,"438":1,"452":1},"1":{"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"52":1,"53":1,"54":1,"55":1,"67":1,"305":1,"306":1,"307":1,"308":1,"309":1,"310":1,"410":1,"411":1,"412":1,"413":1},"2":{"0":1,"13":6,"14":1,"15":1,"18":1,"19":2,"20":3,"21":1,"25":1,"26":1,"28":1,"29":1,"43":1,"48":1,"49":1,"51":2,"52":2,"53":1,"54":1,"55":5,"66":3,"67":1,"69":1,"75":4,"80":5,"91":2,"94":1,"95":3,"96":3,"99":1,"102":1,"103":1,"104":1,"106":1,"107":3,"108":1,"111":1,"113":1,"115":1,"116":4,"117":2,"118":3,"120":2,"131":1,"241":1,"247":5,"281":1,"305":3,"306":1,"307":1,"308":3,"309":1,"310":1,"365":4,"372":2,"384":1,"393":3,"409":2,"411":2,"412":1,"413":2,"438":3,"452":4,"453":1,"478":1,"480":1,"511":1}}]],"serializationVersion":2}'; +export { + _localSearchIndexroot as default +}; diff --git a/docs-site/.vitepress/.temp/VPLocalSearchBox.B_D79mPK.js b/docs-site/.vitepress/.temp/VPLocalSearchBox.B_D79mPK.js new file mode 100644 index 00000000..6dbfea02 --- /dev/null +++ b/docs-site/.vitepress/.temp/VPLocalSearchBox.B_D79mPK.js @@ -0,0 +1,367 @@ +var __defProp = Object.defineProperty; +var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); +import { defineComponent, shallowRef, markRaw, computed, ref, watchEffect, watch, createApp, nextTick, onMounted, onBeforeUnmount, unref, useSSRContext } from "vue"; +import { ssrRenderTeleport, ssrRenderAttr, ssrRenderClass, ssrIncludeBooleanAttr, ssrRenderList, ssrInterpolate } from "vue/server-renderer"; +import { computedAsync, useSessionStorage, useLocalStorage, debouncedWatch, onKeyStroke, useEventListener, useScrollLock } from "@vueuse/core"; +import { useFocusTrap } from "@vueuse/integrations/useFocusTrap"; +import Mark from "mark.js/src/vanilla.js"; +import MiniSearch from "minisearch"; +import { u as useData, d as dataSymbol, p as pathToFile, a as useRouter, c as createSearchTranslate, i as inBrowser, e as escapeRegExp } from "./app.js"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +import "mermaid"; +const localSearchIndex = { "root": () => import("./@localSearchIndexroot.BUwey-h1.js") }; +class LRUCache { + constructor(max = 10) { + __publicField(this, "max"); + __publicField(this, "cache"); + this.max = max; + this.cache = /* @__PURE__ */ new Map(); + } + get(key) { + let item = this.cache.get(key); + if (item !== void 0) { + this.cache.delete(key); + this.cache.set(key, item); + } + return item; + } + set(key, val) { + if (this.cache.has(key)) + this.cache.delete(key); + else if (this.cache.size === this.max) + this.cache.delete(this.first()); + this.cache.set(key, val); + } + first() { + return this.cache.keys().next().value; + } + clear() { + this.cache.clear(); + } +} +const _sfc_main = /* @__PURE__ */ defineComponent({ + __name: "VPLocalSearchBox", + __ssrInlineRender: true, + emits: ["close"], + setup(__props, { emit: __emit }) { + var _a, _b; + const emit = __emit; + const el = shallowRef(); + const resultsEl = shallowRef(); + const searchIndexData = shallowRef(localSearchIndex); + const vitePressData = useData(); + const { activate } = useFocusTrap(el, { + immediate: true, + allowOutsideClick: true, + clickOutsideDeactivates: true, + escapeDeactivates: true + }); + const { localeIndex, theme } = vitePressData; + const searchIndex = computedAsync( + async () => { + var _a2, _b2, _c, _d, _e, _f, _g, _h, _i; + return markRaw( + MiniSearch.loadJSON( + (_c = await ((_b2 = (_a2 = searchIndexData.value)[localeIndex.value]) == null ? void 0 : _b2.call(_a2))) == null ? void 0 : _c.default, + { + fields: ["title", "titles", "text"], + storeFields: ["title", "titles"], + searchOptions: { + fuzzy: 0.2, + prefix: true, + boost: { title: 4, text: 2, titles: 1 }, + ...((_d = theme.value.search) == null ? void 0 : _d.provider) === "local" && ((_f = (_e = theme.value.search.options) == null ? void 0 : _e.miniSearch) == null ? void 0 : _f.searchOptions) + }, + ...((_g = theme.value.search) == null ? void 0 : _g.provider) === "local" && ((_i = (_h = theme.value.search.options) == null ? void 0 : _h.miniSearch) == null ? void 0 : _i.options) + } + ) + ); + } + ); + const disableQueryPersistence = computed(() => { + var _a2, _b2; + return ((_a2 = theme.value.search) == null ? void 0 : _a2.provider) === "local" && ((_b2 = theme.value.search.options) == null ? void 0 : _b2.disableQueryPersistence) === true; + }); + const filterText = disableQueryPersistence.value ? ref("") : useSessionStorage("vitepress:local-search-filter", ""); + const showDetailedList = useLocalStorage( + "vitepress:local-search-detailed-list", + ((_a = theme.value.search) == null ? void 0 : _a.provider) === "local" && ((_b = theme.value.search.options) == null ? void 0 : _b.detailedView) === true + ); + const disableDetailedView = computed(() => { + var _a2, _b2, _c; + return ((_a2 = theme.value.search) == null ? void 0 : _a2.provider) === "local" && (((_b2 = theme.value.search.options) == null ? void 0 : _b2.disableDetailedView) === true || ((_c = theme.value.search.options) == null ? void 0 : _c.detailedView) === false); + }); + const buttonText = computed(() => { + var _a2, _b2, _c, _d, _e, _f, _g; + const options = ((_a2 = theme.value.search) == null ? void 0 : _a2.options) ?? theme.value.algolia; + return ((_e = (_d = (_c = (_b2 = options == null ? void 0 : options.locales) == null ? void 0 : _b2[localeIndex.value]) == null ? void 0 : _c.translations) == null ? void 0 : _d.button) == null ? void 0 : _e.buttonText) || ((_g = (_f = options == null ? void 0 : options.translations) == null ? void 0 : _f.button) == null ? void 0 : _g.buttonText) || "Search"; + }); + watchEffect(() => { + if (disableDetailedView.value) { + showDetailedList.value = false; + } + }); + const results = shallowRef([]); + const enableNoResults = ref(false); + watch(filterText, () => { + enableNoResults.value = false; + }); + const mark = computedAsync(async () => { + if (!resultsEl.value) return; + return markRaw(new Mark(resultsEl.value)); + }, null); + const cache = new LRUCache(16); + debouncedWatch( + () => [searchIndex.value, filterText.value, showDetailedList.value], + async ([index, filterTextValue, showDetailedListValue], old, onCleanup) => { + var _a2, _b2, _c, _d; + if ((old == null ? void 0 : old[0]) !== index) { + cache.clear(); + } + let canceled = false; + onCleanup(() => { + canceled = true; + }); + if (!index) return; + results.value = index.search(filterTextValue).slice(0, 16); + enableNoResults.value = true; + const mods = showDetailedListValue ? await Promise.all(results.value.map((r) => fetchExcerpt(r.id))) : []; + if (canceled) return; + for (const { id, mod } of mods) { + const mapId = id.slice(0, id.indexOf("#")); + let map = cache.get(mapId); + if (map) continue; + map = /* @__PURE__ */ new Map(); + cache.set(mapId, map); + const comp = mod.default ?? mod; + if ((comp == null ? void 0 : comp.render) || (comp == null ? void 0 : comp.setup)) { + const app = createApp(comp); + app.config.warnHandler = () => { + }; + app.provide(dataSymbol, vitePressData); + Object.defineProperties(app.config.globalProperties, { + $frontmatter: { + get() { + return vitePressData.frontmatter.value; + } + }, + $params: { + get() { + return vitePressData.page.value.params; + } + } + }); + const div = document.createElement("div"); + app.mount(div); + const headings = div.querySelectorAll("h1, h2, h3, h4, h5, h6"); + headings.forEach((el2) => { + var _a3; + const href = (_a3 = el2.querySelector("a")) == null ? void 0 : _a3.getAttribute("href"); + const anchor = (href == null ? void 0 : href.startsWith("#")) && href.slice(1); + if (!anchor) return; + let html = ""; + while ((el2 = el2.nextElementSibling) && !/^h[1-6]$/i.test(el2.tagName)) + html += el2.outerHTML; + map.set(anchor, html); + }); + app.unmount(); + } + if (canceled) return; + } + const terms = /* @__PURE__ */ new Set(); + results.value = results.value.map((r) => { + const [id, anchor] = r.id.split("#"); + const map = cache.get(id); + const text = (map == null ? void 0 : map.get(anchor)) ?? ""; + for (const term in r.match) { + terms.add(term); + } + return { ...r, text }; + }); + await nextTick(); + if (canceled) return; + await new Promise((r) => { + var _a3; + (_a3 = mark.value) == null ? void 0 : _a3.unmark({ + done: () => { + var _a4; + (_a4 = mark.value) == null ? void 0 : _a4.markRegExp(formMarkRegex(terms), { done: r }); + } + }); + }); + const excerpts = ((_a2 = el.value) == null ? void 0 : _a2.querySelectorAll(".result .excerpt")) ?? []; + for (const excerpt of excerpts) { + (_b2 = excerpt.querySelector('mark[data-markjs="true"]')) == null ? void 0 : _b2.scrollIntoView({ block: "center" }); + } + (_d = (_c = resultsEl.value) == null ? void 0 : _c.firstElementChild) == null ? void 0 : _d.scrollIntoView({ block: "start" }); + }, + { debounce: 200, immediate: true } + ); + async function fetchExcerpt(id) { + const file = pathToFile(id.slice(0, id.indexOf("#"))); + try { + if (!file) throw new Error(`Cannot find file for id: ${id}`); + return { id, mod: await import( + /*@vite-ignore*/ + file + ) }; + } catch (e) { + console.error(e); + return { id, mod: {} }; + } + } + const searchInput = ref(); + const disableReset = computed(() => { + var _a2; + return ((_a2 = filterText.value) == null ? void 0 : _a2.length) <= 0; + }); + function focusSearchInput(select = true) { + var _a2, _b2; + (_a2 = searchInput.value) == null ? void 0 : _a2.focus(); + select && ((_b2 = searchInput.value) == null ? void 0 : _b2.select()); + } + onMounted(() => { + focusSearchInput(); + }); + const selectedIndex = ref(-1); + const disableMouseOver = ref(true); + watch(results, (r) => { + selectedIndex.value = r.length ? 0 : -1; + scrollToSelectedResult(); + }); + function scrollToSelectedResult() { + nextTick(() => { + const selectedEl = document.querySelector(".result.selected"); + selectedEl == null ? void 0 : selectedEl.scrollIntoView({ block: "nearest" }); + }); + } + onKeyStroke("ArrowUp", (event) => { + event.preventDefault(); + selectedIndex.value--; + if (selectedIndex.value < 0) { + selectedIndex.value = results.value.length - 1; + } + disableMouseOver.value = true; + scrollToSelectedResult(); + }); + onKeyStroke("ArrowDown", (event) => { + event.preventDefault(); + selectedIndex.value++; + if (selectedIndex.value >= results.value.length) { + selectedIndex.value = 0; + } + disableMouseOver.value = true; + scrollToSelectedResult(); + }); + const router = useRouter(); + onKeyStroke("Enter", (e) => { + if (e.isComposing) return; + if (e.target instanceof HTMLButtonElement && e.target.type !== "submit") + return; + const selectedPackage = results.value[selectedIndex.value]; + if (e.target instanceof HTMLInputElement && !selectedPackage) { + e.preventDefault(); + return; + } + if (selectedPackage) { + router.go(selectedPackage.id); + emit("close"); + } + }); + onKeyStroke("Escape", () => { + emit("close"); + }); + const defaultTranslations = { + modal: { + displayDetails: "Display detailed list", + resetButtonTitle: "Reset search", + backButtonTitle: "Close search", + noResultsText: "No results for", + footer: { + selectText: "to select", + selectKeyAriaLabel: "enter", + navigateText: "to navigate", + navigateUpKeyAriaLabel: "up arrow", + navigateDownKeyAriaLabel: "down arrow", + closeText: "to close", + closeKeyAriaLabel: "escape" + } + } + }; + const translate = createSearchTranslate(defaultTranslations); + onMounted(() => { + window.history.pushState(null, "", null); + }); + useEventListener("popstate", (event) => { + event.preventDefault(); + emit("close"); + }); + const isLocked = useScrollLock(inBrowser ? document.body : null); + onMounted(() => { + nextTick(() => { + isLocked.value = true; + nextTick().then(() => activate()); + }); + }); + onBeforeUnmount(() => { + isLocked.value = false; + }); + function formMarkRegex(terms) { + return new RegExp( + [...terms].sort((a, b) => b.length - a.length).map((term) => `(${escapeRegExp(term)})`).join("|"), + "gi" + ); + } + return (_ctx, _push, _parent, _attrs) => { + ssrRenderTeleport(_push, (_push2) => { + var _a2, _b2, _c, _d, _e; + _push2(`
`); + }, "body", false, _parent); + }; + } +}); +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPLocalSearchBox.vue"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const VPLocalSearchBox = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-ce626c7c"]]); +export { + VPLocalSearchBox as default +}; diff --git a/docs-site/.vitepress/.temp/ai_architecture.md.js b/docs-site/.vitepress/.temp/ai_architecture.md.js new file mode 100644 index 00000000..5fe6f475 --- /dev/null +++ b/docs-site/.vitepress/.temp/ai_architecture.md.js @@ -0,0 +1,60 @@ +import { resolveComponent, useSSRContext } from "vue"; +import { ssrRenderAttrs, ssrRenderSuspense, ssrRenderComponent, ssrRenderStyle } from "vue/server-renderer"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse(`{"title":"AI Architecture","description":"Comprehensive architecture documentation for Notely's local-first AI subsystem, AIFlow master orchestrator, 4-Layer Decoupled Planning Architecture, Context Compaction engine, vector search, knowledge graph, prompt pipeline, and telemetry tracing.","frontmatter":{"title":"AI Architecture","description":"Comprehensive architecture documentation for Notely's local-first AI subsystem, AIFlow master orchestrator, 4-Layer Decoupled Planning Architecture, Context Compaction engine, vector search, knowledge graph, prompt pipeline, and telemetry tracing.","keywords":"AI architecture, AIFlow, CompactionEngine, ContextOrchestrator, IntentAnalyzer, CapabilityResolver, Planner, QueryExecutor, PromptPipeline, retrievalQuality, plannerDecision, LLM fallback, vector embeddings, graph DB, SQLite, CTE, ReAct, SelfCorrectionEngine, Module Facades","category":"AI"},"headers":[],"relativePath":"ai/architecture.md","filePath":"ai/architecture.md","lastUpdated":1785093423000}`); +const _sfc_main = { name: "ai/architecture.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + const _component_Mermaid = resolveComponent("Mermaid"); + _push(`

AI Subsystem & Master Flow Architecture

Notely implements a local-first, offline-ready 13-domain AI architecture designed for privacy, low latency, multi-tool evidence orchestration, zero-latency context compaction, and deterministic grounding. Markdown notes remain the single source of truth, parsed and indexed into offline-first SQLite databases.


13-Domain Decoupled Module Facade Blueprint

All 13 sub-domains expose a mandatory single entry point facade (index.js). No external module or Electron handler is permitted to import private internal files of another module. All query executions are coordinated by the master orchestrator AIFlow.js through a 5-stage pipeline with structured telemetry logging to LogDB (FlowTracker) and zero-latency Context Compaction (ai/compaction/).

`); + ssrRenderSuspense(_push, { + default: () => { + _push(ssrRenderComponent(_component_Mermaid, { + id: "mermaid-13", + class: "mermaid", + graph: "flowchart%20TD%0A%20%20%20%20subgraph%20Renderer%5B%22Renderer%20Process%20(React%20%2F%20Vite)%22%5D%0A%20%20%20%20%20%20%20%20direction%20LR%0A%20%20%20%20%20%20%20%20AICP%5B%22AIChatPanel%20(Sidebar%20Chat)%22%5D%20%26%20AIP%5B%22AIPalette%20(Inline%20AI)%22%5D%20%26%20AIH%5B%22AIHealthPage%20(Diagnostics%20%26%20Traces)%22%5D%20%26%20KGV%5B%22KnowledgeGraph%20(Visualizer)%22%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20Preload%5B%22Preload%20Bridge%20(preload.cjs)%22%5D%0A%20%20%20%20%20%20%20%20CB%5B%22window.notesApi.ai*%20(45%2B%20IPC%20methods)%22%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20Handlers%5B%22AI%20IPC%20Handlers%20(aiHandlers.cjs)%22%5D%0A%20%20%20%20%20%20%20%20TRUST%5B%22Trusted%20Sender%20Guard%22%5D%0A%20%20%20%20%20%20%20%20CHAN%5B%22IPC_EVENTS%20Protocol%20Constants%20(ai%2Futils%2FipcProtocol.js)%22%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20AIService%5B%22AI%20Service%20Coordinator%20(AIService.js)%22%5D%0A%20%20%20%20%20%20%20%20SW%5B%22Master%20Enable%20%2F%20Disable%20Switch%22%5D%0A%20%20%20%20%20%20%20%20AIFLOW%5B%22AIFlow.js%20(Master%205-Stage%20Orchestrator)%22%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20Domains%20%5B%2213%20Decoupled%20Domain%20Modules%20(index.js%20Facades)%22%5D%0A%20%20%20%20%20%20%20%20COMP%5B%22compaction%20(CompactionEngine)%22%5D%0A%20%20%20%20%20%20%20%20PLAN%5B%22planner%20(IntentAnalyzer%2C%20CapabilityResolver%2C%20Planner)%22%5D%0A%20%20%20%20%20%20%20%20PERS%5B%22personas%20(PersonaDB%2C%20PersonaStore)%22%5D%0A%20%20%20%20%20%20%20%20PROM%5B%22prompts%20(PromptPipeline%2C%20PromptLoader)%22%5D%0A%20%20%20%20%20%20%20%20CTX%5B%22context%20(ContextEngine%2C%20HybridRetriever)%22%5D%0A%20%20%20%20%20%20%20%20GRAPH%5B%22graph%20(GraphDB%2C%20GraphService%2C%20EvidenceStore)%22%5D%0A%20%20%20%20%20%20%20%20EMB%5B%22embeddings%20(EmbeddingDB%2C%20ONNXEmbedder)%22%5D%0A%20%20%20%20%20%20%20%20MEM%5B%22memory%20(MemoryDB%2C%20ConversationStore)%22%5D%0A%20%20%20%20%20%20%20%20EXEC%5B%22executor%20(QueryExecutor%2C%20SelfCorrectionEngine)%22%5D%0A%20%20%20%20%20%20%20%20TOOL%5B%22tools%20(ToolRegistry%2C%20getRegisteredTools)%22%5D%0A%20%20%20%20%20%20%20%20GND%5B%22grounding%20(GroundingEngine)%22%5D%0A%20%20%20%20%20%20%20%20FMT%5B%22formatter%20(TaskSummaryFormatter)%22%5D%0A%20%20%20%20%20%20%20%20TEST%5B%22testing%20(PipelineRegression)%22%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20BackgroundProcess%20%5B%22Utility%20Process%20(electron%2Fai%2FworkerProcess.cjs)%22%5D%0A%20%20%20%20%20%20%20%20INDEXWRK%5B%22IndexWorker%20(Embeddings)%22%5D%20%26%20GRAPHWRK%5B%22GraphWorker%20(Knowledge%20Graph)%22%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20Storage%20%5B%22SQLite%20Storage%20%E2%80%94%20WAL%20Mode%22%5D%0A%20%20%20%20%20%20%20%20direction%20LR%0A%20%20%20%20%20%20%20%20EMBDB%5B(%22ai-embeddings.db%22)%5D%20%26%20GRDB%5B(%22ai-graph.db%22)%5D%20%26%20MEMDB%5B(%22ai-memory.db%20%2F%20personas.db%22)%5D%20%26%20TELDB%5B(%22ai-telemetry.db%22)%5D%20%26%20LOGDB%5B(%22ai-logs.db%22)%5D%0A%20%20%20%20end%0A%0A%20%20%20%20Renderer%20--%3E%7C%22IPC%20%C2%B7%20contextBridge%22%7C%20Preload%0A%20%20%20%20Preload%20--%3E%7C%22ipcMain.handle%20%2F%20IPC_EVENTS%22%7C%20Handlers%0A%20%20%20%20Handlers%20--%3E%20AIService%0A%20%20%20%20AIService%20--%3E%20AIFLOW%0A%20%20%20%20AIFLOW%20--%3E%20Domains%0A%20%20%20%20Domains%20--%3E%20Storage%0A%20%20%20%20BackgroundProcess%20--%3E%7C%22Consumes%20Facades%22%7C%20Domains%0A" + }, null, _parent)); + }, + fallback: () => { + _push(` Loading... `); + }, + _: 1 + }); + _push(`

1. Master Flow Orchestrator (AIFlow.js) & 5-Stage Execution Pipeline

Every query executes through AIFlow.js:

  1. Stage 1 (Context & Persona Resolution): Resolves conversation state, loads active persona, and applies 0ms context compaction (ai/compaction/).
  2. Stage 2 (Intent Planning & Hybrid Retrieval): ContextOrchestrator executes the 4-layer planning architecture, running tool capability discovery, parallel retrieval, relevance filtering (score >= 0.25), and logging plannerDecision and retrievalQuality metrics.
  3. Stage 3 (System Prompt Assembly & Safety Audit): PromptPipeline assembles system prompt using pre-compiled static policy caching and runs safety invariant audit.
  4. Stage 4 (Runtime Dynamic Strategy Execution & Tools): QueryExecutor resolves runtime strategy (multi-step tool loop, LLM provider fallback sequence) and runs GroundingEngine.
  5. Stage 5 (Memory Persistence & Telemetry Logging): Persists turn to ConversationStore and logs full 5-stage trace payload to LogDB (FlowTracker).

2. 4-Layer Decoupled Planning Architecture

The planning system maps user queries into dynamic tool execution DAGs without hardcoded query strings or function signatures.

`); + ssrRenderSuspense(_push, { + default: () => { + _push(ssrRenderComponent(_component_Mermaid, { + id: "mermaid-55", + class: "mermaid", + graph: "flowchart%20LR%0A%20%20%20%20L1%5B%22Layer%201%3A%20IntentAnalyzer%5Cn(Intent%20%26%20Needs%20Extraction)%22%5D%20--%3E%20L2%5B%22Layer%202%3A%20CapabilityResolver%5Cn(Tool%20Registry%20%26%20Capability%20Binding)%22%5D%0A%20%20%20%20L2%20--%3E%20L3%5B%22Layer%203%3A%20Planner%5Cn(DAG%20Execution%20Plan%20%26%20Deduplication)%22%5D%0A%20%20%20%20L3%20--%3E%20L4%5B%22Layer%204%3A%20ContextOrchestrator%5Cn(Parallel%20Execution%20%26%20Evidence%20Aggregation)%22%5D%0A" + }, null, _parent)); + }, + fallback: () => { + _push(` Loading... `); + }, + _: 1 + }); + _push(`

Layer 1: Intent Analysis (IntentAnalyzer.js)

  • Dynamically matches query terms against registered tool metadata in ApplicationToolRegistry.
  • Classifies intents such as workspace_task_summary (confidence >0.80), explore_knowledge_graph, reconstruct_project_timeline, and fetch_external_web_data.
  • Enforces capability priority: Task Intent > Workspace Search > Graph Exploration.

Layer 2: Capability Resolution (CapabilityResolver.js)

  • Resolves abstract information needs (action_items, tasks, entity_relationships, recent_changes) into bound tool capabilities (tasks:extract, notes:search, graph:traverse).

Layer 3: Plan DAG Generation (Planner.js)

  • Constructs deduplicated execution plan steps by toolName.
  • Restricts graph search (explore_topic_graph) for task queries unless relation/graph traversal is explicitly requested in the query.
  • Emits structured plannerDecision telemetry:
    json
    {
    +  "intent": "workspace_task_summary",
    +  "confidence": 0.92,
    +  "selectedStrategy": "task_pipeline",
    +  "rejectedStrategies": ["graph_search"]
    +}

Layer 4: Multi-Tool Context Orchestration (ContextOrchestrator.js)

  • Retrieval Priority Ordering:
    1. Primary Task Database / Tool (get_tasks)
    2. Markdown Task Syntax Parser (- [ ], TODO, FIXME, status fields)
    3. Recent Workspace Activity (workspace.recent_activity)
    4. Vector Semantic Search (search_notes)
    5. Graph Traversal (explore_topic_graph, only when requested)
  • Empty Retrieval Handling: If get_tasks() returns empty, executes markdown task syntax parsing and recent workspace activity. If still empty, returns "No tasks found in your workspace." without fabricating unrelated notes or running graph search.
  • Relevance Filtering: Rejects evidence items with similarity score < 0.25.
  • Evidence Quality Telemetry: Captures retrievalQuality items:
    json
    {
    +  "sourceType": "notes.extract_tasks",
    +  "similarityScore": 0.02,
    +  "accepted": false,
    +  "rejectedReason": "below relevance threshold"
    +}

3. Persona Registry & Markdown Source of Truth

Notely treats Markdown (.md) files as the single source of truth for both system prompts and personas:

  • Markdown Storage: Builtin personas reside in resources/prompts/personas/*.md and custom user personas reside in appData/personas/*.md.
  • Frontmatter & Body: Personas use YAML frontmatter for metadata (id, name, tone, verbosity, responseStructure) and Markdown body for role definitions & instructions.
  • SQLite Indexing: SQLite (personas.db) acts purely as a fast metadata index registry (without redundant prompt body columns). Frontmatter metadata and prompt body are hydrated dynamically from .md files at runtime.
  • Automatic Migration: Persona DB migrations automatically drop obsolete string columns (ALTER TABLE personas DROP COLUMN prompt) during startup.

4. Static Prompt Assembly Caching (PromptPipeline.js)

To optimize prompt construction latency and prevent redundant byte joins, PromptPipeline splits system prompts into static and dynamic blocks:

  • Static Block (Pre-compiled & Cached): Core foundational policies (base-system, behavior-policy, safety-policy, response-policy, conversation-policy, formatting-policy, permission-policy, grounding-policy) and Tool Calling Discipline in planning-policy.md.
  • Dynamic Block: Runtime context (persona, workspaceContext, retrievedEvidence, uiContext).
  • Clean Evidence Truncation: Evidence payloads are capped at 4,000 characters with newline-aware truncation (lastIndexOf('\\n')) to avoid slicing words mid-sentence.
  • Evidence Sanitation: Tool execution errors, missing capability messages, and duplicate error strings are stripped prior to prompt injection.

4. Multi-Tier LLM Provider Fallback (QueryExecutor.js)

When an active LLM provider fails (e.g. rate limit 429, network timeout, API error):

  1. Attempts execution via secondary configured LLM provider in LLMRegistry.
  2. Falls back to local ONNX model (local-onnx).
  3. Returns structured error payload if all providers fail.
  4. Emits llmFallbackTriggered: true in execution telemetry.

5. Zero-Latency Context Compaction Engine (ai/compaction/)

  • 2-Tier Sliding Window Algorithm:
    • Tier 1 (Verbatim Window): Recent 4 messages preserved verbatim for immediate context.
    • Tier 2 (Executive Memory Summary): Older turns programmatically compressed into structured bullet points using 0ms NLP intent & outcome extraction heuristics:
      markdown
      [EXECUTIVE MEMORY SUMMARY OF PAST TURNS]
      +- Turn 1: User requested "explain auth" -> Referenced notes: Architecture Notes
      +- Turn 2: User requested "add telemetry" -> Generated code snippet/action
  • Benefits: ~75-80% input token reduction, faster LLM latency, zero text redundancy.

6. UI Diagnostics & Flow Telemetry (AIHealthPage.jsx)

  • Messages Tab: Clean conversation transcript (technical tool call boxes removed).
  • Flow Telemetry Tab: Interactive 5-stage execution trace view displaying:
    1. Timeline & duration per stage
    2. Persona & active note context
    3. Pre-retrieval trace steps, confidence score & plannerDecision
    4. System prompt viewer with Copy & Expand
    5. retrievalQuality list with similarity scores and acceptance/rejection reasons
    6. Tool calls with input arguments & output payloads
    7. Compaction stats (compactedTurnsCount, isCompacted)
    8. Token consumption, latency breakdown & llmFallbackTriggered flag

7. Automated Test Verification

Covered by Vitest test suites under tests/ai/ (62 test files / 270 tests passing 100%):

  • tests/ai/pipelineRegression.spec.js: Task intent routing, graph restriction, task parser fallback, relevance filtering (<0.25 rejection), and concept graph retrieval regression tests.
  • tests/ai/flow.spec.js: Master AIFlow 5-stage orchestration & telemetry tests.
  • tests/ai/decoupledPlanning.spec.js: 4-Layer Decoupled Planning Architecture tests.
  • tests/ai/compaction.spec.js: Zero-latency NLP intent extraction & sliding window compaction tests.
  • tests/ai/grounding.spec.js: Citation link verification & prompt composition tests.
`); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("ai/architecture.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const architecture = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + architecture as default +}; diff --git a/docs-site/.vitepress/.temp/ai_features.md.js b/docs-site/.vitepress/.temp/ai_features.md.js new file mode 100644 index 00000000..8560e76b --- /dev/null +++ b/docs-site/.vitepress/.temp/ai_features.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Using AI Features","description":"Learn how to invoke AI chat, use the AI rewrite palette, and explore semantic search.","frontmatter":{"title":"Using AI Features","description":"Learn how to invoke AI chat, use the AI rewrite palette, and explore semantic search.","keywords":"AI chat, AI palette, rewrite, summarize, translate, semantic search, diagnostic trace, references","category":"AI"},"headers":[],"relativePath":"ai/features.md","filePath":"ai/features.md","lastUpdated":1785093423000}'); +const _sfc_main = { name: "ai/features.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

AI Features

AI capabilities in Notely are integrated across your editor workspace, left panel dashboards, and settings.


1. Global & Note-Scoped Chat Panel

You can chat with Notely's assistant in two ways:

  • Note-Scoped: While editing a note, toggle the assistant from the right side edge or the toolbar to brainstorm inside the active document.
  • Global Chat: While on the landing page (with no note open), click the Sparkles icon under the Quick Actions toolbar on the left panel rail. This opens the AI sidebar to chat about the entire workspace.

Context Scope Options

Inside the chat panel, you can choose what context to send with your message:

  1. Auto: Selects highlighted text if active, otherwise the current note.
  2. Selection: Restricts context to active text selection.
  3. Block: Restricts context to active cursor paragraph.
  4. Note: Sends the entire note.
  5. Workspace: Extends context by searching relevant chunks across the whole note library.

Sourced References

Whenever the assistant retrieves documents to answer your question, a Referred Notes chip list is rendered under the assistant message bubble. Hover over these chips to see file paths and relevance match percentages.


2. AI Palette Actions

Refactor or rewrite text inside the editor:

  1. Highlight target text selection in the Markdown editor.
  2. Press Ctrl + Space or right-click and select AI Actions.
  3. Choose an action from the palette (e.g. Summarize, Change Tone, Improve Readability).

3. Persona Customization & Markdown Source of Truth

Customize how the AI talks to you:

  • Open AI Settings and click Manage Personas.
  • Markdown Source of Truth: All personas (builtin and custom) are authored as Markdown files (.md) with YAML frontmatter. Custom personas created in the UI are persisted as formatted .md files to disk (appData/personas/*.md), while SQLite acts strictly as an index.
  • Select or edit custom personas, modify frontmatter metadata (tone, verbosity, structure), and update prompt instructions.
  • Select a preset emoji avatar (🤖, 💻, 🧠, etc.) next to the custom avatar field to represent them in the chat panel.

4. Diagnostics, Flow Telemetry & Prompt Tracker Log

If you want to inspect how the AI retrieves data, what system prompts are assembled, or what tools it invokes:

  1. Go to AI Diagnostics / AI Health page.
  2. Select a conversation session from the list.
  3. Use the dual-tab inspector pane:
    • Messages: View clean chat conversation transcript (technical tool execution boxes separated for clutter-free reading).
    • Flow Telemetry: View a 3-column continuous timeline stream connecting 5-stage execution breakdown (AIFlow.js), latency metrics, persistent session tokens (LogDB), expandable tool call arguments/outputs, zero-latency Context Compaction stats (ai/compaction/), system prompt inspector (with Copy/Expand), and full flow trace JSON export.
`); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("ai/features.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const features = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + features as default +}; diff --git a/docs-site/.vitepress/.temp/ai_index.md.js b/docs-site/.vitepress/.temp/ai_index.md.js new file mode 100644 index 00000000..33be4580 --- /dev/null +++ b/docs-site/.vitepress/.temp/ai_index.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse(`{"title":"AI Overview","description":"Learn about Notely's 13-domain modular, local-first AI platform, AIFlow master orchestrator, and Context Compaction engine.","frontmatter":{"title":"AI Overview","description":"Learn about Notely's 13-domain modular, local-first AI platform, AIFlow master orchestrator, and Context Compaction engine.","keywords":"ai, local llm, openai, huggingface, vector database, knowledge graph, AIFlow, compaction","category":"AI"},"headers":[],"relativePath":"ai/index.md","filePath":"ai/index.md","lastUpdated":1785093423000}`); +const _sfc_main = { name: "ai/index.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

AI Subsystem Overview

Notely features a 13-domain modular, local-first AI platform designed around private data control. Markdown files remain the absolute source of truth, parsed and indexed into offline-first databases to fuel assistant reasoning.


Capabilities at a Glance

1. Master Flow Orchestrator (AIFlow.js) & 13-Domain Architecture

  • All LLM queries flow through AIFlow.js, executing a 5-stage pipeline across 13 decoupled domain module facades (compaction, planner, personas, prompts, context, graph, embeddings, memory, executor, tools, grounding, formatter, testing).

2. Zero-Latency Context Compaction (ai/compaction/)

  • Automatically compacts long chat sessions (>4 messages) into an Executive Memory Summary + recent 4 turns verbatim, slashing LLM input tokens by ~75-80% with 0ms overhead.

3. SQLite Knowledge Graph

  • Outbound relations, tags, and CTE traversals mapped into ai-graph.db.
  • Visualized interactively in the sidebar.

4. Local Embedding Indexer

  • High-performance ai-embeddings.db storing note chunk vectors.
  • Runs entirely offline using a local ONNX runtime for BGE-small-en-v1.5 embeddings, or falls back to HuggingFace APIs.
  • Background Index Worker priority queues processing note changes debounced.

5. Persona Registry (Markdown Source of Truth)

  • All personas (builtin and custom) use .md files with YAML frontmatter as their authoritative Source of Truth.
  • SQLite (personas.db) acts strictly as an index registry. Custom personas persist as formatted .md files to disk (appData/personas/*.md).
  • Customize instructions, descriptions, metadata, and preset avatar icons (🤖, 💻, 🧠, etc.).

6. Diagnostics, Flow Telemetry & Trace Logs

  • Professional AI Health panel to verify subsystem initialization.
  • Flow Telemetry tab displaying 5-stage timeline cards, system prompt viewer (Copy/Expand), tool calls, compaction stats, and latency breakdown.
`); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("ai/index.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + index as default +}; diff --git a/docs-site/.vitepress/.temp/ai_knowledge-graph.md.js b/docs-site/.vitepress/.temp/ai_knowledge-graph.md.js new file mode 100644 index 00000000..2c1b23be --- /dev/null +++ b/docs-site/.vitepress/.temp/ai_knowledge-graph.md.js @@ -0,0 +1,76 @@ +import { resolveComponent, useSSRContext } from "vue"; +import { ssrRenderAttrs, ssrRenderSuspense, ssrRenderComponent } from "vue/server-renderer"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Knowledge Graph Generation Engine","description":"","frontmatter":{},"headers":[],"relativePath":"ai/knowledge-graph.md","filePath":"ai/knowledge-graph.md","lastUpdated":1785942184000}'); +const _sfc_main = { name: "ai/knowledge-graph.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + const _component_Mermaid = resolveComponent("Mermaid"); + _push(`

Knowledge Graph Generation Engine

Notely features an offline, local-first, AI-powered 8-Stage Knowledge Graph Generation Engine. It operates without any cloud dependencies, transforming raw Markdown notes, image annotations, and workspace metadata into an interconnected Property Graph using local FP16 ONNX neural models, SQLite vector storage, deterministic domain pattern mining, and hybrid GraphRAG retrieval.


Architecture Overview

The system uses an 8-stage pipeline separating document structure parsing from model-agnostic neural semantic extraction, vector embedding deduplication, and evidence fusion.

`); + ssrRenderSuspense(_push, { + default: () => { + _push(ssrRenderComponent(_component_Mermaid, { + id: "mermaid-13", + class: "mermaid", + graph: "flowchart%20TD%0A%20%20%20%20MD%5BMarkdown%20Note%20.md%5D%20--%3E%20S1%5BStage%201%3A%20AST%20Structural%20Parser%20%26%20Pre-Cleansing%5D%0A%20%20%20%20S1%20--%3E%20S2%5BStage%202%3A%20Linguistic%20Noun-Phrase%20%26%20Prose%20Isolator%5D%0A%20%20%20%20S2%20--%3E%20S3%5BStage%203%3A%20Deterministic%20Domain%20Pattern%20Mining%5D%0A%20%20%20%20S2%20--%3E%20S4%5BStage%204%3A%20GLiNER2%20ONNX%20Neural%20Extraction%5D%0A%20%20%20%20S3%20%26%20S4%20--%3E%20S5%5BStage%205%3A%20Universal%20Quality%20Gate%20%26%20Noise%20Filtering%5D%0A%20%20%20%20S5%20--%3E%20S6%5BStage%206%3A%20Algorithmic%20Entity%20Type%20Sanitization%5D%0A%20%20%20%20S6%20--%3E%20S7%5BStage%207%3A%20ONNX%20Vector%20Embedding%20Concept%20Deduplication%5D%0A%20%20%20%20S7%20--%3E%20S8%5BStage%208%3A%20Evidence%20Fusion%20Engine%20%26%20Plausibility%20Matrix%5D%0A%0A%20%20%20%20S8%20--%3E%20DB%5B(SQLite%20Property%20Graph%20ai-graph.db)%5D%0A%20%20%20%20DB%20--%3E%20CD%5BCommunity%20Detector%20Label%20Propagation%5D%0A%20%20%20%20DB%20--%3E%20VAL%5BGraphValidationEngine%2016-Rule%20Pass%5D%0A%20%20%20%20DB%20--%3E%20CTE%5BRecursive%20CTE%20Graph%20Walk%5D%0A" + }, null, _parent)); + }, + fallback: () => { + _push(` Loading... `); + }, + _: 1 + }); + _push(`

The 8 Pipeline Stages

Stage 1: AST Structural Parser & Pre-Cleansing

  • Component: MarkdownASTParser.js
  • Role: Extracts structural AST entities (Note, Section, Tag, Media, CodeBlock, Task, Formula, ExternalURL, Document). Strips HTML attributes ({data-*="..."}), markdown tables (| ... |), image tags, key-value metadata lines, and frontmatter metadata to produce clean natural prose text for neural extraction.

Stage 2: Linguistic Noun-Phrase & Prose Isolator

  • Component: MarkdownASTParser.cleanse()
  • Role: Produces cleansedContent — stripped natural language prose from which all markdown structure, code syntax, and editor artifacts have been removed. This cleansed text is the sole input to both Stages 3 and 4, preventing structural tokens from corrupting neural inference or pattern matching.

Stage 3: Deterministic Domain Pattern Mining

  • Component: DeterministicSemanticMiner.js
  • Role: Mines pattern-based technical domain relationships (USES, DEPENDS_ON, GENERATES, INTEGRATES_WITH, IMPLEMENTS, ENABLES, WORKS_ON) directly from prose sentences with $0.88 - 0.92$ baseline confidence. Also performs cross-note plain text mention mining (confidence 0.85) against a live note name index (refreshed every 30s). Results are fused via EvidenceFusionEngine.fuseTriple().

Stage 4: GLiNER2 ONNX Neural Zero-Shot Extraction

  • Component: GLiNER2RelexAdapter.js
  • Role: Runs 5-graph ONNX Runtime inference using gliner2-multi-v1-onnx. Extracts neural entities and relationships with calibrated sigmoid scoring (_sigmoid(val + 1.2)), capped candidate span width (maxWidth = 4), and compound disjunctive entity splitting ("Gemini or Groq" $\\rightarrow$ "Gemini", "Groq").

Stage 5: Universal Quality Gate & Noise Filtering

  • Component: EntityResolver.isValidEntityName()
  • Role: Enforces 5 universal rules before any entity can enter the graph:
    1. Length & Acronym Rule — $2 \\le \\text{chars} \\le 35$, max 4 words; 2–3 char terms must be whitelisted acronyms (AI, UI, DB, API, SDK, CLI, SQL, etc.)
    2. Grammatical Boundary Rule — rejects terms starting or ending with prepositions, articles, connectives, or common verb fragments
    3. Sentence Clause & Aux Verb Rule — rejects clause fragments containing auxiliary verbs (will, would, could, should, have, etc.)
    4. Character Entropy & Phonetic Rule — must contain at least one vowel; rejects 4+ repeated characters and 5+ consecutive consonant clusters
    5. Markup & Syntax Artifact Rule — rejects editor markup, HTML attributes (data-), decimal numbers, and table cell patterns

Stage 6: Algorithmic Entity Type Sanitization & Coercion

  • Component: EntityResolver.sanitizeEntityType()
  • Role: Applies 7 deterministic type coercion rules. Title-Cased multi-word proper names → Person. Strict organization typing requires explicit org suffixes (Corp, Inc, Ltd, Technologies, Labs, etc.). Generic UI terms and structural media terms (screenshot, diagram, note) coerce to Concept. No hardcoded entity word lists.

Stage 7: ONNX Vector Embedding Concept Deduplication & Alias Fusion

  • Component: EntityResolver.resolveMentionVector() + EntityResolver._cosineSimilarity() + entity_embeddings table
  • Role: Leverages the existing local ONNX embedder (bge-small-en-v1.5) to compute 384-dimensional dense vectors stored in SQLite (entity_embeddings table). EntityResolver orchestrates the full dedup pipeline: GraphDB canonical name lookup → FTS5 alias search → vector cosine similarity check at $> 0.88$ threshold to automatically merge concept variations ("SQLite DB" $\\leftrightarrow$ "SQLite Database").

Stage 8: Evidence Fusion Engine, Plausibility Matrix & Community Detection

  • Component: EvidenceFusionEngine.js, CommunityDetector.js, GraphDB.js
  • Role: Merges edge confidence scores using probabilistic union $P(A \\cup B) = 1 - (1 - P(A))(1 - P(B))$. Enforces the Semantic Relationship Plausibility Matrix (blocks structural node domain actions, restricts COMMUNICATES_WITH, IMPLEMENTS, GENERATES predicates to compatible entity types). Executes label propagation community clustering over the cleaned graph.

Ingestion Lifecycle

Full Rebuild Flow (GraphBuilder.rebuild())

Triggered explicitly (e.g., from Settings → Rebuild Graph):

`); + ssrRenderSuspense(_push, { + default: () => { + _push(ssrRenderComponent(_component_Mermaid, { + id: "mermaid-175", + class: "mermaid", + graph: "flowchart%20TD%0A%20%20%20%20START(%5BRebuild%20Triggered%5D)%20--%3E%20CLR%5BClear%20all%20graph%20tables%5D%0A%20%20%20%20CLR%20--%3E%20REG%5BRegister%20KnowledgeSources%5D%0A%20%20%20%20REG%20--%3E%20DISC%5BdiscoverAll%3A%20workspace%20root%5D%0A%20%20%20%20DISC%20--%3E%20NONMD%5BExtract%20non-Markdown%20sources%5CnWorkspaceMetadata%20%C2%B7%20FolderHierarchy%20%C2%B7%20ImageAnnotation%5CnExcalidraw%20%C2%B7%20Drawio%20%C2%B7%20Mermaid%5D%0A%20%20%20%20NONMD%20--%3E%20SCAN%5BEnumerate%20.md%20files%5Cnbatch%20size%20%3D%204%5D%0A%20%20%20%20SCAN%20--%3E%20PROC%5BGraphService.processNote%20per%20note%5Cn8-Stage%20Pipeline%5D%0A%20%20%20%20PROC%20--%3E%20SEED%5BSeed%20workspace%20root%20entity%5D%0A%20%20%20%20SEED%20--%3E%20CD2%5BCommunityDetector.detect%5D%0A%20%20%20%20CD2%20--%3E%20VAL2%5BGraphValidationEngine.validate%5Cn16%20rules%5D%0A%20%20%20%20VAL2%20--%3E%20OPT%5BPRAGMA%20ANALYZE%5D%0A%20%20%20%20OPT%20--%3E%20DONE(%5BRebuild%20Complete%5D)%0A" + }, null, _parent)); + }, + fallback: () => { + _push(` Loading... `); + }, + _: 1 + }); + _push(`

Incremental Indexing Flow (GraphWorker)

Triggered on note save, create, or rename via Electron IPC:

`); + ssrRenderSuspense(_push, { + default: () => { + _push(ssrRenderComponent(_component_Mermaid, { + id: "mermaid-182", + class: "mermaid", + graph: "sequenceDiagram%0A%20%20%20%20autonumber%0A%20%20%20%20participant%20UI%20as%20Electron%20Renderer%0A%20%20%20%20participant%20Worker%20as%20Background%20UtilityProcess%0A%20%20%20%20participant%20AST%20as%20Markdown%20AST%20Parser%0A%20%20%20%20participant%20DSM%20as%20Deterministic%20Semantic%20Miner%0A%20%20%20%20participant%20SEE%20as%20Semantic%20Extraction%20Engine%0A%20%20%20%20participant%20ER%20as%20Entity%20Resolver%20%26%20Vector%20Deduplicator%0A%20%20%20%20participant%20EV%20as%20Evidence%20Fusion%20Engine%0A%20%20%20%20participant%20DB%20as%20SQLite%20GraphDB%0A%0A%20%20%20%20UI-%3E%3EWorker%3A%20Enqueue%20Note%20(Path%2C%20Content)%0A%20%20%20%20Worker-%3E%3EAST%3A%20Parse%20Markdown%20AST%20%26%20Pre-Cleanse%20Prose%0A%20%20%20%20AST--%3E%3EWorker%3A%20Return%20Structural%20Tokens%20%26%20cleansedContent%0A%20%20%20%20Worker-%3E%3EDB%3A%20Upsert%20Root%20Note%20%26%20Structural%20Entities%20%5Btransaction%5D%0A%0A%20%20%20%20Worker-%3E%3EDSM%3A%20Mine%20Technical%20Pattern%20Triples%0A%20%20%20%20Worker-%3E%3ESEE%3A%20Execute%20GLiNER2%20ONNX%20Inference%0A%20%20%20%20SEE--%3E%3EWorker%3A%20Return%20Zero-Shot%20Entity%20%26%20Relation%20Candidates%0A%0A%20%20%20%20Worker-%3E%3EER%3A%20Apply%205-Rule%20Quality%20Gate%20%26%20Type%20Coercion%20%5BStage%205%2B6%5D%0A%20%20%20%20Worker-%3E%3EER%3A%20Stage%207%20Vector%20Cosine%20Deduplication%20%26%20Alias%20Linking%0A%0A%20%20%20%20Worker-%3E%3EEV%3A%20Apply%20Semantic%20Plausibility%20Matrix%20%26%20Fuse%20Triples%0A%20%20%20%20EV-%3E%3EDB%3A%20Upsert%20Clean%20Entities%2C%20Relationships%20%26%20Evidence%20Records%0A%20%20%20%20Worker--%3E%3EUI%3A%20Broadcast%20IPC%20Progress%20(ai%3Agraph%3Aprogress)%0A" + }, null, _parent)); + }, + fallback: () => { + _push(` Loading... `); + }, + _: 1 + }); + _push(`

When the queue empties, GraphWorker runs GraphMaintenance automatically (orphan purging, stale edge decay, alias deduplication).


Database Schema & Vector Storage

Knowledge graph data is stored locally in .notes-app/ai-graph.db using native SQLite (node:sqlite) with Write-Ahead Logging (PRAGMA journal_mode = WAL;).

`); + ssrRenderSuspense(_push, { + default: () => { + _push(ssrRenderComponent(_component_Mermaid, { + id: "mermaid-193", + class: "mermaid", + graph: "erDiagram%0A%20%20%20%20entities%20%7C%7C--o%7B%20relationships%20%3A%20%22source_id%22%0A%20%20%20%20entities%20%7C%7C--o%7B%20relationships%20%3A%20%22target_id%22%0A%20%20%20%20entities%20%7C%7C--o%7B%20entity_aliases%20%3A%20%22entity_id%22%0A%20%20%20%20entities%20%7C%7C--o%7C%20entity_embeddings%20%3A%20%22entity_id%22%0A%20%20%20%20evidence%20%7C%7C--o%7B%20relationships%20%3A%20%22evidence_id%22%0A%20%20%20%20relationships%20%7C%7C--o%7B%20relationship_evidence%20%3A%20%22relationship_id%22%0A%20%20%20%20evidence%20%7C%7C--o%7B%20relationship_evidence%20%3A%20%22evidence_id%22%0A%20%20%20%20entities%20%7Do--o%7C%20communities%20%3A%20%22community_id%22%0A%0A%20%20%20%20entities%20%7B%0A%20%20%20%20%20%20%20%20string%20id%20PK%0A%20%20%20%20%20%20%20%20string%20name%0A%20%20%20%20%20%20%20%20string%20canonical_name%0A%20%20%20%20%20%20%20%20string%20type%0A%20%20%20%20%20%20%20%20string%20note_path%0A%20%20%20%20%20%20%20%20json%20properties%0A%20%20%20%20%20%20%20%20string%20extractor%0A%20%20%20%20%20%20%20%20string%20model_version%0A%20%20%20%20%20%20%20%20real%20confidence%0A%20%20%20%20%20%20%20%20int%20community_id%0A%20%20%20%20%20%20%20%20string%20ontology_class%0A%20%20%20%20%20%20%20%20int%20source_count%0A%20%20%20%20%20%20%20%20datetime%20first_seen_at%0A%20%20%20%20%20%20%20%20int%20is_retired%0A%20%20%20%20%20%20%20%20string%20merged_into%0A%20%20%20%20%20%20%20%20datetime%20created_at%0A%20%20%20%20%20%20%20%20datetime%20updated_at%0A%20%20%20%20%7D%0A%0A%20%20%20%20relationships%20%7B%0A%20%20%20%20%20%20%20%20int%20id%20PK%0A%20%20%20%20%20%20%20%20string%20source_id%20FK%0A%20%20%20%20%20%20%20%20string%20target_id%20FK%0A%20%20%20%20%20%20%20%20string%20type%0A%20%20%20%20%20%20%20%20real%20weight%0A%20%20%20%20%20%20%20%20real%20confidence%0A%20%20%20%20%20%20%20%20string%20extractor%0A%20%20%20%20%20%20%20%20string%20model_version%0A%20%20%20%20%20%20%20%20json%20metadata%0A%20%20%20%20%20%20%20%20string%20evidence_id%20FK%0A%20%20%20%20%20%20%20%20datetime%20created_at%0A%20%20%20%20%7D%0A%0A%20%20%20%20entity_embeddings%20%7B%0A%20%20%20%20%20%20%20%20string%20entity_id%20PK%0A%20%20%20%20%20%20%20%20blob%20vector%0A%20%20%20%20%20%20%20%20int%20dimension%0A%20%20%20%20%20%20%20%20datetime%20updated_at%0A%20%20%20%20%7D%0A%0A%20%20%20%20entity_aliases%20%7B%0A%20%20%20%20%20%20%20%20string%20alias%20PK%0A%20%20%20%20%20%20%20%20string%20entity_id%20FK%0A%20%20%20%20%20%20%20%20real%20confidence%0A%20%20%20%20%7D%0A%0A%20%20%20%20evidence%20%7B%0A%20%20%20%20%20%20%20%20string%20id%20PK%0A%20%20%20%20%20%20%20%20string%20source_id%0A%20%20%20%20%20%20%20%20string%20extractor%0A%20%20%20%20%20%20%20%20string%20subject_text%0A%20%20%20%20%20%20%20%20int%20subject_span_start%0A%20%20%20%20%20%20%20%20int%20subject_span_end%0A%20%20%20%20%20%20%20%20string%20predicate_text%0A%20%20%20%20%20%20%20%20string%20object_text%0A%20%20%20%20%20%20%20%20int%20object_span_start%0A%20%20%20%20%20%20%20%20int%20object_span_end%0A%20%20%20%20%20%20%20%20string%20raw_sentence%0A%20%20%20%20%20%20%20%20real%20confidence%0A%20%20%20%20%20%20%20%20datetime%20created_at%0A%20%20%20%20%7D%0A%0A%20%20%20%20relationship_evidence%20%7B%0A%20%20%20%20%20%20%20%20int%20relationship_id%20FK%0A%20%20%20%20%20%20%20%20string%20evidence_id%20FK%0A%20%20%20%20%7D%0A%0A%20%20%20%20communities%20%7B%0A%20%20%20%20%20%20%20%20int%20id%20PK%0A%20%20%20%20%20%20%20%20string%20label%0A%20%20%20%20%20%20%20%20string%20centroid_id%20FK%0A%20%20%20%20%20%20%20%20int%20node_count%0A%20%20%20%20%20%20%20%20datetime%20created_at%0A%20%20%20%20%20%20%20%20datetime%20updated_at%0A%20%20%20%20%7D%0A%0A%20%20%20%20graph_queue%20%7B%0A%20%20%20%20%20%20%20%20string%20id%20PK%0A%20%20%20%20%20%20%20%20string%20note_path%0A%20%20%20%20%20%20%20%20int%20priority%0A%20%20%20%20%20%20%20%20string%20status%0A%20%20%20%20%20%20%20%20string%20error%0A%20%20%20%20%20%20%20%20int%20retries%0A%20%20%20%20%20%20%20%20int%20created_at%0A%20%20%20%20%7D%0A" + }, null, _parent)); + }, + fallback: () => { + _push(` Loading... `); + }, + _: 1 + }); + _push(`

SQLite Indexes

Performance indexes on relationships (source_id, target_id, type, evidence_id, confidence, weight), entities (type, name, note_path, canonical_name, LOWER(canonical_name)), entity_aliases (entity_id), evidence (source_id, extractor, span), graph_queue (status, priority DESC), plus FTS5 virtual table entity_fts for sub-millisecond full-text entity lookup.


Graph Quality & Provenance Validation

Universal Quality Gate (EntityResolver.isValidEntityName())

Inspects candidate terms before persistence, rejecting stop words, grammatical prepositions, verb fragments, non-word gibberish, and editor syntax artifacts via 5 deterministic rules (see Stage 5).

Semantic Relationship Plausibility Matrix (EvidenceFusionEngine.js)

Enforces predicate compatibility rules:

  • Structural nodes (Note, Tag, Section) cannot engage in semantic domain relations.
  • COMMUNICATES_WITH requires communicating entity types (Person, Service, System, Technology).
  • IMPLEMENTS & GENERATES require valid technical sources and targets.

Evidence Provenance (EvidenceStore.js)

Every AI relationship links to an evidence record preserving exact source offsets, raw sentence text, extractor identity, and confidence score. Evidence records are content-addressed (SHA-256 hash key) and linked to relationships via the relationship_evidence junction table.

Post-Build Validation (GraphValidationEngine.js)

Runs automatically at the end of every full rebuild across 16 rules:

#RuleMetric
1Orphan non-structural entitiesorphans
2Confidence values out of bounds [0, 1]confidenceAnomalies
3Evidenceless neural extractor edgesevidencelessEdges
4Self-loops (source_id == target_id)selfLoops
5Duplicate edges (same source/target/type)duplicateEdges
6Type overloading (>20% Concept type)typeOverloading
7Star topology (single hub >15x avg degree)starTopology
8Missing workspace root nodemissingWorkspace
9Empty graphemptyGraph
10Low density (edges/nodes < 0.1)lowDensity
11Stale note_path references (file deleted)staleEntities
12FTS5 sync discrepancy vs. entities tablefts5SyncDiscrepancy
13Entities with unassigned community_idunassignedCommunities
14Dangling aliases (orphaned entity_id)danglingAliases
15Evidence coverage ratio (neural edges)evidenceCoverageRatio
16Duplicate entities sharing canonical nameduplicateEntities

Results are logged to ai-logs.db via LogDB.


Community Detection & Maintenance

  1. Label Propagation Clustering (CommunityDetector.js): Groups graph nodes into dense semantic communities using fast label propagation clustering. community_id is stored on each entity row.

  2. Self-Healing Background Maintenance (GraphMaintenance.js): Runs automatically when GraphWorker queue drains:

    • Orphan Purging: Deletes unlinked non-note entities.
    • Stale Edge Decay: Applies decay factor ($W \\times 0.95$) to relationships older than 30 days.
    • Alias Deduplication: Merges candidate duplicate entity mentions using vector distance and string similarity.
`); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("ai/knowledge-graph.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const knowledgeGraph = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + knowledgeGraph as default +}; diff --git a/docs-site/.vitepress/.temp/ai_setup.md.js b/docs-site/.vitepress/.temp/ai_setup.md.js new file mode 100644 index 00000000..a670ee3e --- /dev/null +++ b/docs-site/.vitepress/.temp/ai_setup.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Setting Up AI Providers","description":"Configure AI settings, API keys, local endpoints, and feature flags.","frontmatter":{"title":"Setting Up AI Providers","description":"Configure AI settings, API keys, local endpoints, and feature flags.","keywords":"AI settings, API key, OpenAI, Gemini, Groq, HuggingFace, ONNX, BGE embeddings","category":"AI"},"headers":[],"relativePath":"ai/setup.md","filePath":"ai/setup.md","lastUpdated":1786126353000}'); +const _sfc_main = { name: "ai/setup.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

AI Setup

Configure LLM provider models, API tokens, and local vector index settings inside AI → AI Settings.


1. Text Generation Providers

Notely connects to cloud and custom LLM providers using the Vercel AI SDK:

  • Google Gemini: Requires a Gemini API key. Default provider (gemini-2.0-flash), recommended for rich tool calling.
  • Groq: Requires a Groq API key (supports models like llama-3.3-70b-versatile, llama-3.1-8b-instant, deepseek-r1-distill-llama-70b).
  • OpenAI / OpenAI-Compatible: Connect to OpenAI (gpt-4o, gpt-4o-mini) or custom compatible endpoints by setting an API Key and custom Base URL.
  • Connection Diagnostics: Click the Test button next to any configured provider in AI Settings to verify connection status.

2. Embedding Index Setup

Vector embeddings enable Semantic Search and Context Retrieval:

  • Local BGE Model (Recommended): Runs entirely offline inside your app. Downloads a lightweight BGE-small-en-v1.5 ONNX model (~130MB) into %AppData%/notely/ai-model/ and runs vector calculations locally via onnxruntime-node.
  • HuggingFace API: Runs cloud-based embeddings using an API key token.

3. Knowledge Graph Engine

Relationship extraction and entity graph generation:

  • GLiNER2-Relex ONNX (Always Local): The Knowledge Graph uses a dedicated gliner2-multi-v1-onnx model running locally via ONNX Runtime. This is separate from your text generation provider — it runs entirely offline with no API key required and is not user-configurable.
  • Model Location: Downloaded automatically to %AppData%/notely/models/gliner2-relex/ on first graph build.
  • Confidence Threshold: Adjustable in AI Settings (graphConfidence, default 0.45–0.60). Higher values produce fewer but more precise relationships.

4. SQLite Database Locality

All AI databases are workspace-scoped and stored inside the hidden {workspace}/.notes-app/ folder to keep your data local and portable:

  1. ai-embeddings.db: Stores chunk text, line mappings, content hashes, and indexing queues.
  2. ai-graph.db: Stores extracted entity nodes and relationships.
  3. ai-memory.db: Stores conversation sessions, message logs, and persona configurations.
  4. ai-logs.db: Stores 5-stage execution traces, flow telemetry logs (FlowTracker), and prompt tracking payloads (LogDB).

PRAGMA journal_mode = WAL and synchronous = NORMAL are enabled across all databases for high performance without write blocks.

`); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("ai/setup.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const setup = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + setup as default +}; diff --git a/docs-site/.vitepress/.temp/app.js b/docs-site/.vitepress/.temp/app.js new file mode 100644 index 00000000..db484ac6 --- /dev/null +++ b/docs-site/.vitepress/.temp/app.js @@ -0,0 +1,5461 @@ +import { ssrRenderAttrs, ssrRenderSlot, ssrInterpolate, ssrRenderAttr, ssrRenderList, ssrRenderComponent, ssrRenderVNode, ssrRenderClass, renderToString } from "vue/server-renderer"; +import { shallowRef, inject, computed, ref, watch, onUnmounted, reactive, markRaw, readonly, nextTick, defineComponent, h, toRaw, onMounted, mergeProps, useSSRContext, unref, watchEffect, watchPostEffect, onUpdated, resolveComponent, createVNode, resolveDynamicComponent, withCtx, renderSlot, createTextVNode, toDisplayString, openBlock, createBlock, createCommentVNode, Fragment, renderList, defineAsyncComponent, provide, toHandlers, withKeys, onBeforeUnmount, useSlots, createSSRApp } from "vue"; +import mermaid from "mermaid"; +import { usePreferredDark, useDark, useMediaQuery, useWindowSize, onKeyStroke, useWindowScroll, useScrollLock } from "@vueuse/core"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const init = async (externalDiagrams) => { + try { + if (mermaid.registerExternalDiagrams) + await mermaid.registerExternalDiagrams(externalDiagrams); + } catch (e) { + console.error(e); + } +}; +const render$1 = async (id, code, config) => { + mermaid.initialize(config); + const { svg } = await mermaid.render(id, code); + return svg; +}; +function deserializeFunctions(r) { + return Array.isArray(r) ? r.map(deserializeFunctions) : typeof r == "object" && r !== null ? Object.keys(r).reduce((t, n) => (t[n] = deserializeFunctions(r[n]), t), {}) : typeof r == "string" && r.startsWith("_vp-fn_") ? new Function(`return ${r.slice(7)}`)() : r; +} +const siteData = deserializeFunctions(JSON.parse(`{"lang":"en-US","dir":"ltr","title":"Notely","description":"Documentation for Notely — the desktop Markdown notes app with Git version control, AI assistance, and P2P sync.","base":"/","head":[],"router":{"prefetchLinks":true},"appearance":false,"themeConfig":{"logo":"/assets/icon.png","siteTitle":"Notely","socialLinks":[{"icon":"github","link":"https://github.com/WGLabz/notely"}],"nav":[{"text":"Home","link":"/"},{"text":"Getting Started","link":"/getting-started/"},{"text":"Editor","link":"/editor/"},{"text":"Workspace","link":"/workspace/"},{"text":"Git","link":"/git/"},{"text":"AI","link":"/ai/"},{"text":"Download","link":"https://github.com/WGLabz/notely/releases/latest"}],"sidebar":[{"text":"Getting Started","collapsed":false,"items":[{"text":"Overview","link":"/getting-started/"},{"text":"Your First Note","link":"/getting-started/first-note"}]},{"text":"Editor","collapsed":false,"items":[{"text":"Editor Overview","link":"/editor/"},{"text":"Markdown Guide","link":"/editor/markdown-guide"},{"text":"Toolbar Reference","link":"/editor/markdown-toolbar"},{"text":"Code Blocks","link":"/editor/code-blocks"},{"text":"Tables","link":"/editor/tables"},{"text":"Diagrams","link":"/editor/diagrams"},{"text":"Focus Mode & Outline","link":"/editor/focus-mode"}]},{"text":"Search","collapsed":true,"items":[{"text":"Search","link":"/search"}]},{"text":"Workspace","collapsed":false,"items":[{"text":"Workspace Overview","link":"/workspace/"},{"text":"Tasks","link":"/workspace/tasks"},{"text":"Calendar","link":"/workspace/calendar"},{"text":"Media","link":"/workspace/media"},{"text":"Screen Capture","link":"/workspace/screen-capture"},{"text":"Workspace Graph","link":"/workspace/graph"},{"text":"Downloads & History","link":"/workspace/downloads"},{"text":"Export","link":"/workspace/export"}]},{"text":"Export & Import","collapsed":false,"items":[{"text":"Export Reference","link":"/export-reference"},{"text":"Downloads Manager","link":"/workspace/downloads"},{"text":"Website View","link":"/web-view"},{"text":"Note Packages","link":"/export-import"}]},{"text":"Git Version Control","collapsed":false,"items":[{"text":"Git Overview","link":"/git/"},{"text":"Setup & Repository","link":"/git/setup"},{"text":"Commit & Stage","link":"/git/commit"},{"text":"History & Restore","link":"/git/history"},{"text":"Branches & Remote","link":"/git/branches"}]},{"text":"AI Features","collapsed":false,"items":[{"text":"AI Overview","link":"/ai/"},{"text":"AI Setup","link":"/ai/setup"},{"text":"AI Features","link":"/ai/features"},{"text":"AI Architecture","link":"/ai/architecture"},{"text":"Knowledge Graph Engine","link":"/ai/knowledge-graph"}]},{"text":"Sync","collapsed":true,"items":[{"text":"P2P Sync","link":"/sync/"}]},{"text":"Reference","collapsed":false,"items":[{"text":"Settings","link":"/settings-reference"},{"text":"Keyboard Shortcuts","link":"/keyboard-shortcuts"},{"text":"Feature Availability","link":"/feature-availability"}]},{"text":"Help","collapsed":false,"items":[{"text":"Troubleshooting","link":"/troubleshooting"},{"text":"FAQ","link":"/faq"},{"text":"Release Notes","link":"/release-notes"}]},{"text":"Developer","collapsed":true,"items":[{"text":"Developer Docs","link":"/developer/"},{"text":"Application Architecture","link":"/architecture"},{"text":"License","link":"/license"}]}],"search":{"provider":"local","options":{"miniSearch":{"options":{"tokenize":"_vp-fn_(text) => text.split(/[\\\\s\\\\-_/]+/).filter(Boolean)"},"searchOptions":{"fuzzy":0.2,"prefix":true,"boost":{"title":4,"text":2,"titles":1}}},"detailedView":true}},"editLink":{"pattern":"https://github.com/WGLabz/notely/edit/main/docs/:path","text":"Edit this page on GitHub"},"footer":{"message":"Released under the CC-BY-NC-4.0 License.","copyright":"Copyright © 2026 WGLabz"},"lastUpdated":{"text":"Last updated","formatOptions":{"dateStyle":"medium"}},"docFooter":{"prev":"← Previous","next":"Next →"},"outline":{"level":[2,3],"label":"On this page"}},"locales":{},"scrollOffset":134,"cleanUrls":false}`)); +const __vite_import_meta_env__ = {}; +const EXTERNAL_URL_RE = /^(?:[a-z]+:|\/\/)/i; +const APPEARANCE_KEY = "vitepress-theme-appearance"; +const HASH_RE = /#.*$/; +const HASH_OR_QUERY_RE = /[?#].*$/; +const INDEX_OR_EXT_RE = /(?:(^|\/)index)?\.(?:md|html)$/; +const inBrowser = typeof document !== "undefined"; +const notFoundPageData = { + relativePath: "404.md", + filePath: "", + title: "404", + description: "Not Found", + headers: [], + frontmatter: { sidebar: false, layout: "page" }, + lastUpdated: 0, + isNotFound: true +}; +function isActive(currentPath, matchPath, asRegex = false) { + if (matchPath === void 0) { + return false; + } + currentPath = normalize(`/${currentPath}`); + if (asRegex) { + return new RegExp(matchPath).test(currentPath); + } + if (normalize(matchPath) !== currentPath) { + return false; + } + const hashMatch = matchPath.match(HASH_RE); + if (hashMatch) { + return (inBrowser ? location.hash : "") === hashMatch[0]; + } + return true; +} +function normalize(path) { + return decodeURI(path).replace(HASH_OR_QUERY_RE, "").replace(INDEX_OR_EXT_RE, "$1"); +} +function isExternal(path) { + return EXTERNAL_URL_RE.test(path); +} +function getLocaleForPath(siteData2, relativePath) { + return Object.keys((siteData2 == null ? void 0 : siteData2.locales) || {}).find((key) => key !== "root" && !isExternal(key) && isActive(relativePath, `/${key}/`, true)) || "root"; +} +function resolveSiteDataByRoute(siteData2, relativePath) { + var _a, _b, _c, _d, _e, _f, _g; + const localeIndex = getLocaleForPath(siteData2, relativePath); + return Object.assign({}, siteData2, { + localeIndex, + lang: ((_a = siteData2.locales[localeIndex]) == null ? void 0 : _a.lang) ?? siteData2.lang, + dir: ((_b = siteData2.locales[localeIndex]) == null ? void 0 : _b.dir) ?? siteData2.dir, + title: ((_c = siteData2.locales[localeIndex]) == null ? void 0 : _c.title) ?? siteData2.title, + titleTemplate: ((_d = siteData2.locales[localeIndex]) == null ? void 0 : _d.titleTemplate) ?? siteData2.titleTemplate, + description: ((_e = siteData2.locales[localeIndex]) == null ? void 0 : _e.description) ?? siteData2.description, + head: mergeHead(siteData2.head, ((_f = siteData2.locales[localeIndex]) == null ? void 0 : _f.head) ?? []), + themeConfig: { + ...siteData2.themeConfig, + ...(_g = siteData2.locales[localeIndex]) == null ? void 0 : _g.themeConfig + } + }); +} +function createTitle(siteData2, pageData) { + const title = pageData.title || siteData2.title; + const template = pageData.titleTemplate ?? siteData2.titleTemplate; + if (typeof template === "string" && template.includes(":title")) { + return template.replace(/:title/g, title); + } + const templateString = createTitleTemplate(siteData2.title, template); + if (title === templateString.slice(3)) { + return title; + } + return `${title}${templateString}`; +} +function createTitleTemplate(siteTitle, template) { + if (template === false) { + return ""; + } + if (template === true || template === void 0) { + return ` | ${siteTitle}`; + } + if (siteTitle === template) { + return ""; + } + return ` | ${template}`; +} +function hasTag(head, tag) { + const [tagType, tagAttrs] = tag; + if (tagType !== "meta") + return false; + const keyAttr = Object.entries(tagAttrs)[0]; + if (keyAttr == null) + return false; + return head.some(([type, attrs]) => type === tagType && attrs[keyAttr[0]] === keyAttr[1]); +} +function mergeHead(prev, curr) { + return [...prev.filter((tagAttrs) => !hasTag(curr, tagAttrs)), ...curr]; +} +const INVALID_CHAR_REGEX = /[\u0000-\u001F"#$&*+,:;<=>?[\]^`{|}\u007F]/g; +const DRIVE_LETTER_REGEX = /^[a-z]:/i; +function sanitizeFileName(name) { + const match = DRIVE_LETTER_REGEX.exec(name); + const driveLetter = match ? match[0] : ""; + return driveLetter + name.slice(driveLetter.length).replace(INVALID_CHAR_REGEX, "_").replace(/(^|\/)_+(?=[^/]*$)/, "$1"); +} +const KNOWN_EXTENSIONS = /* @__PURE__ */ new Set(); +function treatAsHtml(filename) { + var _a; + if (KNOWN_EXTENSIONS.size === 0) { + const extraExts = typeof process === "object" && ((_a = process.env) == null ? void 0 : _a.VITE_EXTRA_EXTENSIONS) || (__vite_import_meta_env__ == null ? void 0 : __vite_import_meta_env__.VITE_EXTRA_EXTENSIONS) || ""; + ("3g2,3gp,aac,ai,apng,au,avif,bin,bmp,cer,class,conf,crl,css,csv,dll,doc,eps,epub,exe,gif,gz,ics,ief,jar,jpe,jpeg,jpg,js,json,jsonld,m4a,man,mid,midi,mjs,mov,mp2,mp3,mp4,mpe,mpeg,mpg,mpp,oga,ogg,ogv,ogx,opus,otf,p10,p7c,p7m,p7s,pdf,png,ps,qt,roff,rtf,rtx,ser,svg,t,tif,tiff,tr,ts,tsv,ttf,txt,vtt,wav,weba,webm,webp,woff,woff2,xhtml,xml,yaml,yml,zip" + (extraExts && typeof extraExts === "string" ? "," + extraExts : "")).split(",").forEach((ext2) => KNOWN_EXTENSIONS.add(ext2)); + } + const ext = filename.split(".").pop(); + return ext == null || !KNOWN_EXTENSIONS.has(ext.toLowerCase()); +} +function escapeRegExp(str) { + return str.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d"); +} +const dataSymbol = Symbol(); +const siteDataRef = shallowRef(siteData); +function initData(route) { + const site = computed(() => resolveSiteDataByRoute(siteDataRef.value, route.data.relativePath)); + const appearance = site.value.appearance; + const isDark = appearance === "force-dark" ? ref(true) : appearance === "force-auto" ? usePreferredDark() : appearance ? useDark({ + storageKey: APPEARANCE_KEY, + initialValue: () => appearance === "dark" ? "dark" : "auto", + ...typeof appearance === "object" ? appearance : {} + }) : ref(false); + const hashRef = ref(inBrowser ? location.hash : ""); + if (inBrowser) { + window.addEventListener("hashchange", () => { + hashRef.value = location.hash; + }); + } + watch(() => route.data, () => { + hashRef.value = inBrowser ? location.hash : ""; + }); + return { + site, + theme: computed(() => site.value.themeConfig), + page: computed(() => route.data), + frontmatter: computed(() => route.data.frontmatter), + params: computed(() => route.data.params), + lang: computed(() => site.value.lang), + dir: computed(() => route.data.frontmatter.dir || site.value.dir), + localeIndex: computed(() => site.value.localeIndex || "root"), + title: computed(() => createTitle(site.value, route.data)), + description: computed(() => route.data.description || site.value.description), + isDark, + hash: computed(() => hashRef.value) + }; +} +function useData$1() { + const data = inject(dataSymbol); + if (!data) { + throw new Error("vitepress data not properly injected in app"); + } + return data; +} +function joinPath(base, path) { + return `${base}${path}`.replace(/\/+/g, "/"); +} +function withBase(path) { + return EXTERNAL_URL_RE.test(path) || !path.startsWith("/") ? path : joinPath(siteDataRef.value.base, path); +} +function pathToFile(path) { + let pagePath = path.replace(/\.html$/, ""); + pagePath = decodeURIComponent(pagePath); + pagePath = pagePath.replace(/\/$/, "/index"); + { + if (inBrowser) { + const base = "/"; + pagePath = sanitizeFileName(pagePath.slice(base.length).replace(/\//g, "_") || "index") + ".md"; + let pageHash = __VP_HASH_MAP__[pagePath.toLowerCase()]; + if (!pageHash) { + pagePath = pagePath.endsWith("_index.md") ? pagePath.slice(0, -9) + ".md" : pagePath.slice(0, -3) + "_index.md"; + pageHash = __VP_HASH_MAP__[pagePath.toLowerCase()]; + } + if (!pageHash) + return null; + pagePath = `${base}${"assets"}/${pagePath}.${pageHash}.js`; + } else { + pagePath = `./${sanitizeFileName(pagePath.slice(1).replace(/\//g, "_"))}.md.js`; + } + } + return pagePath; +} +let contentUpdatedCallbacks = []; +function onContentUpdated(fn) { + contentUpdatedCallbacks.push(fn); + onUnmounted(() => { + contentUpdatedCallbacks = contentUpdatedCallbacks.filter((f) => f !== fn); + }); +} +function getScrollOffset() { + let scrollOffset = siteDataRef.value.scrollOffset; + let offset = 0; + let padding = 24; + if (typeof scrollOffset === "object" && "padding" in scrollOffset) { + padding = scrollOffset.padding; + scrollOffset = scrollOffset.selector; + } + if (typeof scrollOffset === "number") { + offset = scrollOffset; + } else if (typeof scrollOffset === "string") { + offset = tryOffsetSelector(scrollOffset, padding); + } else if (Array.isArray(scrollOffset)) { + for (const selector of scrollOffset) { + const res = tryOffsetSelector(selector, padding); + if (res) { + offset = res; + break; + } + } + } + return offset; +} +function tryOffsetSelector(selector, padding) { + const el = document.querySelector(selector); + if (!el) + return 0; + const bot = el.getBoundingClientRect().bottom; + if (bot < 0) + return 0; + return bot + padding; +} +const RouterSymbol = Symbol(); +const fakeHost = "http://a.com"; +const getDefaultRoute = () => ({ + path: "/", + component: null, + data: notFoundPageData +}); +function createRouter(loadPageModule, fallbackComponent) { + const route = reactive(getDefaultRoute()); + const router = { + route, + go + }; + async function go(href = inBrowser ? location.href : "/") { + var _a, _b; + href = normalizeHref(href); + if (await ((_a = router.onBeforeRouteChange) == null ? void 0 : _a.call(router, href)) === false) + return; + if (inBrowser && href !== normalizeHref(location.href)) { + history.replaceState({ scrollPosition: window.scrollY }, ""); + history.pushState({}, "", href); + } + await loadPage(href); + await ((_b = router.onAfterRouteChange ?? router.onAfterRouteChanged) == null ? void 0 : _b(href)); + } + let latestPendingPath = null; + async function loadPage(href, scrollPosition = 0, isRetry = false) { + var _a, _b; + if (await ((_a = router.onBeforePageLoad) == null ? void 0 : _a.call(router, href)) === false) + return; + const targetLoc = new URL(href, fakeHost); + const pendingPath = latestPendingPath = targetLoc.pathname; + try { + let page = await loadPageModule(pendingPath); + if (!page) { + throw new Error(`Page not found: ${pendingPath}`); + } + if (latestPendingPath === pendingPath) { + latestPendingPath = null; + const { default: comp, __pageData } = page; + if (!comp) { + throw new Error(`Invalid route component: ${comp}`); + } + await ((_b = router.onAfterPageLoad) == null ? void 0 : _b.call(router, href)); + route.path = inBrowser ? pendingPath : withBase(pendingPath); + route.component = markRaw(comp); + route.data = true ? markRaw(__pageData) : readonly(__pageData); + if (inBrowser) { + nextTick(() => { + let actualPathname = siteDataRef.value.base + __pageData.relativePath.replace(/(?:(^|\/)index)?\.md$/, "$1"); + if (!siteDataRef.value.cleanUrls && !actualPathname.endsWith("/")) { + actualPathname += ".html"; + } + if (actualPathname !== targetLoc.pathname) { + targetLoc.pathname = actualPathname; + href = actualPathname + targetLoc.search + targetLoc.hash; + history.replaceState({}, "", href); + } + if (targetLoc.hash && !scrollPosition) { + let target = null; + try { + target = document.getElementById(decodeURIComponent(targetLoc.hash).slice(1)); + } catch (e) { + console.warn(e); + } + if (target) { + scrollTo(target, targetLoc.hash); + return; + } + } + window.scrollTo(0, scrollPosition); + }); + } + } + } catch (err) { + if (!/fetch|Page not found/.test(err.message) && !/^\/404(\.html|\/)?$/.test(href)) { + console.error(err); + } + if (!isRetry) { + try { + const res = await fetch(siteDataRef.value.base + "hashmap.json"); + window.__VP_HASH_MAP__ = await res.json(); + await loadPage(href, scrollPosition, true); + return; + } catch (e) { + } + } + if (latestPendingPath === pendingPath) { + latestPendingPath = null; + route.path = inBrowser ? pendingPath : withBase(pendingPath); + route.component = fallbackComponent ? markRaw(fallbackComponent) : null; + const relativePath = inBrowser ? pendingPath.replace(/(^|\/)$/, "$1index").replace(/(\.html)?$/, ".md").replace(/^\//, "") : "404.md"; + route.data = { ...notFoundPageData, relativePath }; + } + } + } + if (inBrowser) { + if (history.state === null) { + history.replaceState({}, ""); + } + window.addEventListener("click", (e) => { + if (e.defaultPrevented || !(e.target instanceof Element) || e.target.closest("button") || // temporary fix for docsearch action buttons + e.button !== 0 || e.ctrlKey || e.shiftKey || e.altKey || e.metaKey) + return; + const link2 = e.target.closest("a"); + if (!link2 || link2.closest(".vp-raw") || link2.hasAttribute("download") || link2.hasAttribute("target")) + return; + const linkHref = link2.getAttribute("href") ?? (link2 instanceof SVGAElement ? link2.getAttribute("xlink:href") : null); + if (linkHref == null) + return; + const { href, origin, pathname, hash, search } = new URL(linkHref, link2.baseURI); + const currentUrl = new URL(location.href); + if (origin === currentUrl.origin && treatAsHtml(pathname)) { + e.preventDefault(); + if (pathname === currentUrl.pathname && search === currentUrl.search) { + if (hash !== currentUrl.hash) { + history.pushState({}, "", href); + window.dispatchEvent(new HashChangeEvent("hashchange", { + oldURL: currentUrl.href, + newURL: href + })); + } + if (hash) { + scrollTo(link2, hash, link2.classList.contains("header-anchor")); + } else { + window.scrollTo(0, 0); + } + } else { + go(href); + } + } + }, { capture: true }); + window.addEventListener("popstate", async (e) => { + var _a; + if (e.state === null) + return; + const href = normalizeHref(location.href); + await loadPage(href, e.state && e.state.scrollPosition || 0); + await ((_a = router.onAfterRouteChange ?? router.onAfterRouteChanged) == null ? void 0 : _a(href)); + }); + window.addEventListener("hashchange", (e) => { + e.preventDefault(); + }); + } + return router; +} +function useRouter() { + const router = inject(RouterSymbol); + if (!router) { + throw new Error("useRouter() is called without provider."); + } + return router; +} +function useRoute() { + return useRouter().route; +} +function scrollTo(el, hash, smooth = false) { + let target = null; + try { + target = el.classList.contains("header-anchor") ? el : document.getElementById(decodeURIComponent(hash).slice(1)); + } catch (e) { + console.warn(e); + } + if (target) { + let scrollToTarget = function() { + if (!smooth || Math.abs(targetTop - window.scrollY) > window.innerHeight) + window.scrollTo(0, targetTop); + else + window.scrollTo({ left: 0, top: targetTop, behavior: "smooth" }); + }; + const targetPadding = parseInt(window.getComputedStyle(target).paddingTop, 10); + const targetTop = window.scrollY + target.getBoundingClientRect().top - getScrollOffset() + targetPadding; + requestAnimationFrame(scrollToTarget); + } +} +function normalizeHref(href) { + const url = new URL(href, fakeHost); + url.pathname = url.pathname.replace(/(^|\/)index(\.html)?$/, "$1"); + if (siteDataRef.value.cleanUrls) + url.pathname = url.pathname.replace(/\.html$/, ""); + else if (!url.pathname.endsWith("/") && !url.pathname.endsWith(".html")) + url.pathname += ".html"; + return url.pathname + url.search + url.hash; +} +const runCbs = () => contentUpdatedCallbacks.forEach((fn) => fn()); +const Content = defineComponent({ + name: "VitePressContent", + props: { + as: { type: [Object, String], default: "div" } + }, + setup(props) { + const route = useRoute(); + const { frontmatter, site } = useData$1(); + watch(frontmatter, runCbs, { deep: true, flush: "post" }); + return () => h(props.as, site.value.contentProps ?? { style: { position: "relative" } }, [ + route.component ? h(route.component, { + onVnodeMounted: runCbs, + onVnodeUpdated: runCbs, + onVnodeUnmounted: runCbs + }) : "404 Page Not Found" + ]); + } +}); +const _sfc_main$19 = { + __name: "Mermaid", + __ssrInlineRender: true, + props: { + graph: { + type: String, + required: true + }, + id: { + type: String, + required: true + }, + class: { + type: String, + required: false, + default: "mermaid" + } + }, + setup(__props) { + const pluginSettings = ref({ + securityLevel: "loose", + startOnLoad: false, + externalDiagrams: [] + }); + const { page } = useData$1(); + const { frontmatter } = toRaw(page.value); + const mermaidPageTheme = frontmatter.mermaidTheme || ""; + const props = __props; + const svg = ref(null); + let mut = null; + onMounted(async () => { + var _a; + await init(pluginSettings.value.externalDiagrams); + let settings = await import("./virtual_mermaid-config.CM0F1BUC.js"); + if (settings == null ? void 0 : settings.default) pluginSettings.value = settings.default; + mut = new MutationObserver(async () => await renderChart()); + mut.observe(document.documentElement, { attributes: true }); + await renderChart(); + const hasImages = ((_a = //.exec(decodeURIComponent(props.graph))) == null ? void 0 : _a.length) > 0; + if (hasImages) + setTimeout(() => { + let imgElements = document.getElementsByTagName("img"); + let imgs = Array.from(imgElements); + if (imgs.length) { + Promise.all( + imgs.filter((img) => !img.complete).map( + (img) => new Promise((resolve) => { + img.onload = img.onerror = resolve; + }) + ) + ).then(async () => { + await renderChart(); + }); + } + }, 100); + }); + onUnmounted(() => mut.disconnect()); + const renderChart = async () => { + const hasDarkClass = document.documentElement.classList.contains("dark"); + let mermaidConfig = { + ...pluginSettings.value + }; + if (mermaidPageTheme) mermaidConfig.theme = mermaidPageTheme; + if (hasDarkClass) mermaidConfig.theme = "dark"; + let svgCode = await render$1( + props.id, + decodeURIComponent(props.graph), + mermaidConfig + ); + const salt = Math.random().toString(36).substring(7); + svg.value = `${svgCode} ${salt}`; + }; + return (_ctx, _push, _parent, _attrs) => { + _push(`${svg.value ?? ""}`); + }; + } +}; +const _sfc_setup$19 = _sfc_main$19.setup; +_sfc_main$19.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress-plugin-mermaid/dist/Mermaid.vue"); + return _sfc_setup$19 ? _sfc_setup$19(props, ctx) : void 0; +}; +const _sfc_main$18 = /* @__PURE__ */ defineComponent({ + __name: "VPBadge", + __ssrInlineRender: true, + props: { + text: {}, + type: { default: "tip" } + }, + setup(__props) { + return (_ctx, _push, _parent, _attrs) => { + _push(``); + ssrRenderSlot(_ctx.$slots, "default", {}, () => { + _push(`${ssrInterpolate(__props.text)}`); + }, _push, _parent); + _push(``); + }; + } +}); +const _sfc_setup$18 = _sfc_main$18.setup; +_sfc_main$18.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue"); + return _sfc_setup$18 ? _sfc_setup$18(props, ctx) : void 0; +}; +const _sfc_main$17 = /* @__PURE__ */ defineComponent({ + __name: "VPBackdrop", + __ssrInlineRender: true, + props: { + show: { type: Boolean } + }, + setup(__props) { + return (_ctx, _push, _parent, _attrs) => { + if (__props.show) { + _push(``); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$17 = _sfc_main$17.setup; +_sfc_main$17.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPBackdrop.vue"); + return _sfc_setup$17 ? _sfc_setup$17(props, ctx) : void 0; +}; +const VPBackdrop = /* @__PURE__ */ _export_sfc(_sfc_main$17, [["__scopeId", "data-v-c79a1216"]]); +const useData = useData$1; +function throttleAndDebounce(fn, delay) { + let timeoutId; + let called = false; + return () => { + if (timeoutId) + clearTimeout(timeoutId); + if (!called) { + fn(); + (called = true) && setTimeout(() => called = false, delay); + } else + timeoutId = setTimeout(fn, delay); + }; +} +function ensureStartingSlash(path) { + return path.startsWith("/") ? path : `/${path}`; +} +function normalizeLink$1(url) { + const { pathname, search, hash, protocol } = new URL(url, "http://a.com"); + if (isExternal(url) || url.startsWith("#") || !protocol.startsWith("http") || !treatAsHtml(pathname)) + return url; + const { site } = useData(); + const normalizedPath = pathname.endsWith("/") || pathname.endsWith(".html") ? url : url.replace(/(?:(^\.+)\/)?.*$/, `$1${pathname.replace(/(\.md)?$/, site.value.cleanUrls ? "" : ".html")}${search}${hash}`); + return withBase(normalizedPath); +} +function useLangs({ correspondingLink = false } = {}) { + const { site, localeIndex, page, theme: theme2, hash } = useData(); + const currentLang = computed(() => { + var _a, _b; + return { + label: (_a = site.value.locales[localeIndex.value]) == null ? void 0 : _a.label, + link: ((_b = site.value.locales[localeIndex.value]) == null ? void 0 : _b.link) || (localeIndex.value === "root" ? "/" : `/${localeIndex.value}/`) + }; + }); + const localeLinks = computed(() => Object.entries(site.value.locales).flatMap(([key, value]) => currentLang.value.label === value.label ? [] : { + text: value.label, + link: normalizeLink(value.link || (key === "root" ? "/" : `/${key}/`), theme2.value.i18nRouting !== false && correspondingLink, page.value.relativePath.slice(currentLang.value.link.length - 1), !site.value.cleanUrls) + hash.value + })); + return { localeLinks, currentLang }; +} +function normalizeLink(link2, addPath, path, addExt) { + return addPath ? link2.replace(/\/$/, "") + ensureStartingSlash(path.replace(/(^|\/)index\.md$/, "$1").replace(/\.md$/, addExt ? ".html" : "")) : link2; +} +const _sfc_main$16 = /* @__PURE__ */ defineComponent({ + __name: "NotFound", + __ssrInlineRender: true, + setup(__props) { + const { theme: theme2 } = useData(); + const { currentLang } = useLangs(); + return (_ctx, _push, _parent, _attrs) => { + var _a, _b, _c, _d, _e; + _push(`

${ssrInterpolate(((_a = unref(theme2).notFound) == null ? void 0 : _a.code) ?? "404")}

${ssrInterpolate(((_b = unref(theme2).notFound) == null ? void 0 : _b.title) ?? "PAGE NOT FOUND")}

${ssrInterpolate(((_c = unref(theme2).notFound) == null ? void 0 : _c.quote) ?? "But if you don't change your direction, and if you keep looking, you may end up where you are heading.")}
`); + }; + } +}); +const _sfc_setup$16 = _sfc_main$16.setup; +_sfc_main$16.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/NotFound.vue"); + return _sfc_setup$16 ? _sfc_setup$16(props, ctx) : void 0; +}; +const NotFound = /* @__PURE__ */ _export_sfc(_sfc_main$16, [["__scopeId", "data-v-d6be1790"]]); +function getSidebar(_sidebar, path) { + if (Array.isArray(_sidebar)) + return addBase(_sidebar); + if (_sidebar == null) + return []; + path = ensureStartingSlash(path); + const dir = Object.keys(_sidebar).sort((a, b) => { + return b.split("/").length - a.split("/").length; + }).find((dir2) => { + return path.startsWith(ensureStartingSlash(dir2)); + }); + const sidebar = dir ? _sidebar[dir] : []; + return Array.isArray(sidebar) ? addBase(sidebar) : addBase(sidebar.items, sidebar.base); +} +function getSidebarGroups(sidebar) { + const groups = []; + let lastGroupIndex = 0; + for (const index in sidebar) { + const item = sidebar[index]; + if (item.items) { + lastGroupIndex = groups.push(item); + continue; + } + if (!groups[lastGroupIndex]) { + groups.push({ items: [] }); + } + groups[lastGroupIndex].items.push(item); + } + return groups; +} +function getFlatSideBarLinks(sidebar) { + const links = []; + function recursivelyExtractLinks(items) { + for (const item of items) { + if (item.text && item.link) { + links.push({ + text: item.text, + link: item.link, + docFooterText: item.docFooterText + }); + } + if (item.items) { + recursivelyExtractLinks(item.items); + } + } + } + recursivelyExtractLinks(sidebar); + return links; +} +function hasActiveLink(path, items) { + if (Array.isArray(items)) { + return items.some((item) => hasActiveLink(path, item)); + } + return isActive(path, items.link) ? true : items.items ? hasActiveLink(path, items.items) : false; +} +function addBase(items, _base) { + return [...items].map((_item) => { + const item = { ..._item }; + const base = item.base || _base; + if (base && item.link) + item.link = base + item.link; + if (item.items) + item.items = addBase(item.items, base); + return item; + }); +} +function useSidebar() { + const { frontmatter, page, theme: theme2 } = useData(); + const is960 = useMediaQuery("(min-width: 960px)"); + const isOpen = ref(false); + const _sidebar = computed(() => { + const sidebarConfig = theme2.value.sidebar; + const relativePath = page.value.relativePath; + return sidebarConfig ? getSidebar(sidebarConfig, relativePath) : []; + }); + const sidebar = ref(_sidebar.value); + watch(_sidebar, (next, prev) => { + if (JSON.stringify(next) !== JSON.stringify(prev)) + sidebar.value = _sidebar.value; + }); + const hasSidebar = computed(() => { + return frontmatter.value.sidebar !== false && sidebar.value.length > 0 && frontmatter.value.layout !== "home"; + }); + const leftAside = computed(() => { + if (hasAside) + return frontmatter.value.aside == null ? theme2.value.aside === "left" : frontmatter.value.aside === "left"; + return false; + }); + const hasAside = computed(() => { + if (frontmatter.value.layout === "home") + return false; + if (frontmatter.value.aside != null) + return !!frontmatter.value.aside; + return theme2.value.aside !== false; + }); + const isSidebarEnabled = computed(() => hasSidebar.value && is960.value); + const sidebarGroups = computed(() => { + return hasSidebar.value ? getSidebarGroups(sidebar.value) : []; + }); + function open() { + isOpen.value = true; + } + function close() { + isOpen.value = false; + } + function toggle() { + isOpen.value ? close() : open(); + } + return { + isOpen, + sidebar, + sidebarGroups, + hasSidebar, + hasAside, + leftAside, + isSidebarEnabled, + open, + close, + toggle + }; +} +function useCloseSidebarOnEscape(isOpen, close) { + let triggerElement; + watchEffect(() => { + triggerElement = isOpen.value ? document.activeElement : void 0; + }); + onMounted(() => { + window.addEventListener("keyup", onEscape); + }); + onUnmounted(() => { + window.removeEventListener("keyup", onEscape); + }); + function onEscape(e) { + if (e.key === "Escape" && isOpen.value) { + close(); + triggerElement == null ? void 0 : triggerElement.focus(); + } + } +} +function useSidebarControl(item) { + const { page, hash } = useData(); + const collapsed = ref(false); + const collapsible = computed(() => { + return item.value.collapsed != null; + }); + const isLink = computed(() => { + return !!item.value.link; + }); + const isActiveLink = ref(false); + const updateIsActiveLink = () => { + isActiveLink.value = isActive(page.value.relativePath, item.value.link); + }; + watch([page, item, hash], updateIsActiveLink); + onMounted(updateIsActiveLink); + const hasActiveLink$1 = computed(() => { + if (isActiveLink.value) { + return true; + } + return item.value.items ? hasActiveLink(page.value.relativePath, item.value.items) : false; + }); + const hasChildren = computed(() => { + return !!(item.value.items && item.value.items.length); + }); + watchEffect(() => { + collapsed.value = !!(collapsible.value && item.value.collapsed); + }); + watchPostEffect(() => { + (isActiveLink.value || hasActiveLink$1.value) && (collapsed.value = false); + }); + function toggle() { + if (collapsible.value) { + collapsed.value = !collapsed.value; + } + } + return { + collapsed, + collapsible, + isLink, + isActiveLink, + hasActiveLink: hasActiveLink$1, + hasChildren, + toggle + }; +} +function useAside() { + const { hasSidebar } = useSidebar(); + const is960 = useMediaQuery("(min-width: 960px)"); + const is1280 = useMediaQuery("(min-width: 1280px)"); + const isAsideEnabled = computed(() => { + if (!is1280.value && !is960.value) { + return false; + } + return hasSidebar.value ? is1280.value : is960.value; + }); + return { + isAsideEnabled + }; +} +const ignoreRE = /\b(?:VPBadge|header-anchor|footnote-ref|ignore-header)\b/; +const resolvedHeaders = []; +function resolveTitle(theme2) { + return typeof theme2.outline === "object" && !Array.isArray(theme2.outline) && theme2.outline.label || theme2.outlineTitle || "On this page"; +} +function getHeaders(range) { + const headers = [ + ...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)") + ].filter((el) => el.id && el.hasChildNodes()).map((el) => { + const level = Number(el.tagName[1]); + return { + element: el, + title: serializeHeader(el), + link: "#" + el.id, + level + }; + }); + return resolveHeaders(headers, range); +} +function serializeHeader(h2) { + let ret = ""; + for (const node of h2.childNodes) { + if (node.nodeType === 1) { + if (ignoreRE.test(node.className)) + continue; + ret += node.textContent; + } else if (node.nodeType === 3) { + ret += node.textContent; + } + } + return ret.trim(); +} +function resolveHeaders(headers, range) { + if (range === false) { + return []; + } + const levelsRange = (typeof range === "object" && !Array.isArray(range) ? range.level : range) || 2; + const [high, low] = typeof levelsRange === "number" ? [levelsRange, levelsRange] : levelsRange === "deep" ? [2, 6] : levelsRange; + return buildTree(headers, high, low); +} +function useActiveAnchor(container, marker) { + const { isAsideEnabled } = useAside(); + const onScroll = throttleAndDebounce(setActiveLink, 100); + let prevActiveLink = null; + onMounted(() => { + requestAnimationFrame(setActiveLink); + window.addEventListener("scroll", onScroll); + }); + onUpdated(() => { + activateLink(location.hash); + }); + onUnmounted(() => { + window.removeEventListener("scroll", onScroll); + }); + function setActiveLink() { + if (!isAsideEnabled.value) { + return; + } + const scrollY = window.scrollY; + const innerHeight = window.innerHeight; + const offsetHeight = document.body.offsetHeight; + const isBottom = Math.abs(scrollY + innerHeight - offsetHeight) < 1; + const headers = resolvedHeaders.map(({ element, link: link2 }) => ({ + link: link2, + top: getAbsoluteTop(element) + })).filter(({ top }) => !Number.isNaN(top)).sort((a, b) => a.top - b.top); + if (!headers.length) { + activateLink(null); + return; + } + if (scrollY < 1) { + activateLink(null); + return; + } + if (isBottom) { + activateLink(headers[headers.length - 1].link); + return; + } + let activeLink = null; + for (const { link: link2, top } of headers) { + if (top > scrollY + getScrollOffset() + 4) { + break; + } + activeLink = link2; + } + activateLink(activeLink); + } + function activateLink(hash) { + if (prevActiveLink) { + prevActiveLink.classList.remove("active"); + } + if (hash == null) { + prevActiveLink = null; + } else { + prevActiveLink = container.value.querySelector(`a[href="${decodeURIComponent(hash)}"]`); + } + const activeLink = prevActiveLink; + if (activeLink) { + activeLink.classList.add("active"); + marker.value.style.top = activeLink.offsetTop + 39 + "px"; + marker.value.style.opacity = "1"; + } else { + marker.value.style.top = "33px"; + marker.value.style.opacity = "0"; + } + } +} +function getAbsoluteTop(element) { + let offsetTop = 0; + while (element !== document.body) { + if (element === null) { + return NaN; + } + offsetTop += element.offsetTop; + element = element.offsetParent; + } + return offsetTop; +} +function buildTree(data, min, max) { + resolvedHeaders.length = 0; + const result = []; + const stack = []; + data.forEach((item) => { + const node = { ...item, children: [] }; + let parent = stack[stack.length - 1]; + while (parent && parent.level >= node.level) { + stack.pop(); + parent = stack[stack.length - 1]; + } + if (node.element.classList.contains("ignore-header") || parent && "shouldIgnore" in parent) { + stack.push({ level: node.level, shouldIgnore: true }); + return; + } + if (node.level > max || node.level < min) + return; + resolvedHeaders.push({ element: node.element, link: node.link }); + if (parent) + parent.children.push(node); + else + result.push(node); + stack.push(node); + }); + return result; +} +const _sfc_main$15 = /* @__PURE__ */ defineComponent({ + __name: "VPDocOutlineItem", + __ssrInlineRender: true, + props: { + headers: {}, + root: { type: Boolean } + }, + setup(__props) { + return (_ctx, _push, _parent, _attrs) => { + const _component_VPDocOutlineItem = resolveComponent("VPDocOutlineItem", true); + _push(``); + ssrRenderList(__props.headers, ({ children, link: link2, title }) => { + _push(`
  • ${ssrInterpolate(title)}`); + if (children == null ? void 0 : children.length) { + _push(ssrRenderComponent(_component_VPDocOutlineItem, { headers: children }, null, _parent)); + } else { + _push(``); + } + _push(`
  • `); + }); + _push(``); + }; + } +}); +const _sfc_setup$15 = _sfc_main$15.setup; +_sfc_main$15.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPDocOutlineItem.vue"); + return _sfc_setup$15 ? _sfc_setup$15(props, ctx) : void 0; +}; +const VPDocOutlineItem = /* @__PURE__ */ _export_sfc(_sfc_main$15, [["__scopeId", "data-v-b933a997"]]); +const _sfc_main$14 = /* @__PURE__ */ defineComponent({ + __name: "VPDocAsideOutline", + __ssrInlineRender: true, + setup(__props) { + const { frontmatter, theme: theme2 } = useData(); + const headers = shallowRef([]); + onContentUpdated(() => { + headers.value = getHeaders(frontmatter.value.outline ?? theme2.value.outline); + }); + const container = ref(); + const marker = ref(); + useActiveAnchor(container, marker); + return (_ctx, _push, _parent, _attrs) => { + _push(` 0 }], + ref_key: "container", + ref: container + }, _attrs))} data-v-a5bbad30>
    ${ssrInterpolate(unref(resolveTitle)(unref(theme2)))}
    `); + _push(ssrRenderComponent(VPDocOutlineItem, { + headers: headers.value, + root: true + }, null, _parent)); + _push(`
    `); + }; + } +}); +const _sfc_setup$14 = _sfc_main$14.setup; +_sfc_main$14.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPDocAsideOutline.vue"); + return _sfc_setup$14 ? _sfc_setup$14(props, ctx) : void 0; +}; +const VPDocAsideOutline = /* @__PURE__ */ _export_sfc(_sfc_main$14, [["__scopeId", "data-v-a5bbad30"]]); +const _sfc_main$13 = /* @__PURE__ */ defineComponent({ + __name: "VPDocAsideCarbonAds", + __ssrInlineRender: true, + props: { + carbonAds: {} + }, + setup(__props) { + const VPCarbonAds = () => null; + return (_ctx, _push, _parent, _attrs) => { + _push(``); + _push(ssrRenderComponent(unref(VPCarbonAds), { "carbon-ads": __props.carbonAds }, null, _parent)); + _push(``); + }; + } +}); +const _sfc_setup$13 = _sfc_main$13.setup; +_sfc_main$13.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPDocAsideCarbonAds.vue"); + return _sfc_setup$13 ? _sfc_setup$13(props, ctx) : void 0; +}; +const _sfc_main$12 = /* @__PURE__ */ defineComponent({ + __name: "VPDocAside", + __ssrInlineRender: true, + setup(__props) { + const { theme: theme2 } = useData(); + return (_ctx, _push, _parent, _attrs) => { + _push(``); + ssrRenderSlot(_ctx.$slots, "aside-top", {}, null, _push, _parent); + ssrRenderSlot(_ctx.$slots, "aside-outline-before", {}, null, _push, _parent); + _push(ssrRenderComponent(VPDocAsideOutline, null, null, _parent)); + ssrRenderSlot(_ctx.$slots, "aside-outline-after", {}, null, _push, _parent); + _push(`
    `); + ssrRenderSlot(_ctx.$slots, "aside-ads-before", {}, null, _push, _parent); + if (unref(theme2).carbonAds) { + _push(ssrRenderComponent(_sfc_main$13, { + "carbon-ads": unref(theme2).carbonAds + }, null, _parent)); + } else { + _push(``); + } + ssrRenderSlot(_ctx.$slots, "aside-ads-after", {}, null, _push, _parent); + ssrRenderSlot(_ctx.$slots, "aside-bottom", {}, null, _push, _parent); + _push(``); + }; + } +}); +const _sfc_setup$12 = _sfc_main$12.setup; +_sfc_main$12.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPDocAside.vue"); + return _sfc_setup$12 ? _sfc_setup$12(props, ctx) : void 0; +}; +const VPDocAside = /* @__PURE__ */ _export_sfc(_sfc_main$12, [["__scopeId", "data-v-3f215769"]]); +function useEditLink() { + const { theme: theme2, page } = useData(); + return computed(() => { + const { text = "Edit this page", pattern = "" } = theme2.value.editLink || {}; + let url; + if (typeof pattern === "function") { + url = pattern(page.value); + } else { + url = pattern.replace(/:path/g, page.value.filePath); + } + return { url, text }; + }); +} +function usePrevNext() { + const { page, theme: theme2, frontmatter } = useData(); + return computed(() => { + var _a, _b, _c, _d, _e, _f, _g, _h; + const sidebar = getSidebar(theme2.value.sidebar, page.value.relativePath); + const links = getFlatSideBarLinks(sidebar); + const candidates = uniqBy(links, (link2) => link2.link.replace(/[?#].*$/, "")); + const index = candidates.findIndex((link2) => { + return isActive(page.value.relativePath, link2.link); + }); + const hidePrev = ((_a = theme2.value.docFooter) == null ? void 0 : _a.prev) === false && !frontmatter.value.prev || frontmatter.value.prev === false; + const hideNext = ((_b = theme2.value.docFooter) == null ? void 0 : _b.next) === false && !frontmatter.value.next || frontmatter.value.next === false; + return { + prev: hidePrev ? void 0 : { + text: (typeof frontmatter.value.prev === "string" ? frontmatter.value.prev : typeof frontmatter.value.prev === "object" ? frontmatter.value.prev.text : void 0) ?? ((_c = candidates[index - 1]) == null ? void 0 : _c.docFooterText) ?? ((_d = candidates[index - 1]) == null ? void 0 : _d.text), + link: (typeof frontmatter.value.prev === "object" ? frontmatter.value.prev.link : void 0) ?? ((_e = candidates[index - 1]) == null ? void 0 : _e.link) + }, + next: hideNext ? void 0 : { + text: (typeof frontmatter.value.next === "string" ? frontmatter.value.next : typeof frontmatter.value.next === "object" ? frontmatter.value.next.text : void 0) ?? ((_f = candidates[index + 1]) == null ? void 0 : _f.docFooterText) ?? ((_g = candidates[index + 1]) == null ? void 0 : _g.text), + link: (typeof frontmatter.value.next === "object" ? frontmatter.value.next.link : void 0) ?? ((_h = candidates[index + 1]) == null ? void 0 : _h.link) + } + }; + }); +} +function uniqBy(array, keyFn) { + const seen = /* @__PURE__ */ new Set(); + return array.filter((item) => { + const k = keyFn(item); + return seen.has(k) ? false : seen.add(k); + }); +} +const _sfc_main$11 = /* @__PURE__ */ defineComponent({ + __name: "VPLink", + __ssrInlineRender: true, + props: { + tag: {}, + href: {}, + noIcon: { type: Boolean }, + target: {}, + rel: {} + }, + setup(__props) { + const props = __props; + const tag = computed(() => props.tag ?? (props.href ? "a" : "span")); + const isExternal2 = computed( + () => props.href && EXTERNAL_URL_RE.test(props.href) || props.target === "_blank" + ); + return (_ctx, _push, _parent, _attrs) => { + ssrRenderVNode(_push, createVNode(resolveDynamicComponent(tag.value), mergeProps({ + class: ["VPLink", { + link: __props.href, + "vp-external-link-icon": isExternal2.value, + "no-icon": __props.noIcon + }], + href: __props.href ? unref(normalizeLink$1)(__props.href) : void 0, + target: __props.target ?? (isExternal2.value ? "_blank" : void 0), + rel: __props.rel ?? (isExternal2.value ? "noreferrer" : void 0) + }, _attrs), { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "default", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "default") + ]; + } + }), + _: 3 + }), _parent); + }; + } +}); +const _sfc_setup$11 = _sfc_main$11.setup; +_sfc_main$11.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPLink.vue"); + return _sfc_setup$11 ? _sfc_setup$11(props, ctx) : void 0; +}; +const _sfc_main$10 = /* @__PURE__ */ defineComponent({ + __name: "VPDocFooterLastUpdated", + __ssrInlineRender: true, + setup(__props) { + const { theme: theme2, page, lang } = useData(); + const date = computed( + () => new Date(page.value.lastUpdated) + ); + const isoDatetime = computed(() => date.value.toISOString()); + const datetime = ref(""); + onMounted(() => { + watchEffect(() => { + var _a, _b, _c; + datetime.value = new Intl.DateTimeFormat( + ((_b = (_a = theme2.value.lastUpdated) == null ? void 0 : _a.formatOptions) == null ? void 0 : _b.forceLocale) ? lang.value : void 0, + ((_c = theme2.value.lastUpdated) == null ? void 0 : _c.formatOptions) ?? { + dateStyle: "short", + timeStyle: "short" + } + ).format(date.value); + }); + }); + return (_ctx, _push, _parent, _attrs) => { + var _a; + _push(`${ssrInterpolate(((_a = unref(theme2).lastUpdated) == null ? void 0 : _a.text) || unref(theme2).lastUpdatedText || "Last updated")}: ${ssrInterpolate(datetime.value)}

    `); + }; + } +}); +const _sfc_setup$10 = _sfc_main$10.setup; +_sfc_main$10.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPDocFooterLastUpdated.vue"); + return _sfc_setup$10 ? _sfc_setup$10(props, ctx) : void 0; +}; +const VPDocFooterLastUpdated = /* @__PURE__ */ _export_sfc(_sfc_main$10, [["__scopeId", "data-v-e98dd255"]]); +const _sfc_main$$ = /* @__PURE__ */ defineComponent({ + __name: "VPDocFooter", + __ssrInlineRender: true, + setup(__props) { + const { theme: theme2, page, frontmatter } = useData(); + const editLink = useEditLink(); + const control = usePrevNext(); + const hasEditLink = computed( + () => theme2.value.editLink && frontmatter.value.editLink !== false + ); + const hasLastUpdated = computed(() => page.value.lastUpdated); + const showFooter = computed( + () => hasEditLink.value || hasLastUpdated.value || control.value.prev || control.value.next + ); + return (_ctx, _push, _parent, _attrs) => { + var _a, _b, _c, _d; + if (showFooter.value) { + _push(``); + ssrRenderSlot(_ctx.$slots, "doc-footer-before", {}, null, _push, _parent); + if (hasEditLink.value || hasLastUpdated.value) { + _push(`
    `); + if (hasEditLink.value) { + _push(``); + } else { + _push(``); + } + if (hasLastUpdated.value) { + _push(`
    `); + _push(ssrRenderComponent(VPDocFooterLastUpdated, null, null, _parent)); + _push(`
    `); + } else { + _push(``); + } + _push(`
    `); + } else { + _push(``); + } + if (((_a = unref(control).prev) == null ? void 0 : _a.link) || ((_b = unref(control).next) == null ? void 0 : _b.link)) { + _push(``); + } else { + _push(``); + } + _push(``); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$$ = _sfc_main$$.setup; +_sfc_main$$.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPDocFooter.vue"); + return _sfc_setup$$ ? _sfc_setup$$(props, ctx) : void 0; +}; +const VPDocFooter = /* @__PURE__ */ _export_sfc(_sfc_main$$, [["__scopeId", "data-v-e257564d"]]); +const _sfc_main$_ = /* @__PURE__ */ defineComponent({ + __name: "VPDoc", + __ssrInlineRender: true, + setup(__props) { + const { theme: theme2 } = useData(); + const route = useRoute(); + const { hasSidebar, hasAside, leftAside } = useSidebar(); + const pageName = computed( + () => route.path.replace(/[./]+/g, "_").replace(/_html$/, "") + ); + return (_ctx, _push, _parent, _attrs) => { + const _component_Content = resolveComponent("Content"); + _push(``); + ssrRenderSlot(_ctx.$slots, "doc-top", {}, null, _push, _parent); + _push(`
    `); + if (unref(hasAside)) { + _push(`
    `); + _push(ssrRenderComponent(VPDocAside, null, { + "aside-top": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-top", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-top", {}, void 0, true) + ]; + } + }), + "aside-bottom": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-bottom", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-bottom", {}, void 0, true) + ]; + } + }), + "aside-outline-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-outline-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-outline-before", {}, void 0, true) + ]; + } + }), + "aside-outline-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-outline-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-outline-after", {}, void 0, true) + ]; + } + }), + "aside-ads-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-ads-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-ads-before", {}, void 0, true) + ]; + } + }), + "aside-ads-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-ads-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-ads-after", {}, void 0, true) + ]; + } + }), + _: 3 + }, _parent)); + _push(`
    `); + } else { + _push(``); + } + _push(`
    `); + ssrRenderSlot(_ctx.$slots, "doc-before", {}, null, _push, _parent); + _push(`
    `); + _push(ssrRenderComponent(_component_Content, { + class: ["vp-doc", [ + pageName.value, + unref(theme2).externalLinkIcon && "external-link-icon-enabled" + ]] + }, null, _parent)); + _push(`
    `); + _push(ssrRenderComponent(VPDocFooter, null, { + "doc-footer-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "doc-footer-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "doc-footer-before", {}, void 0, true) + ]; + } + }), + _: 3 + }, _parent)); + ssrRenderSlot(_ctx.$slots, "doc-after", {}, null, _push, _parent); + _push(`
    `); + ssrRenderSlot(_ctx.$slots, "doc-bottom", {}, null, _push, _parent); + _push(``); + }; + } +}); +const _sfc_setup$_ = _sfc_main$_.setup; +_sfc_main$_.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPDoc.vue"); + return _sfc_setup$_ ? _sfc_setup$_(props, ctx) : void 0; +}; +const VPDoc = /* @__PURE__ */ _export_sfc(_sfc_main$_, [["__scopeId", "data-v-39a288b8"]]); +const _sfc_main$Z = /* @__PURE__ */ defineComponent({ + __name: "VPButton", + __ssrInlineRender: true, + props: { + tag: {}, + size: { default: "medium" }, + theme: { default: "brand" }, + text: {}, + href: {}, + target: {}, + rel: {} + }, + setup(__props) { + const props = __props; + const isExternal2 = computed( + () => props.href && EXTERNAL_URL_RE.test(props.href) + ); + const component = computed(() => { + return props.tag || (props.href ? "a" : "button"); + }); + return (_ctx, _push, _parent, _attrs) => { + ssrRenderVNode(_push, createVNode(resolveDynamicComponent(component.value), mergeProps({ + class: ["VPButton", [__props.size, __props.theme]], + href: __props.href ? unref(normalizeLink$1)(__props.href) : void 0, + target: props.target ?? (isExternal2.value ? "_blank" : void 0), + rel: props.rel ?? (isExternal2.value ? "noreferrer" : void 0) + }, _attrs), { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + _push2(`${ssrInterpolate(__props.text)}`); + } else { + return [ + createTextVNode(toDisplayString(__props.text), 1) + ]; + } + }), + _: 1 + }), _parent); + }; + } +}); +const _sfc_setup$Z = _sfc_main$Z.setup; +_sfc_main$Z.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPButton.vue"); + return _sfc_setup$Z ? _sfc_setup$Z(props, ctx) : void 0; +}; +const VPButton = /* @__PURE__ */ _export_sfc(_sfc_main$Z, [["__scopeId", "data-v-fa7799d5"]]); +const _sfc_main$Y = /* @__PURE__ */ defineComponent({ + ...{ inheritAttrs: false }, + __name: "VPImage", + __ssrInlineRender: true, + props: { + image: {}, + alt: {} + }, + setup(__props) { + return (_ctx, _push, _parent, _attrs) => { + const _component_VPImage = resolveComponent("VPImage", true); + if (__props.image) { + _push(``); + if (typeof __props.image === "string" || "src" in __props.image) { + _push(``); + } else { + _push(``); + _push(ssrRenderComponent(_component_VPImage, mergeProps({ + class: "dark", + image: __props.image.dark, + alt: __props.image.alt + }, _ctx.$attrs), null, _parent)); + _push(ssrRenderComponent(_component_VPImage, mergeProps({ + class: "light", + image: __props.image.light, + alt: __props.image.alt + }, _ctx.$attrs), null, _parent)); + _push(``); + } + _push(``); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$Y = _sfc_main$Y.setup; +_sfc_main$Y.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPImage.vue"); + return _sfc_setup$Y ? _sfc_setup$Y(props, ctx) : void 0; +}; +const VPImage = /* @__PURE__ */ _export_sfc(_sfc_main$Y, [["__scopeId", "data-v-8426fc1a"]]); +const _sfc_main$X = /* @__PURE__ */ defineComponent({ + __name: "VPHero", + __ssrInlineRender: true, + props: { + name: {}, + text: {}, + tagline: {}, + image: {}, + actions: {} + }, + setup(__props) { + const heroImageSlotExists = inject("hero-image-slot-exists"); + return (_ctx, _push, _parent, _attrs) => { + _push(`
    `); + ssrRenderSlot(_ctx.$slots, "home-hero-info-before", {}, null, _push, _parent); + ssrRenderSlot(_ctx.$slots, "home-hero-info", {}, () => { + _push(`

    `); + if (__props.name) { + _push(`${__props.name ?? ""}`); + } else { + _push(``); + } + if (__props.text) { + _push(`${__props.text ?? ""}`); + } else { + _push(``); + } + _push(`

    `); + if (__props.tagline) { + _push(`

    ${__props.tagline ?? ""}

    `); + } else { + _push(``); + } + }, _push, _parent); + ssrRenderSlot(_ctx.$slots, "home-hero-info-after", {}, null, _push, _parent); + if (__props.actions) { + _push(`
    `); + ssrRenderList(__props.actions, (action) => { + _push(`
    `); + _push(ssrRenderComponent(VPButton, { + tag: "a", + size: "medium", + theme: action.theme, + text: action.text, + href: action.link, + target: action.target, + rel: action.rel + }, null, _parent)); + _push(`
    `); + }); + _push(`
    `); + } else { + _push(``); + } + ssrRenderSlot(_ctx.$slots, "home-hero-actions-after", {}, null, _push, _parent); + _push(`
    `); + if (__props.image || unref(heroImageSlotExists)) { + _push(`
    `); + ssrRenderSlot(_ctx.$slots, "home-hero-image", {}, () => { + if (__props.image) { + _push(ssrRenderComponent(VPImage, { + class: "image-src", + image: __props.image + }, null, _parent)); + } else { + _push(``); + } + }, _push, _parent); + _push(`
    `); + } else { + _push(``); + } + _push(`
    `); + }; + } +}); +const _sfc_setup$X = _sfc_main$X.setup; +_sfc_main$X.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPHero.vue"); + return _sfc_setup$X ? _sfc_setup$X(props, ctx) : void 0; +}; +const VPHero = /* @__PURE__ */ _export_sfc(_sfc_main$X, [["__scopeId", "data-v-4f9c455b"]]); +const _sfc_main$W = /* @__PURE__ */ defineComponent({ + __name: "VPHomeHero", + __ssrInlineRender: true, + setup(__props) { + const { frontmatter: fm } = useData(); + return (_ctx, _push, _parent, _attrs) => { + if (unref(fm).hero) { + _push(ssrRenderComponent(VPHero, mergeProps({ + class: "VPHomeHero", + name: unref(fm).hero.name, + text: unref(fm).hero.text, + tagline: unref(fm).hero.tagline, + image: unref(fm).hero.image, + actions: unref(fm).hero.actions + }, _attrs), { + "home-hero-info-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-info-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-info-before") + ]; + } + }), + "home-hero-info": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-info", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-info") + ]; + } + }), + "home-hero-info-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-info-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-info-after") + ]; + } + }), + "home-hero-actions-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-actions-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-actions-after") + ]; + } + }), + "home-hero-image": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-image", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-image") + ]; + } + }), + _: 3 + }, _parent)); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$W = _sfc_main$W.setup; +_sfc_main$W.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPHomeHero.vue"); + return _sfc_setup$W ? _sfc_setup$W(props, ctx) : void 0; +}; +const _sfc_main$V = /* @__PURE__ */ defineComponent({ + __name: "VPFeature", + __ssrInlineRender: true, + props: { + icon: {}, + title: {}, + details: {}, + link: {}, + linkText: {}, + rel: {}, + target: {} + }, + setup(__props) { + return (_ctx, _push, _parent, _attrs) => { + _push(ssrRenderComponent(_sfc_main$11, mergeProps({ + class: "VPFeature", + href: __props.link, + rel: __props.rel, + target: __props.target, + "no-icon": true, + tag: __props.link ? "a" : "div" + }, _attrs), { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + _push2(`
    `); + if (typeof __props.icon === "object" && __props.icon.wrap) { + _push2(`
    `); + _push2(ssrRenderComponent(VPImage, { + image: __props.icon, + alt: __props.icon.alt, + height: __props.icon.height || 48, + width: __props.icon.width || 48 + }, null, _parent2, _scopeId)); + _push2(`
    `); + } else if (typeof __props.icon === "object") { + _push2(ssrRenderComponent(VPImage, { + image: __props.icon, + alt: __props.icon.alt, + height: __props.icon.height || 48, + width: __props.icon.width || 48 + }, null, _parent2, _scopeId)); + } else if (__props.icon) { + _push2(`
    ${__props.icon ?? ""}
    `); + } else { + _push2(``); + } + _push2(`

    ${__props.title ?? ""}

    `); + if (__props.details) { + _push2(`

    ${__props.details ?? ""}

    `); + } else { + _push2(``); + } + if (__props.linkText) { + _push2(``); + } else { + _push2(``); + } + _push2(`
    `); + } else { + return [ + createVNode("article", { class: "box" }, [ + typeof __props.icon === "object" && __props.icon.wrap ? (openBlock(), createBlock("div", { + key: 0, + class: "icon" + }, [ + createVNode(VPImage, { + image: __props.icon, + alt: __props.icon.alt, + height: __props.icon.height || 48, + width: __props.icon.width || 48 + }, null, 8, ["image", "alt", "height", "width"]) + ])) : typeof __props.icon === "object" ? (openBlock(), createBlock(VPImage, { + key: 1, + image: __props.icon, + alt: __props.icon.alt, + height: __props.icon.height || 48, + width: __props.icon.width || 48 + }, null, 8, ["image", "alt", "height", "width"])) : __props.icon ? (openBlock(), createBlock("div", { + key: 2, + class: "icon", + innerHTML: __props.icon + }, null, 8, ["innerHTML"])) : createCommentVNode("", true), + createVNode("h2", { + class: "title", + innerHTML: __props.title + }, null, 8, ["innerHTML"]), + __props.details ? (openBlock(), createBlock("p", { + key: 3, + class: "details", + innerHTML: __props.details + }, null, 8, ["innerHTML"])) : createCommentVNode("", true), + __props.linkText ? (openBlock(), createBlock("div", { + key: 4, + class: "link-text" + }, [ + createVNode("p", { class: "link-text-value" }, [ + createTextVNode(toDisplayString(__props.linkText) + " ", 1), + createVNode("span", { class: "vpi-arrow-right link-text-icon" }) + ]) + ])) : createCommentVNode("", true) + ]) + ]; + } + }), + _: 1 + }, _parent)); + }; + } +}); +const _sfc_setup$V = _sfc_main$V.setup; +_sfc_main$V.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPFeature.vue"); + return _sfc_setup$V ? _sfc_setup$V(props, ctx) : void 0; +}; +const VPFeature = /* @__PURE__ */ _export_sfc(_sfc_main$V, [["__scopeId", "data-v-a3976bdc"]]); +const _sfc_main$U = /* @__PURE__ */ defineComponent({ + __name: "VPFeatures", + __ssrInlineRender: true, + props: { + features: {} + }, + setup(__props) { + const props = __props; + const grid = computed(() => { + const length = props.features.length; + if (!length) { + return; + } else if (length === 2) { + return "grid-2"; + } else if (length === 3) { + return "grid-3"; + } else if (length % 3 === 0) { + return "grid-6"; + } else if (length > 3) { + return "grid-4"; + } + }); + return (_ctx, _push, _parent, _attrs) => { + if (__props.features) { + _push(`
    `); + ssrRenderList(__props.features, (feature) => { + _push(`
    `); + _push(ssrRenderComponent(VPFeature, { + icon: feature.icon, + title: feature.title, + details: feature.details, + link: feature.link, + "link-text": feature.linkText, + rel: feature.rel, + target: feature.target + }, null, _parent)); + _push(`
    `); + }); + _push(`
    `); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$U = _sfc_main$U.setup; +_sfc_main$U.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPFeatures.vue"); + return _sfc_setup$U ? _sfc_setup$U(props, ctx) : void 0; +}; +const VPFeatures = /* @__PURE__ */ _export_sfc(_sfc_main$U, [["__scopeId", "data-v-a6181336"]]); +const _sfc_main$T = /* @__PURE__ */ defineComponent({ + __name: "VPHomeFeatures", + __ssrInlineRender: true, + setup(__props) { + const { frontmatter: fm } = useData(); + return (_ctx, _push, _parent, _attrs) => { + if (unref(fm).features) { + _push(ssrRenderComponent(VPFeatures, mergeProps({ + class: "VPHomeFeatures", + features: unref(fm).features + }, _attrs), null, _parent)); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$T = _sfc_main$T.setup; +_sfc_main$T.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPHomeFeatures.vue"); + return _sfc_setup$T ? _sfc_setup$T(props, ctx) : void 0; +}; +const _sfc_main$S = /* @__PURE__ */ defineComponent({ + __name: "VPHomeContent", + __ssrInlineRender: true, + setup(__props) { + const { width: vw } = useWindowSize({ + initialWidth: 0, + includeScrollbar: false + }); + return (_ctx, _push, _parent, _attrs) => { + _push(``); + ssrRenderSlot(_ctx.$slots, "default", {}, null, _push, _parent); + _push(``); + }; + } +}); +const _sfc_setup$S = _sfc_main$S.setup; +_sfc_main$S.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPHomeContent.vue"); + return _sfc_setup$S ? _sfc_setup$S(props, ctx) : void 0; +}; +const VPHomeContent = /* @__PURE__ */ _export_sfc(_sfc_main$S, [["__scopeId", "data-v-8e2d4988"]]); +const _sfc_main$R = /* @__PURE__ */ defineComponent({ + __name: "VPHome", + __ssrInlineRender: true, + setup(__props) { + const { frontmatter, theme: theme2 } = useData(); + return (_ctx, _push, _parent, _attrs) => { + const _component_Content = resolveComponent("Content"); + _push(``); + ssrRenderSlot(_ctx.$slots, "home-hero-before", {}, null, _push, _parent); + _push(ssrRenderComponent(_sfc_main$W, null, { + "home-hero-info-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-info-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-info-before", {}, void 0, true) + ]; + } + }), + "home-hero-info": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-info", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-info", {}, void 0, true) + ]; + } + }), + "home-hero-info-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-info-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-info-after", {}, void 0, true) + ]; + } + }), + "home-hero-actions-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-actions-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-actions-after", {}, void 0, true) + ]; + } + }), + "home-hero-image": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-image", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-image", {}, void 0, true) + ]; + } + }), + _: 3 + }, _parent)); + ssrRenderSlot(_ctx.$slots, "home-hero-after", {}, null, _push, _parent); + ssrRenderSlot(_ctx.$slots, "home-features-before", {}, null, _push, _parent); + _push(ssrRenderComponent(_sfc_main$T, null, null, _parent)); + ssrRenderSlot(_ctx.$slots, "home-features-after", {}, null, _push, _parent); + if (unref(frontmatter).markdownStyles !== false) { + _push(ssrRenderComponent(VPHomeContent, null, { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + _push2(ssrRenderComponent(_component_Content, null, null, _parent2, _scopeId)); + } else { + return [ + createVNode(_component_Content) + ]; + } + }), + _: 1 + }, _parent)); + } else { + _push(ssrRenderComponent(_component_Content, null, null, _parent)); + } + _push(``); + }; + } +}); +const _sfc_setup$R = _sfc_main$R.setup; +_sfc_main$R.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPHome.vue"); + return _sfc_setup$R ? _sfc_setup$R(props, ctx) : void 0; +}; +const VPHome = /* @__PURE__ */ _export_sfc(_sfc_main$R, [["__scopeId", "data-v-8b561e3d"]]); +const _sfc_main$Q = {}; +function _sfc_ssrRender$1(_ctx, _push, _parent, _attrs) { + const _component_Content = resolveComponent("Content"); + _push(``); + ssrRenderSlot(_ctx.$slots, "page-top", {}, null, _push, _parent); + _push(ssrRenderComponent(_component_Content, null, null, _parent)); + ssrRenderSlot(_ctx.$slots, "page-bottom", {}, null, _push, _parent); + _push(``); +} +const _sfc_setup$Q = _sfc_main$Q.setup; +_sfc_main$Q.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPPage.vue"); + return _sfc_setup$Q ? _sfc_setup$Q(props, ctx) : void 0; +}; +const VPPage = /* @__PURE__ */ _export_sfc(_sfc_main$Q, [["ssrRender", _sfc_ssrRender$1]]); +const _sfc_main$P = /* @__PURE__ */ defineComponent({ + __name: "VPContent", + __ssrInlineRender: true, + setup(__props) { + const { page, frontmatter } = useData(); + const { hasSidebar } = useSidebar(); + return (_ctx, _push, _parent, _attrs) => { + _push(``); + if (unref(page).isNotFound) { + ssrRenderSlot(_ctx.$slots, "not-found", {}, () => { + _push(ssrRenderComponent(NotFound, null, null, _parent)); + }, _push, _parent); + } else if (unref(frontmatter).layout === "page") { + _push(ssrRenderComponent(VPPage, null, { + "page-top": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "page-top", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "page-top", {}, void 0, true) + ]; + } + }), + "page-bottom": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "page-bottom", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "page-bottom", {}, void 0, true) + ]; + } + }), + _: 3 + }, _parent)); + } else if (unref(frontmatter).layout === "home") { + _push(ssrRenderComponent(VPHome, null, { + "home-hero-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-before", {}, void 0, true) + ]; + } + }), + "home-hero-info-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-info-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-info-before", {}, void 0, true) + ]; + } + }), + "home-hero-info": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-info", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-info", {}, void 0, true) + ]; + } + }), + "home-hero-info-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-info-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-info-after", {}, void 0, true) + ]; + } + }), + "home-hero-actions-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-actions-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-actions-after", {}, void 0, true) + ]; + } + }), + "home-hero-image": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-image", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-image", {}, void 0, true) + ]; + } + }), + "home-hero-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-after", {}, void 0, true) + ]; + } + }), + "home-features-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-features-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-features-before", {}, void 0, true) + ]; + } + }), + "home-features-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-features-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-features-after", {}, void 0, true) + ]; + } + }), + _: 3 + }, _parent)); + } else if (unref(frontmatter).layout && unref(frontmatter).layout !== "doc") { + ssrRenderVNode(_push, createVNode(resolveDynamicComponent(unref(frontmatter).layout), null, null), _parent); + } else { + _push(ssrRenderComponent(VPDoc, null, { + "doc-top": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "doc-top", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "doc-top", {}, void 0, true) + ]; + } + }), + "doc-bottom": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "doc-bottom", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "doc-bottom", {}, void 0, true) + ]; + } + }), + "doc-footer-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "doc-footer-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "doc-footer-before", {}, void 0, true) + ]; + } + }), + "doc-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "doc-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "doc-before", {}, void 0, true) + ]; + } + }), + "doc-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "doc-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "doc-after", {}, void 0, true) + ]; + } + }), + "aside-top": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-top", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-top", {}, void 0, true) + ]; + } + }), + "aside-outline-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-outline-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-outline-before", {}, void 0, true) + ]; + } + }), + "aside-outline-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-outline-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-outline-after", {}, void 0, true) + ]; + } + }), + "aside-ads-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-ads-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-ads-before", {}, void 0, true) + ]; + } + }), + "aside-ads-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-ads-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-ads-after", {}, void 0, true) + ]; + } + }), + "aside-bottom": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-bottom", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-bottom", {}, void 0, true) + ]; + } + }), + _: 3 + }, _parent)); + } + _push(``); + }; + } +}); +const _sfc_setup$P = _sfc_main$P.setup; +_sfc_main$P.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPContent.vue"); + return _sfc_setup$P ? _sfc_setup$P(props, ctx) : void 0; +}; +const VPContent = /* @__PURE__ */ _export_sfc(_sfc_main$P, [["__scopeId", "data-v-1428d186"]]); +const _sfc_main$O = /* @__PURE__ */ defineComponent({ + __name: "VPFooter", + __ssrInlineRender: true, + setup(__props) { + const { theme: theme2, frontmatter } = useData(); + const { hasSidebar } = useSidebar(); + return (_ctx, _push, _parent, _attrs) => { + if (unref(theme2).footer && unref(frontmatter).footer !== false) { + _push(`
    `); + if (unref(theme2).footer.message) { + _push(`

    ${unref(theme2).footer.message ?? ""}

    `); + } else { + _push(``); + } + if (unref(theme2).footer.copyright) { + _push(``); + } else { + _push(``); + } + _push(`
    `); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$O = _sfc_main$O.setup; +_sfc_main$O.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPFooter.vue"); + return _sfc_setup$O ? _sfc_setup$O(props, ctx) : void 0; +}; +const VPFooter = /* @__PURE__ */ _export_sfc(_sfc_main$O, [["__scopeId", "data-v-e315a0ad"]]); +function useLocalNav() { + const { theme: theme2, frontmatter } = useData(); + const headers = shallowRef([]); + const hasLocalNav = computed(() => { + return headers.value.length > 0; + }); + onContentUpdated(() => { + headers.value = getHeaders(frontmatter.value.outline ?? theme2.value.outline); + }); + return { + headers, + hasLocalNav + }; +} +const _sfc_main$N = /* @__PURE__ */ defineComponent({ + __name: "VPLocalNavOutlineDropdown", + __ssrInlineRender: true, + props: { + headers: {}, + navHeight: {} + }, + setup(__props) { + const { theme: theme2 } = useData(); + const open = ref(false); + const vh = ref(0); + const main = ref(); + ref(); + function closeOnClickOutside(e) { + var _a; + if (!((_a = main.value) == null ? void 0 : _a.contains(e.target))) { + open.value = false; + } + } + watch(open, (value) => { + if (value) { + document.addEventListener("click", closeOnClickOutside); + return; + } + document.removeEventListener("click", closeOnClickOutside); + }); + onKeyStroke("Escape", () => { + open.value = false; + }); + onContentUpdated(() => { + open.value = false; + }); + return (_ctx, _push, _parent, _attrs) => { + _push(``); + if (__props.headers.length > 0) { + _push(``); + } else { + _push(``); + } + if (open.value) { + _push(`
    `); + _push(ssrRenderComponent(VPDocOutlineItem, { headers: __props.headers }, null, _parent)); + _push(`
    `); + } else { + _push(``); + } + _push(``); + }; + } +}); +const _sfc_setup$N = _sfc_main$N.setup; +_sfc_main$N.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPLocalNavOutlineDropdown.vue"); + return _sfc_setup$N ? _sfc_setup$N(props, ctx) : void 0; +}; +const VPLocalNavOutlineDropdown = /* @__PURE__ */ _export_sfc(_sfc_main$N, [["__scopeId", "data-v-8a42e2b4"]]); +const _sfc_main$M = /* @__PURE__ */ defineComponent({ + __name: "VPLocalNav", + __ssrInlineRender: true, + props: { + open: { type: Boolean } + }, + emits: ["open-menu"], + setup(__props) { + const { theme: theme2, frontmatter } = useData(); + const { hasSidebar } = useSidebar(); + const { headers } = useLocalNav(); + const { y } = useWindowScroll(); + const navHeight = ref(0); + onMounted(() => { + navHeight.value = parseInt( + getComputedStyle(document.documentElement).getPropertyValue( + "--vp-nav-height" + ) + ); + }); + onContentUpdated(() => { + headers.value = getHeaders(frontmatter.value.outline ?? theme2.value.outline); + }); + const empty = computed(() => { + return headers.value.length === 0; + }); + const emptyAndNoSidebar = computed(() => { + return empty.value && !hasSidebar.value; + }); + const classes = computed(() => { + return { + VPLocalNav: true, + "has-sidebar": hasSidebar.value, + empty: empty.value, + fixed: emptyAndNoSidebar.value + }; + }); + return (_ctx, _push, _parent, _attrs) => { + if (unref(frontmatter).layout !== "home" && (!emptyAndNoSidebar.value || unref(y) >= navHeight.value)) { + _push(`
    `); + if (unref(hasSidebar)) { + _push(``); + } else { + _push(``); + } + _push(ssrRenderComponent(VPLocalNavOutlineDropdown, { + headers: unref(headers), + navHeight: navHeight.value + }, null, _parent)); + _push(`
    `); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$M = _sfc_main$M.setup; +_sfc_main$M.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPLocalNav.vue"); + return _sfc_setup$M ? _sfc_setup$M(props, ctx) : void 0; +}; +const VPLocalNav = /* @__PURE__ */ _export_sfc(_sfc_main$M, [["__scopeId", "data-v-a6f0e41e"]]); +function useNav() { + const isScreenOpen = ref(false); + function openScreen() { + isScreenOpen.value = true; + window.addEventListener("resize", closeScreenOnTabletWindow); + } + function closeScreen() { + isScreenOpen.value = false; + window.removeEventListener("resize", closeScreenOnTabletWindow); + } + function toggleScreen() { + isScreenOpen.value ? closeScreen() : openScreen(); + } + function closeScreenOnTabletWindow() { + window.outerWidth >= 768 && closeScreen(); + } + const route = useRoute(); + watch(() => route.path, closeScreen); + return { + isScreenOpen, + openScreen, + closeScreen, + toggleScreen + }; +} +const _sfc_main$L = {}; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs) { + _push(``); + if (_ctx.$slots.default) { + _push(``); + ssrRenderSlot(_ctx.$slots, "default", {}, null, _push, _parent); + _push(``); + } else { + _push(``); + } + _push(``); +} +const _sfc_setup$L = _sfc_main$L.setup; +_sfc_main$L.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPSwitch.vue"); + return _sfc_setup$L ? _sfc_setup$L(props, ctx) : void 0; +}; +const VPSwitch = /* @__PURE__ */ _export_sfc(_sfc_main$L, [["ssrRender", _sfc_ssrRender], ["__scopeId", "data-v-1d5665e3"]]); +const _sfc_main$K = /* @__PURE__ */ defineComponent({ + __name: "VPSwitchAppearance", + __ssrInlineRender: true, + setup(__props) { + const { isDark, theme: theme2 } = useData(); + const toggleAppearance = inject("toggle-appearance", () => { + isDark.value = !isDark.value; + }); + const switchTitle = ref(""); + watchPostEffect(() => { + switchTitle.value = isDark.value ? theme2.value.lightModeSwitchTitle || "Switch to light theme" : theme2.value.darkModeSwitchTitle || "Switch to dark theme"; + }); + return (_ctx, _push, _parent, _attrs) => { + _push(ssrRenderComponent(VPSwitch, mergeProps({ + title: switchTitle.value, + class: "VPSwitchAppearance", + "aria-checked": unref(isDark), + onClick: unref(toggleAppearance) + }, _attrs), { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + _push2(``); + } else { + return [ + createVNode("span", { class: "vpi-sun sun" }), + createVNode("span", { class: "vpi-moon moon" }) + ]; + } + }), + _: 1 + }, _parent)); + }; + } +}); +const _sfc_setup$K = _sfc_main$K.setup; +_sfc_main$K.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPSwitchAppearance.vue"); + return _sfc_setup$K ? _sfc_setup$K(props, ctx) : void 0; +}; +const VPSwitchAppearance = /* @__PURE__ */ _export_sfc(_sfc_main$K, [["__scopeId", "data-v-5337faa4"]]); +const _sfc_main$J = /* @__PURE__ */ defineComponent({ + __name: "VPNavBarAppearance", + __ssrInlineRender: true, + setup(__props) { + const { site } = useData(); + return (_ctx, _push, _parent, _attrs) => { + if (unref(site).appearance && unref(site).appearance !== "force-dark" && unref(site).appearance !== "force-auto") { + _push(``); + _push(ssrRenderComponent(VPSwitchAppearance, null, null, _parent)); + _push(``); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$J = _sfc_main$J.setup; +_sfc_main$J.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavBarAppearance.vue"); + return _sfc_setup$J ? _sfc_setup$J(props, ctx) : void 0; +}; +const VPNavBarAppearance = /* @__PURE__ */ _export_sfc(_sfc_main$J, [["__scopeId", "data-v-6c893767"]]); +const focusedElement = ref(); +let active = false; +let listeners = 0; +function useFlyout(options) { + const focus = ref(false); + if (inBrowser) { + !active && activateFocusTracking(); + listeners++; + const unwatch = watch(focusedElement, (el) => { + var _a, _b, _c; + if (el === options.el.value || ((_a = options.el.value) == null ? void 0 : _a.contains(el))) { + focus.value = true; + (_b = options.onFocus) == null ? void 0 : _b.call(options); + } else { + focus.value = false; + (_c = options.onBlur) == null ? void 0 : _c.call(options); + } + }); + onUnmounted(() => { + unwatch(); + listeners--; + if (!listeners) { + deactivateFocusTracking(); + } + }); + } + return readonly(focus); +} +function activateFocusTracking() { + document.addEventListener("focusin", handleFocusIn); + active = true; + focusedElement.value = document.activeElement; +} +function deactivateFocusTracking() { + document.removeEventListener("focusin", handleFocusIn); +} +function handleFocusIn() { + focusedElement.value = document.activeElement; +} +const _sfc_main$I = /* @__PURE__ */ defineComponent({ + __name: "VPMenuLink", + __ssrInlineRender: true, + props: { + item: {} + }, + setup(__props) { + const { page } = useData(); + return (_ctx, _push, _parent, _attrs) => { + _push(``); + _push(ssrRenderComponent(_sfc_main$11, { + class: { + active: unref(isActive)( + unref(page).relativePath, + __props.item.activeMatch || __props.item.link, + !!__props.item.activeMatch + ) + }, + href: __props.item.link, + target: __props.item.target, + rel: __props.item.rel, + "no-icon": __props.item.noIcon + }, { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + _push2(`${__props.item.text ?? ""}`); + } else { + return [ + createVNode("span", { + innerHTML: __props.item.text + }, null, 8, ["innerHTML"]) + ]; + } + }), + _: 1 + }, _parent)); + _push(``); + }; + } +}); +const _sfc_setup$I = _sfc_main$I.setup; +_sfc_main$I.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPMenuLink.vue"); + return _sfc_setup$I ? _sfc_setup$I(props, ctx) : void 0; +}; +const VPMenuLink = /* @__PURE__ */ _export_sfc(_sfc_main$I, [["__scopeId", "data-v-35975db6"]]); +const _sfc_main$H = /* @__PURE__ */ defineComponent({ + __name: "VPMenuGroup", + __ssrInlineRender: true, + props: { + text: {}, + items: {} + }, + setup(__props) { + return (_ctx, _push, _parent, _attrs) => { + _push(``); + if (__props.text) { + _push(`

    ${ssrInterpolate(__props.text)}

    `); + } else { + _push(``); + } + _push(``); + ssrRenderList(__props.items, (item) => { + _push(``); + if ("link" in item) { + _push(ssrRenderComponent(VPMenuLink, { item }, null, _parent)); + } else { + _push(``); + } + _push(``); + }); + _push(``); + }; + } +}); +const _sfc_setup$H = _sfc_main$H.setup; +_sfc_main$H.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPMenuGroup.vue"); + return _sfc_setup$H ? _sfc_setup$H(props, ctx) : void 0; +}; +const VPMenuGroup = /* @__PURE__ */ _export_sfc(_sfc_main$H, [["__scopeId", "data-v-69e747b5"]]); +const _sfc_main$G = /* @__PURE__ */ defineComponent({ + __name: "VPMenu", + __ssrInlineRender: true, + props: { + items: {} + }, + setup(__props) { + return (_ctx, _push, _parent, _attrs) => { + _push(``); + if (__props.items) { + _push(`
    `); + ssrRenderList(__props.items, (item) => { + _push(``); + if ("link" in item) { + _push(ssrRenderComponent(VPMenuLink, { item }, null, _parent)); + } else if ("component" in item) { + ssrRenderVNode(_push, createVNode(resolveDynamicComponent(item.component), mergeProps({ ref_for: true }, item.props), null), _parent); + } else { + _push(ssrRenderComponent(VPMenuGroup, { + text: item.text, + items: item.items + }, null, _parent)); + } + _push(``); + }); + _push(`
    `); + } else { + _push(``); + } + ssrRenderSlot(_ctx.$slots, "default", {}, null, _push, _parent); + _push(``); + }; + } +}); +const _sfc_setup$G = _sfc_main$G.setup; +_sfc_main$G.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPMenu.vue"); + return _sfc_setup$G ? _sfc_setup$G(props, ctx) : void 0; +}; +const VPMenu = /* @__PURE__ */ _export_sfc(_sfc_main$G, [["__scopeId", "data-v-b98bc113"]]); +const _sfc_main$F = /* @__PURE__ */ defineComponent({ + __name: "VPFlyout", + __ssrInlineRender: true, + props: { + icon: {}, + button: {}, + label: {}, + items: {} + }, + setup(__props) { + const open = ref(false); + const el = ref(); + useFlyout({ el, onBlur }); + function onBlur() { + open.value = false; + } + return (_ctx, _push, _parent, _attrs) => { + _push(``); + }; + } +}); +const _sfc_setup$F = _sfc_main$F.setup; +_sfc_main$F.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPFlyout.vue"); + return _sfc_setup$F ? _sfc_setup$F(props, ctx) : void 0; +}; +const VPFlyout = /* @__PURE__ */ _export_sfc(_sfc_main$F, [["__scopeId", "data-v-cf11d7a2"]]); +const _sfc_main$E = /* @__PURE__ */ defineComponent({ + __name: "VPSocialLink", + __ssrInlineRender: true, + props: { + icon: {}, + link: {}, + ariaLabel: {} + }, + setup(__props) { + var _a; + const props = __props; + const el = ref(); + onMounted(async () => { + var _a2; + await nextTick(); + const span = (_a2 = el.value) == null ? void 0 : _a2.children[0]; + if (span instanceof HTMLElement && span.className.startsWith("vpi-social-") && (getComputedStyle(span).maskImage || getComputedStyle(span).webkitMaskImage) === "none") { + span.style.setProperty( + "--icon", + `url('https://api.iconify.design/simple-icons/${props.icon}.svg')` + ); + } + }); + const svg = computed(() => { + if (typeof props.icon === "object") return props.icon.svg; + return ``; + }); + { + typeof props.icon === "string" && ((_a = useSSRContext()) == null ? void 0 : _a.vpSocialIcons.add(props.icon)); + } + return (_ctx, _push, _parent, _attrs) => { + _push(`${svg.value ?? ""}`); + }; + } +}); +const _sfc_setup$E = _sfc_main$E.setup; +_sfc_main$E.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPSocialLink.vue"); + return _sfc_setup$E ? _sfc_setup$E(props, ctx) : void 0; +}; +const VPSocialLink = /* @__PURE__ */ _export_sfc(_sfc_main$E, [["__scopeId", "data-v-bd121fe5"]]); +const _sfc_main$D = /* @__PURE__ */ defineComponent({ + __name: "VPSocialLinks", + __ssrInlineRender: true, + props: { + links: {} + }, + setup(__props) { + return (_ctx, _push, _parent, _attrs) => { + _push(``); + ssrRenderList(__props.links, ({ link: link2, icon, ariaLabel }) => { + _push(ssrRenderComponent(VPSocialLink, { + key: link2, + icon, + link: link2, + ariaLabel + }, null, _parent)); + }); + _push(``); + }; + } +}); +const _sfc_setup$D = _sfc_main$D.setup; +_sfc_main$D.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPSocialLinks.vue"); + return _sfc_setup$D ? _sfc_setup$D(props, ctx) : void 0; +}; +const VPSocialLinks = /* @__PURE__ */ _export_sfc(_sfc_main$D, [["__scopeId", "data-v-7bc22406"]]); +const _sfc_main$C = /* @__PURE__ */ defineComponent({ + __name: "VPNavBarExtra", + __ssrInlineRender: true, + setup(__props) { + const { site, theme: theme2 } = useData(); + const { localeLinks, currentLang } = useLangs({ correspondingLink: true }); + const hasExtraContent = computed( + () => localeLinks.value.length && currentLang.value.label || site.value.appearance || theme2.value.socialLinks + ); + return (_ctx, _push, _parent, _attrs) => { + if (hasExtraContent.value) { + _push(ssrRenderComponent(VPFlyout, mergeProps({ + class: "VPNavBarExtra", + label: "extra navigation" + }, _attrs), { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + if (unref(localeLinks).length && unref(currentLang).label) { + _push2(`

    ${ssrInterpolate(unref(currentLang).label)}

    `); + ssrRenderList(unref(localeLinks), (locale) => { + _push2(ssrRenderComponent(VPMenuLink, { item: locale }, null, _parent2, _scopeId)); + }); + _push2(`
    `); + } else { + _push2(``); + } + if (unref(site).appearance && unref(site).appearance !== "force-dark" && unref(site).appearance !== "force-auto") { + _push2(`

    ${ssrInterpolate(unref(theme2).darkModeSwitchLabel || "Appearance")}

    `); + _push2(ssrRenderComponent(VPSwitchAppearance, null, null, _parent2, _scopeId)); + _push2(`
    `); + } else { + _push2(``); + } + if (unref(theme2).socialLinks) { + _push2(`
    `); + } else { + _push2(``); + } + } else { + return [ + unref(localeLinks).length && unref(currentLang).label ? (openBlock(), createBlock("div", { + key: 0, + class: "group translations" + }, [ + createVNode("p", { class: "trans-title" }, toDisplayString(unref(currentLang).label), 1), + (openBlock(true), createBlock(Fragment, null, renderList(unref(localeLinks), (locale) => { + return openBlock(), createBlock(VPMenuLink, { + key: locale.link, + item: locale + }, null, 8, ["item"]); + }), 128)) + ])) : createCommentVNode("", true), + unref(site).appearance && unref(site).appearance !== "force-dark" && unref(site).appearance !== "force-auto" ? (openBlock(), createBlock("div", { + key: 1, + class: "group" + }, [ + createVNode("div", { class: "item appearance" }, [ + createVNode("p", { class: "label" }, toDisplayString(unref(theme2).darkModeSwitchLabel || "Appearance"), 1), + createVNode("div", { class: "appearance-action" }, [ + createVNode(VPSwitchAppearance) + ]) + ]) + ])) : createCommentVNode("", true), + unref(theme2).socialLinks ? (openBlock(), createBlock("div", { + key: 2, + class: "group" + }, [ + createVNode("div", { class: "item social-links" }, [ + createVNode(VPSocialLinks, { + class: "social-links-list", + links: unref(theme2).socialLinks + }, null, 8, ["links"]) + ]) + ])) : createCommentVNode("", true) + ]; + } + }), + _: 1 + }, _parent)); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$C = _sfc_main$C.setup; +_sfc_main$C.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavBarExtra.vue"); + return _sfc_setup$C ? _sfc_setup$C(props, ctx) : void 0; +}; +const VPNavBarExtra = /* @__PURE__ */ _export_sfc(_sfc_main$C, [["__scopeId", "data-v-bb2aa2f0"]]); +const _sfc_main$B = /* @__PURE__ */ defineComponent({ + __name: "VPNavBarHamburger", + __ssrInlineRender: true, + props: { + active: { type: Boolean } + }, + emits: ["click"], + setup(__props) { + return (_ctx, _push, _parent, _attrs) => { + _push(``); + }; + } +}); +const _sfc_setup$B = _sfc_main$B.setup; +_sfc_main$B.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavBarHamburger.vue"); + return _sfc_setup$B ? _sfc_setup$B(props, ctx) : void 0; +}; +const VPNavBarHamburger = /* @__PURE__ */ _export_sfc(_sfc_main$B, [["__scopeId", "data-v-e5dd9c1c"]]); +const _sfc_main$A = /* @__PURE__ */ defineComponent({ + __name: "VPNavBarMenuLink", + __ssrInlineRender: true, + props: { + item: {} + }, + setup(__props) { + const { page } = useData(); + return (_ctx, _push, _parent, _attrs) => { + _push(ssrRenderComponent(_sfc_main$11, mergeProps({ + class: { + VPNavBarMenuLink: true, + active: unref(isActive)( + unref(page).relativePath, + __props.item.activeMatch || __props.item.link, + !!__props.item.activeMatch + ) + }, + href: __props.item.link, + target: __props.item.target, + rel: __props.item.rel, + "no-icon": __props.item.noIcon, + tabindex: "0" + }, _attrs), { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + _push2(`${__props.item.text ?? ""}`); + } else { + return [ + createVNode("span", { + innerHTML: __props.item.text + }, null, 8, ["innerHTML"]) + ]; + } + }), + _: 1 + }, _parent)); + }; + } +}); +const _sfc_setup$A = _sfc_main$A.setup; +_sfc_main$A.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavBarMenuLink.vue"); + return _sfc_setup$A ? _sfc_setup$A(props, ctx) : void 0; +}; +const VPNavBarMenuLink = /* @__PURE__ */ _export_sfc(_sfc_main$A, [["__scopeId", "data-v-e56f3d57"]]); +const _sfc_main$z = /* @__PURE__ */ defineComponent({ + __name: "VPNavBarMenuGroup", + __ssrInlineRender: true, + props: { + item: {} + }, + setup(__props) { + const props = __props; + const { page } = useData(); + const isChildActive = (navItem) => { + if ("component" in navItem) return false; + if ("link" in navItem) { + return isActive( + page.value.relativePath, + navItem.link, + !!props.item.activeMatch + ); + } + return navItem.items.some(isChildActive); + }; + const childrenActive = computed(() => isChildActive(props.item)); + return (_ctx, _push, _parent, _attrs) => { + _push(ssrRenderComponent(VPFlyout, mergeProps({ + class: { + VPNavBarMenuGroup: true, + active: unref(isActive)(unref(page).relativePath, __props.item.activeMatch, !!__props.item.activeMatch) || childrenActive.value + }, + button: __props.item.text, + items: __props.item.items + }, _attrs), null, _parent)); + }; + } +}); +const _sfc_setup$z = _sfc_main$z.setup; +_sfc_main$z.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavBarMenuGroup.vue"); + return _sfc_setup$z ? _sfc_setup$z(props, ctx) : void 0; +}; +const _sfc_main$y = /* @__PURE__ */ defineComponent({ + __name: "VPNavBarMenu", + __ssrInlineRender: true, + setup(__props) { + const { theme: theme2 } = useData(); + return (_ctx, _push, _parent, _attrs) => { + if (unref(theme2).nav) { + _push(` Main Navigation `); + ssrRenderList(unref(theme2).nav, (item) => { + _push(``); + if ("link" in item) { + _push(ssrRenderComponent(VPNavBarMenuLink, { item }, null, _parent)); + } else if ("component" in item) { + ssrRenderVNode(_push, createVNode(resolveDynamicComponent(item.component), mergeProps({ ref_for: true }, item.props), null), _parent); + } else { + _push(ssrRenderComponent(_sfc_main$z, { item }, null, _parent)); + } + _push(``); + }); + _push(``); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$y = _sfc_main$y.setup; +_sfc_main$y.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavBarMenu.vue"); + return _sfc_setup$y ? _sfc_setup$y(props, ctx) : void 0; +}; +const VPNavBarMenu = /* @__PURE__ */ _export_sfc(_sfc_main$y, [["__scopeId", "data-v-dc692963"]]); +function createSearchTranslate(defaultTranslations) { + const { localeIndex, theme: theme2 } = useData(); + function translate(key) { + var _a, _b, _c; + const keyPath = key.split("."); + const themeObject = (_a = theme2.value.search) == null ? void 0 : _a.options; + const isObject = themeObject && typeof themeObject === "object"; + const locales = isObject && ((_c = (_b = themeObject.locales) == null ? void 0 : _b[localeIndex.value]) == null ? void 0 : _c.translations) || null; + const translations = isObject && themeObject.translations || null; + let localeResult = locales; + let translationResult = translations; + let defaultResult = defaultTranslations; + const lastKey = keyPath.pop(); + for (const k of keyPath) { + let fallbackResult = null; + const foundInFallback = defaultResult == null ? void 0 : defaultResult[k]; + if (foundInFallback) { + fallbackResult = defaultResult = foundInFallback; + } + const foundInTranslation = translationResult == null ? void 0 : translationResult[k]; + if (foundInTranslation) { + fallbackResult = translationResult = foundInTranslation; + } + const foundInLocale = localeResult == null ? void 0 : localeResult[k]; + if (foundInLocale) { + fallbackResult = localeResult = foundInLocale; + } + if (!foundInFallback) { + defaultResult = fallbackResult; + } + if (!foundInTranslation) { + translationResult = fallbackResult; + } + if (!foundInLocale) { + localeResult = fallbackResult; + } + } + return (localeResult == null ? void 0 : localeResult[lastKey]) ?? (translationResult == null ? void 0 : translationResult[lastKey]) ?? (defaultResult == null ? void 0 : defaultResult[lastKey]) ?? ""; + } + return translate; +} +const _sfc_main$x = /* @__PURE__ */ defineComponent({ + __name: "VPNavBarSearchButton", + __ssrInlineRender: true, + setup(__props) { + const defaultTranslations = { + button: { + buttonText: "Search", + buttonAriaLabel: "Search" + } + }; + const translate = createSearchTranslate(defaultTranslations); + return (_ctx, _push, _parent, _attrs) => { + _push(`${ssrInterpolate(unref(translate)("button.buttonText"))}K`); + }; + } +}); +const _sfc_setup$x = _sfc_main$x.setup; +_sfc_main$x.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavBarSearchButton.vue"); + return _sfc_setup$x ? _sfc_setup$x(props, ctx) : void 0; +}; +const _sfc_main$w = /* @__PURE__ */ defineComponent({ + __name: "VPNavBarSearch", + __ssrInlineRender: true, + setup(__props) { + const VPLocalSearchBox = defineAsyncComponent(() => import("./VPLocalSearchBox.B_D79mPK.js")); + const VPAlgoliaSearchBox = () => null; + const { theme: theme2 } = useData(); + const loaded = ref(false); + const actuallyLoaded = ref(false); + onMounted(() => { + { + return; + } + }); + function load() { + if (!loaded.value) { + loaded.value = true; + setTimeout(poll, 16); + } + } + function poll() { + const e = new Event("keydown"); + e.key = "k"; + e.metaKey = true; + window.dispatchEvent(e); + setTimeout(() => { + if (!document.querySelector(".DocSearch-Modal")) { + poll(); + } + }, 16); + } + function isEditingContent(event) { + const element = event.target; + const tagName = element.tagName; + return element.isContentEditable || tagName === "INPUT" || tagName === "SELECT" || tagName === "TEXTAREA"; + } + const showSearch = ref(false); + { + onKeyStroke("k", (event) => { + if (event.ctrlKey || event.metaKey) { + event.preventDefault(); + showSearch.value = true; + } + }); + onKeyStroke("/", (event) => { + if (!isEditingContent(event)) { + event.preventDefault(); + showSearch.value = true; + } + }); + } + const provider = "local"; + return (_ctx, _push, _parent, _attrs) => { + var _a; + _push(``); + if (unref(provider) === "local") { + _push(``); + if (showSearch.value) { + _push(ssrRenderComponent(unref(VPLocalSearchBox), { + onClose: ($event) => showSearch.value = false + }, null, _parent)); + } else { + _push(``); + } + _push(``); + } else if (unref(provider) === "algolia") { + _push(``); + if (loaded.value) { + _push(ssrRenderComponent(unref(VPAlgoliaSearchBox), { + algolia: ((_a = unref(theme2).search) == null ? void 0 : _a.options) ?? unref(theme2).algolia, + onVnodeBeforeMount: ($event) => actuallyLoaded.value = true + }, null, _parent)); + } else { + _push(``); + } + if (!actuallyLoaded.value) { + _push(`
    `); + _push(ssrRenderComponent(_sfc_main$x, { onClick: load }, null, _parent)); + _push(`
    `); + } else { + _push(``); + } + _push(``); + } else { + _push(``); + } + _push(``); + }; + } +}); +const _sfc_setup$w = _sfc_main$w.setup; +_sfc_main$w.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavBarSearch.vue"); + return _sfc_setup$w ? _sfc_setup$w(props, ctx) : void 0; +}; +const _sfc_main$v = /* @__PURE__ */ defineComponent({ + __name: "VPNavBarSocialLinks", + __ssrInlineRender: true, + setup(__props) { + const { theme: theme2 } = useData(); + return (_ctx, _push, _parent, _attrs) => { + if (unref(theme2).socialLinks) { + _push(ssrRenderComponent(VPSocialLinks, mergeProps({ + class: "VPNavBarSocialLinks", + links: unref(theme2).socialLinks + }, _attrs), null, _parent)); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$v = _sfc_main$v.setup; +_sfc_main$v.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavBarSocialLinks.vue"); + return _sfc_setup$v ? _sfc_setup$v(props, ctx) : void 0; +}; +const VPNavBarSocialLinks = /* @__PURE__ */ _export_sfc(_sfc_main$v, [["__scopeId", "data-v-0394ad82"]]); +const _sfc_main$u = /* @__PURE__ */ defineComponent({ + __name: "VPNavBarTitle", + __ssrInlineRender: true, + setup(__props) { + const { site, theme: theme2 } = useData(); + const { hasSidebar } = useSidebar(); + const { currentLang } = useLangs(); + const link2 = computed( + () => { + var _a; + return typeof theme2.value.logoLink === "string" ? theme2.value.logoLink : (_a = theme2.value.logoLink) == null ? void 0 : _a.link; + } + ); + const rel = computed( + () => { + var _a; + return typeof theme2.value.logoLink === "string" ? void 0 : (_a = theme2.value.logoLink) == null ? void 0 : _a.rel; + } + ); + const target = computed( + () => { + var _a; + return typeof theme2.value.logoLink === "string" ? void 0 : (_a = theme2.value.logoLink) == null ? void 0 : _a.target; + } + ); + return (_ctx, _push, _parent, _attrs) => { + _push(``); + ssrRenderSlot(_ctx.$slots, "nav-bar-title-before", {}, null, _push, _parent); + if (unref(theme2).logo) { + _push(ssrRenderComponent(VPImage, { + class: "logo", + image: unref(theme2).logo + }, null, _parent)); + } else { + _push(``); + } + if (unref(theme2).siteTitle) { + _push(`${unref(theme2).siteTitle ?? ""}`); + } else if (unref(theme2).siteTitle === void 0) { + _push(`${ssrInterpolate(unref(site).title)}`); + } else { + _push(``); + } + ssrRenderSlot(_ctx.$slots, "nav-bar-title-after", {}, null, _push, _parent); + _push(``); + }; + } +}); +const _sfc_setup$u = _sfc_main$u.setup; +_sfc_main$u.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavBarTitle.vue"); + return _sfc_setup$u ? _sfc_setup$u(props, ctx) : void 0; +}; +const VPNavBarTitle = /* @__PURE__ */ _export_sfc(_sfc_main$u, [["__scopeId", "data-v-1168a8e4"]]); +const _sfc_main$t = /* @__PURE__ */ defineComponent({ + __name: "VPNavBarTranslations", + __ssrInlineRender: true, + setup(__props) { + const { theme: theme2 } = useData(); + const { localeLinks, currentLang } = useLangs({ correspondingLink: true }); + return (_ctx, _push, _parent, _attrs) => { + if (unref(localeLinks).length && unref(currentLang).label) { + _push(ssrRenderComponent(VPFlyout, mergeProps({ + class: "VPNavBarTranslations", + icon: "vpi-languages", + label: unref(theme2).langMenuLabel || "Change language" + }, _attrs), { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + _push2(`

    ${ssrInterpolate(unref(currentLang).label)}

    `); + ssrRenderList(unref(localeLinks), (locale) => { + _push2(ssrRenderComponent(VPMenuLink, { item: locale }, null, _parent2, _scopeId)); + }); + _push2(`
    `); + } else { + return [ + createVNode("div", { class: "items" }, [ + createVNode("p", { class: "title" }, toDisplayString(unref(currentLang).label), 1), + (openBlock(true), createBlock(Fragment, null, renderList(unref(localeLinks), (locale) => { + return openBlock(), createBlock(VPMenuLink, { + key: locale.link, + item: locale + }, null, 8, ["item"]); + }), 128)) + ]) + ]; + } + }), + _: 1 + }, _parent)); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$t = _sfc_main$t.setup; +_sfc_main$t.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavBarTranslations.vue"); + return _sfc_setup$t ? _sfc_setup$t(props, ctx) : void 0; +}; +const VPNavBarTranslations = /* @__PURE__ */ _export_sfc(_sfc_main$t, [["__scopeId", "data-v-88af2de4"]]); +const _sfc_main$s = /* @__PURE__ */ defineComponent({ + __name: "VPNavBar", + __ssrInlineRender: true, + props: { + isScreenOpen: { type: Boolean } + }, + emits: ["toggle-screen"], + setup(__props) { + const props = __props; + const { y } = useWindowScroll(); + const { hasSidebar } = useSidebar(); + const { frontmatter } = useData(); + const classes = ref({}); + watchPostEffect(() => { + classes.value = { + "has-sidebar": hasSidebar.value, + "home": frontmatter.value.layout === "home", + "top": y.value === 0, + "screen-open": props.isScreenOpen + }; + }); + return (_ctx, _push, _parent, _attrs) => { + _push(`
    `); + _push(ssrRenderComponent(VPNavBarTitle, null, { + "nav-bar-title-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "nav-bar-title-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "nav-bar-title-before", {}, void 0, true) + ]; + } + }), + "nav-bar-title-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "nav-bar-title-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "nav-bar-title-after", {}, void 0, true) + ]; + } + }), + _: 3 + }, _parent)); + _push(`
    `); + ssrRenderSlot(_ctx.$slots, "nav-bar-content-before", {}, null, _push, _parent); + _push(ssrRenderComponent(_sfc_main$w, { class: "search" }, null, _parent)); + _push(ssrRenderComponent(VPNavBarMenu, { class: "menu" }, null, _parent)); + _push(ssrRenderComponent(VPNavBarTranslations, { class: "translations" }, null, _parent)); + _push(ssrRenderComponent(VPNavBarAppearance, { class: "appearance" }, null, _parent)); + _push(ssrRenderComponent(VPNavBarSocialLinks, { class: "social-links" }, null, _parent)); + _push(ssrRenderComponent(VPNavBarExtra, { class: "extra" }, null, _parent)); + ssrRenderSlot(_ctx.$slots, "nav-bar-content-after", {}, null, _push, _parent); + _push(ssrRenderComponent(VPNavBarHamburger, { + class: "hamburger", + active: __props.isScreenOpen, + onClick: ($event) => _ctx.$emit("toggle-screen") + }, null, _parent)); + _push(`
    `); + }; + } +}); +const _sfc_setup$s = _sfc_main$s.setup; +_sfc_main$s.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavBar.vue"); + return _sfc_setup$s ? _sfc_setup$s(props, ctx) : void 0; +}; +const VPNavBar = /* @__PURE__ */ _export_sfc(_sfc_main$s, [["__scopeId", "data-v-6aa21345"]]); +const _sfc_main$r = /* @__PURE__ */ defineComponent({ + __name: "VPNavScreenAppearance", + __ssrInlineRender: true, + setup(__props) { + const { site, theme: theme2 } = useData(); + return (_ctx, _push, _parent, _attrs) => { + if (unref(site).appearance && unref(site).appearance !== "force-dark" && unref(site).appearance !== "force-auto") { + _push(`

    ${ssrInterpolate(unref(theme2).darkModeSwitchLabel || "Appearance")}

    `); + _push(ssrRenderComponent(VPSwitchAppearance, null, null, _parent)); + _push(``); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$r = _sfc_main$r.setup; +_sfc_main$r.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavScreenAppearance.vue"); + return _sfc_setup$r ? _sfc_setup$r(props, ctx) : void 0; +}; +const VPNavScreenAppearance = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["__scopeId", "data-v-b44890b2"]]); +const _sfc_main$q = /* @__PURE__ */ defineComponent({ + __name: "VPNavScreenMenuLink", + __ssrInlineRender: true, + props: { + item: {} + }, + setup(__props) { + const closeScreen = inject("close-screen"); + return (_ctx, _push, _parent, _attrs) => { + _push(ssrRenderComponent(_sfc_main$11, mergeProps({ + class: "VPNavScreenMenuLink", + href: __props.item.link, + target: __props.item.target, + rel: __props.item.rel, + "no-icon": __props.item.noIcon, + onClick: unref(closeScreen) + }, _attrs), { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + _push2(`${__props.item.text ?? ""}`); + } else { + return [ + createVNode("span", { + innerHTML: __props.item.text + }, null, 8, ["innerHTML"]) + ]; + } + }), + _: 1 + }, _parent)); + }; + } +}); +const _sfc_setup$q = _sfc_main$q.setup; +_sfc_main$q.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavScreenMenuLink.vue"); + return _sfc_setup$q ? _sfc_setup$q(props, ctx) : void 0; +}; +const VPNavScreenMenuLink = /* @__PURE__ */ _export_sfc(_sfc_main$q, [["__scopeId", "data-v-df37e6dd"]]); +const _sfc_main$p = /* @__PURE__ */ defineComponent({ + __name: "VPNavScreenMenuGroupLink", + __ssrInlineRender: true, + props: { + item: {} + }, + setup(__props) { + const closeScreen = inject("close-screen"); + return (_ctx, _push, _parent, _attrs) => { + _push(ssrRenderComponent(_sfc_main$11, mergeProps({ + class: "VPNavScreenMenuGroupLink", + href: __props.item.link, + target: __props.item.target, + rel: __props.item.rel, + "no-icon": __props.item.noIcon, + onClick: unref(closeScreen) + }, _attrs), { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + _push2(`${__props.item.text ?? ""}`); + } else { + return [ + createVNode("span", { + innerHTML: __props.item.text + }, null, 8, ["innerHTML"]) + ]; + } + }), + _: 1 + }, _parent)); + }; + } +}); +const _sfc_setup$p = _sfc_main$p.setup; +_sfc_main$p.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavScreenMenuGroupLink.vue"); + return _sfc_setup$p ? _sfc_setup$p(props, ctx) : void 0; +}; +const VPNavScreenMenuGroupLink = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["__scopeId", "data-v-3e9c20e4"]]); +const _sfc_main$o = /* @__PURE__ */ defineComponent({ + __name: "VPNavScreenMenuGroupSection", + __ssrInlineRender: true, + props: { + text: {}, + items: {} + }, + setup(__props) { + return (_ctx, _push, _parent, _attrs) => { + _push(``); + if (__props.text) { + _push(`

    ${ssrInterpolate(__props.text)}

    `); + } else { + _push(``); + } + _push(``); + ssrRenderList(__props.items, (item) => { + _push(ssrRenderComponent(VPNavScreenMenuGroupLink, { + key: item.text, + item + }, null, _parent)); + }); + _push(``); + }; + } +}); +const _sfc_setup$o = _sfc_main$o.setup; +_sfc_main$o.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavScreenMenuGroupSection.vue"); + return _sfc_setup$o ? _sfc_setup$o(props, ctx) : void 0; +}; +const VPNavScreenMenuGroupSection = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["__scopeId", "data-v-8133b170"]]); +const _sfc_main$n = /* @__PURE__ */ defineComponent({ + __name: "VPNavScreenMenuGroup", + __ssrInlineRender: true, + props: { + text: {}, + items: {} + }, + setup(__props) { + const props = __props; + const isOpen = ref(false); + const groupId = computed( + () => `NavScreenGroup-${props.text.replace(" ", "-").toLowerCase()}` + ); + return (_ctx, _push, _parent, _attrs) => { + _push(``); + ssrRenderList(__props.items, (item) => { + _push(``); + if ("link" in item) { + _push(`
    `); + _push(ssrRenderComponent(VPNavScreenMenuGroupLink, { item }, null, _parent)); + _push(`
    `); + } else if ("component" in item) { + _push(`
    `); + ssrRenderVNode(_push, createVNode(resolveDynamicComponent(item.component), mergeProps({ ref_for: true }, item.props, { "screen-menu": "" }), null), _parent); + _push(`
    `); + } else { + _push(`
    `); + _push(ssrRenderComponent(VPNavScreenMenuGroupSection, { + text: item.text, + items: item.items + }, null, _parent)); + _push(`
    `); + } + _push(``); + }); + _push(``); + }; + } +}); +const _sfc_setup$n = _sfc_main$n.setup; +_sfc_main$n.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavScreenMenuGroup.vue"); + return _sfc_setup$n ? _sfc_setup$n(props, ctx) : void 0; +}; +const VPNavScreenMenuGroup = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["__scopeId", "data-v-b9ab8c58"]]); +const _sfc_main$m = /* @__PURE__ */ defineComponent({ + __name: "VPNavScreenMenu", + __ssrInlineRender: true, + setup(__props) { + const { theme: theme2 } = useData(); + return (_ctx, _push, _parent, _attrs) => { + if (unref(theme2).nav) { + _push(``); + ssrRenderList(unref(theme2).nav, (item) => { + _push(``); + if ("link" in item) { + _push(ssrRenderComponent(VPNavScreenMenuLink, { item }, null, _parent)); + } else if ("component" in item) { + ssrRenderVNode(_push, createVNode(resolveDynamicComponent(item.component), mergeProps({ ref_for: true }, item.props, { "screen-menu": "" }), null), _parent); + } else { + _push(ssrRenderComponent(VPNavScreenMenuGroup, { + text: item.text || "", + items: item.items + }, null, _parent)); + } + _push(``); + }); + _push(``); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$m = _sfc_main$m.setup; +_sfc_main$m.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavScreenMenu.vue"); + return _sfc_setup$m ? _sfc_setup$m(props, ctx) : void 0; +}; +const _sfc_main$l = /* @__PURE__ */ defineComponent({ + __name: "VPNavScreenSocialLinks", + __ssrInlineRender: true, + setup(__props) { + const { theme: theme2 } = useData(); + return (_ctx, _push, _parent, _attrs) => { + if (unref(theme2).socialLinks) { + _push(ssrRenderComponent(VPSocialLinks, mergeProps({ + class: "VPNavScreenSocialLinks", + links: unref(theme2).socialLinks + }, _attrs), null, _parent)); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$l = _sfc_main$l.setup; +_sfc_main$l.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavScreenSocialLinks.vue"); + return _sfc_setup$l ? _sfc_setup$l(props, ctx) : void 0; +}; +const _sfc_main$k = /* @__PURE__ */ defineComponent({ + __name: "VPNavScreenTranslations", + __ssrInlineRender: true, + setup(__props) { + const { localeLinks, currentLang } = useLangs({ correspondingLink: true }); + const isOpen = ref(false); + return (_ctx, _push, _parent, _attrs) => { + if (unref(localeLinks).length && unref(currentLang).label) { + _push(`
      `); + ssrRenderList(unref(localeLinks), (locale) => { + _push(`
    • `); + _push(ssrRenderComponent(_sfc_main$11, { + class: "link", + href: locale.link + }, { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + _push2(`${ssrInterpolate(locale.text)}`); + } else { + return [ + createTextVNode(toDisplayString(locale.text), 1) + ]; + } + }), + _: 2 + }, _parent)); + _push(`
    • `); + }); + _push(`
    `); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$k = _sfc_main$k.setup; +_sfc_main$k.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavScreenTranslations.vue"); + return _sfc_setup$k ? _sfc_setup$k(props, ctx) : void 0; +}; +const VPNavScreenTranslations = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["__scopeId", "data-v-858fe1a4"]]); +const _sfc_main$j = /* @__PURE__ */ defineComponent({ + __name: "VPNavScreen", + __ssrInlineRender: true, + props: { + open: { type: Boolean } + }, + setup(__props) { + const screen = ref(null); + useScrollLock(inBrowser ? document.body : null); + return (_ctx, _push, _parent, _attrs) => { + if (__props.open) { + _push(`
    `); + ssrRenderSlot(_ctx.$slots, "nav-screen-content-before", {}, null, _push, _parent); + _push(ssrRenderComponent(_sfc_main$m, { class: "menu" }, null, _parent)); + _push(ssrRenderComponent(VPNavScreenTranslations, { class: "translations" }, null, _parent)); + _push(ssrRenderComponent(VPNavScreenAppearance, { class: "appearance" }, null, _parent)); + _push(ssrRenderComponent(_sfc_main$l, { class: "social-links" }, null, _parent)); + ssrRenderSlot(_ctx.$slots, "nav-screen-content-after", {}, null, _push, _parent); + _push(`
    `); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$j = _sfc_main$j.setup; +_sfc_main$j.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNavScreen.vue"); + return _sfc_setup$j ? _sfc_setup$j(props, ctx) : void 0; +}; +const VPNavScreen = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["__scopeId", "data-v-f2779853"]]); +const _sfc_main$i = /* @__PURE__ */ defineComponent({ + __name: "VPNav", + __ssrInlineRender: true, + setup(__props) { + const { isScreenOpen, closeScreen, toggleScreen } = useNav(); + const { frontmatter } = useData(); + const hasNavbar = computed(() => { + return frontmatter.value.navbar !== false; + }); + provide("close-screen", closeScreen); + watchEffect(() => { + if (inBrowser) { + document.documentElement.classList.toggle("hide-nav", !hasNavbar.value); + } + }); + return (_ctx, _push, _parent, _attrs) => { + if (hasNavbar.value) { + _push(``); + _push(ssrRenderComponent(VPNavBar, { + "is-screen-open": unref(isScreenOpen), + onToggleScreen: unref(toggleScreen) + }, { + "nav-bar-title-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "nav-bar-title-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "nav-bar-title-before", {}, void 0, true) + ]; + } + }), + "nav-bar-title-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "nav-bar-title-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "nav-bar-title-after", {}, void 0, true) + ]; + } + }), + "nav-bar-content-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "nav-bar-content-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "nav-bar-content-before", {}, void 0, true) + ]; + } + }), + "nav-bar-content-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "nav-bar-content-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "nav-bar-content-after", {}, void 0, true) + ]; + } + }), + _: 3 + }, _parent)); + _push(ssrRenderComponent(VPNavScreen, { open: unref(isScreenOpen) }, { + "nav-screen-content-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "nav-screen-content-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "nav-screen-content-before", {}, void 0, true) + ]; + } + }), + "nav-screen-content-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "nav-screen-content-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "nav-screen-content-after", {}, void 0, true) + ]; + } + }), + _: 3 + }, _parent)); + _push(``); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$i = _sfc_main$i.setup; +_sfc_main$i.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPNav.vue"); + return _sfc_setup$i ? _sfc_setup$i(props, ctx) : void 0; +}; +const VPNav = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["__scopeId", "data-v-ae24b3ad"]]); +const _sfc_main$h = /* @__PURE__ */ defineComponent({ + __name: "VPSidebarItem", + __ssrInlineRender: true, + props: { + item: {}, + depth: {} + }, + setup(__props) { + const props = __props; + const { + collapsed, + collapsible, + isLink, + isActiveLink, + hasActiveLink: hasActiveLink2, + hasChildren, + toggle + } = useSidebarControl(computed(() => props.item)); + const sectionTag = computed(() => hasChildren.value ? "section" : `div`); + const linkTag = computed(() => isLink.value ? "a" : "div"); + const textTag = computed(() => { + return !hasChildren.value ? "p" : props.depth + 2 === 7 ? "p" : `h${props.depth + 2}`; + }); + const itemRole = computed(() => isLink.value ? void 0 : "button"); + const classes = computed(() => [ + [`level-${props.depth}`], + { collapsible: collapsible.value }, + { collapsed: collapsed.value }, + { "is-link": isLink.value }, + { "is-active": isActiveLink.value }, + { "has-active": hasActiveLink2.value } + ]); + function onItemInteraction(e) { + if ("key" in e && e.key !== "Enter") { + return; + } + !props.item.link && toggle(); + } + function onCaretClick() { + props.item.link && toggle(); + } + return (_ctx, _push, _parent, _attrs) => { + const _component_VPSidebarItem = resolveComponent("VPSidebarItem", true); + ssrRenderVNode(_push, createVNode(resolveDynamicComponent(sectionTag.value), mergeProps({ + class: ["VPSidebarItem", classes.value] + }, _attrs), { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + if (__props.item.text) { + _push2(`
    `); + if (__props.item.link) { + _push2(ssrRenderComponent(_sfc_main$11, { + tag: linkTag.value, + class: "link", + href: __props.item.link, + rel: __props.item.rel, + target: __props.item.target + }, { + default: withCtx((_2, _push3, _parent3, _scopeId2) => { + if (_push3) { + ssrRenderVNode(_push3, createVNode(resolveDynamicComponent(textTag.value), { class: "text" }, null), _parent3, _scopeId2); + } else { + return [ + (openBlock(), createBlock(resolveDynamicComponent(textTag.value), { + class: "text", + innerHTML: __props.item.text + }, null, 8, ["innerHTML"])) + ]; + } + }), + _: 1 + }, _parent2, _scopeId)); + } else { + ssrRenderVNode(_push2, createVNode(resolveDynamicComponent(textTag.value), { class: "text" }, null), _parent2, _scopeId); + } + if (__props.item.collapsed != null && __props.item.items && __props.item.items.length) { + _push2(`
    `); + } else { + _push2(``); + } + _push2(`
    `); + } else { + _push2(``); + } + if (__props.item.items && __props.item.items.length) { + _push2(`
    `); + if (__props.depth < 5) { + _push2(``); + ssrRenderList(__props.item.items, (i) => { + _push2(ssrRenderComponent(_component_VPSidebarItem, { + key: i.text, + item: i, + depth: __props.depth + 1 + }, null, _parent2, _scopeId)); + }); + _push2(``); + } else { + _push2(``); + } + _push2(`
    `); + } else { + _push2(``); + } + } else { + return [ + __props.item.text ? (openBlock(), createBlock("div", mergeProps({ + key: 0, + class: "item", + role: itemRole.value + }, toHandlers( + __props.item.items ? { click: onItemInteraction, keydown: onItemInteraction } : {}, + true + ), { + tabindex: __props.item.items && 0 + }), [ + createVNode("div", { class: "indicator" }), + __props.item.link ? (openBlock(), createBlock(_sfc_main$11, { + key: 0, + tag: linkTag.value, + class: "link", + href: __props.item.link, + rel: __props.item.rel, + target: __props.item.target + }, { + default: withCtx(() => [ + (openBlock(), createBlock(resolveDynamicComponent(textTag.value), { + class: "text", + innerHTML: __props.item.text + }, null, 8, ["innerHTML"])) + ]), + _: 1 + }, 8, ["tag", "href", "rel", "target"])) : (openBlock(), createBlock(resolveDynamicComponent(textTag.value), { + key: 1, + class: "text", + innerHTML: __props.item.text + }, null, 8, ["innerHTML"])), + __props.item.collapsed != null && __props.item.items && __props.item.items.length ? (openBlock(), createBlock("div", { + key: 2, + class: "caret", + role: "button", + "aria-label": "toggle section", + onClick: onCaretClick, + onKeydown: withKeys(onCaretClick, ["enter"]), + tabindex: "0" + }, [ + createVNode("span", { class: "vpi-chevron-right caret-icon" }) + ], 32)) : createCommentVNode("", true) + ], 16, ["role", "tabindex"])) : createCommentVNode("", true), + __props.item.items && __props.item.items.length ? (openBlock(), createBlock("div", { + key: 1, + class: "items" + }, [ + __props.depth < 5 ? (openBlock(true), createBlock(Fragment, { key: 0 }, renderList(__props.item.items, (i) => { + return openBlock(), createBlock(_component_VPSidebarItem, { + key: i.text, + item: i, + depth: __props.depth + 1 + }, null, 8, ["item", "depth"]); + }), 128)) : createCommentVNode("", true) + ])) : createCommentVNode("", true) + ]; + } + }), + _: 1 + }), _parent); + }; + } +}); +const _sfc_setup$h = _sfc_main$h.setup; +_sfc_main$h.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPSidebarItem.vue"); + return _sfc_setup$h ? _sfc_setup$h(props, ctx) : void 0; +}; +const VPSidebarItem = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["__scopeId", "data-v-b3fd67f8"]]); +const _sfc_main$g = /* @__PURE__ */ defineComponent({ + __name: "VPSidebarGroup", + __ssrInlineRender: true, + props: { + items: {} + }, + setup(__props) { + const disableTransition = ref(true); + let timer = null; + onMounted(() => { + timer = setTimeout(() => { + timer = null; + disableTransition.value = false; + }, 300); + }); + onBeforeUnmount(() => { + if (timer != null) { + clearTimeout(timer); + timer = null; + } + }); + return (_ctx, _push, _parent, _attrs) => { + _push(``); + ssrRenderList(__props.items, (item) => { + _push(`
    `); + _push(ssrRenderComponent(VPSidebarItem, { + item, + depth: 0 + }, null, _parent)); + _push(`
    `); + }); + _push(``); + }; + } +}); +const _sfc_setup$g = _sfc_main$g.setup; +_sfc_main$g.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPSidebarGroup.vue"); + return _sfc_setup$g ? _sfc_setup$g(props, ctx) : void 0; +}; +const VPSidebarGroup = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["__scopeId", "data-v-c40bc020"]]); +const _sfc_main$f = /* @__PURE__ */ defineComponent({ + __name: "VPSidebar", + __ssrInlineRender: true, + props: { + open: { type: Boolean } + }, + setup(__props) { + const { sidebarGroups, hasSidebar } = useSidebar(); + const props = __props; + const navEl = ref(null); + const isLocked = useScrollLock(inBrowser ? document.body : null); + watch( + [props, navEl], + () => { + var _a; + if (props.open) { + isLocked.value = true; + (_a = navEl.value) == null ? void 0 : _a.focus(); + } else isLocked.value = false; + }, + { immediate: true, flush: "post" } + ); + const key = ref(0); + watch( + sidebarGroups, + () => { + key.value += 1; + }, + { deep: true } + ); + return (_ctx, _push, _parent, _attrs) => { + if (unref(hasSidebar)) { + _push(`
    `); + } else { + _push(``); + } + }; + } +}); +const _sfc_setup$f = _sfc_main$f.setup; +_sfc_main$f.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPSidebar.vue"); + return _sfc_setup$f ? _sfc_setup$f(props, ctx) : void 0; +}; +const VPSidebar = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["__scopeId", "data-v-319d5ca6"]]); +const _sfc_main$e = /* @__PURE__ */ defineComponent({ + __name: "VPSkipLink", + __ssrInlineRender: true, + setup(__props) { + const { theme: theme2 } = useData(); + const route = useRoute(); + const backToTop = ref(); + watch(() => route.path, () => backToTop.value.focus()); + return (_ctx, _push, _parent, _attrs) => { + _push(`${ssrInterpolate(unref(theme2).skipToContentLabel || "Skip to content")}`); + }; + } +}); +const _sfc_setup$e = _sfc_main$e.setup; +_sfc_main$e.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPSkipLink.vue"); + return _sfc_setup$e ? _sfc_setup$e(props, ctx) : void 0; +}; +const VPSkipLink = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["__scopeId", "data-v-0b0ada53"]]); +const _sfc_main$d = /* @__PURE__ */ defineComponent({ + __name: "Layout", + __ssrInlineRender: true, + setup(__props) { + const { + isOpen: isSidebarOpen, + open: openSidebar, + close: closeSidebar + } = useSidebar(); + const route = useRoute(); + watch(() => route.path, closeSidebar); + useCloseSidebarOnEscape(isSidebarOpen, closeSidebar); + const { frontmatter } = useData(); + const slots = useSlots(); + const heroImageSlotExists = computed(() => !!slots["home-hero-image"]); + provide("hero-image-slot-exists", heroImageSlotExists); + return (_ctx, _push, _parent, _attrs) => { + const _component_Content = resolveComponent("Content"); + if (unref(frontmatter).layout !== false) { + _push(``); + ssrRenderSlot(_ctx.$slots, "layout-top", {}, null, _push, _parent); + _push(ssrRenderComponent(VPSkipLink, null, null, _parent)); + _push(ssrRenderComponent(VPBackdrop, { + class: "backdrop", + show: unref(isSidebarOpen), + onClick: unref(closeSidebar) + }, null, _parent)); + _push(ssrRenderComponent(VPNav, null, { + "nav-bar-title-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "nav-bar-title-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "nav-bar-title-before", {}, void 0, true) + ]; + } + }), + "nav-bar-title-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "nav-bar-title-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "nav-bar-title-after", {}, void 0, true) + ]; + } + }), + "nav-bar-content-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "nav-bar-content-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "nav-bar-content-before", {}, void 0, true) + ]; + } + }), + "nav-bar-content-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "nav-bar-content-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "nav-bar-content-after", {}, void 0, true) + ]; + } + }), + "nav-screen-content-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "nav-screen-content-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "nav-screen-content-before", {}, void 0, true) + ]; + } + }), + "nav-screen-content-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "nav-screen-content-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "nav-screen-content-after", {}, void 0, true) + ]; + } + }), + _: 3 + }, _parent)); + _push(ssrRenderComponent(VPLocalNav, { + open: unref(isSidebarOpen), + onOpenMenu: unref(openSidebar) + }, null, _parent)); + _push(ssrRenderComponent(VPSidebar, { open: unref(isSidebarOpen) }, { + "sidebar-nav-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "sidebar-nav-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "sidebar-nav-before", {}, void 0, true) + ]; + } + }), + "sidebar-nav-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "sidebar-nav-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "sidebar-nav-after", {}, void 0, true) + ]; + } + }), + _: 3 + }, _parent)); + _push(ssrRenderComponent(VPContent, null, { + "page-top": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "page-top", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "page-top", {}, void 0, true) + ]; + } + }), + "page-bottom": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "page-bottom", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "page-bottom", {}, void 0, true) + ]; + } + }), + "not-found": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "not-found", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "not-found", {}, void 0, true) + ]; + } + }), + "home-hero-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-before", {}, void 0, true) + ]; + } + }), + "home-hero-info-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-info-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-info-before", {}, void 0, true) + ]; + } + }), + "home-hero-info": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-info", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-info", {}, void 0, true) + ]; + } + }), + "home-hero-info-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-info-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-info-after", {}, void 0, true) + ]; + } + }), + "home-hero-actions-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-actions-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-actions-after", {}, void 0, true) + ]; + } + }), + "home-hero-image": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-image", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-image", {}, void 0, true) + ]; + } + }), + "home-hero-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-hero-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-hero-after", {}, void 0, true) + ]; + } + }), + "home-features-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-features-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-features-before", {}, void 0, true) + ]; + } + }), + "home-features-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "home-features-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "home-features-after", {}, void 0, true) + ]; + } + }), + "doc-footer-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "doc-footer-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "doc-footer-before", {}, void 0, true) + ]; + } + }), + "doc-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "doc-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "doc-before", {}, void 0, true) + ]; + } + }), + "doc-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "doc-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "doc-after", {}, void 0, true) + ]; + } + }), + "doc-top": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "doc-top", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "doc-top", {}, void 0, true) + ]; + } + }), + "doc-bottom": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "doc-bottom", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "doc-bottom", {}, void 0, true) + ]; + } + }), + "aside-top": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-top", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-top", {}, void 0, true) + ]; + } + }), + "aside-bottom": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-bottom", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-bottom", {}, void 0, true) + ]; + } + }), + "aside-outline-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-outline-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-outline-before", {}, void 0, true) + ]; + } + }), + "aside-outline-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-outline-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-outline-after", {}, void 0, true) + ]; + } + }), + "aside-ads-before": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-ads-before", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-ads-before", {}, void 0, true) + ]; + } + }), + "aside-ads-after": withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + ssrRenderSlot(_ctx.$slots, "aside-ads-after", {}, null, _push2, _parent2, _scopeId); + } else { + return [ + renderSlot(_ctx.$slots, "aside-ads-after", {}, void 0, true) + ]; + } + }), + _: 3 + }, _parent)); + _push(ssrRenderComponent(VPFooter, null, null, _parent)); + ssrRenderSlot(_ctx.$slots, "layout-bottom", {}, null, _push, _parent); + _push(``); + } else { + _push(ssrRenderComponent(_component_Content, _attrs, null, _parent)); + } + }; + } +}); +const _sfc_setup$d = _sfc_main$d.setup; +_sfc_main$d.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/Layout.vue"); + return _sfc_setup$d ? _sfc_setup$d(props, ctx) : void 0; +}; +const Layout = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["__scopeId", "data-v-5d98c3a5"]]); +const GridSettings = { + xmini: [[0, 2]], + mini: [], + small: [ + [920, 6], + [768, 5], + [640, 4], + [480, 3], + [0, 2] + ], + medium: [ + [960, 5], + [832, 4], + [640, 3], + [480, 2] + ], + big: [ + [832, 3], + [640, 2] + ] +}; +function useSponsorsGrid({ el, size = "medium" }) { + const onResize = throttleAndDebounce(manage, 100); + onMounted(() => { + manage(); + window.addEventListener("resize", onResize); + }); + onUnmounted(() => { + window.removeEventListener("resize", onResize); + }); + function manage() { + adjustSlots(el.value, size); + } +} +function adjustSlots(el, size) { + const tsize = el.children.length; + const asize = el.querySelectorAll(".vp-sponsor-grid-item:not(.empty)").length; + const grid = setGrid(el, size, asize); + manageSlots(el, grid, tsize, asize); +} +function setGrid(el, size, items) { + const settings = GridSettings[size]; + const screen = window.innerWidth; + let grid = 1; + settings.some(([breakpoint, value]) => { + if (screen >= breakpoint) { + grid = items < value ? items : value; + return true; + } + }); + setGridData(el, grid); + return grid; +} +function setGridData(el, value) { + el.dataset.vpGrid = String(value); +} +function manageSlots(el, grid, tsize, asize) { + const diff = tsize - asize; + const rem = asize % grid; + const drem = rem === 0 ? rem : grid - rem; + neutralizeSlots(el, drem - diff); +} +function neutralizeSlots(el, count) { + if (count === 0) { + return; + } + count > 0 ? addSlots(el, count) : removeSlots(el, count * -1); +} +function addSlots(el, count) { + for (let i = 0; i < count; i++) { + const slot = document.createElement("div"); + slot.classList.add("vp-sponsor-grid-item", "empty"); + el.append(slot); + } +} +function removeSlots(el, count) { + for (let i = 0; i < count; i++) { + el.removeChild(el.lastElementChild); + } +} +const _sfc_main$c = /* @__PURE__ */ defineComponent({ + __name: "VPSponsorsGrid", + __ssrInlineRender: true, + props: { + size: { default: "medium" }, + data: {} + }, + setup(__props) { + const props = __props; + const el = ref(null); + useSponsorsGrid({ el, size: props.size }); + return (_ctx, _push, _parent, _attrs) => { + _push(``); + ssrRenderList(__props.data, (sponsor) => { + _push(``); + }); + _push(``); + }; + } +}); +const _sfc_setup$c = _sfc_main$c.setup; +_sfc_main$c.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPSponsorsGrid.vue"); + return _sfc_setup$c ? _sfc_setup$c(props, ctx) : void 0; +}; +const _sfc_main$b = /* @__PURE__ */ defineComponent({ + __name: "VPSponsors", + __ssrInlineRender: true, + props: { + mode: { default: "normal" }, + tier: {}, + size: {}, + data: {} + }, + setup(__props) { + const props = __props; + const sponsors = computed(() => { + const isSponsors = props.data.some((s) => { + return "items" in s; + }); + if (isSponsors) { + return props.data; + } + return [ + { tier: props.tier, size: props.size, items: props.data } + ]; + }); + return (_ctx, _push, _parent, _attrs) => { + _push(``); + ssrRenderList(sponsors.value, (sponsor, index) => { + _push(`
    `); + if (sponsor.tier) { + _push(`

    ${ssrInterpolate(sponsor.tier)}

    `); + } else { + _push(``); + } + _push(ssrRenderComponent(_sfc_main$c, { + size: sponsor.size, + data: sponsor.items + }, null, _parent)); + _push(`
    `); + }); + _push(``); + }; + } +}); +const _sfc_setup$b = _sfc_main$b.setup; +_sfc_main$b.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPSponsors.vue"); + return _sfc_setup$b ? _sfc_setup$b(props, ctx) : void 0; +}; +const _sfc_main$a = /* @__PURE__ */ defineComponent({ + __name: "VPDocAsideSponsors", + __ssrInlineRender: true, + props: { + tier: {}, + size: {}, + data: {} + }, + setup(__props) { + return (_ctx, _push, _parent, _attrs) => { + _push(``); + _push(ssrRenderComponent(_sfc_main$b, { + mode: "aside", + tier: __props.tier, + size: __props.size, + data: __props.data + }, null, _parent)); + _push(``); + }; + } +}); +const _sfc_setup$a = _sfc_main$a.setup; +_sfc_main$a.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPDocAsideSponsors.vue"); + return _sfc_setup$a ? _sfc_setup$a(props, ctx) : void 0; +}; +const _sfc_main$9 = /* @__PURE__ */ defineComponent({ + __name: "VPHomeSponsors", + __ssrInlineRender: true, + props: { + message: {}, + actionText: { default: "Become a sponsor" }, + actionLink: {}, + data: {} + }, + setup(__props) { + return (_ctx, _push, _parent, _attrs) => { + _push(`
    `); + if (__props.message) { + _push(`

    ${ssrInterpolate(__props.message)}

    `); + } else { + _push(``); + } + _push(`
    `); + _push(ssrRenderComponent(_sfc_main$b, { data: __props.data }, null, _parent)); + _push(`
    `); + if (__props.actionLink) { + _push(`
    `); + _push(ssrRenderComponent(VPButton, { + theme: "sponsor", + text: __props.actionText, + href: __props.actionLink + }, null, _parent)); + _push(`
    `); + } else { + _push(``); + } + _push(`
    `); + }; + } +}); +const _sfc_setup$9 = _sfc_main$9.setup; +_sfc_main$9.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPHomeSponsors.vue"); + return _sfc_setup$9 ? _sfc_setup$9(props, ctx) : void 0; +}; +const _sfc_main$8 = /* @__PURE__ */ defineComponent({ + __name: "VPTeamMembersItem", + __ssrInlineRender: true, + props: { + size: { default: "medium" }, + member: {} + }, + setup(__props) { + return (_ctx, _push, _parent, _attrs) => { + _push(`

    ${ssrInterpolate(__props.member.name)}

    `); + if (__props.member.title || __props.member.org) { + _push(`

    `); + if (__props.member.title) { + _push(`${ssrInterpolate(__props.member.title)}`); + } else { + _push(``); + } + if (__props.member.title && __props.member.org) { + _push(` @ `); + } else { + _push(``); + } + if (__props.member.org) { + _push(ssrRenderComponent(_sfc_main$11, { + class: ["org", { link: __props.member.orgLink }], + href: __props.member.orgLink, + "no-icon": "" + }, { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + _push2(`${ssrInterpolate(__props.member.org)}`); + } else { + return [ + createTextVNode(toDisplayString(__props.member.org), 1) + ]; + } + }), + _: 1 + }, _parent)); + } else { + _push(``); + } + _push(`

    `); + } else { + _push(``); + } + if (__props.member.desc) { + _push(`

    ${__props.member.desc ?? ""}

    `); + } else { + _push(``); + } + if (__props.member.links) { + _push(``); + } else { + _push(``); + } + _push(`
    `); + if (__props.member.sponsor) { + _push(`
    `); + _push(ssrRenderComponent(_sfc_main$11, { + class: "sp-link", + href: __props.member.sponsor, + "no-icon": "" + }, { + default: withCtx((_, _push2, _parent2, _scopeId) => { + if (_push2) { + _push2(` ${ssrInterpolate(__props.member.actionText || "Sponsor")}`); + } else { + return [ + createVNode("span", { class: "vpi-heart sp-icon" }), + createTextVNode(" " + toDisplayString(__props.member.actionText || "Sponsor"), 1) + ]; + } + }), + _: 1 + }, _parent)); + _push(`
    `); + } else { + _push(``); + } + _push(``); + }; + } +}); +const _sfc_setup$8 = _sfc_main$8.setup; +_sfc_main$8.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPTeamMembersItem.vue"); + return _sfc_setup$8 ? _sfc_setup$8(props, ctx) : void 0; +}; +const VPTeamMembersItem = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-f3fa364a"]]); +const _sfc_main$7 = /* @__PURE__ */ defineComponent({ + __name: "VPTeamMembers", + __ssrInlineRender: true, + props: { + size: { default: "medium" }, + members: {} + }, + setup(__props) { + const props = __props; + const classes = computed(() => [props.size, `count-${props.members.length}`]); + return (_ctx, _push, _parent, _attrs) => { + _push(`
    `); + ssrRenderList(__props.members, (member) => { + _push(`
    `); + _push(ssrRenderComponent(VPTeamMembersItem, { + size: __props.size, + member + }, null, _parent)); + _push(`
    `); + }); + _push(`
    `); + }; + } +}); +const _sfc_setup$7 = _sfc_main$7.setup; +_sfc_main$7.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPTeamMembers.vue"); + return _sfc_setup$7 ? _sfc_setup$7(props, ctx) : void 0; +}; +const _sfc_main$6 = {}; +const _sfc_setup$6 = _sfc_main$6.setup; +_sfc_main$6.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPTeamPage.vue"); + return _sfc_setup$6 ? _sfc_setup$6(props, ctx) : void 0; +}; +const _sfc_main$5 = {}; +const _sfc_setup$5 = _sfc_main$5.setup; +_sfc_main$5.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPTeamPageSection.vue"); + return _sfc_setup$5 ? _sfc_setup$5(props, ctx) : void 0; +}; +const _sfc_main$4 = {}; +const _sfc_setup$4 = _sfc_main$4.setup; +_sfc_main$4.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../node_modules/vitepress/dist/client/theme-default/components/VPTeamPageTitle.vue"); + return _sfc_setup$4 ? _sfc_setup$4(props, ctx) : void 0; +}; +const theme = { + Layout, + enhanceApp: ({ app }) => { + app.component("Badge", _sfc_main$18); + } +}; +const _sfc_main$3 = /* @__PURE__ */ defineComponent({ + __name: "NotelyCallout", + __ssrInlineRender: true, + props: { + type: { default: "info" }, + label: {} + }, + setup(__props) { + const props = __props; + const icon = computed(() => { + const icons = { + info: "ℹ", + tip: "💡", + warning: "⚠️", + danger: "🚨", + important: "📌", + success: "✅" + }; + return icons[props.type] ?? "ℹ"; + }); + const labelText = computed(() => { + if (props.label) return props.label; + const defaults = { + info: "Info", + tip: "Tip", + warning: "Warning", + danger: "Danger", + important: "Important", + success: "Success" + }; + return defaults[props.type] ?? "Note"; + }); + return (_ctx, _push, _parent, _attrs) => { + _push(`
    ${ssrInterpolate(labelText.value)}
    `); + ssrRenderSlot(_ctx.$slots, "default", {}, null, _push, _parent); + _push(`
    `); + }; + } +}); +const _sfc_setup$3 = _sfc_main$3.setup; +_sfc_main$3.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../docs-site/.vitepress/theme/components/NotelyCallout.vue"); + return _sfc_setup$3 ? _sfc_setup$3(props, ctx) : void 0; +}; +const NotelyCallout = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-42f108e5"]]); +const _sfc_main$2 = /* @__PURE__ */ defineComponent({ + __name: "ShortcutTable", + __ssrInlineRender: true, + props: { + shortcuts: {}, + context: { default: "Keyboard" } + }, + setup(__props) { + function toKeyList(key) { + return key.split("+").map((k) => k.trim()); + } + function macify(key) { + return key.replace(/Ctrl/gi, "⌘").replace(/Alt/gi, "⌥").replace(/Shift/gi, "⇧").replace(/Cmd/gi, "⌘"); + } + return (_ctx, _push, _parent, _attrs) => { + _push(``); + ssrRenderList(__props.shortcuts, (s) => { + _push(``); + }); + _push(`
    ActionWindows / LinuxmacOS
    ${ssrInterpolate(s.action)}`); + ssrRenderList(toKeyList(s.win ?? s.key), (key) => { + _push(`${ssrInterpolate(key)}`); + }); + _push(``); + ssrRenderList(toKeyList(s.mac ?? macify(s.key)), (key) => { + _push(`${ssrInterpolate(key)}`); + }); + _push(`
    `); + }; + } +}); +const _sfc_setup$2 = _sfc_main$2.setup; +_sfc_main$2.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../docs-site/.vitepress/theme/components/ShortcutTable.vue"); + return _sfc_setup$2 ? _sfc_setup$2(props, ctx) : void 0; +}; +const ShortcutTable = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-4607adc0"]]); +const _sfc_main$1 = /* @__PURE__ */ defineComponent({ + __name: "FeatureMatrix", + __ssrInlineRender: true, + props: { + features: {} + }, + setup(__props) { + const StatusIcon = defineComponent({ + props: { value: [Boolean, String] }, + render() { + const v = this.value; + if (v === true || v === "Yes") + return h("span", { class: "status-yes", "aria-label": "Yes" }, "✓"); + if (v === false || v === "No" || v === "") + return h("span", { class: "status-no", "aria-label": "No" }, "—"); + return h("span", { class: "status-partial", "aria-label": String(v) }, "◦"); + } + }); + return (_ctx, _push, _parent, _attrs) => { + _push(``); + ssrRenderList(__props.features, (f) => { + _push(``); + }); + _push(`
    FeatureAvailable by defaultNeeds setupInternet required
    ${ssrInterpolate(f.feature)}`); + _push(ssrRenderComponent(unref(StatusIcon), { + value: f.available + }, null, _parent)); + _push(``); + if (f.setup && f.setup !== "No") { + _push(`${ssrInterpolate(f.setup)}`); + } else { + _push(ssrRenderComponent(unref(StatusIcon), { + value: f.setup === "No" ? false : false + }, null, _parent)); + } + _push(``); + _push(ssrRenderComponent(unref(StatusIcon), { + value: f.internet + }, null, _parent)); + _push(`
    `); + }; + } +}); +const _sfc_setup$1 = _sfc_main$1.setup; +_sfc_main$1.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../docs-site/.vitepress/theme/components/FeatureMatrix.vue"); + return _sfc_setup$1 ? _sfc_setup$1(props, ctx) : void 0; +}; +const FeatureMatrix = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-e0e0ebb4"]]); +const _sfc_main = /* @__PURE__ */ defineComponent({ + __name: "HomeLayout", + __ssrInlineRender: true, + setup(__props) { + useRoute(); + return (_ctx, _push, _parent, _attrs) => { + _push(ssrRenderComponent(unref(theme).Layout, _attrs, null, _parent)); + }; + } +}); +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../docs-site/.vitepress/theme/HomeLayout.vue"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const RawTheme = { + extends: theme, + Layout: _sfc_main, + enhanceApp({ app }) { + app.component("NotelyCallout", NotelyCallout); + app.component("ShortcutTable", ShortcutTable); + app.component("FeatureMatrix", FeatureMatrix); + } +}; +const ClientOnly = defineComponent({ + setup(_, { slots }) { + const show = ref(false); + onMounted(() => { + show.value = true; + }); + return () => show.value && slots.default ? slots.default() : null; + } +}); +function useCodeGroups() { + if (inBrowser) { + window.addEventListener("click", (e) => { + var _a; + const el = e.target; + if (el.matches(".vp-code-group input")) { + const group = (_a = el.parentElement) == null ? void 0 : _a.parentElement; + if (!group) + return; + const i = Array.from(group.querySelectorAll("input")).indexOf(el); + if (i < 0) + return; + const blocks = group.querySelector(".blocks"); + if (!blocks) + return; + const current = Array.from(blocks.children).find((child) => child.classList.contains("active")); + if (!current) + return; + const next = blocks.children[i]; + if (!next || current === next) + return; + current.classList.remove("active"); + next.classList.add("active"); + const label = group == null ? void 0 : group.querySelector(`label[for="${el.id}"]`); + label == null ? void 0 : label.scrollIntoView({ block: "nearest" }); + } + }); + } +} +function useCopyCode() { + if (inBrowser) { + const timeoutIdMap = /* @__PURE__ */ new WeakMap(); + window.addEventListener("click", (e) => { + var _a; + const el = e.target; + if (el.matches('div[class*="language-"] > button.copy')) { + const parent = el.parentElement; + const sibling = (_a = el.nextElementSibling) == null ? void 0 : _a.nextElementSibling; + if (!parent || !sibling) { + return; + } + const isShell = /language-(shellscript|shell|bash|sh|zsh)/.test(parent.className); + const ignoredNodes = [".vp-copy-ignore", ".diff.remove"]; + const clone = sibling.cloneNode(true); + clone.querySelectorAll(ignoredNodes.join(",")).forEach((node) => node.remove()); + let text = clone.textContent || ""; + if (isShell) { + text = text.replace(/^ *(\$|>) /gm, "").trim(); + } + copyToClipboard(text).then(() => { + el.classList.add("copied"); + clearTimeout(timeoutIdMap.get(el)); + const timeoutId = setTimeout(() => { + el.classList.remove("copied"); + el.blur(); + timeoutIdMap.delete(el); + }, 2e3); + timeoutIdMap.set(el, timeoutId); + }); + } + }); + } +} +async function copyToClipboard(text) { + try { + return navigator.clipboard.writeText(text); + } catch { + const element = document.createElement("textarea"); + const previouslyFocusedElement = document.activeElement; + element.value = text; + element.setAttribute("readonly", ""); + element.style.contain = "strict"; + element.style.position = "absolute"; + element.style.left = "-9999px"; + element.style.fontSize = "12pt"; + const selection = document.getSelection(); + const originalRange = selection ? selection.rangeCount > 0 && selection.getRangeAt(0) : null; + document.body.appendChild(element); + element.select(); + element.selectionStart = 0; + element.selectionEnd = text.length; + document.execCommand("copy"); + document.body.removeChild(element); + if (originalRange) { + selection.removeAllRanges(); + selection.addRange(originalRange); + } + if (previouslyFocusedElement) { + previouslyFocusedElement.focus(); + } + } +} +function useUpdateHead(route, siteDataByRouteRef) { + let isFirstUpdate = true; + let managedHeadElements = []; + const updateHeadTags = (newTags) => { + if (isFirstUpdate) { + isFirstUpdate = false; + newTags.forEach((tag) => { + const headEl = createHeadElement(tag); + for (const el of document.head.children) { + if (el.isEqualNode(headEl)) { + managedHeadElements.push(el); + return; + } + } + }); + return; + } + const newElements = newTags.map(createHeadElement); + managedHeadElements.forEach((oldEl, oldIndex) => { + const matchedIndex = newElements.findIndex((newEl) => newEl == null ? void 0 : newEl.isEqualNode(oldEl ?? null)); + if (matchedIndex !== -1) { + delete newElements[matchedIndex]; + } else { + oldEl == null ? void 0 : oldEl.remove(); + delete managedHeadElements[oldIndex]; + } + }); + newElements.forEach((el) => el && document.head.appendChild(el)); + managedHeadElements = [...managedHeadElements, ...newElements].filter(Boolean); + }; + watchEffect(() => { + const pageData = route.data; + const siteData2 = siteDataByRouteRef.value; + const pageDescription = pageData && pageData.description; + const frontmatterHead = pageData && pageData.frontmatter.head || []; + const title = createTitle(siteData2, pageData); + if (title !== document.title) { + document.title = title; + } + const description = pageDescription || siteData2.description; + let metaDescriptionElement = document.querySelector(`meta[name=description]`); + if (metaDescriptionElement) { + if (metaDescriptionElement.getAttribute("content") !== description) { + metaDescriptionElement.setAttribute("content", description); + } + } else { + createHeadElement(["meta", { name: "description", content: description }]); + } + updateHeadTags(mergeHead(siteData2.head, filterOutHeadDescription(frontmatterHead))); + }); +} +function createHeadElement([tag, attrs, innerHTML]) { + const el = document.createElement(tag); + for (const key in attrs) { + el.setAttribute(key, attrs[key]); + } + if (innerHTML) { + el.innerHTML = innerHTML; + } + if (tag === "script" && attrs.async == null) { + el.async = false; + } + return el; +} +function isMetaDescription(headConfig) { + return headConfig[0] === "meta" && headConfig[1] && headConfig[1].name === "description"; +} +function filterOutHeadDescription(head) { + return head.filter((h2) => !isMetaDescription(h2)); +} +const hasFetched = /* @__PURE__ */ new Set(); +const createLink = () => document.createElement("link"); +const viaDOM = (url) => { + const link2 = createLink(); + link2.rel = `prefetch`; + link2.href = url; + document.head.appendChild(link2); +}; +const viaXHR = (url) => { + const req = new XMLHttpRequest(); + req.open("GET", url, req.withCredentials = true); + req.send(); +}; +let link; +const doFetch = inBrowser && (link = createLink()) && link.relList && link.relList.supports && link.relList.supports("prefetch") ? viaDOM : viaXHR; +function usePrefetch() { + if (!inBrowser) { + return; + } + if (!window.IntersectionObserver) { + return; + } + let conn; + if ((conn = navigator.connection) && (conn.saveData || /2g/.test(conn.effectiveType))) { + return; + } + const rIC = window.requestIdleCallback || setTimeout; + let observer = null; + const observeLinks = () => { + if (observer) { + observer.disconnect(); + } + observer = new IntersectionObserver((entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + const link2 = entry.target; + observer.unobserve(link2); + const { pathname } = link2; + if (!hasFetched.has(pathname)) { + hasFetched.add(pathname); + const pageChunkPath = pathToFile(pathname); + if (pageChunkPath) + doFetch(pageChunkPath); + } + } + }); + }); + rIC(() => { + document.querySelectorAll("#app a").forEach((link2) => { + const { hostname, pathname } = new URL(link2.href instanceof SVGAnimatedString ? link2.href.animVal : link2.href, link2.baseURI); + const extMatch = pathname.match(/\.\w+$/); + if (extMatch && extMatch[0] !== ".html") { + return; + } + if ( + // only prefetch same tab navigation, since a new tab will load + // the lean js chunk instead. + link2.target !== "_blank" && // only prefetch inbound links + hostname === location.hostname + ) { + if (pathname !== location.pathname) { + observer.observe(link2); + } else { + hasFetched.add(pathname); + } + } + }); + }); + }; + onMounted(observeLinks); + const route = useRoute(); + watch(() => route.path, observeLinks); + onUnmounted(() => { + observer && observer.disconnect(); + }); +} +function resolveThemeExtends(theme2) { + if (theme2.extends) { + const base = resolveThemeExtends(theme2.extends); + return { + ...base, + ...theme2, + async enhanceApp(ctx) { + if (base.enhanceApp) + await base.enhanceApp(ctx); + if (theme2.enhanceApp) + await theme2.enhanceApp(ctx); + } + }; + } + return theme2; +} +const Theme = resolveThemeExtends(RawTheme); +const VitePressApp = defineComponent({ + name: "VitePressApp", + setup() { + const { site, lang, dir } = useData$1(); + onMounted(() => { + watchEffect(() => { + document.documentElement.lang = lang.value; + document.documentElement.dir = dir.value; + }); + }); + if (site.value.router.prefetchLinks) { + usePrefetch(); + } + useCopyCode(); + useCodeGroups(); + if (Theme.setup) + Theme.setup(); + return () => h(Theme.Layout); + } +}); +async function createApp() { + globalThis.__VITEPRESS__ = true; + const router = newRouter(); + const app = newApp(); + app.provide(RouterSymbol, router); + const data = initData(router.route); + app.provide(dataSymbol, data); + app.component("Mermaid", _sfc_main$19); + app.component("Content", Content); + app.component("ClientOnly", ClientOnly); + Object.defineProperties(app.config.globalProperties, { + $frontmatter: { + get() { + return data.frontmatter.value; + } + }, + $params: { + get() { + return data.page.value.params; + } + } + }); + if (Theme.enhanceApp) { + await Theme.enhanceApp({ + app, + router, + siteData: siteDataRef + }); + } + return { app, router, data }; +} +function newApp() { + return createSSRApp(VitePressApp); +} +function newRouter() { + let isInitialPageLoad = inBrowser; + return createRouter((path) => { + let pageFilePath = pathToFile(path); + let pageModule = null; + if (pageFilePath) { + if (isInitialPageLoad) { + pageFilePath = pageFilePath.replace(/\.js$/, ".lean.js"); + } + if (false) ; + else { + pageModule = import( + /*@vite-ignore*/ + pageFilePath + ); + } + } + if (inBrowser) { + isInitialPageLoad = false; + } + return pageModule; + }, Theme.NotFound); +} +if (inBrowser) { + createApp().then(({ app, router, data }) => { + router.go().then(() => { + useUpdateHead(router.route, data.site); + app.mount("#app"); + }); + }); +} +async function render(path) { + const { app, router } = await createApp(); + await router.go(path); + const ctx = { content: "", vpSocialIcons: /* @__PURE__ */ new Set() }; + ctx.content = await renderToString(app, ctx); + return ctx; +} +export { + useRouter as a, + createSearchTranslate as c, + dataSymbol as d, + escapeRegExp as e, + inBrowser as i, + pathToFile as p, + render, + useData as u +}; diff --git a/docs-site/.vitepress/.temp/architecture.md.js b/docs-site/.vitepress/.temp/architecture.md.js new file mode 100644 index 00000000..fda4365b --- /dev/null +++ b/docs-site/.vitepress/.temp/architecture.md.js @@ -0,0 +1,70 @@ +import { resolveComponent, useSSRContext } from "vue"; +import { ssrRenderAttrs, ssrRenderSuspense, ssrRenderComponent, ssrRenderStyle } from "vue/server-renderer"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse(`{"title":"Application Architecture","description":"Comprehensive overview of Notely's offline-first desktop application architecture, subsystems, IPC messaging, storage layers, and logging infrastructure.","frontmatter":{"title":"Application Architecture","description":"Comprehensive overview of Notely's offline-first desktop application architecture, subsystems, IPC messaging, storage layers, and logging infrastructure.","keywords":"architecture, Electron, React, CodeMirror, SQLite, Git, P2P sync, IPC, LogDB","category":"Developer"},"headers":[],"relativePath":"architecture.md","filePath":"architecture.md","lastUpdated":1786126353000}`); +const _sfc_main = { name: "architecture.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + const _component_Mermaid = resolveComponent("Mermaid"); + _push(`

    Notely Application Architecture

    Notely is an offline-first, local-first markdown note-taking and knowledge management application built using Electron, React, CodeMirror 6, and Node.js.


    1. High-Level Architecture Overview

    Notely separates execution between a sandboxed Renderer Process (React UI) and a privileged Main Process (Node.js backend) communicating via secure IPC channels.

    `); + ssrRenderSuspense(_push, { + default: () => { + _push(ssrRenderComponent(_component_Mermaid, { + id: "mermaid-13", + class: "mermaid", + graph: "graph%20TD%0A%20%20%20%20subgraph%20Renderer%20%5B%22Renderer%20Process%20(React%20%2B%20Vite)%22%5D%0A%20%20%20%20%20%20%20%20UI%5BApp%20Layout%20%26%20TopBar%5D%0A%20%20%20%20%20%20%20%20CM%5BCodeMirror%206%20Editor%5D%0A%20%20%20%20%20%20%20%20Prev%5BMarkdown%20Preview%20%26%20Media%5D%0A%20%20%20%20%20%20%20%20Ctx%5BUIState%20%26%20Document%20Contexts%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20Bridge%20%5B%22Secure%20Preload%20Bridge%22%5D%0A%20%20%20%20%20%20%20%20IPC%5Bpreload.cjs%20-%20ContextBridge%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20Main%20%5B%22Main%20Process%20(Electron%20%2F%20Node.js)%22%5D%0A%20%20%20%20%20%20%20%20FS%5BDocument%20%26%20File%20System%20Service%5D%0A%20%20%20%20%20%20%20%20Git%5BGit%20Version%20Control%20Subsystem%5D%0A%20%20%20%20%20%20%20%20Sync%5BP2P%20Sync%20Engine%5D%0A%20%20%20%20%20%20%20%20Exp%5BPackage%20%26%20Export%20Manager%5D%0A%20%20%20%20%20%20%20%20AI%5BAI%20Agent%20%26%20Context%20Engine%5D%0A%20%20%20%20%20%20%20%20Logs%5BCentralized%20LogDB%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20Storage%20%5B%22Workspace%20%26%20Application%20Storage%22%5D%0A%20%20%20%20%20%20%20%20Files%5BMarkdown%20Note%20Files%5D%0A%20%20%20%20%20%20%20%20AppDb%5B(app.sqlite%20-%20Global%20Config)%5D%0A%20%20%20%20%20%20%20%20LogsDb%5B(.notes-app%2Fai-logs.db)%5D%0A%20%20%20%20%20%20%20%20VecDb%5B(.notes-app%2Fai-embeddings.db)%5D%0A%20%20%20%20%20%20%20%20GraphDb%5B(.notes-app%2Fai-graph.db)%5D%0A%20%20%20%20end%0A%0A%20%20%20%20UI%20--%3E%20IPC%0A%20%20%20%20CM%20--%3E%20IPC%0A%20%20%20%20IPC%20--%3E%20FS%0A%20%20%20%20IPC%20--%3E%20Git%0A%20%20%20%20IPC%20--%3E%20Sync%0A%20%20%20%20IPC%20--%3E%20Exp%0A%20%20%20%20IPC%20--%3E%20AI%0A%20%20%20%20IPC%20--%3E%20Logs%0A%0A%20%20%20%20FS%20--%3E%20Files%0A%20%20%20%20Main%20--%3E%20AppDb%0A%20%20%20%20Logs%20--%3E%20LogsDb%0A%20%20%20%20AI%20--%3E%20VecDb%0A%20%20%20%20AI%20--%3E%20GraphDb%0A" + }, null, _parent)); + }, + fallback: () => { + _push(` Loading... `); + }, + _: 1 + }); + _push(`

    2. Renderer Layer (React & Editor Architecture)

    The user interface is powered by React 18, Vite, and custom CSS variables supporting dynamic light/dark mode themes.

    Component Structure

    • App Shell (App.jsx): Manages primary navigation, view routing, full-screen page overlays (KnowledgeGraph, EmbeddingsPage, AppLogsPage, AIPersonasManager, AIHealthPage, GitVC), and footer status bar.
    • Layout Engine (LandingView.jsx, EditorPane.jsx, DocumentDetail.jsx): Responsive split-pane layout supporting Edit mode, Preview mode, and Live Split View.
    • Editor Core (CodeMirrorEditor.jsx, MarkdownEditor.jsx): Built on CodeMirror 6 with custom extensions for syntax highlighting, line numbers, block folding, spell-checking, search/replace, and hotkeys.
    • Preview Renderer (MarkdownPreview.jsx): Full GitHub-Flavored Markdown (GFM) renderer supporting LaTeX equations (katex), task lists, local media resolution, and Wikilink navigation ([[Note]]).
    • Mermaid.js Integration: Real-time evaluation and SVG rendering of GFM code blocks (\`\`\`mermaid) for flowcharts, sequence diagrams, class diagrams, Gantt charts, and mindmaps across preview mode, split view, and exported documents.
    • Excalidraw Drawing Editor: Embedded interactive whiteboard component allowing users to sketch visual diagrams, hand-drawn wireframes, and architectural schematics. Drawings are persisted as human-readable .excalidraw JSON files or embedded SVG graphics inside workspace notes.

    State Management & Contexts

    • UIStateContext.jsx: Controls global dialogs, sidebar panels, active full-screen pages, theme preferences, and zoom factors.
    • DocumentContext.jsx: Tracks the open document list, active document handle, unsaved dirty states, file content buffers, and document metadata.

    3. Main Process & Application Subsystems

    The Electron main process (electron/main.cjs & electron/lib/) coordinates application logic across core subsystems:

    A. Document & File System Service

    • File Watcher (chokidar): Watches workspace directory tree recursively for external file additions, edits, renames, and deletions.
    • Subfolder & Path Traversal: Resolves relative note paths, handles file CRUD operations safely, and computes workspace-wide document statistics.

    B. Git Version Control Subsystem (gitService.cjs)

    • Local Git Execution: Runs native git CLI commands synchronously or asynchronously without external cloud dependencies.
    • Feature Set: Workspace initialization, status tracking (staged/unstaged files), diff generation, commit creation, branch management, and commit history inspection.

    C. P2P Local Sync Engine (p2pService.cjs)

    • Peer Discovery: Discovers local network peers for direct device-to-device note synchronization.
    • Status Snapshots: Tracks live peer connection states and sync progress.

    D. Package, Import & Export Subsystem (notePackageIpc.cjs)

    Document Exporters:

    • Exports individual markdown notes to HTML and PDF formats via Headless Chromium rendering (CSS theme applied, media resolved).

    Note Package System (.note bundle format):

    • Bundles selected .md files with all linked assets into a single portable .note file via File → Export / Import Note Package.
    • Bundled assets: markdown files, media/images/, Excalidraw diagrams (.notes-app/excali-diagrams/), Draw.io diagrams (media/draw.io/), and auto-generated metadata.json.
    • Security: AES-256 encrypted bundle (not readable by generic ZIP tools). Each file is SHA-256 hashed and verified on import to reject tampered packages. Optional password protection stores a salted SHA-256 signature in the manifest.
    • Import: Decrypts and verifies bundle integrity, resolves asset path conflicts, and places all files into the active workspace. See Export & Import Reference for full user-facing documentation.

    E. AI & Context Engine Subsystem (aiService.cjs)

    • Vector Embeddings Engine (EmbeddingDB.js): Stores 384-dimensional BGE-small vector chunks in {workspace}/.notes-app/ai-embeddings.db. Features physical vector dimension validation (verifyModelDimensions) to prevent dimension mismatches.
    • Knowledge Graph Subsystem (GraphService.js, GraphDB.js): Maps note relations, tags, mentions, Wikilinks, Images, Local Documents, and External URLs in {workspace}/.notes-app/ai-graph.db. Executes relation traversals via SQLite Recursive Common Table Expressions (CTEs).
    • Agent & Tool Orchestration: Integrates with a local embedding runtime and cloud LLMs (Gemini, Groq, OpenAI) using the Vercel AI SDK.
    • Local ONNX Neural Models: Vector embeddings (BGE-small-en-v1.5) and Knowledge Graph entity/relationship extraction (gliner2-multi-v1-onnx) run 100% on-device and offline using onnxruntime-node.

    AI Layer Architecture

    The following diagram shows the full request path from the React UI through each layer to inference and storage:

    `); + ssrRenderSuspense(_push, { + default: () => { + _push(ssrRenderComponent(_component_Mermaid, { + id: "mermaid-192", + class: "mermaid", + graph: "flowchart%20TD%0A%20%20%20%20subgraph%20Renderer%5B%22Renderer%20Process%20(React%20%2F%20Vite)%22%5D%0A%20%20%20%20%20%20%20%20direction%20LR%0A%20%20%20%20%20%20%20%20ACP%5B%22AIChatPanel%22%5D%20%26%20AIS%5B%22AISettings%22%5D%20%26%20EBP%5B%22EmbeddingsPage%22%5D%20%26%20KGV%5B%22KnowledgeGraph%22%5D%0A%20%20%20%20%20%20%20%20UAI%5B%22useAIAssistant%20hook%22%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20Preload%5B%22Preload%20Bridge%20(preload.cjs)%22%5D%0A%20%20%20%20%20%20%20%20CB%5B%22window.electronAPI.ai.*%22%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20Handlers%5B%22AI%20IPC%20Handlers%20%E2%80%94%20aiHandlers.cjs%22%5D%0A%20%20%20%20%20%20%20%20TRUST%5B%22Trusted%20Sender%20Guard%22%5D%0A%20%20%20%20%20%20%20%20CHAN%5B%2255%2B%20ipcMain.handle%20channels%22%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20AIService%5B%22AI%20Service%20%E2%80%94%20AIService.js%20(Singleton)%22%5D%0A%20%20%20%20%20%20%20%20SW%5B%22Master%20Enable%20%2F%20Disable%20Switch%22%5D%0A%20%20%20%20%20%20%20%20HOOKS%5B%22Note%20Save%20%C2%B7%20Delete%20%C2%B7%20Rename%20Hooks%22%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20Agent%5B%22Agent%20Orchestrator%20%E2%80%94%20Agent.js%22%5D%0A%20%20%20%20%20%20%20%20direction%20LR%0A%20%20%20%20%20%20%20%20LR%5B%22LLMRegistry%22%5D%20%26%20ES%5B%22EmbeddingService%22%5D%20%26%20GS%5B%22GraphService%22%5D%20%26%20CE%5B%22ContextEngine%22%5D%20%26%20QE%5B%22QueryExecutor%22%5D%0A%20%20%20%20%20%20%20%20GP%5B%22graphProvider%22%5D%20%26%20LMM%5B%22localModelManager%22%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20Providers%5B%22Inference%20Providers%22%5D%0A%20%20%20%20%20%20%20%20direction%20LR%0A%20%20%20%20%20%20%20%20GEM%5B%22GeminiProvider%22%5D%20%26%20GRQ%5B%22GroqProvider%22%5D%20%26%20OAI%5B%22OpenAICompatibleProvider%22%5D%20%26%20LLP%5B%22LocalLlamaProvider%20(Qwen2.5)%22%5D%0A%20%20%20%20%20%20%20%20HFEP%5B%22HuggingFaceEmbeddingProvider%22%5D%20%26%20ONNXE%5B%22ONNXEmbedder%20(BGE-small)%22%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20Retrieval%5B%22Context%20Assembly%22%5D%0A%20%20%20%20%20%20%20%20direction%20LR%0A%20%20%20%20%20%20%20%20SR%5B%22SemanticRetriever%22%5D%20%26%20GR%5B%22GraphRetriever%22%5D%20%26%20HR%5B%22HybridRetriever%20(RRF)%22%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20Storage%5B%22SQLite%20Storage%20%E2%80%94%20WAL%20Mode%22%5D%0A%20%20%20%20%20%20%20%20direction%20LR%0A%20%20%20%20%20%20%20%20EMBDB%5B(%22ai-embeddings.db%22)%5D%20%26%20GRDB%5B(%22ai-graph.db%22)%5D%20%26%20MEMDB%5B(%22memory.db%20%2F%20personas.db%22)%5D%0A%20%20%20%20end%0A%0A%20%20%20%20Renderer%20--%3E%7C%22IPC%20%C2%B7%20contextBridge%22%7C%20Preload%0A%20%20%20%20Preload%20--%3E%7C%22ipcMain.handle%22%7C%20Handlers%0A%20%20%20%20Handlers%20--%3E%20AIService%0A%20%20%20%20AIService%20--%3E%20Agent%0A%0A%20%20%20%20LR%20--%3E%20GEM%20%26%20GRQ%20%26%20OAI%20%26%20LLP%0A%20%20%20%20ES%20--%3E%20HFEP%20%26%20ONNXE%0A%0A%20%20%20%20CE%20--%3E%20SR%20%26%20GR%0A%20%20%20%20HR%20--%3E%20SR%20%26%20GR%0A%0A%20%20%20%20ES%20--%3E%20EMBDB%0A%20%20%20%20GS%20--%3E%20GRDB%0A%20%20%20%20CE%20--%3E%20MEMDB%0A" + }, null, _parent)); + }, + fallback: () => { + _push(` Loading... `); + }, + _: 1 + }); + _push(`

    For a detailed walkthrough of each layer, see AI Subsystem Architecture.


    4. Centralized System Logging Infrastructure (LogDB.js)

    Logging across Notely is managed by a centralized, generic SQLite log store (LogDB.js).

    Database Schema

    Logs are persisted inside the active workspace directory at {workspace}/.notes-app/ai-logs.db:

    sql
    CREATE TABLE IF NOT EXISTS logs (
    +  id INTEGER PRIMARY KEY AUTOINCREMENT,
    +  subsystem TEXT NOT NULL,
    +  level TEXT DEFAULT 'info',
    +  message TEXT NOT NULL,
    +  metadata TEXT,
    +  timestamp TEXT NOT NULL
    +);
    +CREATE INDEX IF NOT EXISTS idx_logs_subsystem ON logs(subsystem);

    Log Subsystem Categories

    • app: Application startup, settings updates, file system I/O, package import/export.
    • git: Git status checks, staging, commits, diffs, branch operations.
    • embeddings: Vector indexing pipeline, model loading, chunking, database updates.
    • graph: Knowledge Graph entity extractions, relationship linking, graph rebuilds.
    • ai: LLM queries, tool invocations, prompt context assembly.

    User Diagnostics & Management UI

    • System Logs Console (AppLogsPage.jsx): Accessible via Help -> System & Application Logs. Features live search, subsystem/severity dropdown filters, live auto-refresh toggle, log clearing, and JSON log export.
    • Subsystem Log Feeds: Embedded log panels inside EmbeddingsPage and KnowledgeGraph display real-time subsystem-filtered events.
    • Subsystem Data Clear Buttons: EmbeddingsPage features a Clear Embeddings Data button (aiClearEmbeddingsData), and KnowledgeGraph features a Clear Knowledge Graph Data button (aiClearGraphData) to clear data caches independently of logs.

    5. Data Storage & Workspace Directory Structure

    Notely maintains a clean separation between global application config, human-readable workspace files, and local metadata caches:

    Workspace Storage Diagram

    `); + ssrRenderSuspense(_push, { + default: () => { + _push(ssrRenderComponent(_component_Mermaid, { + id: "mermaid-270", + class: "mermaid", + graph: "graph%20TD%0A%20%20%20%20subgraph%20Workspace%20%5B%22Active%20Workspace%20Directory%22%5D%0A%20%20%20%20%20%20%20%20MD1%5B%22%F0%9F%93%84%20note-1.md%20(Raw%20Markdown)%22%5D%0A%20%20%20%20%20%20%20%20MD2%5B%22%F0%9F%93%81%20Subfolder%20%2F%20note-2.md%22%5D%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20subgraph%20MediaDir%20%5B%22%F0%9F%93%81%20Media%20Assets%20Directory%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20IMG%5B%22%F0%9F%96%BC%EF%B8%8F%20image.png%20%2F%20arch.svg%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20DOC%5B%22%F0%9F%93%91%20specs.pdf%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20DRAW%5B%22%F0%9F%8E%A8%20diagram.excalidraw%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20AV%5B%22%F0%9F%8E%B5%20recording.mp3%20%2F%20video.mp4%22%5D%0A%20%20%20%20%20%20%20%20end%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20subgraph%20CacheDir%20%5B%22%F0%9F%93%81%20.notes-app%20(Hidden%20Cache%20Folder)%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20TDB%5B(%22task-db.sqlite%3Cbr%2F%3E(Task%20DB%20%26%20Bi-directional%20Sync)%22)%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20VECDB%5B(%22ai-embeddings.db%3Cbr%2F%3E(384-dim%20Vector%20BLOBs)%22)%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20GDB%5B(%22ai-graph.db%3Cbr%2F%3E(Entities%20%26%20CTE%20Edges)%22)%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20LDB%5B(%22ai-logs.db%3Cbr%2F%3E(System%20%26%20App%20Logs)%22)%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20STATE%5B%22app-state.json%20%2F%20metadata%22%5D%0A%20%20%20%20%20%20%20%20end%0A%20%20%20%20end%0A%20%20%20%20%0A%20%20%20%20subgraph%20AppData%20%5B%22Global%20User%20AppData%20(%25APPDATA%25%2FNotely%2F)%22%5D%0A%20%20%20%20%20%20%20%20APPDB%5B(%22app.sqlite%3Cbr%2F%3E(Settings%2C%20Keys%2C%20Themes)%22)%5D%0A%20%20%20%20end%0A%20%20%20%20%0A%20%20%20%20MD1%20-.-%3E%20%7CReferences%7C%20MediaDir%0A%20%20%20%20MD2%20-.-%3E%20%7CReferences%7C%20MediaDir%0A%20%20%20%20MD1%20-.-%3E%20%7CIndexed%20by%7C%20CacheDir%0A%20%20%20%20MD2%20-.-%3E%20%7CIndexed%20by%7C%20CacheDir%0A" + }, null, _parent)); + }, + fallback: () => { + _push(` Loading... `); + }, + _: 1 + }); + _push(`

    Global Configuration

    • Global App Database (%APPDATA%/Notely/app.sqlite): Manages user preferences, API keys, active themes, window dimensions, P2P sync pairs, and recently opened workspaces.

    Workspace File Structure

    • Raw .md Files: Notes are saved as plain-text UTF-8 Markdown files directly in workspace root and subdirectories ({workspace}/**/*.md). Notely imposes zero proprietary database wrapping or lock-in, enabling seamless external editing with Git, VS Code, or Obsidian.
    • Media/ Assets Folder: A dedicated assets directory located at {workspace}/Media/ created to house user-attached media files:
      • Images (.png, .jpg, .jpeg, .gif, .svg, .webp).
      • Video & Audio recordings (.mp4, .webm, .mp3, .wav, .m4a).
      • Document attachments (.pdf).
      • Excalidraw drawing files (.excalidraw).
    • Hidden Subsystem Folder ({workspace}/.notes-app/): Internal SQLite caches for AI, tasks, and system features:
      • task-db.sqlite: Stores workspace-wide task metadata, priorities, due dates, assignee tags, source note hashes, and line indices for bi-directional checklist synchronization.
      • ai-embeddings.db: Stores chunk text, line offsets, hashes, and 384-dimensional binary vector BLOBs.
      • ai-graph.db: Stores extracted Knowledge Graph entity nodes, Wikilinks, media links, and relationship edges.
      • ai-logs.db: Stores multitenant application, git, embedding, graph, and AI log entries.
      • app-state.json: Caches workspace UI state, last opened note handles, and view preferences.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("architecture.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const architecture = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + architecture as default +}; diff --git a/docs-site/.vitepress/.temp/assets/icon.png b/docs-site/.vitepress/.temp/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0d833b958bc5180c02a01b4fd5412eb139a99dfb GIT binary patch literal 3843 zcmaJ^3s6&68jiZ%SgpZ!*LZylsOVrTG+uWcX;JXG3Y`+W?i3Uogiv3tK-g-o5E8Yz zYPrZm-FC(*wOvOotqCajNJ0?E^}#B-Yw(c=tQU(F38oMe9)UgoNlEGSxHEU|z2`sw z`JdnU&wuu>j9)%x)WlH&fnZGRilu)M2!^5GVSr`8JuqU*6s7yXqP)_&P^ zX1Xx@-tF3&cYn8K{oXj+OQJ`KJH{_tR`d65w~FSB*!ItA$z4h2#Ugui<~ZxKuX|pP zw6QUgSJvD+>JR`L5t9U(a^Wr|DW@q@VT?SGo6*T*sZPh44+%$H9uJt z5qw8~zClkrtKlQ8U>0^bqC2^$L5SVk0xa_$TduEUFi z{fo;O0ba~Z!HcV3Xt-a9unP%^f01+L7vvodb;TrpCsJ*39$0XV;+I^vud$t0HmMMK z9OJo>ppU9}L1^$SEh_@%z2v|o0>Bg-s(ODYwNu(#z^VTe29fjX&pLXYN3`3NX#pH5 zAL=uz9^@+oO}U*GXM8w-ak`u>h)|{|gjKzk1U)Tk(I@9t=tuktjjQHxUT?8{SIhMXHe#pXVrH{g|a z?^bs>V1B1<@NbsO&$*Fy)FU0nlU8^6+xyTfTZ-h)mDQ!%_Mnji@lzqUQ~T0DTMZ~W zeCY#8>G&+Y?0w$o-)+iPWH9F)`42*vTNI#N_z7ayUIj%u(2+?3G!7U6GKH=%Fq^Rx z=EmkJ?joZ$vq3HUSvvZ#DlSjq@e|h3!8J%>zN<#er+@%TvJr=$nF$_pqgS(g|Ax$x z8+PCV!%qcEsg6yr67;a1OmMi2w8g~yalA6-_9~7liHrW;%rIDkR7Yw3CWQI}rRA_e zq2XL9#82M0N6cF;qHxmv!?E|DeLa)-@SdY6&o6-&7c|S>`y=T&WM(R`=P@a?^X8_g z4wMlw|7KtzrKw9bWMjiZbd<8~+)<@mweTIn_M6lHB?6yu2g=k$Wf)<9Aq5VkKvs?2 zi4yZGvEq<$ZV8}_l6*`DbH6Yomcnb*b|Y0sLKy#r%H(;n?%YbLPl% zU=u3vK|dn%B`tuvsS#Z5+n}{0g${lY&|15i;Mro%cL9alRYb~Tp6gk>b^AO{sw22O zl|KM*viq>R!w2K-FeM03edF}TvRlotCB`z$}cTm05^&{FxB5 zR9eIXR{9RiAjD-th&5n}M@)!|j^e|hVz_RRW(!>|1kiNbegX>8Xc5jbb`Es|ILo7P z{!o8l!0-&(K#SUub*Mq$A$y+TfW-NS%#`FY#H5yZeDd)q9_cC-Arkw{R19F)uLmVn zC4k5{9jR=SB9Or|5u7&xk|9cYnIMES0wDb&mXn|s&Uv9|Z?>Hz53=TVx#Xl5g^A_UvPNGU0WIykkak)WZi#*6+yKt&?!8V>ObzUj9@b`@BctY%%i zFq!+Ad=HZm_b`Zt&1j}VFy{w3)8wplM#;ZZ*`UXe|MUogmO_O9T-78JVU0RV5~8=S zh2u5_UMB!iHSlUCNJropY*N+bP%sPOl?4kI0cITa*a?>m1RO&z<=DWSy1b#kUDKoO z-rZ9&kn4$q%3hF((ltVlPgnFO?7D9n=(U7(r5V0Jf_+1}0#v&_PzX!@b&w5e2KO6K z?tBRF2i_>Tlgdh;B3j3fumK7xy>-#OR#S4mVquA|y-6EgW~P*Q%{NJ`A`F=|FZx?E z<c5iCe&e-D5|quT0S`%X`cawVGJjr5A85`)6RClo$M#$)x}Gp z{yy!-_~bJjlV9b{+PVR!gOn#k>jHVQBE&a_uwM~8bQf0Tx*lz26TXsEt+k&Hn;=)M zxR{g|)p!J{oUd~rm2y(q#>iTcQE8!qPR+B%5rBp*DrW@7`|r!=7dk#J73!F=c(4No zWy};9*veo~&dkPx<1jeOEX0E%7@T8P;=xWBxLbC**C+WJHw^S%n#6~;-KfmYB%QHC zHs#~aEpxf$cUrA)3?UMV?lHq_xmDk*+s-B@qxN75`j-`*G`tD4kGkDk=W(OE`#ZO| zM=jWXqG~{uyyJd=o+L!oVvaqWLJR~ac-R=75&iLaNbgaiP}a_Nk*wl za*S>2L`ycapW-HbFvZ8NQv4Uk(pbgHUv`KsaFI&`@e#4d|pdS>yuUH=1-;okrN literal 0 HcmV?d00001 diff --git a/docs-site/.vitepress/.temp/assets/style.DFNPDK03.css b/docs-site/.vitepress/.temp/assets/style.DFNPDK03.css new file mode 100644 index 00000000..116c1a0b --- /dev/null +++ b/docs-site/.vitepress/.temp/assets/style.DFNPDK03.css @@ -0,0 +1,5943 @@ + + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 100 900; + font-display: swap; + src: url('/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2') format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 100 900; + font-display: swap; + src: url('/assets/inter-roman-cyrillic.C5lxZ8CY.woff2') format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 100 900; + font-display: swap; + src: url('/assets/inter-roman-greek-ext.CqjqNYQ-.woff2') format('woff2'); + unicode-range: U+1F00-1FFF; +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 100 900; + font-display: swap; + src: url('/assets/inter-roman-greek.BBVDIX6e.woff2') format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, + U+03A3-03FF; +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 100 900; + font-display: swap; + src: url('/assets/inter-roman-vietnamese.BjW4sHH5.woff2') format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, + U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, + U+0329, U+1EA0-1EF9, U+20AB; +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 100 900; + font-display: swap; + src: url('/assets/inter-roman-latin-ext.4ZJIpNVo.woff2') format('woff2'); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 100 900; + font-display: swap; + src: url('/assets/inter-roman-latin.Di8DUHzh.woff2') format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 100 900; + font-display: swap; + src: url('/assets/inter-italic-cyrillic-ext.r48I6akx.woff2') format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 100 900; + font-display: swap; + src: url('/assets/inter-italic-cyrillic.By2_1cv3.woff2') format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 100 900; + font-display: swap; + src: url('/assets/inter-italic-greek-ext.1u6EdAuj.woff2') format('woff2'); + unicode-range: U+1F00-1FFF; +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 100 900; + font-display: swap; + src: url('/assets/inter-italic-greek.DJ8dCoTZ.woff2') format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, + U+03A3-03FF; +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 100 900; + font-display: swap; + src: url('/assets/inter-italic-vietnamese.BSbpV94h.woff2') format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, + U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, + U+0329, U+1EA0-1EF9, U+20AB; +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 100 900; + font-display: swap; + src: url('/assets/inter-italic-latin-ext.CN1xVJS-.woff2') format('woff2'); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 100 900; + font-display: swap; + src: url('/assets/inter-italic-latin.C2AdPX0b.woff2') format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +@font-face { + font-family: 'Punctuation SC'; + font-weight: 400; + src: local('PingFang SC Regular'), local('Noto Sans CJK SC'), + local('Microsoft YaHei'); + unicode-range: U+201C, U+201D, U+2018, U+2019, U+2E3A, U+2014, U+2013, U+2026, + U+00B7, U+007E, U+002F; +} + +@font-face { + font-family: 'Punctuation SC'; + font-weight: 500; + src: local('PingFang SC Medium'), local('Noto Sans CJK SC'), + local('Microsoft YaHei'); + unicode-range: U+201C, U+201D, U+2018, U+2019, U+2E3A, U+2014, U+2013, U+2026, + U+00B7, U+007E, U+002F; +} + +@font-face { + font-family: 'Punctuation SC'; + font-weight: 600; + src: local('PingFang SC Semibold'), local('Noto Sans CJK SC Bold'), + local('Microsoft YaHei Bold'); + unicode-range: U+201C, U+201D, U+2018, U+2019, U+2E3A, U+2014, U+2013, U+2026, + U+00B7, U+007E, U+002F; +} + +@font-face { + font-family: 'Punctuation SC'; + font-weight: 700; + src: local('PingFang SC Semibold'), local('Noto Sans CJK SC Bold'), + local('Microsoft YaHei Bold'); + unicode-range: U+201C, U+201D, U+2018, U+2019, U+2E3A, U+2014, U+2013, U+2026, + U+00B7, U+007E, U+002F; +} + +/* Generate the subsetted fonts using: `pyftsubset .woff2 --unicodes="" --output-file="inter-\3c style>-.woff2" --flavor=woff2` */ +/** + * Colors: Solid + * -------------------------------------------------------------------------- */ + +:root { + --vp-c-white: #ffffff; + --vp-c-black: #000000; + + --vp-c-neutral: var(--vp-c-black); + --vp-c-neutral-inverse: var(--vp-c-white); +} + +.dark { + --vp-c-neutral: var(--vp-c-white); + --vp-c-neutral-inverse: var(--vp-c-black); +} + +/** + * Colors: Palette + * + * The primitive colors used for accent colors. These colors are referenced + * by functional colors such as "Text", "Background", or "Brand". + * + * Each colors have exact same color scale system with 3 levels of solid + * colors with different brightness, and 1 soft color. + * + * - `XXX-1`: The most solid color used mainly for colored text. It must + * satisfy the contrast ratio against when used on top of `XXX-soft`. + * + * - `XXX-2`: The color used mainly for hover state of the button. + * + * - `XXX-3`: The color for solid background, such as bg color of the button. + * It must satisfy the contrast ratio with pure white (#ffffff) text on + * top of it. + * + * - `XXX-soft`: The color used for subtle background such as custom container + * or badges. It must satisfy the contrast ratio when putting `XXX-1` colors + * on top of it. + * + * The soft color must be semi transparent alpha channel. This is crucial + * because it allows adding multiple "soft" colors on top of each other + * to create a accent, such as when having inline code block inside + * custom containers. + * -------------------------------------------------------------------------- */ + +:root { + --vp-c-gray-1: #dddde3; + --vp-c-gray-2: #e4e4e9; + --vp-c-gray-3: #ebebef; + --vp-c-gray-soft: rgba(142, 150, 170, 0.14); + + --vp-c-indigo-1: #3451b2; + --vp-c-indigo-2: #3a5ccc; + --vp-c-indigo-3: #5672cd; + --vp-c-indigo-soft: rgba(100, 108, 255, 0.14); + + --vp-c-purple-1: #6f42c1; + --vp-c-purple-2: #7e4cc9; + --vp-c-purple-3: #8e5cd9; + --vp-c-purple-soft: rgba(159, 122, 234, 0.14); + + --vp-c-green-1: #18794e; + --vp-c-green-2: #299764; + --vp-c-green-3: #30a46c; + --vp-c-green-soft: rgba(16, 185, 129, 0.14); + + --vp-c-yellow-1: #915930; + --vp-c-yellow-2: #946300; + --vp-c-yellow-3: #9f6a00; + --vp-c-yellow-soft: rgba(234, 179, 8, 0.14); + + --vp-c-red-1: #b8272c; + --vp-c-red-2: #d5393e; + --vp-c-red-3: #e0575b; + --vp-c-red-soft: rgba(244, 63, 94, 0.14); + + --vp-c-sponsor: #db2777; +} + +.dark { + --vp-c-gray-1: #515c67; + --vp-c-gray-2: #414853; + --vp-c-gray-3: #32363f; + --vp-c-gray-soft: rgba(101, 117, 133, 0.16); + + --vp-c-indigo-1: #a8b1ff; + --vp-c-indigo-2: #5c73e7; + --vp-c-indigo-3: #3e63dd; + --vp-c-indigo-soft: rgba(100, 108, 255, 0.16); + + --vp-c-purple-1: #c8abfa; + --vp-c-purple-2: #a879e6; + --vp-c-purple-3: #8e5cd9; + --vp-c-purple-soft: rgba(159, 122, 234, 0.16); + + --vp-c-green-1: #3dd68c; + --vp-c-green-2: #30a46c; + --vp-c-green-3: #298459; + --vp-c-green-soft: rgba(16, 185, 129, 0.16); + + --vp-c-yellow-1: #f9b44e; + --vp-c-yellow-2: #da8b17; + --vp-c-yellow-3: #a46a0a; + --vp-c-yellow-soft: rgba(234, 179, 8, 0.16); + + --vp-c-red-1: #f66f81; + --vp-c-red-2: #f14158; + --vp-c-red-3: #b62a3c; + --vp-c-red-soft: rgba(244, 63, 94, 0.16); +} + +/** + * Colors: Background + * + * - `bg`: The bg color used for main screen. + * + * - `bg-alt`: The alternative bg color used in places such as "sidebar", + * or "code block". + * + * - `bg-elv`: The elevated bg color. This is used at parts where it "floats", + * such as "dialog". + * + * - `bg-soft`: The bg color to slightly distinguish some components from + * the page. Used for things like "carbon ads" or "table". + * -------------------------------------------------------------------------- */ + +:root { + --vp-c-bg: #ffffff; + --vp-c-bg-alt: #f6f6f7; + --vp-c-bg-elv: #ffffff; + --vp-c-bg-soft: #f6f6f7; +} + +.dark { + --vp-c-bg: #1b1b1f; + --vp-c-bg-alt: #161618; + --vp-c-bg-elv: #202127; + --vp-c-bg-soft: #202127; +} + +/** + * Colors: Borders + * + * - `divider`: This is used for separators. This is used to divide sections + * within the same components, such as having separator on "h2" heading. + * + * - `border`: This is designed for borders on interactive components. + * For example this should be used for a button outline. + * + * - `gutter`: This is used to divide components in the page. For example + * the header and the lest of the page. + * -------------------------------------------------------------------------- */ + +:root { + --vp-c-border: #c2c2c4; + --vp-c-divider: #e2e2e3; + --vp-c-gutter: #e2e2e3; +} + +.dark { + --vp-c-border: #3c3f44; + --vp-c-divider: #2e2e32; + --vp-c-gutter: #000000; +} + +/** + * Colors: Text + * + * - `text-1`: Used for primary text. + * + * - `text-2`: Used for muted texts, such as "inactive menu" or "info texts". + * + * - `text-3`: Used for subtle texts, such as "placeholders" or "caret icon". + * -------------------------------------------------------------------------- */ + +:root { + --vp-c-text-1: #3c3c43; + --vp-c-text-2: #67676c; + --vp-c-text-3: #929295; +} + +.dark { + --vp-c-text-1: #dfdfd6; + --vp-c-text-2: #98989f; + --vp-c-text-3: #6a6a71; +} + +/** + * Colors: Function + * + * - `default`: The color used purely for subtle indication without any + * special meanings attached to it such as bg color for menu hover state. + * + * - `brand`: Used for primary brand colors, such as link text, button with + * brand theme, etc. + * + * - `tip`: Used to indicate useful information. The default theme uses the + * brand color for this by default. + * + * - `warning`: Used to indicate warning to the users. Used in custom + * container, badges, etc. + * + * - `danger`: Used to show error, or dangerous message to the users. Used + * in custom container, badges, etc. + * + * To understand the scaling system, refer to "Colors: Palette" section. + * -------------------------------------------------------------------------- */ + +:root { + --vp-c-default-1: var(--vp-c-gray-1); + --vp-c-default-2: var(--vp-c-gray-2); + --vp-c-default-3: var(--vp-c-gray-3); + --vp-c-default-soft: var(--vp-c-gray-soft); + + --vp-c-brand-1: var(--vp-c-indigo-1); + --vp-c-brand-2: var(--vp-c-indigo-2); + --vp-c-brand-3: var(--vp-c-indigo-3); + --vp-c-brand-soft: var(--vp-c-indigo-soft); + + /* DEPRECATED: Use `--vp-c-brand-1` instead. */ + --vp-c-brand: var(--vp-c-brand-1); + + --vp-c-tip-1: var(--vp-c-brand-1); + --vp-c-tip-2: var(--vp-c-brand-2); + --vp-c-tip-3: var(--vp-c-brand-3); + --vp-c-tip-soft: var(--vp-c-brand-soft); + + --vp-c-note-1: var(--vp-c-brand-1); + --vp-c-note-2: var(--vp-c-brand-2); + --vp-c-note-3: var(--vp-c-brand-3); + --vp-c-note-soft: var(--vp-c-brand-soft); + + --vp-c-success-1: var(--vp-c-green-1); + --vp-c-success-2: var(--vp-c-green-2); + --vp-c-success-3: var(--vp-c-green-3); + --vp-c-success-soft: var(--vp-c-green-soft); + + --vp-c-important-1: var(--vp-c-purple-1); + --vp-c-important-2: var(--vp-c-purple-2); + --vp-c-important-3: var(--vp-c-purple-3); + --vp-c-important-soft: var(--vp-c-purple-soft); + + --vp-c-warning-1: var(--vp-c-yellow-1); + --vp-c-warning-2: var(--vp-c-yellow-2); + --vp-c-warning-3: var(--vp-c-yellow-3); + --vp-c-warning-soft: var(--vp-c-yellow-soft); + + --vp-c-danger-1: var(--vp-c-red-1); + --vp-c-danger-2: var(--vp-c-red-2); + --vp-c-danger-3: var(--vp-c-red-3); + --vp-c-danger-soft: var(--vp-c-red-soft); + + --vp-c-caution-1: var(--vp-c-red-1); + --vp-c-caution-2: var(--vp-c-red-2); + --vp-c-caution-3: var(--vp-c-red-3); + --vp-c-caution-soft: var(--vp-c-red-soft); +} + +/** + * Typography + * -------------------------------------------------------------------------- */ + +:root { + --vp-font-family-base: 'Inter', ui-sans-serif, system-ui, sans-serif, + 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + --vp-font-family-mono: ui-monospace, 'Menlo', 'Monaco', 'Consolas', + 'Liberation Mono', 'Courier New', monospace; + font-optical-sizing: auto; +} + +:root:where(:lang(zh)) { + --vp-font-family-base: 'Punctuation SC', 'Inter', ui-sans-serif, system-ui, + sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', + 'Noto Color Emoji'; +} + +/** + * Shadows + * -------------------------------------------------------------------------- */ + +:root { + --vp-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06); + --vp-shadow-2: 0 3px 12px rgba(0, 0, 0, 0.07), 0 1px 4px rgba(0, 0, 0, 0.07); + --vp-shadow-3: 0 12px 32px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(0, 0, 0, 0.08); + --vp-shadow-4: 0 14px 44px rgba(0, 0, 0, 0.12), 0 3px 9px rgba(0, 0, 0, 0.12); + --vp-shadow-5: 0 18px 56px rgba(0, 0, 0, 0.16), 0 4px 12px rgba(0, 0, 0, 0.16); +} + +/** + * Z-indexes + * -------------------------------------------------------------------------- */ + +:root { + --vp-z-index-footer: 10; + --vp-z-index-local-nav: 20; + --vp-z-index-nav: 30; + --vp-z-index-layout-top: 40; + --vp-z-index-backdrop: 50; + --vp-z-index-sidebar: 60; +} + +@media (min-width: 960px) { + :root { + --vp-z-index-sidebar: 25; + } +} + +/** + * Layouts + * -------------------------------------------------------------------------- */ + +:root { + --vp-layout-max-width: 1440px; +} + +/** + * Component: Header Anchor + * -------------------------------------------------------------------------- */ + +:root { + --vp-header-anchor-symbol: '#'; +} + +/** + * Component: Code + * -------------------------------------------------------------------------- */ + +:root { + --vp-code-line-height: 1.7; + --vp-code-font-size: 0.875em; + --vp-code-color: var(--vp-c-brand-1); + --vp-code-link-color: var(--vp-c-brand-1); + --vp-code-link-hover-color: var(--vp-c-brand-2); + --vp-code-bg: var(--vp-c-default-soft); + + --vp-code-block-color: var(--vp-c-text-2); + --vp-code-block-bg: var(--vp-c-bg-alt); + --vp-code-block-divider-color: var(--vp-c-gutter); + + --vp-code-lang-color: var(--vp-c-text-3); + + --vp-code-line-highlight-color: var(--vp-c-default-soft); + --vp-code-line-number-color: var(--vp-c-text-3); + + --vp-code-line-diff-add-color: var(--vp-c-success-soft); + --vp-code-line-diff-add-symbol-color: var(--vp-c-success-1); + + --vp-code-line-diff-remove-color: var(--vp-c-danger-soft); + --vp-code-line-diff-remove-symbol-color: var(--vp-c-danger-1); + + --vp-code-line-warning-color: var(--vp-c-warning-soft); + --vp-code-line-error-color: var(--vp-c-danger-soft); + + --vp-code-copy-code-border-color: var(--vp-c-divider); + --vp-code-copy-code-bg: var(--vp-c-bg-soft); + --vp-code-copy-code-hover-border-color: var(--vp-c-divider); + --vp-code-copy-code-hover-bg: var(--vp-c-bg); + --vp-code-copy-code-active-text: var(--vp-c-text-2); + --vp-code-copy-copied-text-content: 'Copied'; + + --vp-code-tab-divider: var(--vp-code-block-divider-color); + --vp-code-tab-text-color: var(--vp-c-text-2); + --vp-code-tab-bg: var(--vp-code-block-bg); + --vp-code-tab-hover-text-color: var(--vp-c-text-1); + --vp-code-tab-active-text-color: var(--vp-c-text-1); + --vp-code-tab-active-bar-color: var(--vp-c-brand-1); +} + +:lang(es), +:lang(pt) { + --vp-code-copy-copied-text-content: 'Copiado'; +} +:lang(fa) { + --vp-code-copy-copied-text-content: 'کپی شد'; +} +:lang(ko) { + --vp-code-copy-copied-text-content: '복사됨'; +} +:lang(ru) { + --vp-code-copy-copied-text-content: 'Скопировано'; +} +:lang(zh) { + --vp-code-copy-copied-text-content: '已复制'; +} + +/** + * Component: Button + * -------------------------------------------------------------------------- */ + +:root { + --vp-button-brand-border: transparent; + --vp-button-brand-text: var(--vp-c-white); + --vp-button-brand-bg: var(--vp-c-brand-3); + --vp-button-brand-hover-border: transparent; + --vp-button-brand-hover-text: var(--vp-c-white); + --vp-button-brand-hover-bg: var(--vp-c-brand-2); + --vp-button-brand-active-border: transparent; + --vp-button-brand-active-text: var(--vp-c-white); + --vp-button-brand-active-bg: var(--vp-c-brand-1); + + --vp-button-alt-border: transparent; + --vp-button-alt-text: var(--vp-c-text-1); + --vp-button-alt-bg: var(--vp-c-default-3); + --vp-button-alt-hover-border: transparent; + --vp-button-alt-hover-text: var(--vp-c-text-1); + --vp-button-alt-hover-bg: var(--vp-c-default-2); + --vp-button-alt-active-border: transparent; + --vp-button-alt-active-text: var(--vp-c-text-1); + --vp-button-alt-active-bg: var(--vp-c-default-1); + + --vp-button-sponsor-border: var(--vp-c-text-2); + --vp-button-sponsor-text: var(--vp-c-text-2); + --vp-button-sponsor-bg: transparent; + --vp-button-sponsor-hover-border: var(--vp-c-sponsor); + --vp-button-sponsor-hover-text: var(--vp-c-sponsor); + --vp-button-sponsor-hover-bg: transparent; + --vp-button-sponsor-active-border: var(--vp-c-sponsor); + --vp-button-sponsor-active-text: var(--vp-c-sponsor); + --vp-button-sponsor-active-bg: transparent; +} + +/** + * Component: Custom Block + * -------------------------------------------------------------------------- */ + +:root { + --vp-custom-block-font-size: 14px; + --vp-custom-block-code-font-size: 13px; + + --vp-custom-block-info-border: transparent; + --vp-custom-block-info-text: var(--vp-c-text-1); + --vp-custom-block-info-bg: var(--vp-c-default-soft); + --vp-custom-block-info-code-bg: var(--vp-c-default-soft); + + --vp-custom-block-note-border: transparent; + --vp-custom-block-note-text: var(--vp-c-text-1); + --vp-custom-block-note-bg: var(--vp-c-default-soft); + --vp-custom-block-note-code-bg: var(--vp-c-default-soft); + + --vp-custom-block-tip-border: transparent; + --vp-custom-block-tip-text: var(--vp-c-text-1); + --vp-custom-block-tip-bg: var(--vp-c-tip-soft); + --vp-custom-block-tip-code-bg: var(--vp-c-tip-soft); + + --vp-custom-block-important-border: transparent; + --vp-custom-block-important-text: var(--vp-c-text-1); + --vp-custom-block-important-bg: var(--vp-c-important-soft); + --vp-custom-block-important-code-bg: var(--vp-c-important-soft); + + --vp-custom-block-warning-border: transparent; + --vp-custom-block-warning-text: var(--vp-c-text-1); + --vp-custom-block-warning-bg: var(--vp-c-warning-soft); + --vp-custom-block-warning-code-bg: var(--vp-c-warning-soft); + + --vp-custom-block-danger-border: transparent; + --vp-custom-block-danger-text: var(--vp-c-text-1); + --vp-custom-block-danger-bg: var(--vp-c-danger-soft); + --vp-custom-block-danger-code-bg: var(--vp-c-danger-soft); + + --vp-custom-block-caution-border: transparent; + --vp-custom-block-caution-text: var(--vp-c-text-1); + --vp-custom-block-caution-bg: var(--vp-c-caution-soft); + --vp-custom-block-caution-code-bg: var(--vp-c-caution-soft); + + --vp-custom-block-details-border: var(--vp-custom-block-info-border); + --vp-custom-block-details-text: var(--vp-custom-block-info-text); + --vp-custom-block-details-bg: var(--vp-custom-block-info-bg); + --vp-custom-block-details-code-bg: var(--vp-custom-block-info-code-bg); +} + +/** + * Component: Input + * -------------------------------------------------------------------------- */ + +:root { + --vp-input-border-color: var(--vp-c-border); + --vp-input-bg-color: var(--vp-c-bg-alt); + + --vp-input-switch-bg-color: var(--vp-c-default-soft); +} + +/** + * Component: Nav + * -------------------------------------------------------------------------- */ + +:root { + --vp-nav-height: 64px; + --vp-nav-bg-color: var(--vp-c-bg); + --vp-nav-screen-bg-color: var(--vp-c-bg); + --vp-nav-logo-height: 24px; +} + +.hide-nav { + --vp-nav-height: 0px; +} + +.hide-nav .VPSidebar { + --vp-nav-height: 22px; +} + +/** + * Component: Local Nav + * -------------------------------------------------------------------------- */ + +:root { + --vp-local-nav-bg-color: var(--vp-c-bg); +} + +/** + * Component: Sidebar + * -------------------------------------------------------------------------- */ + +:root { + --vp-sidebar-width: 272px; + --vp-sidebar-bg-color: var(--vp-c-bg-alt); +} + +/** + * Colors Backdrop + * -------------------------------------------------------------------------- */ + +:root { + --vp-backdrop-bg-color: rgba(0, 0, 0, 0.6); +} + +/** + * Component: Home + * -------------------------------------------------------------------------- */ + +:root { + --vp-home-hero-name-color: var(--vp-c-brand-1); + --vp-home-hero-name-background: transparent; + + --vp-home-hero-image-background-image: none; + --vp-home-hero-image-filter: none; +} + +/** + * Component: Badge + * -------------------------------------------------------------------------- */ + +:root { + --vp-badge-info-border: transparent; + --vp-badge-info-text: var(--vp-c-text-2); + --vp-badge-info-bg: var(--vp-c-default-soft); + + --vp-badge-tip-border: transparent; + --vp-badge-tip-text: var(--vp-c-tip-1); + --vp-badge-tip-bg: var(--vp-c-tip-soft); + + --vp-badge-warning-border: transparent; + --vp-badge-warning-text: var(--vp-c-warning-1); + --vp-badge-warning-bg: var(--vp-c-warning-soft); + + --vp-badge-danger-border: transparent; + --vp-badge-danger-text: var(--vp-c-danger-1); + --vp-badge-danger-bg: var(--vp-c-danger-soft); +} + +/** + * Component: Carbon Ads + * -------------------------------------------------------------------------- */ + +:root { + --vp-carbon-ads-text-color: var(--vp-c-text-1); + --vp-carbon-ads-poweredby-color: var(--vp-c-text-2); + --vp-carbon-ads-bg-color: var(--vp-c-bg-soft); + --vp-carbon-ads-hover-text-color: var(--vp-c-brand-1); + --vp-carbon-ads-hover-poweredby-color: var(--vp-c-text-1); +} + +/** + * Component: Local Search + * -------------------------------------------------------------------------- */ + +:root { + --vp-local-search-bg: var(--vp-c-bg); + --vp-local-search-result-bg: var(--vp-c-bg); + --vp-local-search-result-border: var(--vp-c-divider); + --vp-local-search-result-selected-bg: var(--vp-c-bg); + --vp-local-search-result-selected-border: var(--vp-c-brand-1); + --vp-local-search-highlight-bg: var(--vp-c-brand-1); + --vp-local-search-highlight-text: var(--vp-c-neutral-inverse); +} +@media (prefers-reduced-motion: reduce) { + *, + ::before, + ::after { + animation-delay: -1ms !important; + animation-duration: 1ms !important; + animation-iteration-count: 1 !important; + background-attachment: initial !important; + scroll-behavior: auto !important; + transition-duration: 0s !important; + transition-delay: 0s !important; + } +} + +*, +::before, +::after { + box-sizing: border-box; +} + +html { + line-height: 1.4; + font-size: 16px; + -webkit-text-size-adjust: 100%; +} + +html.dark { + color-scheme: dark; +} + +body { + margin: 0; + width: 100%; + min-width: 320px; + min-height: 100vh; + line-height: 24px; + font-family: var(--vp-font-family-base); + font-size: 16px; + font-weight: 400; + color: var(--vp-c-text-1); + background-color: var(--vp-c-bg); + font-synthesis: style; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +main { + display: block; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0; + line-height: 24px; + font-size: 16px; + font-weight: 400; +} + +p { + margin: 0; +} + +strong, +b { + font-weight: 600; +} + +/** + * Avoid 300ms click delay on touch devices that support the `touch-action` + * CSS property. + * + * In particular, unlike most other browsers, IE11+Edge on Windows 10 on + * touch devices and IE Mobile 10-11 DON'T remove the click delay when + * `` is present. + * However, they DO support removing the click delay via + * `touch-action: manipulation`. + * + * See: + * - http://v4-alpha.getbootstrap.com/content/reboot/#click-delay-optimization-for-touch + * - http://caniuse.com/#feat=css-touch-action + * - http://patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay + */ +a, +area, +button, +[role='button'], +input, +label, +select, +summary, +textarea { + touch-action: manipulation; +} + +a { + color: inherit; + text-decoration: inherit; +} + +ol, +ul { + list-style: none; + margin: 0; + padding: 0; +} + +blockquote { + margin: 0; +} + +pre, +code, +kbd, +samp { + font-family: var(--vp-font-family-mono); +} + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; +} + +figure { + margin: 0; +} + +img, +video { + max-width: 100%; + height: auto; +} + +button, +input, +optgroup, +select, +textarea { + border: 0; + padding: 0; + line-height: inherit; + color: inherit; +} + +button { + padding: 0; + font-family: inherit; + background-color: transparent; + background-image: none; +} + +button:enabled, +[role='button']:enabled { + cursor: pointer; +} + +button:focus, +button:focus-visible { + outline: 1px dotted; + outline: 4px auto -webkit-focus-ring-color; +} + +button:focus:not(:focus-visible) { + outline: none !important; +} + +input:focus, +textarea:focus, +select:focus { + outline: none; +} + +table { + border-collapse: collapse; +} + +input { + background-color: transparent; +} + +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: var(--vp-c-text-3); +} + +input::-ms-input-placeholder, +textarea::-ms-input-placeholder { + color: var(--vp-c-text-3); +} + +input::placeholder, +textarea::placeholder { + color: var(--vp-c-text-3); +} + +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + +input[type='number'] { + -moz-appearance: textfield; +} + +textarea { + resize: vertical; +} + +select { + -webkit-appearance: none; +} + +fieldset { + margin: 0; + padding: 0; +} + +h1, +h2, +h3, +h4, +h5, +h6, +li, +p { + overflow-wrap: break-word; +} + +vite-error-overlay { + z-index: 9999; +} + +mjx-container { + overflow-x: auto; +} + +mjx-container > svg { + display: inline-block; + margin: auto; +} +[class^='vpi-'], +[class*=' vpi-'], +.vp-icon { + width: 1em; + height: 1em; +} +[class^='vpi-'].bg, +[class*=' vpi-'].bg, +.vp-icon.bg { + background-size: 100% 100%; + background-color: transparent; +} +[class^='vpi-']:not(.bg), +[class*=' vpi-']:not(.bg), +.vp-icon:not(.bg) { + -webkit-mask: var(--icon) no-repeat; + mask: var(--icon) no-repeat; + -webkit-mask-size: 100% 100%; + mask-size: 100% 100%; + background-color: currentColor; + color: inherit; +} + +/* internal icons - used under ISC from https://lucide.dev/ */ +.vpi-align-left { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M21 6H3M15 12H3M17 18H3'/%3E%3C/svg%3E"); +} +.vpi-arrow-right, +.vpi-arrow-down, +.vpi-arrow-left, +.vpi-arrow-up { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5l7 7-7 7'/%3E%3C/svg%3E"); +} +.vpi-chevron-right, +.vpi-chevron-down, +.vpi-chevron-left, +.vpi-chevron-up { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E"); +} +.vpi-chevron-down, +.vpi-arrow-down { + /*rtl:ignore*/ + transform: rotate(90deg); +} +.vpi-chevron-left, +.vpi-arrow-left { + /*rtl:ignore*/ + transform: rotate(180deg); +} +.vpi-chevron-up, +.vpi-arrow-up { + /*rtl:ignore*/ + transform: rotate(-90deg); +} +.vpi-square-pen { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7'/%3E%3Cpath d='M18.375 2.625a2.121 2.121 0 1 1 3 3L12 15l-4 1 1-4Z'/%3E%3C/svg%3E"); +} +.vpi-plus { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5v14'/%3E%3C/svg%3E"); +} +.vpi-sun { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41'/%3E%3C/svg%3E"); +} +.vpi-moon { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z'/%3E%3C/svg%3E"); +} +.vpi-more-horizontal { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='1'/%3E%3Ccircle cx='19' cy='12' r='1'/%3E%3Ccircle cx='5' cy='12' r='1'/%3E%3C/svg%3E"); +} +.vpi-languages { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m5 8 6 6M4 14l6-6 2-3M2 5h12M7 2h1M22 22l-5-10-5 10M14 18h6'/%3E%3C/svg%3E"); +} +.vpi-heart { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3C/svg%3E"); +} +.vpi-search { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E"); +} +.vpi-layout-list { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='7' height='7' x='3' y='3' rx='1'/%3E%3Crect width='7' height='7' x='3' y='14' rx='1'/%3E%3Cpath d='M14 4h7M14 9h7M14 15h7M14 20h7'/%3E%3C/svg%3E"); +} +.vpi-delete { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M20 5H9l-7 7 7 7h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2ZM18 9l-6 6M12 9l6 6'/%3E%3C/svg%3E"); +} +.vpi-corner-down-left { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 10-5 5 5 5'/%3E%3Cpath d='M20 4v7a4 4 0 0 1-4 4H4'/%3E%3C/svg%3E"); +} +:root { + /* clipboard */ + --vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E"); + /* clipboard-copy */ + --vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E"); +} +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + white-space: nowrap; + clip: rect(0 0 0 0); + clip-path: inset(50%); + overflow: hidden; +} +.custom-block { + border: 1px solid transparent; + border-radius: 8px; + padding: 16px 16px 8px; + line-height: 24px; + font-size: var(--vp-custom-block-font-size); + color: var(--vp-c-text-2); +} + +.custom-block.info { + border-color: var(--vp-custom-block-info-border); + color: var(--vp-custom-block-info-text); + background-color: var(--vp-custom-block-info-bg); +} + +.custom-block.info a, +.custom-block.info code { + color: var(--vp-c-brand-1); +} + +.custom-block.info a:hover, +.custom-block.info a:hover > code { + color: var(--vp-c-brand-2); +} + +.custom-block.info code { + background-color: var(--vp-custom-block-info-code-bg); +} + +.custom-block.note { + border-color: var(--vp-custom-block-note-border); + color: var(--vp-custom-block-note-text); + background-color: var(--vp-custom-block-note-bg); +} + +.custom-block.note a, +.custom-block.note code { + color: var(--vp-c-brand-1); +} + +.custom-block.note a:hover, +.custom-block.note a:hover > code { + color: var(--vp-c-brand-2); +} + +.custom-block.note code { + background-color: var(--vp-custom-block-note-code-bg); +} + +.custom-block.tip { + border-color: var(--vp-custom-block-tip-border); + color: var(--vp-custom-block-tip-text); + background-color: var(--vp-custom-block-tip-bg); +} + +.custom-block.tip a, +.custom-block.tip code { + color: var(--vp-c-tip-1); +} + +.custom-block.tip a:hover, +.custom-block.tip a:hover > code { + color: var(--vp-c-tip-2); +} + +.custom-block.tip code { + background-color: var(--vp-custom-block-tip-code-bg); +} + +.custom-block.important { + border-color: var(--vp-custom-block-important-border); + color: var(--vp-custom-block-important-text); + background-color: var(--vp-custom-block-important-bg); +} + +.custom-block.important a, +.custom-block.important code { + color: var(--vp-c-important-1); +} + +.custom-block.important a:hover, +.custom-block.important a:hover > code { + color: var(--vp-c-important-2); +} + +.custom-block.important code { + background-color: var(--vp-custom-block-important-code-bg); +} + +.custom-block.warning { + border-color: var(--vp-custom-block-warning-border); + color: var(--vp-custom-block-warning-text); + background-color: var(--vp-custom-block-warning-bg); +} + +.custom-block.warning a, +.custom-block.warning code { + color: var(--vp-c-warning-1); +} + +.custom-block.warning a:hover, +.custom-block.warning a:hover > code { + color: var(--vp-c-warning-2); +} + +.custom-block.warning code { + background-color: var(--vp-custom-block-warning-code-bg); +} + +.custom-block.danger { + border-color: var(--vp-custom-block-danger-border); + color: var(--vp-custom-block-danger-text); + background-color: var(--vp-custom-block-danger-bg); +} + +.custom-block.danger a, +.custom-block.danger code { + color: var(--vp-c-danger-1); +} + +.custom-block.danger a:hover, +.custom-block.danger a:hover > code { + color: var(--vp-c-danger-2); +} + +.custom-block.danger code { + background-color: var(--vp-custom-block-danger-code-bg); +} + +.custom-block.caution { + border-color: var(--vp-custom-block-caution-border); + color: var(--vp-custom-block-caution-text); + background-color: var(--vp-custom-block-caution-bg); +} + +.custom-block.caution a, +.custom-block.caution code { + color: var(--vp-c-caution-1); +} + +.custom-block.caution a:hover, +.custom-block.caution a:hover > code { + color: var(--vp-c-caution-2); +} + +.custom-block.caution code { + background-color: var(--vp-custom-block-caution-code-bg); +} + +.custom-block.details { + border-color: var(--vp-custom-block-details-border); + color: var(--vp-custom-block-details-text); + background-color: var(--vp-custom-block-details-bg); +} + +.custom-block.details a { + color: var(--vp-c-brand-1); +} + +.custom-block.details a:hover, +.custom-block.details a:hover > code { + color: var(--vp-c-brand-2); +} + +.custom-block.details code { + background-color: var(--vp-custom-block-details-code-bg); +} + +.custom-block-title { + font-weight: 600; +} + +.custom-block p + p { + margin: 8px 0; +} + +.custom-block.details summary { + margin: 0 0 8px; + font-weight: 700; + cursor: pointer; + user-select: none; +} + +.custom-block.details summary + p { + margin: 8px 0; +} + +.custom-block a { + color: inherit; + font-weight: 600; + text-decoration: underline; + text-underline-offset: 2px; + transition: opacity 0.25s; +} + +.custom-block a:hover { + opacity: 0.75; +} + +.custom-block code { + font-size: var(--vp-custom-block-code-font-size); +} + +.custom-block.custom-block th, +.custom-block.custom-block blockquote > p { + font-size: var(--vp-custom-block-font-size); + color: inherit; +} +.dark .vp-code span { + color: var(--shiki-dark, inherit); +} + +html:not(.dark) .vp-code span { + color: var(--shiki-light, inherit); +} +.vp-code-group { + margin-top: 16px; +} + +.vp-code-group .tabs { + position: relative; + display: flex; + margin-right: -24px; + margin-left: -24px; + padding: 0 12px; + background-color: var(--vp-code-tab-bg); + overflow-x: auto; + overflow-y: hidden; + box-shadow: inset 0 -1px var(--vp-code-tab-divider); +} + +@media (min-width: 640px) { + .vp-code-group .tabs { + margin-right: 0; + margin-left: 0; + border-radius: 8px 8px 0 0; + } +} + +.vp-code-group .tabs input { + position: fixed; + opacity: 0; + pointer-events: none; +} + +.vp-code-group .tabs label { + position: relative; + display: inline-block; + border-bottom: 1px solid transparent; + padding: 0 12px; + line-height: 48px; + font-size: 14px; + font-weight: 500; + color: var(--vp-code-tab-text-color); + white-space: nowrap; + cursor: pointer; + transition: color 0.25s; +} + +.vp-code-group .tabs label::after { + position: absolute; + right: 8px; + bottom: -1px; + left: 8px; + z-index: 1; + height: 2px; + border-radius: 2px; + content: ''; + background-color: transparent; + transition: background-color 0.25s; +} + +.vp-code-group label:hover { + color: var(--vp-code-tab-hover-text-color); +} + +.vp-code-group input:checked + label { + color: var(--vp-code-tab-active-text-color); +} + +.vp-code-group input:checked + label::after { + background-color: var(--vp-code-tab-active-bar-color); +} + +.vp-code-group div[class*='language-'], +.vp-block { + display: none; + margin-top: 0 !important; + border-top-left-radius: 0 !important; + border-top-right-radius: 0 !important; +} + +.vp-code-group div[class*='language-'].active, +.vp-block.active { + display: block; +} + +.vp-block { + padding: 20px 24px; +} +/** + * Headings + * -------------------------------------------------------------------------- */ + +.vp-doc h1, +.vp-doc h2, +.vp-doc h3, +.vp-doc h4, +.vp-doc h5, +.vp-doc h6 { + position: relative; + font-weight: 600; + outline: none; +} + +.vp-doc h1 { + letter-spacing: -0.02em; + line-height: 40px; + font-size: 28px; +} + +.vp-doc h2 { + margin: 48px 0 16px; + border-top: 1px solid var(--vp-c-divider); + padding-top: 24px; + letter-spacing: -0.02em; + line-height: 32px; + font-size: 24px; +} + +.vp-doc h3 { + margin: 32px 0 0; + letter-spacing: -0.01em; + line-height: 28px; + font-size: 20px; +} + +.vp-doc h4 { + margin: 24px 0 0; + letter-spacing: -0.01em; + line-height: 24px; + font-size: 18px; +} + +.vp-doc .header-anchor { + position: absolute; + top: 0; + left: 0; + margin-left: -0.87em; + font-weight: 500; + user-select: none; + opacity: 0; + text-decoration: none; + transition: + color 0.25s, + opacity 0.25s; +} + +.vp-doc .header-anchor:before { + content: var(--vp-header-anchor-symbol); +} + +.vp-doc h1:hover .header-anchor, +.vp-doc h1 .header-anchor:focus, +.vp-doc h2:hover .header-anchor, +.vp-doc h2 .header-anchor:focus, +.vp-doc h3:hover .header-anchor, +.vp-doc h3 .header-anchor:focus, +.vp-doc h4:hover .header-anchor, +.vp-doc h4 .header-anchor:focus, +.vp-doc h5:hover .header-anchor, +.vp-doc h5 .header-anchor:focus, +.vp-doc h6:hover .header-anchor, +.vp-doc h6 .header-anchor:focus { + opacity: 1; +} + +@media (min-width: 768px) { + .vp-doc h1 { + letter-spacing: -0.02em; + line-height: 40px; + font-size: 32px; + } +} + +.vp-doc h2 .header-anchor { + top: 24px; +} + +/** + * Paragraph and inline elements + * -------------------------------------------------------------------------- */ + +.vp-doc p, +.vp-doc summary { + margin: 16px 0; +} + +.vp-doc p { + line-height: 28px; +} + +.vp-doc blockquote { + margin: 16px 0; + border-left: 2px solid var(--vp-c-divider); + padding-left: 16px; + transition: border-color 0.5s; + color: var(--vp-c-text-2); +} + +.vp-doc blockquote > p { + margin: 0; + font-size: 16px; + transition: color 0.5s; +} + +.vp-doc a { + font-weight: 500; + color: var(--vp-c-brand-1); + text-decoration: underline; + text-underline-offset: 2px; + transition: + color 0.25s, + opacity 0.25s; +} + +.vp-doc a:hover { + color: var(--vp-c-brand-2); +} + +.vp-doc strong { + font-weight: 600; +} + +/** + * Lists + * -------------------------------------------------------------------------- */ + +.vp-doc ul, +.vp-doc ol { + padding-left: 1.25rem; + margin: 16px 0; +} + +.vp-doc ul { + list-style: disc; +} + +.vp-doc ol { + list-style: decimal; +} + +.vp-doc li + li { + margin-top: 8px; +} + +.vp-doc li > ol, +.vp-doc li > ul { + margin: 8px 0 0; +} + +/** + * Table + * -------------------------------------------------------------------------- */ + +.vp-doc table { + display: block; + border-collapse: collapse; + margin: 20px 0; + overflow-x: auto; +} + +.vp-doc tr { + background-color: var(--vp-c-bg); + border-top: 1px solid var(--vp-c-divider); + transition: background-color 0.5s; +} + +.vp-doc tr:nth-child(2n) { + background-color: var(--vp-c-bg-soft); +} + +.vp-doc th, +.vp-doc td { + border: 1px solid var(--vp-c-divider); + padding: 8px 16px; +} + +.vp-doc th { + text-align: left; + font-size: 14px; + font-weight: 600; + color: var(--vp-c-text-2); + background-color: var(--vp-c-bg-soft); +} + +.vp-doc td { + font-size: 14px; +} + +/** + * Decorational elements + * -------------------------------------------------------------------------- */ + +.vp-doc hr { + margin: 16px 0; + border: none; + border-top: 1px solid var(--vp-c-divider); +} + +/** + * Custom Block + * -------------------------------------------------------------------------- */ + +.vp-doc .custom-block { + margin: 16px 0; +} + +.vp-doc .custom-block p { + margin: 8px 0; + line-height: 24px; +} + +.vp-doc .custom-block p:first-child { + margin: 0; +} + +.vp-doc .custom-block div[class*='language-'] { + margin: 8px 0; + border-radius: 8px; +} + +.vp-doc .custom-block div[class*='language-'] code { + font-weight: 400; + background-color: transparent; +} + +.vp-doc .custom-block .vp-code-group .tabs { + margin: 0; + border-radius: 8px 8px 0 0; +} + +/** + * Code + * -------------------------------------------------------------------------- */ + +/* inline code */ +.vp-doc :not(pre, h1, h2, h3, h4, h5, h6) > code { + font-size: var(--vp-code-font-size); + color: var(--vp-code-color); +} + +.vp-doc :not(pre) > code { + border-radius: 4px; + padding: 3px 6px; + background-color: var(--vp-code-bg); + transition: + color 0.25s, + background-color 0.5s; +} + +.vp-doc a > code { + color: var(--vp-code-link-color); +} + +.vp-doc a:hover > code { + color: var(--vp-code-link-hover-color); +} + +.vp-doc h1 > code, +.vp-doc h2 > code, +.vp-doc h3 > code, +.vp-doc h4 > code { + font-size: 0.9em; +} + +.vp-doc div[class*='language-'], +.vp-block { + position: relative; + margin: 16px -24px; + background-color: var(--vp-code-block-bg); + overflow-x: auto; + transition: background-color 0.5s; +} + +@media (min-width: 640px) { + .vp-doc div[class*='language-'], + .vp-block { + border-radius: 8px; + margin: 16px 0; + } +} + +@media (max-width: 639px) { + .vp-doc li div[class*='language-'] { + border-radius: 8px 0 0 8px; + } +} + +.vp-doc div[class*='language-'] + div[class*='language-'], +.vp-doc div[class$='-api'] + div[class*='language-'], +.vp-doc div[class*='language-'] + div[class$='-api'] > div[class*='language-'] { + margin-top: -8px; +} + +.vp-doc [class*='language-'] pre, +.vp-doc [class*='language-'] code { + /*rtl:ignore*/ + direction: ltr; + /*rtl:ignore*/ + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +.vp-doc [class*='language-'] pre { + position: relative; + z-index: 1; + margin: 0; + padding: 20px 0; + background: transparent; + overflow-x: auto; +} + +.vp-doc [class*='language-'] code { + display: block; + padding: 0 24px; + width: fit-content; + min-width: 100%; + line-height: var(--vp-code-line-height); + font-size: var(--vp-code-font-size); + color: var(--vp-code-block-color); + transition: color 0.5s; +} + +.vp-doc [class*='language-'] code .highlighted { + background-color: var(--vp-code-line-highlight-color); + transition: background-color 0.5s; + margin: 0 -24px; + padding: 0 24px; + width: calc(100% + 2 * 24px); + display: inline-block; +} + +.vp-doc [class*='language-'] code .highlighted.error { + background-color: var(--vp-code-line-error-color); +} + +.vp-doc [class*='language-'] code .highlighted.warning { + background-color: var(--vp-code-line-warning-color); +} + +.vp-doc [class*='language-'] code .diff { + transition: background-color 0.5s; + margin: 0 -24px; + padding: 0 24px; + width: calc(100% + 2 * 24px); + display: inline-block; +} + +.vp-doc [class*='language-'] code .diff::before { + position: absolute; + left: 10px; +} + +.vp-doc [class*='language-'] .has-focused-lines .line:not(.has-focus) { + filter: blur(0.095rem); + opacity: 0.4; + transition: + filter 0.35s, + opacity 0.35s; +} + +.vp-doc [class*='language-'] .has-focused-lines .line:not(.has-focus) { + opacity: 0.7; + transition: + filter 0.35s, + opacity 0.35s; +} + +.vp-doc [class*='language-']:hover .has-focused-lines .line:not(.has-focus) { + filter: blur(0); + opacity: 1; +} + +.vp-doc [class*='language-'] code .diff.remove { + background-color: var(--vp-code-line-diff-remove-color); + opacity: 0.7; +} + +.vp-doc [class*='language-'] code .diff.remove::before { + content: '-'; + color: var(--vp-code-line-diff-remove-symbol-color); +} + +.vp-doc [class*='language-'] code .diff.add { + background-color: var(--vp-code-line-diff-add-color); +} + +.vp-doc [class*='language-'] code .diff.add::before { + content: '+'; + color: var(--vp-code-line-diff-add-symbol-color); +} + +.vp-doc div[class*='language-'].line-numbers-mode { + /*rtl:ignore*/ + padding-left: 32px; +} + +.vp-doc .line-numbers-wrapper { + position: absolute; + top: 0; + bottom: 0; + /*rtl:ignore*/ + left: 0; + z-index: 3; + /*rtl:ignore*/ + border-right: 1px solid var(--vp-code-block-divider-color); + padding-top: 20px; + width: 32px; + text-align: center; + font-family: var(--vp-font-family-mono); + line-height: var(--vp-code-line-height); + font-size: var(--vp-code-font-size); + color: var(--vp-code-line-number-color); + transition: + border-color 0.5s, + color 0.5s; +} + +.vp-doc [class*='language-'] > button.copy { + /*rtl:ignore*/ + direction: ltr; + position: absolute; + top: 12px; + /*rtl:ignore*/ + right: 12px; + z-index: 3; + border: 1px solid var(--vp-code-copy-code-border-color); + border-radius: 4px; + width: 40px; + height: 40px; + background-color: var(--vp-code-copy-code-bg); + opacity: 0; + cursor: pointer; + background-image: var(--vp-icon-copy); + background-position: 50%; + background-size: 20px; + background-repeat: no-repeat; + transition: + border-color 0.25s, + background-color 0.25s, + opacity 0.25s; +} + +.vp-doc [class*='language-']:hover > button.copy, +.vp-doc [class*='language-'] > button.copy:focus { + opacity: 1; +} + +.vp-doc [class*='language-'] > button.copy:hover, +.vp-doc [class*='language-'] > button.copy.copied { + border-color: var(--vp-code-copy-code-hover-border-color); + background-color: var(--vp-code-copy-code-hover-bg); +} + +.vp-doc [class*='language-'] > button.copy.copied, +.vp-doc [class*='language-'] > button.copy:hover.copied { + /*rtl:ignore*/ + border-radius: 0 4px 4px 0; + background-color: var(--vp-code-copy-code-hover-bg); + background-image: var(--vp-icon-copied); +} + +.vp-doc [class*='language-'] > button.copy.copied::before, +.vp-doc [class*='language-'] > button.copy:hover.copied::before { + position: relative; + top: -1px; + /*rtl:ignore*/ + transform: translateX(calc(-100% - 1px)); + display: flex; + justify-content: center; + align-items: center; + border: 1px solid var(--vp-code-copy-code-hover-border-color); + /*rtl:ignore*/ + border-right: 0; + /*rtl:ignore*/ + border-radius: 4px 0 0 4px; + padding: 0 10px; + width: fit-content; + height: 40px; + text-align: center; + font-size: 12px; + font-weight: 500; + color: var(--vp-code-copy-code-active-text); + background-color: var(--vp-code-copy-code-hover-bg); + white-space: nowrap; + content: var(--vp-code-copy-copied-text-content); +} + +.vp-doc [class*='language-'] > span.lang { + position: absolute; + top: 2px; + /*rtl:ignore*/ + right: 8px; + z-index: 2; + font-size: 12px; + font-weight: 500; + user-select: none; + color: var(--vp-code-lang-color); + transition: + color 0.4s, + opacity 0.4s; +} + +.vp-doc [class*='language-']:hover > button.copy + span.lang, +.vp-doc [class*='language-'] > button.copy:focus + span.lang { + opacity: 0; +} + +/** + * Component: Team + * -------------------------------------------------------------------------- */ + +.vp-doc .VPTeamMembers { + margin-top: 24px; +} + +.vp-doc .VPTeamMembers.small.count-1 .container { + margin: 0 !important; + max-width: calc((100% - 24px) / 2) !important; +} + +.vp-doc .VPTeamMembers.small.count-2 .container, +.vp-doc .VPTeamMembers.small.count-3 .container { + max-width: 100% !important; +} + +.vp-doc .VPTeamMembers.medium.count-1 .container { + margin: 0 !important; + max-width: calc((100% - 24px) / 2) !important; +} + +/** + * External links + * -------------------------------------------------------------------------- */ + +/* prettier-ignore */ +:is(.vp-external-link-icon, .vp-doc a[href*='://'], .vp-doc a[target='_blank']):not(:is(.no-icon, svg a, :has(img, svg)))::after { + display: inline-block; + margin-top: -1px; + margin-left: 4px; + width: 11px; + height: 11px; + background: currentColor; + color: var(--vp-c-text-3); + flex-shrink: 0; + --icon: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M0 0h24v24H0V0z' fill='none' /%3E%3Cpath d='M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z' /%3E%3C/svg%3E"); + -webkit-mask-image: var(--icon); + mask-image: var(--icon); + /*rtl:raw:transform: scaleX(-1);*/ +} + +.vp-external-link-icon::after { + content: ''; +} + +/* prettier-ignore */ +.external-link-icon-enabled :is(.vp-doc a[href*='://'], .vp-doc a[target='_blank']):not(:is(.no-icon, svg a, :has(img, svg)))::after { + content: ''; + color: currentColor; +} +/** + * VPSponsors styles are defined as global because a new class gets + * allied in onMounted` hook and we can't use scoped style. + */ +.vp-sponsor { + border-radius: 16px; + overflow: hidden; +} + +.vp-sponsor.aside { + border-radius: 12px; +} + +.vp-sponsor-section + .vp-sponsor-section { + margin-top: 4px; +} + +.vp-sponsor-tier { + margin: 0 0 4px !important; + text-align: center; + letter-spacing: 1px !important; + line-height: 24px; + width: 100%; + font-weight: 600; + color: var(--vp-c-text-2); + background-color: var(--vp-c-bg-soft); +} + +.vp-sponsor.normal .vp-sponsor-tier { + padding: 13px 0 11px; + font-size: 14px; +} + +.vp-sponsor.aside .vp-sponsor-tier { + padding: 9px 0 7px; + font-size: 12px; +} + +.vp-sponsor-grid + .vp-sponsor-tier { + margin-top: 4px; +} + +.vp-sponsor-grid { + display: flex; + flex-wrap: wrap; + gap: 4px; +} + +.vp-sponsor-grid.xmini .vp-sponsor-grid-link { + height: 64px; +} +.vp-sponsor-grid.xmini .vp-sponsor-grid-image { + max-width: 64px; + max-height: 22px; +} + +.vp-sponsor-grid.mini .vp-sponsor-grid-link { + height: 72px; +} +.vp-sponsor-grid.mini .vp-sponsor-grid-image { + max-width: 96px; + max-height: 24px; +} + +.vp-sponsor-grid.small .vp-sponsor-grid-link { + height: 96px; +} +.vp-sponsor-grid.small .vp-sponsor-grid-image { + max-width: 96px; + max-height: 24px; +} + +.vp-sponsor-grid.medium .vp-sponsor-grid-link { + height: 112px; +} +.vp-sponsor-grid.medium .vp-sponsor-grid-image { + max-width: 120px; + max-height: 36px; +} + +.vp-sponsor-grid.big .vp-sponsor-grid-link { + height: 184px; +} +.vp-sponsor-grid.big .vp-sponsor-grid-image { + max-width: 192px; + max-height: 56px; +} + +.vp-sponsor-grid[data-vp-grid='2'] .vp-sponsor-grid-item { + width: calc((100% - 4px) / 2); +} + +.vp-sponsor-grid[data-vp-grid='3'] .vp-sponsor-grid-item { + width: calc((100% - 4px * 2) / 3); +} + +.vp-sponsor-grid[data-vp-grid='4'] .vp-sponsor-grid-item { + width: calc((100% - 4px * 3) / 4); +} + +.vp-sponsor-grid[data-vp-grid='5'] .vp-sponsor-grid-item { + width: calc((100% - 4px * 4) / 5); +} + +.vp-sponsor-grid[data-vp-grid='6'] .vp-sponsor-grid-item { + width: calc((100% - 4px * 5) / 6); +} + +.vp-sponsor-grid-item { + flex-shrink: 0; + width: 100%; + background-color: var(--vp-c-bg-soft); + transition: background-color 0.25s; +} + +.vp-sponsor-grid-item:hover { + background-color: var(--vp-c-default-soft); +} + +.vp-sponsor-grid-item:hover .vp-sponsor-grid-image { + filter: grayscale(0) invert(0); +} + +.vp-sponsor-grid-item.empty:hover { + background-color: var(--vp-c-bg-soft); +} + +.dark .vp-sponsor-grid-item:hover { + background-color: var(--vp-c-white); +} + +.dark .vp-sponsor-grid-item.empty:hover { + background-color: var(--vp-c-bg-soft); +} + +.vp-sponsor-grid-link { + display: flex; +} + +.vp-sponsor-grid-box { + display: flex; + justify-content: center; + align-items: center; + width: 100%; +} + +.vp-sponsor-grid-image { + max-width: 100%; + filter: grayscale(1); + transition: filter 0.25s; +} + +.dark .vp-sponsor-grid-image { + filter: grayscale(1) invert(1); +} + +.VPBadge { + display: inline-block; + margin-left: 2px; + border: 1px solid transparent; + border-radius: 12px; + padding: 0 10px; + line-height: 22px; + font-size: 12px; + font-weight: 500; + transform: translateY(-2px); +} +.VPBadge.small { + padding: 0 6px; + line-height: 18px; + font-size: 10px; + transform: translateY(-8px); +} +.VPDocFooter .VPBadge { + display: none; +} +.vp-doc h1 > .VPBadge { + margin-top: 4px; + vertical-align: top; +} +.vp-doc h2 > .VPBadge { + margin-top: 3px; + padding: 0 8px; + vertical-align: top; +} +.vp-doc h3 > .VPBadge { + vertical-align: middle; +} +.vp-doc h4 > .VPBadge, +.vp-doc h5 > .VPBadge, +.vp-doc h6 > .VPBadge { + vertical-align: middle; + line-height: 18px; +} +.VPBadge.info { + border-color: var(--vp-badge-info-border); + color: var(--vp-badge-info-text); + background-color: var(--vp-badge-info-bg); +} +.VPBadge.tip { + border-color: var(--vp-badge-tip-border); + color: var(--vp-badge-tip-text); + background-color: var(--vp-badge-tip-bg); +} +.VPBadge.warning { + border-color: var(--vp-badge-warning-border); + color: var(--vp-badge-warning-text); + background-color: var(--vp-badge-warning-bg); +} +.VPBadge.danger { + border-color: var(--vp-badge-danger-border); + color: var(--vp-badge-danger-text); + background-color: var(--vp-badge-danger-bg); +} + +.VPBackdrop[data-v-c79a1216] { + position: fixed; + top: 0; + /*rtl:ignore*/ + right: 0; + bottom: 0; + /*rtl:ignore*/ + left: 0; + z-index: var(--vp-z-index-backdrop); + background: var(--vp-backdrop-bg-color); + transition: opacity 0.5s; +} +.VPBackdrop.fade-enter-from[data-v-c79a1216], +.VPBackdrop.fade-leave-to[data-v-c79a1216] { + opacity: 0; +} +.VPBackdrop.fade-leave-active[data-v-c79a1216] { + transition-duration: .25s; +} +@media (min-width: 1280px) { +.VPBackdrop[data-v-c79a1216] { + display: none; +} +} + +.NotFound[data-v-d6be1790] { + padding: 64px 24px 96px; + text-align: center; +} +@media (min-width: 768px) { +.NotFound[data-v-d6be1790] { + padding: 96px 32px 168px; +} +} +.code[data-v-d6be1790] { + line-height: 64px; + font-size: 64px; + font-weight: 600; +} +.title[data-v-d6be1790] { + padding-top: 12px; + letter-spacing: 2px; + line-height: 20px; + font-size: 20px; + font-weight: 700; +} +.divider[data-v-d6be1790] { + margin: 24px auto 18px; + width: 64px; + height: 1px; + background-color: var(--vp-c-divider); +} +.quote[data-v-d6be1790] { + margin: 0 auto; + max-width: 256px; + font-size: 14px; + font-weight: 500; + color: var(--vp-c-text-2); +} +.action[data-v-d6be1790] { + padding-top: 20px; +} +.link[data-v-d6be1790] { + display: inline-block; + border: 1px solid var(--vp-c-brand-1); + border-radius: 16px; + padding: 3px 16px; + font-size: 14px; + font-weight: 500; + color: var(--vp-c-brand-1); + transition: + border-color 0.25s, + color 0.25s; +} +.link[data-v-d6be1790]:hover { + border-color: var(--vp-c-brand-2); + color: var(--vp-c-brand-2); +} + +.root[data-v-b933a997] { + position: relative; + z-index: 1; +} +.nested[data-v-b933a997] { + padding-right: 16px; + padding-left: 16px; +} +.outline-link[data-v-b933a997] { + display: block; + line-height: 32px; + font-size: 14px; + font-weight: 400; + color: var(--vp-c-text-2); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + transition: color 0.5s; +} +.outline-link[data-v-b933a997]:hover, +.outline-link.active[data-v-b933a997] { + color: var(--vp-c-text-1); + transition: color 0.25s; +} +.outline-link.nested[data-v-b933a997] { + padding-left: 13px; +} + +.VPDocAsideOutline[data-v-a5bbad30] { + display: none; +} +.VPDocAsideOutline.has-outline[data-v-a5bbad30] { + display: block; +} +.content[data-v-a5bbad30] { + position: relative; + border-left: 1px solid var(--vp-c-divider); + padding-left: 16px; + font-size: 13px; + font-weight: 500; +} +.outline-marker[data-v-a5bbad30] { + position: absolute; + top: 32px; + left: -1px; + z-index: 0; + opacity: 0; + width: 2px; + border-radius: 2px; + height: 18px; + background-color: var(--vp-c-brand-1); + transition: + top 0.25s cubic-bezier(0, 1, 0.5, 1), + background-color 0.5s, + opacity 0.25s; +} +.outline-title[data-v-a5bbad30] { + line-height: 32px; + font-size: 14px; + font-weight: 600; +} + +.VPDocAside[data-v-3f215769] { + display: flex; + flex-direction: column; + flex-grow: 1; +} +.spacer[data-v-3f215769] { + flex-grow: 1; +} +.VPDocAside[data-v-3f215769] .spacer + .VPDocAsideSponsors, +.VPDocAside[data-v-3f215769] .spacer + .VPDocAsideCarbonAds { + margin-top: 24px; +} +.VPDocAside[data-v-3f215769] .VPDocAsideSponsors + .VPDocAsideCarbonAds { + margin-top: 16px; +} + +.VPLastUpdated[data-v-e98dd255] { + line-height: 24px; + font-size: 14px; + font-weight: 500; + color: var(--vp-c-text-2); +} +@media (min-width: 640px) { +.VPLastUpdated[data-v-e98dd255] { + line-height: 32px; + font-size: 14px; + font-weight: 500; +} +} + +.VPDocFooter[data-v-e257564d] { + margin-top: 64px; +} +.edit-info[data-v-e257564d] { + padding-bottom: 18px; +} +@media (min-width: 640px) { +.edit-info[data-v-e257564d] { + display: flex; + justify-content: space-between; + align-items: center; + padding-bottom: 14px; +} +} +.edit-link-button[data-v-e257564d] { + display: flex; + align-items: center; + border: 0; + line-height: 32px; + font-size: 14px; + font-weight: 500; + color: var(--vp-c-brand-1); + transition: color 0.25s; +} +.edit-link-button[data-v-e257564d]:hover { + color: var(--vp-c-brand-2); +} +.edit-link-icon[data-v-e257564d] { + margin-right: 8px; +} +.prev-next[data-v-e257564d] { + border-top: 1px solid var(--vp-c-divider); + padding-top: 24px; + display: grid; + grid-row-gap: 8px; +} +@media (min-width: 640px) { +.prev-next[data-v-e257564d] { + grid-template-columns: repeat(2, 1fr); + grid-column-gap: 16px; +} +} +.pager-link[data-v-e257564d] { + display: block; + border: 1px solid var(--vp-c-divider); + border-radius: 8px; + padding: 11px 16px 13px; + width: 100%; + height: 100%; + transition: border-color 0.25s; +} +.pager-link[data-v-e257564d]:hover { + border-color: var(--vp-c-brand-1); +} +.pager-link.next[data-v-e257564d] { + margin-left: auto; + text-align: right; +} +.desc[data-v-e257564d] { + display: block; + line-height: 20px; + font-size: 12px; + font-weight: 500; + color: var(--vp-c-text-2); +} +.title[data-v-e257564d] { + display: block; + line-height: 20px; + font-size: 14px; + font-weight: 500; + color: var(--vp-c-brand-1); + transition: color 0.25s; +} + +.VPDoc[data-v-39a288b8] { + padding: 32px 24px 96px; + width: 100%; +} +@media (min-width: 768px) { +.VPDoc[data-v-39a288b8] { + padding: 48px 32px 128px; +} +} +@media (min-width: 960px) { +.VPDoc[data-v-39a288b8] { + padding: 48px 32px 0; +} +.VPDoc:not(.has-sidebar) .container[data-v-39a288b8] { + display: flex; + justify-content: center; + max-width: 992px; +} +.VPDoc:not(.has-sidebar) .content[data-v-39a288b8] { + max-width: 752px; +} +} +@media (min-width: 1280px) { +.VPDoc .container[data-v-39a288b8] { + display: flex; + justify-content: center; +} +.VPDoc .aside[data-v-39a288b8] { + display: block; +} +} +@media (min-width: 1440px) { +.VPDoc:not(.has-sidebar) .content[data-v-39a288b8] { + max-width: 784px; +} +.VPDoc:not(.has-sidebar) .container[data-v-39a288b8] { + max-width: 1104px; +} +} +.container[data-v-39a288b8] { + margin: 0 auto; + width: 100%; +} +.aside[data-v-39a288b8] { + position: relative; + display: none; + order: 2; + flex-grow: 1; + padding-left: 32px; + width: 100%; + max-width: 256px; +} +.left-aside[data-v-39a288b8] { + order: 1; + padding-left: unset; + padding-right: 32px; +} +.aside-container[data-v-39a288b8] { + position: fixed; + top: 0; + padding-top: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + var(--vp-doc-top-height, 0px) + 48px); + width: 224px; + height: 100vh; + overflow-x: hidden; + overflow-y: auto; + scrollbar-width: none; +} +.aside-container[data-v-39a288b8]::-webkit-scrollbar { + display: none; +} +.aside-curtain[data-v-39a288b8] { + position: fixed; + bottom: 0; + z-index: 10; + width: 224px; + height: 32px; + background: linear-gradient(transparent, var(--vp-c-bg) 70%); +} +.aside-content[data-v-39a288b8] { + display: flex; + flex-direction: column; + min-height: calc(100vh - (var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px)); + padding-bottom: 32px; +} +.content[data-v-39a288b8] { + position: relative; + margin: 0 auto; + width: 100%; +} +@media (min-width: 960px) { +.content[data-v-39a288b8] { + padding: 0 32px 128px; +} +} +@media (min-width: 1280px) { +.content[data-v-39a288b8] { + order: 1; + margin: 0; + min-width: 640px; +} +} +.content-container[data-v-39a288b8] { + margin: 0 auto; +} +.VPDoc.has-aside .content-container[data-v-39a288b8] { + max-width: 688px; +} + +.VPButton[data-v-fa7799d5] { + display: inline-block; + border: 1px solid transparent; + text-align: center; + font-weight: 600; + white-space: nowrap; + transition: color 0.25s, border-color 0.25s, background-color 0.25s; +} +.VPButton[data-v-fa7799d5]:active { + transition: color 0.1s, border-color 0.1s, background-color 0.1s; +} +.VPButton.medium[data-v-fa7799d5] { + border-radius: 20px; + padding: 0 20px; + line-height: 38px; + font-size: 14px; +} +.VPButton.big[data-v-fa7799d5] { + border-radius: 24px; + padding: 0 24px; + line-height: 46px; + font-size: 16px; +} +.VPButton.brand[data-v-fa7799d5] { + border-color: var(--vp-button-brand-border); + color: var(--vp-button-brand-text); + background-color: var(--vp-button-brand-bg); +} +.VPButton.brand[data-v-fa7799d5]:hover { + border-color: var(--vp-button-brand-hover-border); + color: var(--vp-button-brand-hover-text); + background-color: var(--vp-button-brand-hover-bg); +} +.VPButton.brand[data-v-fa7799d5]:active { + border-color: var(--vp-button-brand-active-border); + color: var(--vp-button-brand-active-text); + background-color: var(--vp-button-brand-active-bg); +} +.VPButton.alt[data-v-fa7799d5] { + border-color: var(--vp-button-alt-border); + color: var(--vp-button-alt-text); + background-color: var(--vp-button-alt-bg); +} +.VPButton.alt[data-v-fa7799d5]:hover { + border-color: var(--vp-button-alt-hover-border); + color: var(--vp-button-alt-hover-text); + background-color: var(--vp-button-alt-hover-bg); +} +.VPButton.alt[data-v-fa7799d5]:active { + border-color: var(--vp-button-alt-active-border); + color: var(--vp-button-alt-active-text); + background-color: var(--vp-button-alt-active-bg); +} +.VPButton.sponsor[data-v-fa7799d5] { + border-color: var(--vp-button-sponsor-border); + color: var(--vp-button-sponsor-text); + background-color: var(--vp-button-sponsor-bg); +} +.VPButton.sponsor[data-v-fa7799d5]:hover { + border-color: var(--vp-button-sponsor-hover-border); + color: var(--vp-button-sponsor-hover-text); + background-color: var(--vp-button-sponsor-hover-bg); +} +.VPButton.sponsor[data-v-fa7799d5]:active { + border-color: var(--vp-button-sponsor-active-border); + color: var(--vp-button-sponsor-active-text); + background-color: var(--vp-button-sponsor-active-bg); +} + +html:not(.dark) .VPImage.dark[data-v-8426fc1a] { + display: none; +} +.dark .VPImage.light[data-v-8426fc1a] { + display: none; +} + +.VPHero[data-v-4f9c455b] { + margin-top: calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1); + padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px; +} +@media (min-width: 640px) { +.VPHero[data-v-4f9c455b] { + padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px; +} +} +@media (min-width: 960px) { +.VPHero[data-v-4f9c455b] { + padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px; +} +} +.container[data-v-4f9c455b] { + display: flex; + flex-direction: column; + margin: 0 auto; + max-width: 1152px; +} +@media (min-width: 960px) { +.container[data-v-4f9c455b] { + flex-direction: row; +} +} +.main[data-v-4f9c455b] { + position: relative; + z-index: 10; + order: 2; + flex-grow: 1; + flex-shrink: 0; +} +.VPHero.has-image .container[data-v-4f9c455b] { + text-align: center; +} +@media (min-width: 960px) { +.VPHero.has-image .container[data-v-4f9c455b] { + text-align: left; +} +} +@media (min-width: 960px) { +.main[data-v-4f9c455b] { + order: 1; + width: calc((100% / 3) * 2); +} +.VPHero.has-image .main[data-v-4f9c455b] { + max-width: 592px; +} +} +.heading[data-v-4f9c455b] { + display: flex; + flex-direction: column; +} +.name[data-v-4f9c455b], +.text[data-v-4f9c455b] { + width: fit-content; + max-width: 392px; + letter-spacing: -0.4px; + line-height: 40px; + font-size: 32px; + font-weight: 700; + white-space: pre-wrap; +} +.VPHero.has-image .name[data-v-4f9c455b], +.VPHero.has-image .text[data-v-4f9c455b] { + margin: 0 auto; +} +.name[data-v-4f9c455b] { + color: var(--vp-home-hero-name-color); +} +.clip[data-v-4f9c455b] { + background: var(--vp-home-hero-name-background); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: var(--vp-home-hero-name-color); +} +@media (min-width: 640px) { +.name[data-v-4f9c455b], + .text[data-v-4f9c455b] { + max-width: 576px; + line-height: 56px; + font-size: 48px; +} +} +@media (min-width: 960px) { +.name[data-v-4f9c455b], + .text[data-v-4f9c455b] { + line-height: 64px; + font-size: 56px; +} +.VPHero.has-image .name[data-v-4f9c455b], + .VPHero.has-image .text[data-v-4f9c455b] { + margin: 0; +} +} +.tagline[data-v-4f9c455b] { + padding-top: 8px; + max-width: 392px; + line-height: 28px; + font-size: 18px; + font-weight: 500; + white-space: pre-wrap; + color: var(--vp-c-text-2); +} +.VPHero.has-image .tagline[data-v-4f9c455b] { + margin: 0 auto; +} +@media (min-width: 640px) { +.tagline[data-v-4f9c455b] { + padding-top: 12px; + max-width: 576px; + line-height: 32px; + font-size: 20px; +} +} +@media (min-width: 960px) { +.tagline[data-v-4f9c455b] { + line-height: 36px; + font-size: 24px; +} +.VPHero.has-image .tagline[data-v-4f9c455b] { + margin: 0; +} +} +.actions[data-v-4f9c455b] { + display: flex; + flex-wrap: wrap; + margin: -6px; + padding-top: 24px; +} +.VPHero.has-image .actions[data-v-4f9c455b] { + justify-content: center; +} +@media (min-width: 640px) { +.actions[data-v-4f9c455b] { + padding-top: 32px; +} +} +@media (min-width: 960px) { +.VPHero.has-image .actions[data-v-4f9c455b] { + justify-content: flex-start; +} +} +.action[data-v-4f9c455b] { + flex-shrink: 0; + padding: 6px; +} +.image[data-v-4f9c455b] { + order: 1; + margin: -76px -24px -48px; +} +@media (min-width: 640px) { +.image[data-v-4f9c455b] { + margin: -108px -24px -48px; +} +} +@media (min-width: 960px) { +.image[data-v-4f9c455b] { + flex-grow: 1; + order: 2; + margin: 0; + min-height: 100%; +} +} +.image-container[data-v-4f9c455b] { + position: relative; + margin: 0 auto; + width: 320px; + height: 320px; +} +@media (min-width: 640px) { +.image-container[data-v-4f9c455b] { + width: 392px; + height: 392px; +} +} +@media (min-width: 960px) { +.image-container[data-v-4f9c455b] { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + /*rtl:ignore*/ + transform: translate(-32px, -32px); +} +} +.image-bg[data-v-4f9c455b] { + position: absolute; + top: 50%; + /*rtl:ignore*/ + left: 50%; + border-radius: 50%; + width: 192px; + height: 192px; + background-image: var(--vp-home-hero-image-background-image); + filter: var(--vp-home-hero-image-filter); + /*rtl:ignore*/ + transform: translate(-50%, -50%); +} +@media (min-width: 640px) { +.image-bg[data-v-4f9c455b] { + width: 256px; + height: 256px; +} +} +@media (min-width: 960px) { +.image-bg[data-v-4f9c455b] { + width: 320px; + height: 320px; +} +} +[data-v-4f9c455b] .image-src { + position: absolute; + top: 50%; + /*rtl:ignore*/ + left: 50%; + max-width: 192px; + max-height: 192px; + /*rtl:ignore*/ + transform: translate(-50%, -50%); +} +@media (min-width: 640px) { +[data-v-4f9c455b] .image-src { + max-width: 256px; + max-height: 256px; +} +} +@media (min-width: 960px) { +[data-v-4f9c455b] .image-src { + max-width: 320px; + max-height: 320px; +} +} + +.VPFeature[data-v-a3976bdc] { + display: block; + border: 1px solid var(--vp-c-bg-soft); + border-radius: 12px; + height: 100%; + background-color: var(--vp-c-bg-soft); + transition: border-color 0.25s, background-color 0.25s; +} +.VPFeature.link[data-v-a3976bdc]:hover { + border-color: var(--vp-c-brand-1); +} +.box[data-v-a3976bdc] { + display: flex; + flex-direction: column; + padding: 24px; + height: 100%; +} +.box[data-v-a3976bdc] > .VPImage { + margin-bottom: 20px; +} +.icon[data-v-a3976bdc] { + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 20px; + border-radius: 6px; + background-color: var(--vp-c-default-soft); + width: 48px; + height: 48px; + font-size: 24px; + transition: background-color 0.25s; +} +.title[data-v-a3976bdc] { + line-height: 24px; + font-size: 16px; + font-weight: 600; +} +.details[data-v-a3976bdc] { + flex-grow: 1; + padding-top: 8px; + line-height: 24px; + font-size: 14px; + font-weight: 500; + color: var(--vp-c-text-2); +} +.link-text[data-v-a3976bdc] { + padding-top: 8px; +} +.link-text-value[data-v-a3976bdc] { + display: flex; + align-items: center; + font-size: 14px; + font-weight: 500; + color: var(--vp-c-brand-1); +} +.link-text-icon[data-v-a3976bdc] { + margin-left: 6px; +} + +.VPFeatures[data-v-a6181336] { + position: relative; + padding: 0 24px; +} +@media (min-width: 640px) { +.VPFeatures[data-v-a6181336] { + padding: 0 48px; +} +} +@media (min-width: 960px) { +.VPFeatures[data-v-a6181336] { + padding: 0 64px; +} +} +.container[data-v-a6181336] { + margin: 0 auto; + max-width: 1152px; +} +.items[data-v-a6181336] { + display: flex; + flex-wrap: wrap; + margin: -8px; +} +.item[data-v-a6181336] { + padding: 8px; + width: 100%; +} +@media (min-width: 640px) { +.item.grid-2[data-v-a6181336], + .item.grid-4[data-v-a6181336], + .item.grid-6[data-v-a6181336] { + width: calc(100% / 2); +} +} +@media (min-width: 768px) { +.item.grid-2[data-v-a6181336], + .item.grid-4[data-v-a6181336] { + width: calc(100% / 2); +} +.item.grid-3[data-v-a6181336], + .item.grid-6[data-v-a6181336] { + width: calc(100% / 3); +} +} +@media (min-width: 960px) { +.item.grid-4[data-v-a6181336] { + width: calc(100% / 4); +} +} + +.container[data-v-8e2d4988] { + margin: auto; + width: 100%; + max-width: 1280px; + padding: 0 24px; +} +@media (min-width: 640px) { +.container[data-v-8e2d4988] { + padding: 0 48px; +} +} +@media (min-width: 960px) { +.container[data-v-8e2d4988] { + width: 100%; + padding: 0 64px; +} +} +.vp-doc[data-v-8e2d4988] .VPHomeSponsors, +.vp-doc[data-v-8e2d4988] .VPTeamPage { + margin-left: var(--vp-offset, calc(50% - 50vw)); + margin-right: var(--vp-offset, calc(50% - 50vw)); +} +.vp-doc[data-v-8e2d4988] .VPHomeSponsors h2 { + border-top: none; + letter-spacing: normal; +} +.vp-doc[data-v-8e2d4988] .VPHomeSponsors a, +.vp-doc[data-v-8e2d4988] .VPTeamPage a { + text-decoration: none; +} + +.VPHome[data-v-8b561e3d] { + margin-bottom: 96px; +} +@media (min-width: 768px) { +.VPHome[data-v-8b561e3d] { + margin-bottom: 128px; +} +} + +.VPContent[data-v-1428d186] { + flex-grow: 1; + flex-shrink: 0; + margin: var(--vp-layout-top-height, 0px) auto 0; + width: 100%; +} +.VPContent.is-home[data-v-1428d186] { + width: 100%; + max-width: 100%; +} +.VPContent.has-sidebar[data-v-1428d186] { + margin: 0; +} +@media (min-width: 960px) { +.VPContent[data-v-1428d186] { + padding-top: var(--vp-nav-height); +} +.VPContent.has-sidebar[data-v-1428d186] { + margin: var(--vp-layout-top-height, 0px) 0 0; + padding-left: var(--vp-sidebar-width); +} +} +@media (min-width: 1440px) { +.VPContent.has-sidebar[data-v-1428d186] { + padding-right: calc((100vw - var(--vp-layout-max-width)) / 2); + padding-left: calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width)); +} +} + +.VPFooter[data-v-e315a0ad] { + position: relative; + z-index: var(--vp-z-index-footer); + border-top: 1px solid var(--vp-c-gutter); + padding: 32px 24px; + background-color: var(--vp-c-bg); +} +.VPFooter.has-sidebar[data-v-e315a0ad] { + display: none; +} +.VPFooter[data-v-e315a0ad] a { + text-decoration-line: underline; + text-underline-offset: 2px; + transition: color 0.25s; +} +.VPFooter[data-v-e315a0ad] a:hover { + color: var(--vp-c-text-1); +} +@media (min-width: 768px) { +.VPFooter[data-v-e315a0ad] { + padding: 32px; +} +} +.container[data-v-e315a0ad] { + margin: 0 auto; + max-width: var(--vp-layout-max-width); + text-align: center; +} +.message[data-v-e315a0ad], +.copyright[data-v-e315a0ad] { + line-height: 24px; + font-size: 14px; + font-weight: 500; + color: var(--vp-c-text-2); +} + +.VPLocalNavOutlineDropdown[data-v-8a42e2b4] { + padding: 12px 20px 11px; +} +@media (min-width: 960px) { +.VPLocalNavOutlineDropdown[data-v-8a42e2b4] { + padding: 12px 36px 11px; +} +} +.VPLocalNavOutlineDropdown button[data-v-8a42e2b4] { + display: block; + font-size: 12px; + font-weight: 500; + line-height: 24px; + color: var(--vp-c-text-2); + transition: color 0.5s; + position: relative; +} +.VPLocalNavOutlineDropdown button[data-v-8a42e2b4]:hover { + color: var(--vp-c-text-1); + transition: color 0.25s; +} +.VPLocalNavOutlineDropdown button.open[data-v-8a42e2b4] { + color: var(--vp-c-text-1); +} +.icon[data-v-8a42e2b4] { + display: inline-block; + vertical-align: middle; + margin-left: 2px; + font-size: 14px; + transform: rotate(0)/*rtl:rotate(180deg)*/; + transition: transform 0.25s; +} +@media (min-width: 960px) { +.VPLocalNavOutlineDropdown button[data-v-8a42e2b4] { + font-size: 14px; +} +.icon[data-v-8a42e2b4] { + font-size: 16px; +} +} +.open > .icon[data-v-8a42e2b4] { + /*rtl:ignore*/ + transform: rotate(90deg); +} +.items[data-v-8a42e2b4] { + position: absolute; + top: 40px; + right: 16px; + left: 16px; + display: grid; + gap: 1px; + border: 1px solid var(--vp-c-border); + border-radius: 8px; + background-color: var(--vp-c-gutter); + max-height: calc(var(--vp-vh, 100vh) - 86px); + overflow: hidden auto; + box-shadow: var(--vp-shadow-3); +} +@media (min-width: 960px) { +.items[data-v-8a42e2b4] { + right: auto; + left: calc(var(--vp-sidebar-width) + 32px); + width: 320px; +} +} +.header[data-v-8a42e2b4] { + background-color: var(--vp-c-bg-soft); +} +.top-link[data-v-8a42e2b4] { + display: block; + padding: 0 16px; + line-height: 48px; + font-size: 14px; + font-weight: 500; + color: var(--vp-c-brand-1); +} +.outline[data-v-8a42e2b4] { + padding: 8px 0; + background-color: var(--vp-c-bg-soft); +} +.flyout-enter-active[data-v-8a42e2b4] { + transition: all 0.2s ease-out; +} +.flyout-leave-active[data-v-8a42e2b4] { + transition: all 0.15s ease-in; +} +.flyout-enter-from[data-v-8a42e2b4], +.flyout-leave-to[data-v-8a42e2b4] { + opacity: 0; + transform: translateY(-16px); +} + +.VPLocalNav[data-v-a6f0e41e] { + position: sticky; + top: 0; + /*rtl:ignore*/ + left: 0; + z-index: var(--vp-z-index-local-nav); + border-bottom: 1px solid var(--vp-c-gutter); + padding-top: var(--vp-layout-top-height, 0px); + width: 100%; + background-color: var(--vp-local-nav-bg-color); +} +.VPLocalNav.fixed[data-v-a6f0e41e] { + position: fixed; +} +@media (min-width: 960px) { +.VPLocalNav[data-v-a6f0e41e] { + top: var(--vp-nav-height); +} +.VPLocalNav.has-sidebar[data-v-a6f0e41e] { + padding-left: var(--vp-sidebar-width); +} +.VPLocalNav.empty[data-v-a6f0e41e] { + display: none; +} +} +@media (min-width: 1280px) { +.VPLocalNav[data-v-a6f0e41e] { + display: none; +} +} +@media (min-width: 1440px) { +.VPLocalNav.has-sidebar[data-v-a6f0e41e] { + padding-left: calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width)); +} +} +.container[data-v-a6f0e41e] { + display: flex; + justify-content: space-between; + align-items: center; +} +.menu[data-v-a6f0e41e] { + display: flex; + align-items: center; + padding: 12px 24px 11px; + line-height: 24px; + font-size: 12px; + font-weight: 500; + color: var(--vp-c-text-2); + transition: color 0.5s; +} +.menu[data-v-a6f0e41e]:hover { + color: var(--vp-c-text-1); + transition: color 0.25s; +} +@media (min-width: 768px) { +.menu[data-v-a6f0e41e] { + padding: 0 32px; +} +} +@media (min-width: 960px) { +.menu[data-v-a6f0e41e] { + display: none; +} +} +.menu-icon[data-v-a6f0e41e] { + margin-right: 8px; + font-size: 14px; +} +.VPOutlineDropdown[data-v-a6f0e41e] { + padding: 12px 24px 11px; +} +@media (min-width: 768px) { +.VPOutlineDropdown[data-v-a6f0e41e] { + padding: 12px 32px 11px; +} +} + +.VPSwitch[data-v-1d5665e3] { + position: relative; + border-radius: 11px; + display: block; + width: 40px; + height: 22px; + flex-shrink: 0; + border: 1px solid var(--vp-input-border-color); + background-color: var(--vp-input-switch-bg-color); + transition: border-color 0.25s !important; +} +.VPSwitch[data-v-1d5665e3]:hover { + border-color: var(--vp-c-brand-1); +} +.check[data-v-1d5665e3] { + position: absolute; + top: 1px; + /*rtl:ignore*/ + left: 1px; + width: 18px; + height: 18px; + border-radius: 50%; + background-color: var(--vp-c-neutral-inverse); + box-shadow: var(--vp-shadow-1); + transition: transform 0.25s !important; +} +.icon[data-v-1d5665e3] { + position: relative; + display: block; + width: 18px; + height: 18px; + border-radius: 50%; + overflow: hidden; +} +.icon[data-v-1d5665e3] [class^='vpi-'] { + position: absolute; + top: 3px; + left: 3px; + width: 12px; + height: 12px; + color: var(--vp-c-text-2); +} +.dark .icon[data-v-1d5665e3] [class^='vpi-'] { + color: var(--vp-c-text-1); + transition: opacity 0.25s !important; +} + +.sun[data-v-5337faa4] { + opacity: 1; +} +.moon[data-v-5337faa4] { + opacity: 0; +} +.dark .sun[data-v-5337faa4] { + opacity: 0; +} +.dark .moon[data-v-5337faa4] { + opacity: 1; +} +.dark .VPSwitchAppearance[data-v-5337faa4] .check { + /*rtl:ignore*/ + transform: translateX(18px); +} + +.VPNavBarAppearance[data-v-6c893767] { + display: none; +} +@media (min-width: 1280px) { +.VPNavBarAppearance[data-v-6c893767] { + display: flex; + align-items: center; +} +} + +.VPMenuGroup + .VPMenuLink[data-v-35975db6] { + margin: 12px -12px 0; + border-top: 1px solid var(--vp-c-divider); + padding: 12px 12px 0; +} +.link[data-v-35975db6] { + display: block; + border-radius: 6px; + padding: 0 12px; + line-height: 32px; + font-size: 14px; + font-weight: 500; + color: var(--vp-c-text-1); + white-space: nowrap; + transition: + background-color 0.25s, + color 0.25s; +} +.link[data-v-35975db6]:hover { + color: var(--vp-c-brand-1); + background-color: var(--vp-c-default-soft); +} +.link.active[data-v-35975db6] { + color: var(--vp-c-brand-1); +} + +.VPMenuGroup[data-v-69e747b5] { + margin: 12px -12px 0; + border-top: 1px solid var(--vp-c-divider); + padding: 12px 12px 0; +} +.VPMenuGroup[data-v-69e747b5]:first-child { + margin-top: 0; + border-top: 0; + padding-top: 0; +} +.VPMenuGroup + .VPMenuGroup[data-v-69e747b5] { + margin-top: 12px; + border-top: 1px solid var(--vp-c-divider); +} +.title[data-v-69e747b5] { + padding: 0 12px; + line-height: 32px; + font-size: 14px; + font-weight: 600; + color: var(--vp-c-text-2); + white-space: nowrap; + transition: color 0.25s; +} + +.VPMenu[data-v-b98bc113] { + border-radius: 12px; + padding: 12px; + min-width: 128px; + border: 1px solid var(--vp-c-divider); + background-color: var(--vp-c-bg-elv); + box-shadow: var(--vp-shadow-3); + transition: background-color 0.5s; + max-height: calc(100vh - var(--vp-nav-height)); + overflow-y: auto; +} +.VPMenu[data-v-b98bc113] .group { + margin: 0 -12px; + padding: 0 12px 12px; +} +.VPMenu[data-v-b98bc113] .group + .group { + border-top: 1px solid var(--vp-c-divider); + padding: 11px 12px 12px; +} +.VPMenu[data-v-b98bc113] .group:last-child { + padding-bottom: 0; +} +.VPMenu[data-v-b98bc113] .group + .item { + border-top: 1px solid var(--vp-c-divider); + padding: 11px 16px 0; +} +.VPMenu[data-v-b98bc113] .item { + padding: 0 16px; + white-space: nowrap; +} +.VPMenu[data-v-b98bc113] .label { + flex-grow: 1; + line-height: 28px; + font-size: 12px; + font-weight: 500; + color: var(--vp-c-text-2); + transition: color 0.5s; +} +.VPMenu[data-v-b98bc113] .action { + padding-left: 24px; +} + +.VPFlyout[data-v-cf11d7a2] { + position: relative; +} +.VPFlyout[data-v-cf11d7a2]:hover { + color: var(--vp-c-brand-1); + transition: color 0.25s; +} +.VPFlyout:hover .text[data-v-cf11d7a2] { + color: var(--vp-c-text-2); +} +.VPFlyout:hover .icon[data-v-cf11d7a2] { + fill: var(--vp-c-text-2); +} +.VPFlyout.active .text[data-v-cf11d7a2] { + color: var(--vp-c-brand-1); +} +.VPFlyout.active:hover .text[data-v-cf11d7a2] { + color: var(--vp-c-brand-2); +} +.button[aria-expanded="false"] + .menu[data-v-cf11d7a2] { + opacity: 0; + visibility: hidden; + transform: translateY(0); +} +.VPFlyout:hover .menu[data-v-cf11d7a2], +.button[aria-expanded="true"] + .menu[data-v-cf11d7a2] { + opacity: 1; + visibility: visible; + transform: translateY(0); +} +.button[data-v-cf11d7a2] { + display: flex; + align-items: center; + padding: 0 12px; + height: var(--vp-nav-height); + color: var(--vp-c-text-1); + transition: color 0.5s; +} +.text[data-v-cf11d7a2] { + display: flex; + align-items: center; + line-height: var(--vp-nav-height); + font-size: 14px; + font-weight: 500; + color: var(--vp-c-text-1); + transition: color 0.25s; +} +.option-icon[data-v-cf11d7a2] { + margin-right: 0px; + font-size: 16px; +} +.text-icon[data-v-cf11d7a2] { + margin-left: 4px; + font-size: 14px; +} +.icon[data-v-cf11d7a2] { + font-size: 20px; + transition: fill 0.25s; +} +.menu[data-v-cf11d7a2] { + position: absolute; + top: calc(var(--vp-nav-height) / 2 + 20px); + right: 0; + opacity: 0; + visibility: hidden; + transition: opacity 0.25s, visibility 0.25s, transform 0.25s; +} + +.VPSocialLink[data-v-bd121fe5] { + display: flex; + justify-content: center; + align-items: center; + width: 36px; + height: 36px; + color: var(--vp-c-text-2); + transition: color 0.5s; +} +.VPSocialLink[data-v-bd121fe5]:hover { + color: var(--vp-c-text-1); + transition: color 0.25s; +} +.VPSocialLink[data-v-bd121fe5] > svg, +.VPSocialLink[data-v-bd121fe5] > [class^="vpi-social-"] { + width: 20px; + height: 20px; + fill: currentColor; +} + +.VPSocialLinks[data-v-7bc22406] { + display: flex; + justify-content: center; +} + +.VPNavBarExtra[data-v-bb2aa2f0] { + display: none; + margin-right: -12px; +} +@media (min-width: 768px) { +.VPNavBarExtra[data-v-bb2aa2f0] { + display: block; +} +} +@media (min-width: 1280px) { +.VPNavBarExtra[data-v-bb2aa2f0] { + display: none; +} +} +.trans-title[data-v-bb2aa2f0] { + padding: 0 24px 0 12px; + line-height: 32px; + font-size: 14px; + font-weight: 700; + color: var(--vp-c-text-1); +} +.item.appearance[data-v-bb2aa2f0], +.item.social-links[data-v-bb2aa2f0] { + display: flex; + align-items: center; + padding: 0 12px; +} +.item.appearance[data-v-bb2aa2f0] { + min-width: 176px; +} +.appearance-action[data-v-bb2aa2f0] { + margin-right: -2px; +} +.social-links-list[data-v-bb2aa2f0] { + margin: -4px -8px; +} + +.VPNavBarHamburger[data-v-e5dd9c1c] { + display: flex; + justify-content: center; + align-items: center; + width: 48px; + height: var(--vp-nav-height); +} +@media (min-width: 768px) { +.VPNavBarHamburger[data-v-e5dd9c1c] { + display: none; +} +} +.container[data-v-e5dd9c1c] { + position: relative; + width: 16px; + height: 14px; + overflow: hidden; +} +.VPNavBarHamburger:hover .top[data-v-e5dd9c1c] { top: 0; left: 0; transform: translateX(4px); +} +.VPNavBarHamburger:hover .middle[data-v-e5dd9c1c] { top: 6px; left: 0; transform: translateX(0); +} +.VPNavBarHamburger:hover .bottom[data-v-e5dd9c1c] { top: 12px; left: 0; transform: translateX(8px); +} +.VPNavBarHamburger.active .top[data-v-e5dd9c1c] { top: 6px; transform: translateX(0) rotate(225deg); +} +.VPNavBarHamburger.active .middle[data-v-e5dd9c1c] { top: 6px; transform: translateX(16px); +} +.VPNavBarHamburger.active .bottom[data-v-e5dd9c1c] { top: 6px; transform: translateX(0) rotate(135deg); +} +.VPNavBarHamburger.active:hover .top[data-v-e5dd9c1c], +.VPNavBarHamburger.active:hover .middle[data-v-e5dd9c1c], +.VPNavBarHamburger.active:hover .bottom[data-v-e5dd9c1c] { + background-color: var(--vp-c-text-2); + transition: top .25s, background-color .25s, transform .25s; +} +.top[data-v-e5dd9c1c], +.middle[data-v-e5dd9c1c], +.bottom[data-v-e5dd9c1c] { + position: absolute; + width: 16px; + height: 2px; + background-color: var(--vp-c-text-1); + transition: top .25s, background-color .5s, transform .25s; +} +.top[data-v-e5dd9c1c] { top: 0; left: 0; transform: translateX(0); +} +.middle[data-v-e5dd9c1c] { top: 6px; left: 0; transform: translateX(8px); +} +.bottom[data-v-e5dd9c1c] { top: 12px; left: 0; transform: translateX(4px); +} + +.VPNavBarMenuLink[data-v-e56f3d57] { + display: flex; + align-items: center; + padding: 0 12px; + line-height: var(--vp-nav-height); + font-size: 14px; + font-weight: 500; + color: var(--vp-c-text-1); + transition: color 0.25s; +} +.VPNavBarMenuLink.active[data-v-e56f3d57] { + color: var(--vp-c-brand-1); +} +.VPNavBarMenuLink[data-v-e56f3d57]:hover { + color: var(--vp-c-brand-1); +} + +.VPNavBarMenu[data-v-dc692963] { + display: none; +} +@media (min-width: 768px) { +.VPNavBarMenu[data-v-dc692963] { + display: flex; +} +} +/*! @docsearch/css 3.8.2 | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */ +:root{--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:rgba(101,108,133,.8);--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 1px 0 rgba(30,35,90,.4);--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 rgba(69,98,155,.12)}html[data-theme=dark]{--docsearch-text-color:#f5f6f7;--docsearch-container-background:rgba(9,10,17,.8);--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 rgba(3,4,9,.3);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 1px 1px 0 #0304094d;--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 rgba(73,76,106,.5),0 -4px 8px 0 rgba(0,0,0,.2);--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}.DocSearch-Button{align-items:center;background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:var(--docsearch-muted-color);cursor:pointer;display:flex;font-weight:500;height:36px;justify-content:space-between;margin:0 0 0 16px;padding:0 8px;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:var(--docsearch-searchbox-focus-background);box-shadow:var(--docsearch-searchbox-shadow);color:var(--docsearch-text-color);outline:none}.DocSearch-Button-Container{align-items:center;display:flex}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Button .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:var(--docsearch-key-gradient);border:0;border-radius:3px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 2px;position:relative;top:-1px;width:20px}.DocSearch-Button-Key--pressed{box-shadow:var(--docsearch-key-pressed-shadow);transform:translate3d(0,1px,0)}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder{display:none}}.DocSearch--active{overflow:hidden!important}.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}.DocSearch-Container{background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{text-decoration:none}.DocSearch-Link{appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;font:inherit;margin:0;padding:0}.DocSearch-Modal{background:var(--docsearch-modal-background);border-radius:6px;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:var(--docsearch-searchbox-height);margin:0;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{appearance:none;background:transparent;border:0;color:var(--docsearch-text-color);flex:1;font:inherit;font-size:1.2em;height:100%;outline:none;padding:0 0 0 8px;width:80%}.DocSearch-Input::placeholder{color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator{display:none}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{animation:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0;stroke-width:var(--docsearch-icon-stroke-width)}}.DocSearch-Reset{animation:fade-in .1s ease-in forwards;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;padding:2px;right:0;stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset:hover{color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Cancel{display:none}.DocSearch-Dropdown{max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 var(--docsearch-spacing);scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:transparent}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:var(--docsearch-muted-color);border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help,.DocSearch-Label{color:var(--docsearch-muted-color)}.DocSearch-Help{font-size:.9em;margin:0;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{color:var(--docsearch-muted-color);display:flex;font-size:.85em;justify-content:center;margin-bottom:var(--docsearch-spacing);padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--deleting{transition:none}}.DocSearch-Hit--deleting{opacity:0;transition:all .25s linear}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--favoriting{transition:none}}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:all .25s linear;transition-delay:.25s}.DocSearch-Hit a{background:var(--docsearch-hit-background);border-radius:4px;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:var(--docsearch-modal-background);color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{color:var(--docsearch-muted-color);height:var(--docsearch-hit-height);opacity:.5;stroke-width:var(--docsearch-icon-stroke-width);width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:var(--docsearch-highlight-color)}.DocSearch-Hit[aria-selected=true] mark{text-decoration:underline}.DocSearch-Hit-Container{align-items:center;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:var(--docsearch-hit-height);padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{color:var(--docsearch-muted-color);stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{appearance:none;background:none;border:0;border-radius:50%;color:inherit;cursor:pointer;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:rgba(0,0,0,.2);transition:background-color .1s ease-in}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{transition:none}}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] mark{color:var(--docsearch-hit-active-color)!important}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:rgba(0,0,0,.2);transition:none}}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{appearance:none;background:none;border:0;border-radius:1em;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:none;text-decoration:underline}.DocSearch-Footer{align-items:center;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 var(--docsearch-spacing);position:relative;user-select:none;width:100%;z-index:300}.DocSearch-Commands{color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li{align-items:center;display:flex}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{align-items:center;background:var(--docsearch-key-gradient);border:0;border-radius:2px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;width:20px}.DocSearch-VisuallyHiddenForAccessibility{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}@media (max-width:768px){:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%}.DocSearch-Container{height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Dropdown{max-height:calc(var(--docsearch-vh, 1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Cancel{appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:var(--docsearch-spacing);outline:none;overflow:hidden;padding:0;user-select:none;white-space:nowrap}.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}}@keyframes fade-in{0%{opacity:0}to{opacity:1}} +[class*='DocSearch'] { + --docsearch-primary-color: var(--vp-c-brand-1); + --docsearch-highlight-color: var(--docsearch-primary-color); + --docsearch-text-color: var(--vp-c-text-1); + --docsearch-muted-color: var(--vp-c-text-2); + --docsearch-searchbox-shadow: none; + --docsearch-searchbox-background: transparent; + --docsearch-searchbox-focus-background: transparent; + --docsearch-key-gradient: transparent; + --docsearch-key-shadow: none; + --docsearch-modal-background: var(--vp-c-bg-soft); + --docsearch-footer-background: var(--vp-c-bg); +} +.dark [class*='DocSearch'] { + --docsearch-modal-shadow: none; + --docsearch-footer-shadow: none; + --docsearch-logo-color: var(--vp-c-text-2); + --docsearch-hit-background: var(--vp-c-default-soft); + --docsearch-hit-color: var(--vp-c-text-2); + --docsearch-hit-shadow: none; +} +.DocSearch-Button { + display: flex; + justify-content: center; + align-items: center; + margin: 0; + padding: 0; + width: 48px; + height: 55px; + background: transparent; + transition: border-color 0.25s; +} +.DocSearch-Button:hover { + background: transparent; +} +.DocSearch-Button:focus { + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color; +} +.DocSearch-Button-Key--pressed { + transform: none; + box-shadow: none; +} +.DocSearch-Button:focus:not(:focus-visible) { + outline: none !important; +} +@media (min-width: 768px) { +.DocSearch-Button { + justify-content: flex-start; + border: 1px solid transparent; + border-radius: 8px; + padding: 0 10px 0 12px; + width: 100%; + height: 40px; + background-color: var(--vp-c-bg-alt); +} +.DocSearch-Button:hover { + border-color: var(--vp-c-brand-1); + background: var(--vp-c-bg-alt); +} +} +.DocSearch-Button .DocSearch-Button-Container { + display: flex; + align-items: center; +} +.DocSearch-Button .DocSearch-Search-Icon { + position: relative; + width: 16px; + height: 16px; + color: var(--vp-c-text-1); + fill: currentColor; + transition: color 0.5s; +} +.DocSearch-Button:hover .DocSearch-Search-Icon { + color: var(--vp-c-text-1); +} +@media (min-width: 768px) { +.DocSearch-Button .DocSearch-Search-Icon { + top: 1px; + margin-right: 8px; + width: 14px; + height: 14px; + color: var(--vp-c-text-2); +} +} +.DocSearch-Button .DocSearch-Button-Placeholder { + display: none; + margin-top: 2px; + padding: 0 16px 0 0; + font-size: 13px; + font-weight: 500; + color: var(--vp-c-text-2); + transition: color 0.5s; +} +.DocSearch-Button:hover .DocSearch-Button-Placeholder { + color: var(--vp-c-text-1); +} +@media (min-width: 768px) { +.DocSearch-Button .DocSearch-Button-Placeholder { + display: inline-block; +} +} +.DocSearch-Button .DocSearch-Button-Keys { + /*rtl:ignore*/ + direction: ltr; + display: none; + min-width: auto; +} +@media (min-width: 768px) { +.DocSearch-Button .DocSearch-Button-Keys { + display: flex; + align-items: center; +} +} +.DocSearch-Button .DocSearch-Button-Key { + display: block; + margin: 2px 0 0 0; + border: 1px solid var(--vp-c-divider); + /*rtl:begin:ignore*/ + border-right: none; + border-radius: 4px 0 0 4px; + padding-left: 6px; + /*rtl:end:ignore*/ + min-width: 0; + width: auto; + height: 22px; + line-height: 22px; + font-family: var(--vp-font-family-base); + font-size: 12px; + font-weight: 500; + transition: color 0.5s, border-color 0.5s; +} +.DocSearch-Button .DocSearch-Button-Key + .DocSearch-Button-Key { + /*rtl:begin:ignore*/ + border-right: 1px solid var(--vp-c-divider); + border-left: none; + border-radius: 0 4px 4px 0; + padding-left: 2px; + padding-right: 6px; + /*rtl:end:ignore*/ +} +.DocSearch-Button .DocSearch-Button-Key:first-child { + font-size: 0 !important; +} +.DocSearch-Button .DocSearch-Button-Key:first-child:after { + content: 'Ctrl'; + font-size: 12px; + letter-spacing: normal; + color: var(--docsearch-muted-color); +} +.mac .DocSearch-Button .DocSearch-Button-Key:first-child:after { + content: '\2318'; +} +.DocSearch-Button .DocSearch-Button-Key:first-child > * { + display: none; +} +.DocSearch-Search-Icon { + --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke-width='1.6' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' d='m14.386 14.386 4.088 4.088-4.088-4.088A7.533 7.533 0 1 1 3.733 3.733a7.533 7.533 0 0 1 10.653 10.653z'/%3E%3C/svg%3E"); +} + +.VPNavBarSearch { + display: flex; + align-items: center; +} +@media (min-width: 768px) { +.VPNavBarSearch { + flex-grow: 1; + padding-left: 24px; +} +} +@media (min-width: 960px) { +.VPNavBarSearch { + padding-left: 32px; +} +} +.dark .DocSearch-Footer { + border-top: 1px solid var(--vp-c-divider); +} +.DocSearch-Form { + border: 1px solid var(--vp-c-brand-1); + background-color: var(--vp-c-white); +} +.dark .DocSearch-Form { + background-color: var(--vp-c-default-soft); +} +.DocSearch-Screen-Icon > svg { + margin: auto; +} + +.VPNavBarSocialLinks[data-v-0394ad82] { + display: none; +} +@media (min-width: 1280px) { +.VPNavBarSocialLinks[data-v-0394ad82] { + display: flex; + align-items: center; +} +} + +.title[data-v-1168a8e4] { + display: flex; + align-items: center; + border-bottom: 1px solid transparent; + width: 100%; + height: var(--vp-nav-height); + font-size: 16px; + font-weight: 600; + color: var(--vp-c-text-1); + transition: opacity 0.25s; +} +@media (min-width: 960px) { +.title[data-v-1168a8e4] { + flex-shrink: 0; +} +.VPNavBarTitle.has-sidebar .title[data-v-1168a8e4] { + border-bottom-color: var(--vp-c-divider); +} +} +[data-v-1168a8e4] .logo { + margin-right: 8px; + height: var(--vp-nav-logo-height); +} + +.VPNavBarTranslations[data-v-88af2de4] { + display: none; +} +@media (min-width: 1280px) { +.VPNavBarTranslations[data-v-88af2de4] { + display: flex; + align-items: center; +} +} +.title[data-v-88af2de4] { + padding: 0 24px 0 12px; + line-height: 32px; + font-size: 14px; + font-weight: 700; + color: var(--vp-c-text-1); +} + +.VPNavBar[data-v-6aa21345] { + position: relative; + height: var(--vp-nav-height); + pointer-events: none; + white-space: nowrap; + transition: background-color 0.25s; +} +.VPNavBar.screen-open[data-v-6aa21345] { + transition: none; + background-color: var(--vp-nav-bg-color); + border-bottom: 1px solid var(--vp-c-divider); +} +.VPNavBar[data-v-6aa21345]:not(.home) { + background-color: var(--vp-nav-bg-color); +} +@media (min-width: 960px) { +.VPNavBar[data-v-6aa21345]:not(.home) { + background-color: transparent; +} +.VPNavBar[data-v-6aa21345]:not(.has-sidebar):not(.home.top) { + background-color: var(--vp-nav-bg-color); +} +} +.wrapper[data-v-6aa21345] { + padding: 0 8px 0 24px; +} +@media (min-width: 768px) { +.wrapper[data-v-6aa21345] { + padding: 0 32px; +} +} +@media (min-width: 960px) { +.VPNavBar.has-sidebar .wrapper[data-v-6aa21345] { + padding: 0; +} +} +.container[data-v-6aa21345] { + display: flex; + justify-content: space-between; + margin: 0 auto; + max-width: calc(var(--vp-layout-max-width) - 64px); + height: var(--vp-nav-height); + pointer-events: none; +} +.container > .title[data-v-6aa21345], +.container > .content[data-v-6aa21345] { + pointer-events: none; +} +.container[data-v-6aa21345] * { + pointer-events: auto; +} +@media (min-width: 960px) { +.VPNavBar.has-sidebar .container[data-v-6aa21345] { + max-width: 100%; +} +} +.title[data-v-6aa21345] { + flex-shrink: 0; + height: calc(var(--vp-nav-height) - 1px); + transition: background-color 0.5s; +} +@media (min-width: 960px) { +.VPNavBar.has-sidebar .title[data-v-6aa21345] { + position: absolute; + top: 0; + left: 0; + z-index: 2; + padding: 0 32px; + width: var(--vp-sidebar-width); + height: var(--vp-nav-height); + background-color: transparent; +} +} +@media (min-width: 1440px) { +.VPNavBar.has-sidebar .title[data-v-6aa21345] { + padding-left: max(32px, calc((100% - (var(--vp-layout-max-width) - 64px)) / 2)); + width: calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px); +} +} +.content[data-v-6aa21345] { + flex-grow: 1; +} +@media (min-width: 960px) { +.VPNavBar.has-sidebar .content[data-v-6aa21345] { + position: relative; + z-index: 1; + padding-right: 32px; + padding-left: var(--vp-sidebar-width); +} +} +@media (min-width: 1440px) { +.VPNavBar.has-sidebar .content[data-v-6aa21345] { + padding-right: calc((100vw - var(--vp-layout-max-width)) / 2 + 32px); + padding-left: calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width)); +} +} +.content-body[data-v-6aa21345] { + display: flex; + justify-content: flex-end; + align-items: center; + height: var(--vp-nav-height); + transition: background-color 0.5s; +} +@media (min-width: 960px) { +.VPNavBar:not(.home.top) .content-body[data-v-6aa21345] { + position: relative; + background-color: var(--vp-nav-bg-color); +} +.VPNavBar:not(.has-sidebar):not(.home.top) .content-body[data-v-6aa21345] { + background-color: transparent; +} +} +@media (max-width: 767px) { +.content-body[data-v-6aa21345] { + column-gap: 0.5rem; +} +} +.menu + .translations[data-v-6aa21345]::before, +.menu + .appearance[data-v-6aa21345]::before, +.menu + .social-links[data-v-6aa21345]::before, +.translations + .appearance[data-v-6aa21345]::before, +.appearance + .social-links[data-v-6aa21345]::before { + margin-right: 8px; + margin-left: 8px; + width: 1px; + height: 24px; + background-color: var(--vp-c-divider); + content: ""; +} +.menu + .appearance[data-v-6aa21345]::before, +.translations + .appearance[data-v-6aa21345]::before { + margin-right: 16px; +} +.appearance + .social-links[data-v-6aa21345]::before { + margin-left: 16px; +} +.social-links[data-v-6aa21345] { + margin-right: -8px; +} +.divider[data-v-6aa21345] { + width: 100%; + height: 1px; +} +@media (min-width: 960px) { +.VPNavBar.has-sidebar .divider[data-v-6aa21345] { + padding-left: var(--vp-sidebar-width); +} +} +@media (min-width: 1440px) { +.VPNavBar.has-sidebar .divider[data-v-6aa21345] { + padding-left: calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width)); +} +} +.divider-line[data-v-6aa21345] { + width: 100%; + height: 1px; + transition: background-color 0.5s; +} +.VPNavBar:not(.home) .divider-line[data-v-6aa21345] { + background-color: var(--vp-c-gutter); +} +@media (min-width: 960px) { +.VPNavBar:not(.home.top) .divider-line[data-v-6aa21345] { + background-color: var(--vp-c-gutter); +} +.VPNavBar:not(.has-sidebar):not(.home.top) .divider[data-v-6aa21345] { + background-color: var(--vp-c-gutter); +} +} + +.VPNavScreenAppearance[data-v-b44890b2] { + display: flex; + justify-content: space-between; + align-items: center; + border-radius: 8px; + padding: 12px 14px 12px 16px; + background-color: var(--vp-c-bg-soft); +} +.text[data-v-b44890b2] { + line-height: 24px; + font-size: 12px; + font-weight: 500; + color: var(--vp-c-text-2); +} + +.VPNavScreenMenuLink[data-v-df37e6dd] { + display: block; + border-bottom: 1px solid var(--vp-c-divider); + padding: 12px 0 11px; + line-height: 24px; + font-size: 14px; + font-weight: 500; + color: var(--vp-c-text-1); + transition: + border-color 0.25s, + color 0.25s; +} +.VPNavScreenMenuLink[data-v-df37e6dd]:hover { + color: var(--vp-c-brand-1); +} + +.VPNavScreenMenuGroupLink[data-v-3e9c20e4] { + display: block; + margin-left: 12px; + line-height: 32px; + font-size: 14px; + font-weight: 400; + color: var(--vp-c-text-1); + transition: color 0.25s; +} +.VPNavScreenMenuGroupLink[data-v-3e9c20e4]:hover { + color: var(--vp-c-brand-1); +} + +.VPNavScreenMenuGroupSection[data-v-8133b170] { + display: block; +} +.title[data-v-8133b170] { + line-height: 32px; + font-size: 13px; + font-weight: 700; + color: var(--vp-c-text-2); + transition: color 0.25s; +} + +.VPNavScreenMenuGroup[data-v-b9ab8c58] { + border-bottom: 1px solid var(--vp-c-divider); + height: 48px; + overflow: hidden; + transition: border-color 0.5s; +} +.VPNavScreenMenuGroup .items[data-v-b9ab8c58] { + visibility: hidden; +} +.VPNavScreenMenuGroup.open .items[data-v-b9ab8c58] { + visibility: visible; +} +.VPNavScreenMenuGroup.open[data-v-b9ab8c58] { + padding-bottom: 10px; + height: auto; +} +.VPNavScreenMenuGroup.open .button[data-v-b9ab8c58] { + padding-bottom: 6px; + color: var(--vp-c-brand-1); +} +.VPNavScreenMenuGroup.open .button-icon[data-v-b9ab8c58] { + /*rtl:ignore*/ + transform: rotate(45deg); +} +.button[data-v-b9ab8c58] { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 4px 11px 0; + width: 100%; + line-height: 24px; + font-size: 14px; + font-weight: 500; + color: var(--vp-c-text-1); + transition: color 0.25s; +} +.button[data-v-b9ab8c58]:hover { + color: var(--vp-c-brand-1); +} +.button-icon[data-v-b9ab8c58] { + transition: transform 0.25s; +} +.group[data-v-b9ab8c58]:first-child { + padding-top: 0px; +} +.group + .group[data-v-b9ab8c58], +.group + .item[data-v-b9ab8c58] { + padding-top: 4px; +} + +.VPNavScreenTranslations[data-v-858fe1a4] { + height: 24px; + overflow: hidden; +} +.VPNavScreenTranslations.open[data-v-858fe1a4] { + height: auto; +} +.title[data-v-858fe1a4] { + display: flex; + align-items: center; + font-size: 14px; + font-weight: 500; + color: var(--vp-c-text-1); +} +.icon[data-v-858fe1a4] { + font-size: 16px; +} +.icon.lang[data-v-858fe1a4] { + margin-right: 8px; +} +.icon.chevron[data-v-858fe1a4] { + margin-left: 4px; +} +.list[data-v-858fe1a4] { + padding: 4px 0 0 24px; +} +.link[data-v-858fe1a4] { + line-height: 32px; + font-size: 13px; + color: var(--vp-c-text-1); +} + +.VPNavScreen[data-v-f2779853] { + position: fixed; + top: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px)); + /*rtl:ignore*/ + right: 0; + bottom: 0; + /*rtl:ignore*/ + left: 0; + padding: 0 32px; + width: 100%; + background-color: var(--vp-nav-screen-bg-color); + overflow-y: auto; + transition: background-color 0.25s; + pointer-events: auto; +} +.VPNavScreen.fade-enter-active[data-v-f2779853], +.VPNavScreen.fade-leave-active[data-v-f2779853] { + transition: opacity 0.25s; +} +.VPNavScreen.fade-enter-active .container[data-v-f2779853], +.VPNavScreen.fade-leave-active .container[data-v-f2779853] { + transition: transform 0.25s ease; +} +.VPNavScreen.fade-enter-from[data-v-f2779853], +.VPNavScreen.fade-leave-to[data-v-f2779853] { + opacity: 0; +} +.VPNavScreen.fade-enter-from .container[data-v-f2779853], +.VPNavScreen.fade-leave-to .container[data-v-f2779853] { + transform: translateY(-8px); +} +@media (min-width: 768px) { +.VPNavScreen[data-v-f2779853] { + display: none; +} +} +.container[data-v-f2779853] { + margin: 0 auto; + padding: 24px 0 96px; + max-width: 288px; +} +.menu + .translations[data-v-f2779853], +.menu + .appearance[data-v-f2779853], +.translations + .appearance[data-v-f2779853] { + margin-top: 24px; +} +.menu + .social-links[data-v-f2779853] { + margin-top: 16px; +} +.appearance + .social-links[data-v-f2779853] { + margin-top: 16px; +} + +.VPNav[data-v-ae24b3ad] { + position: relative; + top: var(--vp-layout-top-height, 0px); + /*rtl:ignore*/ + left: 0; + z-index: var(--vp-z-index-nav); + width: 100%; + pointer-events: none; + transition: background-color 0.5s; +} +@media (min-width: 960px) { +.VPNav[data-v-ae24b3ad] { + position: fixed; +} +} + +.VPSidebarItem.level-0[data-v-b3fd67f8] { + padding-bottom: 24px; +} +.VPSidebarItem.collapsed.level-0[data-v-b3fd67f8] { + padding-bottom: 10px; +} +.item[data-v-b3fd67f8] { + position: relative; + display: flex; + width: 100%; +} +.VPSidebarItem.collapsible > .item[data-v-b3fd67f8] { + cursor: pointer; +} +.indicator[data-v-b3fd67f8] { + position: absolute; + top: 6px; + bottom: 6px; + left: -17px; + width: 2px; + border-radius: 2px; + transition: background-color 0.25s; +} +.VPSidebarItem.level-2.is-active > .item > .indicator[data-v-b3fd67f8], +.VPSidebarItem.level-3.is-active > .item > .indicator[data-v-b3fd67f8], +.VPSidebarItem.level-4.is-active > .item > .indicator[data-v-b3fd67f8], +.VPSidebarItem.level-5.is-active > .item > .indicator[data-v-b3fd67f8] { + background-color: var(--vp-c-brand-1); +} +.link[data-v-b3fd67f8] { + display: flex; + align-items: center; + flex-grow: 1; +} +.text[data-v-b3fd67f8] { + flex-grow: 1; + padding: 4px 0; + line-height: 24px; + font-size: 14px; + transition: color 0.25s; +} +.VPSidebarItem.level-0 .text[data-v-b3fd67f8] { + font-weight: 700; + color: var(--vp-c-text-1); +} +.VPSidebarItem.level-1 .text[data-v-b3fd67f8], +.VPSidebarItem.level-2 .text[data-v-b3fd67f8], +.VPSidebarItem.level-3 .text[data-v-b3fd67f8], +.VPSidebarItem.level-4 .text[data-v-b3fd67f8], +.VPSidebarItem.level-5 .text[data-v-b3fd67f8] { + font-weight: 500; + color: var(--vp-c-text-2); +} +.VPSidebarItem.level-0.is-link > .item > .link:hover .text[data-v-b3fd67f8], +.VPSidebarItem.level-1.is-link > .item > .link:hover .text[data-v-b3fd67f8], +.VPSidebarItem.level-2.is-link > .item > .link:hover .text[data-v-b3fd67f8], +.VPSidebarItem.level-3.is-link > .item > .link:hover .text[data-v-b3fd67f8], +.VPSidebarItem.level-4.is-link > .item > .link:hover .text[data-v-b3fd67f8], +.VPSidebarItem.level-5.is-link > .item > .link:hover .text[data-v-b3fd67f8] { + color: var(--vp-c-brand-1); +} +.VPSidebarItem.level-0.has-active > .item > .text[data-v-b3fd67f8], +.VPSidebarItem.level-1.has-active > .item > .text[data-v-b3fd67f8], +.VPSidebarItem.level-2.has-active > .item > .text[data-v-b3fd67f8], +.VPSidebarItem.level-3.has-active > .item > .text[data-v-b3fd67f8], +.VPSidebarItem.level-4.has-active > .item > .text[data-v-b3fd67f8], +.VPSidebarItem.level-5.has-active > .item > .text[data-v-b3fd67f8], +.VPSidebarItem.level-0.has-active > .item > .link > .text[data-v-b3fd67f8], +.VPSidebarItem.level-1.has-active > .item > .link > .text[data-v-b3fd67f8], +.VPSidebarItem.level-2.has-active > .item > .link > .text[data-v-b3fd67f8], +.VPSidebarItem.level-3.has-active > .item > .link > .text[data-v-b3fd67f8], +.VPSidebarItem.level-4.has-active > .item > .link > .text[data-v-b3fd67f8], +.VPSidebarItem.level-5.has-active > .item > .link > .text[data-v-b3fd67f8] { + color: var(--vp-c-text-1); +} +.VPSidebarItem.level-0.is-active > .item .link > .text[data-v-b3fd67f8], +.VPSidebarItem.level-1.is-active > .item .link > .text[data-v-b3fd67f8], +.VPSidebarItem.level-2.is-active > .item .link > .text[data-v-b3fd67f8], +.VPSidebarItem.level-3.is-active > .item .link > .text[data-v-b3fd67f8], +.VPSidebarItem.level-4.is-active > .item .link > .text[data-v-b3fd67f8], +.VPSidebarItem.level-5.is-active > .item .link > .text[data-v-b3fd67f8] { + color: var(--vp-c-brand-1); +} +.caret[data-v-b3fd67f8] { + display: flex; + justify-content: center; + align-items: center; + margin-right: -7px; + width: 32px; + height: 32px; + color: var(--vp-c-text-3); + cursor: pointer; + transition: color 0.25s; + flex-shrink: 0; +} +.item:hover .caret[data-v-b3fd67f8] { + color: var(--vp-c-text-2); +} +.item:hover .caret[data-v-b3fd67f8]:hover { + color: var(--vp-c-text-1); +} +.caret-icon[data-v-b3fd67f8] { + font-size: 18px; + /*rtl:ignore*/ + transform: rotate(90deg); + transition: transform 0.25s; +} +.VPSidebarItem.collapsed .caret-icon[data-v-b3fd67f8] { + transform: rotate(0)/*rtl:rotate(180deg)*/; +} +.VPSidebarItem.level-1 .items[data-v-b3fd67f8], +.VPSidebarItem.level-2 .items[data-v-b3fd67f8], +.VPSidebarItem.level-3 .items[data-v-b3fd67f8], +.VPSidebarItem.level-4 .items[data-v-b3fd67f8], +.VPSidebarItem.level-5 .items[data-v-b3fd67f8] { + border-left: 1px solid var(--vp-c-divider); + padding-left: 16px; +} +.VPSidebarItem.collapsed .items[data-v-b3fd67f8] { + display: none; +} + +.no-transition[data-v-c40bc020] .caret-icon { + transition: none; +} +.group + .group[data-v-c40bc020] { + border-top: 1px solid var(--vp-c-divider); + padding-top: 10px; +} +@media (min-width: 960px) { +.group[data-v-c40bc020] { + padding-top: 10px; + width: calc(var(--vp-sidebar-width) - 64px); +} +} + +.VPSidebar[data-v-319d5ca6] { + position: fixed; + top: var(--vp-layout-top-height, 0px); + bottom: 0; + left: 0; + z-index: var(--vp-z-index-sidebar); + padding: 32px 32px 96px; + width: calc(100vw - 64px); + max-width: 320px; + background-color: var(--vp-sidebar-bg-color); + opacity: 0; + box-shadow: var(--vp-c-shadow-3); + overflow-x: hidden; + overflow-y: auto; + transform: translateX(-100%); + transition: opacity 0.5s, transform 0.25s ease; + overscroll-behavior: contain; +} +.VPSidebar.open[data-v-319d5ca6] { + opacity: 1; + visibility: visible; + transform: translateX(0); + transition: opacity 0.25s, + transform 0.5s cubic-bezier(0.19, 1, 0.22, 1); +} +.dark .VPSidebar[data-v-319d5ca6] { + box-shadow: var(--vp-shadow-1); +} +@media (min-width: 960px) { +.VPSidebar[data-v-319d5ca6] { + padding-top: var(--vp-nav-height); + width: var(--vp-sidebar-width); + max-width: 100%; + background-color: var(--vp-sidebar-bg-color); + opacity: 1; + visibility: visible; + box-shadow: none; + transform: translateX(0); +} +} +@media (min-width: 1440px) { +.VPSidebar[data-v-319d5ca6] { + padding-left: max(32px, calc((100% - (var(--vp-layout-max-width) - 64px)) / 2)); + width: calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px); +} +} +@media (min-width: 960px) { +.curtain[data-v-319d5ca6] { + position: sticky; + top: -64px; + left: 0; + z-index: 1; + margin-top: calc(var(--vp-nav-height) * -1); + margin-right: -32px; + margin-left: -32px; + height: var(--vp-nav-height); + background-color: var(--vp-sidebar-bg-color); +} +} +.nav[data-v-319d5ca6] { + outline: 0; +} + +.VPSkipLink[data-v-0b0ada53] { + top: 8px; + left: 8px; + padding: 8px 16px; + z-index: 999; + border-radius: 8px; + font-size: 12px; + font-weight: bold; + text-decoration: none; + color: var(--vp-c-brand-1); + box-shadow: var(--vp-shadow-3); + background-color: var(--vp-c-bg); +} +.VPSkipLink[data-v-0b0ada53]:focus { + height: auto; + width: auto; + clip: auto; + clip-path: none; +} +@media (min-width: 1280px) { +.VPSkipLink[data-v-0b0ada53] { + top: 14px; + left: 16px; +} +} + +.Layout[data-v-5d98c3a5] { + display: flex; + flex-direction: column; + min-height: 100vh; +} + +.VPHomeSponsors[data-v-3d121b4a] { + border-top: 1px solid var(--vp-c-gutter); + padding-top: 88px !important; +} +.VPHomeSponsors[data-v-3d121b4a] { + margin: 96px 0; +} +@media (min-width: 768px) { +.VPHomeSponsors[data-v-3d121b4a] { + margin: 128px 0; +} +} +.VPHomeSponsors[data-v-3d121b4a] { + padding: 0 24px; +} +@media (min-width: 768px) { +.VPHomeSponsors[data-v-3d121b4a] { + padding: 0 48px; +} +} +@media (min-width: 960px) { +.VPHomeSponsors[data-v-3d121b4a] { + padding: 0 64px; +} +} +.container[data-v-3d121b4a] { + margin: 0 auto; + max-width: 1152px; +} +.love[data-v-3d121b4a] { + margin: 0 auto; + width: fit-content; + font-size: 28px; + color: var(--vp-c-text-3); +} +.icon[data-v-3d121b4a] { + display: inline-block; +} +.message[data-v-3d121b4a] { + margin: 0 auto; + padding-top: 10px; + max-width: 320px; + text-align: center; + line-height: 24px; + font-size: 16px; + font-weight: 500; + color: var(--vp-c-text-2); +} +.sponsors[data-v-3d121b4a] { + padding-top: 32px; +} +.action[data-v-3d121b4a] { + padding-top: 40px; + text-align: center; +} + +.VPTeamMembersItem[data-v-f3fa364a] { + display: flex; + flex-direction: column; + gap: 2px; + border-radius: 12px; + width: 100%; + height: 100%; + overflow: hidden; +} +.VPTeamMembersItem.small .profile[data-v-f3fa364a] { + padding: 32px; +} +.VPTeamMembersItem.small .data[data-v-f3fa364a] { + padding-top: 20px; +} +.VPTeamMembersItem.small .avatar[data-v-f3fa364a] { + width: 64px; + height: 64px; +} +.VPTeamMembersItem.small .name[data-v-f3fa364a] { + line-height: 24px; + font-size: 16px; +} +.VPTeamMembersItem.small .affiliation[data-v-f3fa364a] { + padding-top: 4px; + line-height: 20px; + font-size: 14px; +} +.VPTeamMembersItem.small .desc[data-v-f3fa364a] { + padding-top: 12px; + line-height: 20px; + font-size: 14px; +} +.VPTeamMembersItem.small .links[data-v-f3fa364a] { + margin: 0 -16px -20px; + padding: 10px 0 0; +} +.VPTeamMembersItem.medium .profile[data-v-f3fa364a] { + padding: 48px 32px; +} +.VPTeamMembersItem.medium .data[data-v-f3fa364a] { + padding-top: 24px; + text-align: center; +} +.VPTeamMembersItem.medium .avatar[data-v-f3fa364a] { + width: 96px; + height: 96px; +} +.VPTeamMembersItem.medium .name[data-v-f3fa364a] { + letter-spacing: 0.15px; + line-height: 28px; + font-size: 20px; +} +.VPTeamMembersItem.medium .affiliation[data-v-f3fa364a] { + padding-top: 4px; + font-size: 16px; +} +.VPTeamMembersItem.medium .desc[data-v-f3fa364a] { + padding-top: 16px; + max-width: 288px; + font-size: 16px; +} +.VPTeamMembersItem.medium .links[data-v-f3fa364a] { + margin: 0 -16px -12px; + padding: 16px 12px 0; +} +.profile[data-v-f3fa364a] { + flex-grow: 1; + background-color: var(--vp-c-bg-soft); +} +.data[data-v-f3fa364a] { + text-align: center; +} +.avatar[data-v-f3fa364a] { + position: relative; + flex-shrink: 0; + margin: 0 auto; + border-radius: 50%; + box-shadow: var(--vp-shadow-3); +} +.avatar-img[data-v-f3fa364a] { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: 50%; + object-fit: cover; +} +.name[data-v-f3fa364a] { + margin: 0; + font-weight: 600; +} +.affiliation[data-v-f3fa364a] { + margin: 0; + font-weight: 500; + color: var(--vp-c-text-2); +} +.org.link[data-v-f3fa364a] { + color: var(--vp-c-text-2); + transition: color 0.25s; +} +.org.link[data-v-f3fa364a]:hover { + color: var(--vp-c-brand-1); +} +.desc[data-v-f3fa364a] { + margin: 0 auto; +} +.desc[data-v-f3fa364a] a { + font-weight: 500; + color: var(--vp-c-brand-1); + text-decoration-style: dotted; + transition: color 0.25s; +} +.links[data-v-f3fa364a] { + display: flex; + justify-content: center; + height: 56px; +} +.sp-link[data-v-f3fa364a] { + display: flex; + justify-content: center; + align-items: center; + text-align: center; + padding: 16px; + font-size: 14px; + font-weight: 500; + color: var(--vp-c-sponsor); + background-color: var(--vp-c-bg-soft); + transition: color 0.25s, background-color 0.25s; +} +.sp .sp-link.link[data-v-f3fa364a]:hover, +.sp .sp-link.link[data-v-f3fa364a]:focus { + outline: none; + color: var(--vp-c-white); + background-color: var(--vp-c-sponsor); +} +.sp-icon[data-v-f3fa364a] { + margin-right: 8px; + font-size: 16px; +} + +.VPTeamMembers.small .container[data-v-6cb0dbc4] { + grid-template-columns: repeat(auto-fit, minmax(224px, 1fr)); +} +.VPTeamMembers.small.count-1 .container[data-v-6cb0dbc4] { + max-width: 276px; +} +.VPTeamMembers.small.count-2 .container[data-v-6cb0dbc4] { + max-width: calc(276px * 2 + 24px); +} +.VPTeamMembers.small.count-3 .container[data-v-6cb0dbc4] { + max-width: calc(276px * 3 + 24px * 2); +} +.VPTeamMembers.medium .container[data-v-6cb0dbc4] { + grid-template-columns: repeat(auto-fit, minmax(256px, 1fr)); +} +@media (min-width: 375px) { +.VPTeamMembers.medium .container[data-v-6cb0dbc4] { + grid-template-columns: repeat(auto-fit, minmax(288px, 1fr)); +} +} +.VPTeamMembers.medium.count-1 .container[data-v-6cb0dbc4] { + max-width: 368px; +} +.VPTeamMembers.medium.count-2 .container[data-v-6cb0dbc4] { + max-width: calc(368px * 2 + 24px); +} +.container[data-v-6cb0dbc4] { + display: grid; + gap: 24px; + margin: 0 auto; + max-width: 1152px; +} + +.VPTeamPage[data-v-7c57f839] { + margin: 96px 0; +} +@media (min-width: 768px) { +.VPTeamPage[data-v-7c57f839] { + margin: 128px 0; +} +} +.VPHome .VPTeamPageTitle[data-v-7c57f839-s] { + border-top: 1px solid var(--vp-c-gutter); + padding-top: 88px !important; +} +.VPTeamPageSection + .VPTeamPageSection[data-v-7c57f839-s],.VPTeamMembers + .VPTeamPageSection[data-v-7c57f839-s] { + margin-top: 64px; +} +.VPTeamMembers + .VPTeamMembers[data-v-7c57f839-s] { + margin-top: 24px; +} +@media (min-width: 768px) { +.VPTeamPageTitle + .VPTeamPageSection[data-v-7c57f839-s] { + margin-top: 16px; +} +.VPTeamPageSection + .VPTeamPageSection[data-v-7c57f839-s],.VPTeamMembers + .VPTeamPageSection[data-v-7c57f839-s] { + margin-top: 96px; +} +} +.VPTeamMembers[data-v-7c57f839-s] { + padding: 0 24px; +} +@media (min-width: 768px) { +.VPTeamMembers[data-v-7c57f839-s] { + padding: 0 48px; +} +} +@media (min-width: 960px) { +.VPTeamMembers[data-v-7c57f839-s] { + padding: 0 64px; +} +} + +.VPTeamPageSection[data-v-b1a88750] { + padding: 0 32px; +} +@media (min-width: 768px) { +.VPTeamPageSection[data-v-b1a88750] { + padding: 0 48px; +} +} +@media (min-width: 960px) { +.VPTeamPageSection[data-v-b1a88750] { + padding: 0 64px; +} +} +.title[data-v-b1a88750] { + position: relative; + margin: 0 auto; + max-width: 1152px; + text-align: center; + color: var(--vp-c-text-2); +} +.title-line[data-v-b1a88750] { + position: absolute; + top: 16px; + left: 0; + width: 100%; + height: 1px; + background-color: var(--vp-c-divider); +} +.title-text[data-v-b1a88750] { + position: relative; + display: inline-block; + padding: 0 24px; + letter-spacing: 0; + line-height: 32px; + font-size: 20px; + font-weight: 500; + background-color: var(--vp-c-bg); +} +.lead[data-v-b1a88750] { + margin: 0 auto; + max-width: 480px; + padding-top: 12px; + text-align: center; + line-height: 24px; + font-size: 16px; + font-weight: 500; + color: var(--vp-c-text-2); +} +.members[data-v-b1a88750] { + padding-top: 40px; +} + +.VPTeamPageTitle[data-v-bf2cbdac] { + padding: 48px 32px; + text-align: center; +} +@media (min-width: 768px) { +.VPTeamPageTitle[data-v-bf2cbdac] { + padding: 64px 48px 48px; +} +} +@media (min-width: 960px) { +.VPTeamPageTitle[data-v-bf2cbdac] { + padding: 80px 64px 48px; +} +} +.title[data-v-bf2cbdac] { + letter-spacing: 0; + line-height: 44px; + font-size: 36px; + font-weight: 500; +} +@media (min-width: 768px) { +.title[data-v-bf2cbdac] { + letter-spacing: -0.5px; + line-height: 56px; + font-size: 48px; +} +} +.lead[data-v-bf2cbdac] { + margin: 0 auto; + max-width: 512px; + padding-top: 12px; + line-height: 24px; + font-size: 16px; + font-weight: 500; + color: var(--vp-c-text-2); +} +@media (min-width: 768px) { +.lead[data-v-bf2cbdac] { + max-width: 592px; + letter-spacing: 0.15px; + line-height: 28px; + font-size: 20px; +} +} +/* + * tokens.css — AUTO-GENERATED by scripts/sync-design-tokens.cjs + * Source: src/styles.css + * Generated: 2026-08-09T06:16:36.831Z + * + * DO NOT EDIT MANUALLY. Run: node scripts/sync-design-tokens.cjs + */ +:root { + --app-viewport-height: 100vh; + --focus-ring-color: #7fa2a6; + --focus-ring-offset: 1px; + --motion-fast: 120ms ease; + --motion-standard: 180ms ease; + --motion-slow: 240ms ease; + --app-bg: #f2f4f3; + --app-text: #172326; + --surface-bg: #ffffff; + --surface-border: #d9dedb; + --surface-elevated: #f8fbfa; + --surface-muted: #f3f8f6; + --surface-subtle: #f7fbf9; + --surface-accent: #edf5f2; + --surface-accent-strong: #eff6f3; + --surface-overlay: rgba(9, 18, 21, 0.45); + --text-strong: #17343a; + --text-muted: #56666b; + --text-subtle: #60757b; + --text-soft: #5e747c; + --text-secondary: #53686f; + --text-tertiary: #80776d; + --text-on-accent: #f4fbf8; + --border-default: #d9dedb; + --border-soft: #cfd8d4; + --border-subtle: #d9e3df; + --border-ui: #d2ddd9; + --border-muted: #dce7e3; + --accent-strong: #17343a; + --accent-solid: #2f5d62; + --accent-soft: #4f7f8a; + --shadow-overlay: 0 18px 40px rgba(15, 35, 40, 0.18); + --shadow-float: 0 16px 30px rgba(20, 42, 44, 0.13); + --shadow-sm: 0 2px 8px rgba(19, 39, 43, 0.12); + --shadow-md: 0 10px 22px rgba(16, 34, 36, 0.07); + --shadow-lg: 0 14px 32px rgba(17, 36, 40, 0.18); + --shadow-xl: 0 24px 60px rgba(10, 22, 24, 0.24); + --radius-xs: 3px; + --radius-sm: 4px; + --radius-md: 6px; + --radius-lg: 8px; + --radius-xl: 12px; + --radius-2xl: 16px; + --radius-pill: 999px; + --btn-height-sm: 28px; + --btn-height-md: 32px; + --tooltip-bg: rgba(20, 30, 33, 0.92); + --tooltip-text: #f0f8f5; + --tooltip-radius: var(--radius-md); + --font-size-display: 26px; + --font-size-heading-lg: 22px; + --font-size-heading-md: 18px; + --font-size-title: 15px; + --font-size-body: 14px; + --font-size-body-sm: 13px; + --font-size-label: 12px; + --font-size-caption: 11px; + --font-size-meta: 10px; + --space-1: 2px; + --space-2: 4px; + --space-3: 6px; + --space-4: 8px; + --space-5: 12px; + --space-6: 16px; + --space-7: 20px; + --space-8: 24px; + --space-9: 32px; + --space-10: 40px; + --space-11: 48px; + --status-success-bg: #ebfaf4; + --status-success-border: #b7decf; + --status-success-text: #1b6654; + --status-info-bg: #f1f7ff; + --status-info-border: #bdd2e8; + --status-info-text: #23476e; + --status-warning-bg: #fff7e8; + --status-warning-border: #e8d3a2; + --status-warning-text: #73561d; + --status-danger-bg: #fff3f3; + --status-danger-border: #e8c2c2; + --status-danger-text: #8e1b1b; + --accent-red: #c0392b; + --accent-red-bg: #fff3f1; + --accent-red-border: #e8b4b4; + --color-amber-bg: #fff8e6; + --color-amber-border: #e0c76a; + --color-amber-text: #7a5d10; + + --kg-note-bg: #eef2ff; + --kg-note-border: #4f46e5; + --kg-person-bg: #fdf2f8; + --kg-person-border: #db2777; + --kg-project-bg: #ecfdf5; + --kg-project-border: #059669; + --kg-tech-bg: #fffbeb; + --kg-tech-border: #d97706; + --kg-company-bg: #eff6ff; + --kg-company-border: #2563eb; + --kg-concept-bg: #f5f3ff; + --kg-concept-border: #7c3aed; + --kg-task-bg: #fef2f2; + --kg-task-border: #dc2626; + --kg-image-bg: #f0fdf4; + --kg-image-border: #16a34a; + --kg-doc-bg: #fefce8; + --kg-doc-border: #ca8a04; + --kg-url-bg: #faf5ff; + --kg-url-border: #9333ea; + --border-divider: var(--border-muted); + --text-link: var(--accent-solid); + --search-match-bg: color-mix(in srgb, var(--accent-solid) 18%, var(--surface-bg)); + --search-match-text: var(--text-strong); + --kg-default-bg: #f3f4f6; + --kg-default-border: #6b7280; + +} + +:root { + --app-viewport-height: 100dvh; + } + +:root[data-theme="dark"] { + --focus-ring-color: #7fb6bf; + --app-bg: #141b1d; + --app-text: #d9e6e2; + --surface-bg: #1d272a; + --surface-border: #2f3f44; + --surface-elevated: #232f33; + --surface-muted: #223035; + --surface-subtle: #1a2326; + --surface-accent: #24363b; + --surface-accent-strong: #294148; + --surface-overlay: rgba(4, 8, 10, 0.6); + --text-strong: #e3efeb; + --text-muted: #b7c8c4; + --text-subtle: #9eb3ae; + --text-soft: #93a6a2; + --text-secondary: #a4b8b3; + --text-tertiary: #91a49f; + --text-on-accent: #eff8f5; + --border-default: #2f3f44; + --border-soft: #365059; + --border-subtle: #314248; + --border-ui: #314248; + --border-muted: #3b4c51; + --accent-strong: #7fb6bf; + --accent-solid: #5d99a3; + --accent-soft: #8ec1c8; + --shadow-overlay: 0 18px 40px rgba(0, 0, 0, 0.38); + --shadow-float: 0 16px 30px rgba(0, 0, 0, 0.26); + --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.24); + --shadow-md: 0 10px 22px rgba(0, 0, 0, 0.18); + --shadow-lg: 0 14px 32px rgba(0, 0, 0, 0.28); + --shadow-xl: 0 24px 60px rgba(0, 0, 0, 0.42); + --status-success-bg: #173329; + --status-success-border: #2d6f59; + --status-success-text: #9ed8bf; + --status-info-bg: #1c2c3c; + --status-info-border: #31577e; + --status-info-text: #a8c8ea; + --status-warning-bg: #352a18; + --status-warning-border: #8f6a24; + --status-warning-text: #e8cb8b; + --status-danger-bg: #3a1f20; + --status-danger-border: #8c3a40; + --status-danger-text: #ebb0b5; + --accent-red: #e05c4e; + --accent-red-bg: #3a1f1e; + --accent-red-border: #8c4040; + --color-amber-bg: #352a14; + --color-amber-border: #8f6e24; + --color-amber-text: #e8cb8b; + --tooltip-bg: rgba(18, 28, 31, 0.95); + --tooltip-text: #ecf6f2; + + --kg-note-bg: #1e1b4b; + --kg-note-border: #818cf8; + --kg-person-bg: #4c0519; + --kg-person-border: #f472b6; + --kg-project-bg: #064e3b; + --kg-project-border: #34d399; + --kg-tech-bg: #451a03; + --kg-tech-border: #fbbf24; + --kg-company-bg: #1e3a8a; + --kg-company-border: #60a5fa; + --kg-concept-bg: #2e1065; + --kg-concept-border: #a78bfa; + --kg-task-bg: #7f1d1d; + --kg-task-border: #f87171; + --kg-image-bg: #052e16; + --kg-image-border: #4ade80; + --kg-doc-bg: #451a03; + --kg-doc-border: #facc15; + --kg-url-bg: #3b0764; + --kg-url-border: #c084fc; + --kg-default-bg: #1f2937; + --kg-default-border: #9ca3af; + +} + +@supports (height: 100dvh) { + :root { + --app-viewport-height: 100dvh; + } +} +/** + * theme.css + * + * Maps VitePress built-in CSS variables to Notely design tokens. + * Zero hardcoded color values — everything references tokens.css variables. + * + * tokens.css is auto-generated from src/styles.css. + * Run: node scripts/sync-design-tokens.cjs + */ + +/* ─── Brand colors ──────────────────────────────────────────────── */ +:root { + --vp-c-brand-1: var(--accent-solid); + --vp-c-brand-2: var(--accent-soft); + --vp-c-brand-3: var(--accent-strong); + --vp-c-brand-soft: var(--surface-accent); + + --vp-c-text-1: var(--text-strong); + --vp-c-text-2: var(--text-muted); + --vp-c-text-3: var(--text-subtle); + + --vp-c-bg: var(--app-bg); + --vp-c-bg-soft: var(--surface-muted); + --vp-c-bg-mute: var(--surface-accent); + --vp-c-bg-alt: var(--surface-elevated); + + --vp-c-border: var(--border-default); + --vp-c-divider: var(--border-subtle); + + --vp-c-tip-1: var(--status-success-text); + --vp-c-tip-2: var(--status-success-border); + --vp-c-tip-soft: var(--status-success-bg); + + --vp-c-warning-1: var(--status-warning-text); + --vp-c-warning-2: var(--status-warning-border); + --vp-c-warning-soft: var(--status-warning-bg); + + --vp-c-danger-1: var(--status-danger-text); + --vp-c-danger-2: var(--status-danger-border); + --vp-c-danger-soft: var(--status-danger-bg); + + --vp-c-caution-1: var(--status-danger-text); + --vp-c-caution-2: var(--status-danger-border); + --vp-c-caution-soft: var(--status-danger-bg); +} + +/* ─── Typography ────────────────────────────────────────────────── */ +:root { + --vp-font-family-base: Inter, ui-sans-serif, system-ui, -apple-system, + BlinkMacSystemFont, "Segoe UI", sans-serif; + --vp-font-family-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, + Consolas, "Liberation Mono", monospace; +} + +/* ─── Nav bar ───────────────────────────────────────────────────── */ +:root { + --vp-nav-bg-color: var(--surface-bg); + --vp-nav-screen-bg-color: var(--surface-bg); +} + +.VPNav { + border-bottom: 1px solid var(--border-default) !important; + box-shadow: var(--shadow-sm); + backdrop-filter: blur(12px); + background: rgba(var(--surface-bg), 0.92) !important; +} + +.VPNavBar .title { + font-weight: 700; + letter-spacing: -0.01em; + color: var(--text-strong) !important; +} + +/* ─── Sidebar ───────────────────────────────────────────────────── */ +.VPSidebar { + background: var(--surface-bg) !important; + border-right: 1px solid var(--border-subtle) !important; +} + +.VPSidebarItem .text { + font-size: 13px; + color: var(--text-muted); + transition: color var(--motion-standard); +} + +.VPSidebarItem.is-active > .item .text { + color: var(--accent-solid) !important; + font-weight: 600; +} + +.VPSidebarItem:hover > .item .text { + color: var(--text-strong); +} + +.VPSidebarGroup .title { + font-size: 11px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--text-subtle) !important; +} + +/* Active sidebar indicator */ +.VPSidebarItem.is-active > .item { + border-radius: var(--radius-sm); + background: var(--surface-accent); +} + +/* ─── Content area ──────────────────────────────────────────────── */ +.VPContent { + background: var(--app-bg); +} + +.VPDoc .content-container { + max-width: 760px; +} + +/* ─── Headings ──────────────────────────────────────────────────── */ +.vp-doc h1 { + font-size: var(--font-size-display); + font-weight: 700; + color: var(--text-strong); + letter-spacing: -0.02em; + border-bottom: 1px solid var(--border-subtle); + padding-bottom: var(--space-4); + margin-bottom: var(--space-7); +} + +.vp-doc h2 { + font-size: var(--font-size-heading-lg); + font-weight: 600; + color: var(--text-strong); + border-bottom: 1px solid var(--border-muted); + padding-bottom: var(--space-3); + margin-top: var(--space-8); +} + +.vp-doc h3 { + font-size: var(--font-size-heading-md); + font-weight: 600; + color: var(--text-strong); +} + +.vp-doc h4 { + font-size: var(--font-size-title); + font-weight: 600; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.04em; +} + +/* ─── Body text ─────────────────────────────────────────────────── */ +.vp-doc p, +.vp-doc li { + font-size: var(--font-size-body); + line-height: 1.7; + color: var(--app-text); +} + +/* ─── Links ─────────────────────────────────────────────────────── */ +.vp-doc a { + color: var(--accent-solid); + text-decoration: none; + font-weight: 500; + border-bottom: 1px solid transparent; + transition: + color var(--motion-fast), + border-color var(--motion-fast); +} + +.vp-doc a:hover { + color: var(--accent-strong); + border-bottom-color: var(--accent-solid); +} + +/* ─── Code ──────────────────────────────────────────────────────── */ +.vp-doc code:not(pre code) { + font-size: 13px; + padding: 2px 6px; + border-radius: var(--radius-sm); + background: var(--surface-accent); + border: 1px solid var(--border-muted); + color: var(--accent-strong); +} + +.vp-doc pre { + border: 1px solid var(--border-subtle); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-sm); +} + +/* ─── Tables ────────────────────────────────────────────────────── */ +.vp-doc table { + border: 1px solid var(--border-default); + border-radius: var(--radius-md); + overflow: hidden; + border-collapse: separate; + border-spacing: 0; + font-size: var(--font-size-body-sm); +} + +.vp-doc th { + background: var(--surface-accent); + color: var(--text-strong); + font-weight: 600; + font-size: var(--font-size-label); + text-transform: uppercase; + letter-spacing: 0.04em; + padding: var(--space-4) var(--space-5); + border-bottom: 1px solid var(--border-default); +} + +.vp-doc td { + padding: var(--space-4) var(--space-5); + border-bottom: 1px solid var(--border-muted); + color: var(--app-text); + vertical-align: top; +} + +.vp-doc tr:last-child td { + border-bottom: none; +} + +.vp-doc tbody tr:hover { + background: var(--surface-muted); +} + +/* ─── Keyboard keys ─────────────────────────────────────────────── */ +.vp-doc kbd { + display: inline-block; + font-size: 11px; + font-family: var(--vp-font-family-mono); + padding: 2px 6px; + background: var(--surface-elevated); + border: 1px solid var(--border-default); + border-bottom-width: 2px; + border-radius: var(--radius-sm); + color: var(--text-strong); + line-height: 1; + white-space: nowrap; +} + +/* ─── Callout / custom containers ───────────────────────────────── */ +.vp-doc .custom-block.tip { + background: var(--status-success-bg); + border-color: var(--status-success-border); + color: var(--status-success-text); +} + +.vp-doc .custom-block.info { + background: var(--status-info-bg); + border-color: var(--status-info-border); + color: var(--status-info-text); +} + +.vp-doc .custom-block.warning { + background: var(--status-warning-bg); + border-color: var(--status-warning-border); + color: var(--status-warning-text); +} + +.vp-doc .custom-block.danger { + background: var(--status-danger-bg); + border-color: var(--status-danger-border); + color: var(--status-danger-text); +} + +.vp-doc .custom-block .custom-block-title { + font-size: var(--font-size-label); + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.06em; + margin-bottom: var(--space-3); +} + +/* ─── Scrollbar ─────────────────────────────────────────────────── */ +::-webkit-scrollbar { + width: 6px; + height: 6px; +} +::-webkit-scrollbar-track { + background: transparent; +} +::-webkit-scrollbar-thumb { + background: var(--border-soft); + border-radius: 4px; +} +::-webkit-scrollbar-thumb:hover { + background: var(--text-muted); +} + +/* ─── Outline / TOC ─────────────────────────────────────────────── */ +.VPDocAside .outline-link { + font-size: 12px; + color: var(--text-muted); + transition: color var(--motion-fast); +} + +.VPDocAside .outline-link.active { + color: var(--accent-solid); + font-weight: 600; +} + +/* ─── Search ────────────────────────────────────────────────────── */ +.VPLocalSearchBox .search-input { + border: 1px solid var(--border-default); + background: var(--surface-bg); + border-radius: var(--radius-md); + color: var(--text-strong); + font-size: var(--font-size-body); +} + +.VPLocalSearchBox { + --vp-local-search-highlight-bg: var(--surface-accent-strong); + --vp-local-search-highlight-text: var(--accent-strong); +} + +/* ─── Footer ────────────────────────────────────────────────────── */ +.VPFooter { + border-top: 1px solid var(--border-subtle) !important; + background: var(--surface-bg) !important; + color: var(--text-muted); + font-size: var(--font-size-label); +} + +/* ─── Buttons (hero CTA, etc) ───────────────────────────────────── */ +.VPButton.medium.brand { + background: var(--accent-solid); + border-color: var(--accent-solid); + border-radius: var(--radius-md); + font-weight: 600; + transition: + background var(--motion-fast), + box-shadow var(--motion-fast); +} + +.VPButton.medium.brand:hover { + background: var(--accent-strong); + box-shadow: var(--shadow-md); +} + +.VPButton.medium.alt { + border: 1px solid var(--border-default); + background: var(--surface-bg); + color: var(--text-strong); + border-radius: var(--radius-md); + font-weight: 500; + transition: + background var(--motion-fast), + border-color var(--motion-fast); +} + +.VPButton.medium.alt:hover { + background: var(--surface-muted); + border-color: var(--border-soft); +} + +/* ─── Breadcrumbs ───────────────────────────────────────────────── */ +.VPDocFooter .pager-link { + border: 1px solid var(--border-default); + border-radius: var(--radius-md); + background: var(--surface-bg); + transition: + background var(--motion-standard), + border-color var(--motion-standard); +} + +.VPDocFooter .pager-link:hover { + background: var(--surface-muted); + border-color: var(--border-soft); +} + +/* ─── Badge ─────────────────────────────────────────────────────── */ +.vp-badge { + font-size: 10px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.05em; + border-radius: var(--radius-pill); + padding: 2px 7px; +} + +.vp-badge.tip { + background: var(--status-success-bg); + color: var(--status-success-text); +} + +.vp-badge.warning { + background: var(--status-warning-bg); + color: var(--status-warning-text); +} + +.vp-badge.danger { + background: var(--status-danger-bg); + color: var(--status-danger-text); +} + +/* ─── Home hero ─────────────────────────────────────────────────── */ +.VPHero .name { + background: linear-gradient( + 135deg, + var(--accent-strong) 0%, + var(--accent-solid) 50%, + var(--accent-soft) 100% + ); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.VPHero .tagline { + color: var(--text-muted); +} + +.VPFeature { + background: var(--surface-bg); + border: 1px solid var(--border-subtle); + border-radius: var(--radius-xl); + transition: + box-shadow var(--motion-standard), + border-color var(--motion-standard); +} + +.VPFeature:hover { + box-shadow: var(--shadow-md); + border-color: var(--border-soft); +} + +.VPFeature .title { + font-weight: 600; + color: var(--text-strong); +} + +.VPFeature .details { + color: var(--text-muted); + font-size: var(--font-size-body-sm); +} + +/* Remove separator in navigation bar menu */ +.VPNavBarMenu > * { + border-left: none !important; +} + +/* Remove separator between navbar menu and social links */ +.VPNavBar .content-body .menu + .social-links::before { + display: none !important; +} + +/* Prevent hero action buttons from wrapping on desktop */ +@media (min-width: 768px) { + .VPHero .actions { + flex-wrap: nowrap !important; + } +} + +/* Optimize navbar menu spacing on medium screens to prevent overflow */ +@media (min-width: 768px) and (max-width: 1024px) { + .VPNavBarMenuLink { + padding: 0 8px !important; + font-size: 13px !important; + } +} + + +.notely-callout[data-v-42f108e5] { + margin: var(--space-7) 0; + padding: var(--space-5) var(--space-7); + border-left: 3px solid; + border-radius: var(--radius-md); + font-size: var(--font-size-body-sm); + line-height: 1.6; +} +.callout-header[data-v-42f108e5] { + display: flex; + align-items: center; + gap: var(--space-3); + margin-bottom: var(--space-3); +} +.callout-icon[data-v-42f108e5] { + font-size: 14px; + line-height: 1; +} +.callout-label[data-v-42f108e5] { + font-size: var(--font-size-label); + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.06em; +} + +/* Status-mapped colors — all tokens, zero hardcoded values */ +.notely-callout.info[data-v-42f108e5] { + background: var(--status-info-bg); + border-color: var(--status-info-border); + color: var(--status-info-text); +} +.notely-callout.tip[data-v-42f108e5], +.notely-callout.success[data-v-42f108e5] { + background: var(--status-success-bg); + border-color: var(--status-success-border); + color: var(--status-success-text); +} +.notely-callout.warning[data-v-42f108e5] { + background: var(--status-warning-bg); + border-color: var(--status-warning-border); + color: var(--status-warning-text); +} +.notely-callout.danger[data-v-42f108e5] { + background: var(--status-danger-bg); + border-color: var(--status-danger-border); + color: var(--status-danger-text); +} +.notely-callout.important[data-v-42f108e5] { + background: var(--surface-accent-strong); + border-color: var(--accent-solid); + color: var(--text-strong); +} + +.shortcut-table-wrapper[data-v-4607adc0] { + overflow-x: auto; + margin: var(--space-7) 0; + border: 1px solid var(--border-default); + border-radius: var(--radius-md); +} +.shortcut-table[data-v-4607adc0] { + width: 100%; + border-collapse: collapse; + font-size: var(--font-size-body-sm); +} +.shortcut-table th[data-v-4607adc0] { + background: var(--surface-accent); + color: var(--text-strong); + font-size: var(--font-size-label); + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.04em; + padding: var(--space-4) var(--space-5); + text-align: left; + border-bottom: 1px solid var(--border-default); +} +.shortcut-table td[data-v-4607adc0] { + padding: var(--space-4) var(--space-5); + border-bottom: 1px solid var(--border-muted); + color: var(--app-text); + vertical-align: middle; +} +.shortcut-table tbody tr:last-child td[data-v-4607adc0] { + border-bottom: none; +} +.shortcut-table tbody tr[data-v-4607adc0]:hover { + background: var(--surface-muted); +} +.action-cell[data-v-4607adc0] { + font-weight: 500; + color: var(--text-strong); +} +.key-cell[data-v-4607adc0] { + display: flex; + flex-wrap: wrap; + gap: var(--space-2); + align-items: center; +} +kbd[data-v-4607adc0] { + display: inline-block; + font-size: 11px; + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + padding: 2px 6px; + background: var(--surface-elevated); + border: 1px solid var(--border-default); + border-bottom-width: 2px; + border-radius: var(--radius-sm); + color: var(--text-strong); + line-height: 1.4; + white-space: nowrap; +} + +.feature-matrix-wrapper[data-v-e0e0ebb4] { + overflow-x: auto; + margin: var(--space-7) 0; + border: 1px solid var(--border-default); + border-radius: var(--radius-md); +} +.feature-matrix[data-v-e0e0ebb4] { + width: 100%; + border-collapse: collapse; + font-size: var(--font-size-body-sm); +} +.feature-matrix th[data-v-e0e0ebb4] { + background: var(--surface-accent); + color: var(--text-strong); + font-size: var(--font-size-label); + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.04em; + padding: var(--space-4) var(--space-5); + text-align: left; + border-bottom: 1px solid var(--border-default); +} +.feature-matrix td[data-v-e0e0ebb4] { + padding: var(--space-4) var(--space-5); + border-bottom: 1px solid var(--border-muted); + color: var(--app-text); + vertical-align: middle; +} +.feature-matrix tbody tr:last-child td[data-v-e0e0ebb4] { + border-bottom: none; +} +.feature-matrix tbody tr[data-v-e0e0ebb4]:hover { + background: var(--surface-muted); +} +.feature-name[data-v-e0e0ebb4] { + font-weight: 500; + color: var(--text-strong); +} +.setup-label[data-v-e0e0ebb4] { + font-size: var(--font-size-label); + color: var(--status-info-text); + background: var(--status-info-bg); + border: 1px solid var(--status-info-border); + border-radius: var(--radius-pill); + padding: 2px 8px; + white-space: nowrap; +} +[data-v-e0e0ebb4] .status-yes { + color: var(--status-success-text); + font-weight: 700; + font-size: 15px; +} +[data-v-e0e0ebb4] .status-no { + color: var(--text-subtle); + font-weight: 400; +} +[data-v-e0e0ebb4] .status-partial { + color: var(--status-warning-text); + font-weight: 600; +} + +.VPLocalSearchBox[data-v-ce626c7c] { + position: fixed; + z-index: 100; + inset: 0; + display: flex; +} +.backdrop[data-v-ce626c7c] { + position: absolute; + inset: 0; + background: var(--vp-backdrop-bg-color); + transition: opacity 0.5s; +} +.shell[data-v-ce626c7c] { + position: relative; + padding: 12px; + margin: 64px auto; + display: flex; + flex-direction: column; + gap: 16px; + background: var(--vp-local-search-bg); + width: min(100vw - 60px, 900px); + height: min-content; + max-height: min(100vh - 128px, 900px); + border-radius: 6px; +} +@media (max-width: 767px) { +.shell[data-v-ce626c7c] { + margin: 0; + width: 100vw; + height: 100vh; + max-height: none; + border-radius: 0; +} +} +.search-bar[data-v-ce626c7c] { + border: 1px solid var(--vp-c-divider); + border-radius: 4px; + display: flex; + align-items: center; + padding: 0 12px; + cursor: text; +} +@media (max-width: 767px) { +.search-bar[data-v-ce626c7c] { + padding: 0 8px; +} +} +.search-bar[data-v-ce626c7c]:focus-within { + border-color: var(--vp-c-brand-1); +} +.local-search-icon[data-v-ce626c7c] { + display: block; + font-size: 18px; +} +.navigate-icon[data-v-ce626c7c] { + display: block; + font-size: 14px; +} +.search-icon[data-v-ce626c7c] { + margin: 8px; +} +@media (max-width: 767px) { +.search-icon[data-v-ce626c7c] { + display: none; +} +} +.search-input[data-v-ce626c7c] { + padding: 6px 12px; + font-size: inherit; + width: 100%; +} +@media (max-width: 767px) { +.search-input[data-v-ce626c7c] { + padding: 6px 4px; +} +} +.search-actions[data-v-ce626c7c] { + display: flex; + gap: 4px; +} +@media (any-pointer: coarse) { +.search-actions[data-v-ce626c7c] { + gap: 8px; +} +} +@media (min-width: 769px) { +.search-actions.before[data-v-ce626c7c] { + display: none; +} +} +.search-actions button[data-v-ce626c7c] { + padding: 8px; +} +.search-actions button[data-v-ce626c7c]:not([disabled]):hover, +.toggle-layout-button.detailed-list[data-v-ce626c7c] { + color: var(--vp-c-brand-1); +} +.search-actions button.clear-button[data-v-ce626c7c]:disabled { + opacity: 0.37; +} +.search-keyboard-shortcuts[data-v-ce626c7c] { + font-size: 0.8rem; + opacity: 75%; + display: flex; + flex-wrap: wrap; + gap: 16px; + line-height: 14px; +} +.search-keyboard-shortcuts span[data-v-ce626c7c] { + display: flex; + align-items: center; + gap: 4px; +} +@media (max-width: 767px) { +.search-keyboard-shortcuts[data-v-ce626c7c] { + display: none; +} +} +.search-keyboard-shortcuts kbd[data-v-ce626c7c] { + background: rgba(128, 128, 128, 0.1); + border-radius: 4px; + padding: 3px 6px; + min-width: 24px; + display: inline-block; + text-align: center; + vertical-align: middle; + border: 1px solid rgba(128, 128, 128, 0.15); + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.1); +} +.results[data-v-ce626c7c] { + display: flex; + flex-direction: column; + gap: 6px; + overflow-x: hidden; + overflow-y: auto; + overscroll-behavior: contain; +} +.result[data-v-ce626c7c] { + display: flex; + align-items: center; + gap: 8px; + border-radius: 4px; + transition: none; + line-height: 1rem; + border: solid 2px var(--vp-local-search-result-border); + outline: none; +} +.result > div[data-v-ce626c7c] { + margin: 12px; + width: 100%; + overflow: hidden; +} +@media (max-width: 767px) { +.result > div[data-v-ce626c7c] { + margin: 8px; +} +} +.titles[data-v-ce626c7c] { + display: flex; + flex-wrap: wrap; + gap: 4px; + position: relative; + z-index: 1001; + padding: 2px 0; +} +.title[data-v-ce626c7c] { + display: flex; + align-items: center; + gap: 4px; +} +.title.main[data-v-ce626c7c] { + font-weight: 500; +} +.title-icon[data-v-ce626c7c] { + opacity: 0.5; + font-weight: 500; + color: var(--vp-c-brand-1); +} +.title svg[data-v-ce626c7c] { + opacity: 0.5; +} +.result.selected[data-v-ce626c7c] { + --vp-local-search-result-bg: var(--vp-local-search-result-selected-bg); + border-color: var(--vp-local-search-result-selected-border); +} +.excerpt-wrapper[data-v-ce626c7c] { + position: relative; +} +.excerpt[data-v-ce626c7c] { + opacity: 50%; + pointer-events: none; + max-height: 140px; + overflow: hidden; + position: relative; + margin-top: 4px; +} +.result.selected .excerpt[data-v-ce626c7c] { + opacity: 1; +} +.excerpt[data-v-ce626c7c] * { + font-size: 0.8rem !important; + line-height: 130% !important; +} +.titles[data-v-ce626c7c] mark, +.excerpt[data-v-ce626c7c] mark { + background-color: var(--vp-local-search-highlight-bg); + color: var(--vp-local-search-highlight-text); + border-radius: 2px; + padding: 0 2px; +} +.excerpt[data-v-ce626c7c] .vp-code-group .tabs { + display: none; +} +.excerpt[data-v-ce626c7c] .vp-code-group div[class*='language-'] { + border-radius: 8px !important; +} +.excerpt-gradient-bottom[data-v-ce626c7c] { + position: absolute; + bottom: -1px; + left: 0; + width: 100%; + height: 8px; + background: linear-gradient(transparent, var(--vp-local-search-result-bg)); + z-index: 1000; +} +.excerpt-gradient-top[data-v-ce626c7c] { + position: absolute; + top: -1px; + left: 0; + width: 100%; + height: 8px; + background: linear-gradient(var(--vp-local-search-result-bg), transparent); + z-index: 1000; +} +.result.selected .titles[data-v-ce626c7c], +.result.selected .title-icon[data-v-ce626c7c] { + color: var(--vp-c-brand-1) !important; +} +.no-results[data-v-ce626c7c] { + font-size: 0.9rem; + text-align: center; + padding: 12px; +} +svg[data-v-ce626c7c] { + flex: none; +} diff --git a/docs-site/.vitepress/.temp/data-sync-security.md.js b/docs-site/.vitepress/.temp/data-sync-security.md.js new file mode 100644 index 00000000..4f33da3f --- /dev/null +++ b/docs-site/.vitepress/.temp/data-sync-security.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Data & Sync","description":"","frontmatter":{},"headers":[],"relativePath":"data-sync-security.md","filePath":"data-sync-security.md","lastUpdated":1783076990000}'); +const _sfc_main = { name: "data-sync-security.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Data & Sync

    This guide explains how Notely stores your data and how to keep work safe when collaborating.

    1. Where Notely Stores App Data

    Notely keeps your notes in your selected workspace folder.

    It also creates a .notes-app folder for app-managed data such as:

    • Note version history
    • Workspace settings
    • Image annotations

    You usually do not need to open or edit those files yourself.

    2. Keep Your Notes Safe

    Notely includes built-in safety features:

    • Version history for restoring previous note content
    • Managed handling for removed notes/folders
    • Conflict tools when synced changes overlap

    Best practice: make sure your workspace folder is backed up regularly.

    3. Sync with Other Peers (P2P)

    1. Open P2P -> P2P Status.
    2. Start discovery.
    3. Pair with a trusted peer using invite code.
    4. Watch sync status and resolve conflicts if prompted.

    Tips:

    • Pair only with trusted devices.
    • Rotate workspace keys when team access changes.

    If you do not share notes between devices, you can ignore this section.

    4. AI Features for Daily Use

    1. Open AI -> AI Settings.
    2. Add the sign-in details for the AI service you want to use.
    3. Use AI chat, smarter search, and related-note features as needed.

    If the service you chose cannot do something, Notely shows a warning in AI Settings.

    5. When to Use Workspace Graph

    Open Workspace -> Workspace Graph when you want to:

    • Find related notes quickly
    • Spot disconnected notes
    • Understand media-to-note relationships

    6. Before Sharing or Releasing Notes

    Do this quick check:

    1. Validate markdown issues.
    2. Review typo warnings.
    3. Open important diagrams in preview.
    4. Confirm linked files still open correctly.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("data-sync-security.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const dataSyncSecurity = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + dataSyncSecurity as default +}; diff --git a/docs-site/.vitepress/.temp/developer_index.md.js b/docs-site/.vitepress/.temp/developer_index.md.js new file mode 100644 index 00000000..aeb38f0c --- /dev/null +++ b/docs-site/.vitepress/.temp/developer_index.md.js @@ -0,0 +1,46 @@ +import { resolveComponent, useSSRContext } from "vue"; +import { ssrRenderAttrs, ssrRenderSuspense, ssrRenderComponent, ssrRenderStyle } from "vue/server-renderer"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Developer Documentation","description":"Overview of Notely architecture, IPC channels, and development setup.","frontmatter":{"title":"Developer Documentation","description":"Overview of Notely architecture, IPC channels, and development setup.","keywords":"developer, architecture, electron, main process, preload, IPC channels","category":"Developer"},"headers":[],"relativePath":"developer/index.md","filePath":"developer/index.md","lastUpdated":1786126353000}'); +const _sfc_main = { name: "developer/index.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + const _component_Mermaid = resolveComponent("Mermaid"); + _push(`

    Developer Documentation

    Notely is built with Electron, React, and Vite.

    1. Core Architecture & Process Model

    `); + ssrRenderSuspense(_push, { + default: () => { + _push(ssrRenderComponent(_component_Mermaid, { + id: "mermaid-9", + class: "mermaid", + graph: "graph%20TD%0A%20%20%20%20A%5BElectron%20Main%20Process%20main.cjs%5D%20--%3E%7CContextBridge%7C%20B%5BPreload%20Bridge%20preload.cjs%5D%0A%20%20%20%20B%20--%3E%7CReact%20Hooks%20%26%20Services%7C%20C%5BReact%20Renderer%20Process%20src%2F%5D%0A%20%20%20%20A%20--%3E%7CUtilityProcess%7C%20D%5BAI%20Background%20Worker%20workerProcess.cjs%5D%0A%20%20%20%20A%20--%3E%7CNode.js%20child_process%7C%20E%5BNative%20Git%20%26%20PTY%20Terminals%5D%0A%20%20%20%20A%20%3C--%3E%20F%5B(SQLite%20%26%20Markdown%20Storage)%5D%0A" + }, null, _parent)); + }, + fallback: () => { + _push(` Loading... `); + }, + _: 1 + }); + _push(`
    • Main Process (electron/main.cjs): Handles window lifecycle, file I/O, IPC handler registration, menu creation, and system integrations.
    • Background Utility Process (workerManager.cjs / workerProcess.cjs): Spawns an isolated Node.js UtilityProcess for asynchronous vector embedding generation and Knowledge Graph indexing. This keeps background indexing CPU spikes off the main thread.
    • Preload Bridge (electron/preload.cjs): Exposes safe, validated IPC invocation methods to window.electronAPI.
    • Renderer Process (src/): React 18 frontend with Vite, CodeMirror 6 editor canvas, KaTeX rendering, and Lucide icons.

    2. IPC Channel Security Guard Pattern

    All ipcMain.handle endpoints MUST enforce IPC security guards and payload validation:

    1. Sender Authentication (assertTrustedIpcSender): Enforces that IPC invocation events originate strictly from verified internal application renderer windows, rejecting unauthorized external or injected frame messages:
      javascript
      const { assertTrustedIpcSender } = require("./ipcSecurity.cjs");
      +ipcMain.handle("myChannel", async (event, rawPayload) => {
      +  assertTrustedIpcSender(BrowserWindow, event, "myChannel");
      +  // ...
      +});
    2. Payload Schema Validation (ipcSchemas.cjs): Validate raw payloads against strict schema contracts (validatePayload) to ensure type safety before processing file paths or commands.

    3. Development Workflow & Commands

    Development Server

    bash
    npm run dev

    Launches Vite HMR server and Electron wrapper simultaneously.

    Build Production Bundle

    bash
    npm run build

    Compiles Vite frontend assets and validates CommonJS Electron main scripts.

    Documentation Site

    bash
    npm run docs:dev     # Launch VitePress live preview server
    +npm run docs:build   # Build static production docs site

    4. Test Suite Execution

    Notely uses Vitest for comprehensive unit, integration, and IPC service testing:

    bash
    # Run all unit and integration tests
    +npm test
    +
    +# Run tests in watch mode
    +npm run test:watch
    +
    +# Run P2P network integration test harness
    +npm run test:p2p

    Key Test Directories

    • tests/ai/: Core AI orchestration, 5-stage AIFlow, 4-layer planning, compaction, and facade integrity tests.
    • tests/golden_workspace.test.js: Workspace creation, note CRUD, task database sync, and file watcher tests.
    • electron/lib/ipc/codeExecutorIpc.test.js: Code execution runner tests.
    • electron/p2p/p2pLive.test.js: Peer-to-peer discovery and encrypted handshake tests.

    5. Build & Packaging Scripts

    For generating standalone distribution packages:

    • Windows Executable Build Script (build-windows-exe.sh): Compiles and bundles a standalone Windows executable.
    • Release Packaging Script (release.sh): Automates version stamping, package archive creation, and release checksum generation.
    • Icon Generation (scripts/generate-icon.cjs): Generates app icons from source image assets (process.env.NOTELY_ICON_SOURCE).
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("developer/index.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + index as default +}; diff --git a/docs-site/.vitepress/.temp/documentation-audit-2026-07-03.md.js b/docs-site/.vitepress/.temp/documentation-audit-2026-07-03.md.js new file mode 100644 index 00000000..317d1fb5 --- /dev/null +++ b/docs-site/.vitepress/.temp/documentation-audit-2026-07-03.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Notely Documentation Audit","description":"","frontmatter":{},"headers":[],"relativePath":"documentation-audit-2026-07-03.md","filePath":"documentation-audit-2026-07-03.md","lastUpdated":1783077000000}'); +const _sfc_main = { name: "documentation-audit-2026-07-03.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Notely Documentation Audit

    Date: 2026-07-03

    Status note:

    • This audit is a point-in-time snapshot of repository and implementation alignment on 2026-07-03.
    • Some findings in this report may have been addressed by subsequent documentation and shortcut updates after the audit was written.

    Audited surfaces:

    • README.md
    • docs/
    • in-app Help Center and Keyboard Shortcuts modal
    • settings and microcopy surfaces in the renderer
    • Electron menu structure and accelerators
    • developer-facing docs present in the repository

    Method:

    • Code-first verification. No documentation statement was accepted without tracing it to the implementation.
    • Sources of truth used for feature existence and naming were Electron menu actions, renderer action handlers, preload APIs, settings UI, and user-facing components.

    Limitations:

    • No repository screenshots were present in the audited documentation set, so screenshot accuracy could not be validated.
    • This audit covers repository and in-app documentation only. It does not cover any external website, app store listing, or internal release portal.

    Executive Summary

    Notely has a broad documentation set, but it is no longer internally consistent with the implementation. The docs cover many major features, yet several labels, shortcuts, settings descriptions, and help surfaces are stale or incomplete. The most serious problem is that keyboard guidance is split across multiple sources and does not match the implemented shortcut map. The second major problem is terminology drift: documentation still refers to "Notes Folder" and "Help -> Documentation" while the application exposes "Open Workspace" and "Help Center".

    Overall documentation quality: 5.8/10

    Estimated completeness: 72%

    Estimated correctness: 54%

    Highest-priority issues before end-user release:

    1. Replace the hardcoded keyboard guide with an implementation-backed shortcut source and resolve conflicting bindings.
    2. Update all user docs from "Notes Folder" and "Help -> Documentation" to the actual UI labels.
    3. Document currently implemented but undocumented product surfaces: terminal, workspace activity, recent workspaces, favorites/dashboard, reference-note shortcuts, and several settings.
    4. Add missing release notes/changelog and FAQ surfaces.
    5. Correct stale AI and storage details in README and developer docs.

    Phase 1: Verified Feature Inventory

    Verified major user-facing surfaces implemented in the codebase:

    • Workspace selection and recent workspace reopening
    • Note creation, folder creation, rename, remove-to-removed-folder, reload from disk
    • Document list in tile and table modes with density controls
    • Favorites, recent notes, continue-writing dashboard, task dashboard
    • Markdown editing with Edit, Split, Preview, and Web modes
    • Markdown validation, typo checking, quick fixes, find, and find/replace
    • Outline panel and Focus Mode
    • Global search with regex mode and code-block filtering
    • Version history compare, restore, delete, and workspace activity history
    • Media insertion, asset library, workspace health filters, preview, annotation, and original-image restore
    • Screen capture for Windows with Auto Insert and Review Before Insert modes
    • Mermaid and Excalidraw support, including image-to-Excalidraw conversion and restore-original flow
    • AI settings, AI palette, AI chat, embedding generation, relationship graph, and pattern detection
    • Workspace graph with semantic clustering freshness state
    • P2P sync status, invites, trusted peers, conflicts, self-test, and key rotation
    • Embedded terminal with shell selection
    • Command palette with dynamic recent and sibling note commands
    • Workspace zip export with raw, PDF, and web modes plus section-mode options
    • Help Center, About dialog, and keyboard modal
    • Theme, zoom, screen capture, terminal shell, density, view mode, and git metadata controls

    Not implemented as end-user surfaces:

    • Plugin or extension system
    • Generic import workflow beyond opening an existing workspace and inserting media/reference assets
    • Dedicated first-run wizard or tutorial
    • Release notes viewer
    • FAQ surface

    Documentation Coverage Matrix

    FeatureImplementedDocumentedAccurateNotes
    Workspace selectionYesYesPartialDocs say "File -> Notes Folder"; app uses "Open Workspace".
    Recent workspacesYesNoNoImplemented in File -> Open Recent and dialog; not documented.
    Create noteYesYesYesCovered in README and docs.
    Create folderYesYesPartialDocumented loosely; actual command/menu surface not fully described.
    Rename noteYesPartialPartialMentioned in feature reference only; shortcut and menu path omitted.
    Remove note/folder to RemovedYesNoNoImplemented in menu and actions; undocumented workflow.
    Tile/Table viewYesNoNoImplemented via View menu and command palette; absent from docs.
    Density controlsYesNoNoComfortable/Compact documented nowhere.
    FavoritesYesNoNoPresent in dashboard and list actions; undocumented.
    Continue Writing / Recent Notes dashboardYesNoNoLanding dashboard undocumented.
    Markdown edit/split/preview/web modesYesYesMostlyCovered, but keyboard mode switching is undocumented.
    Find in noteYesYesYesDocs reflect current behavior.
    Find and replaceYesPartialPartialExists, but Mac shortcut behavior is undocumented.
    OutlineYesYesPartialDocs omit conflict with reference-link shortcut and Focus mode limitation.
    Focus ModeYesYesPartialDocs omit shortcut conflict with global search.
    Global searchYesYesMostlyRegex/code-block filtering documented well.
    Version historyYesYesMostlyCore flow documented; storage details drift in README.
    Workspace activityYesNoNoImplemented via Workspace menu and panel; undocumented.
    Conflict CenterYesPartialPartialSync conflict handling mentioned, dedicated panel/workflow not explained.
    Media library / Workspace HealthYesPartialPartialBroadly covered; filters, cleanup behavior, and usage inspector under-documented.
    Screen captureYesYesMostlyGood coverage, but menu/help terminology is stale.
    MermaidYesYesYesAccurate at high level.
    ExcalidrawYesYesMostlyCore flow documented; some right-click and restore details are fragmented.
    Reference note preview/link insertionYesNoNoImplemented with shortcuts and toolbar; undocumented.
    Command paletteYesPartialPartialMentioned, but command inventory and personalization are undocumented.
    AI settingsYesYesPartialDocs do not match current provider list and model options.
    AI palette / AI chatYesPartialPartialBroadly described, but actual invocation and shortcut conflicts are inaccurate.
    Workspace graphYesYesMostlyCore flow documented; refresh and freshness are covered.
    P2P status / invites / peersYesYesPartialHigh-level guidance exists; panel tabs and workflows are undocumented.
    Embedded terminalYesNoNoFully implemented, entirely undocumented for end users.
    Workspace zip exportYesYesPartialExport formats documented; section export modes are undocumented.
    PDF exportYesYesPartialExists, but shortcut and some options are not documented.
    Help Center / AboutYesYesPartialDocs use stale label "Documentation" instead of "Help Center".
    Keyboard shortcuts guideYesYesNoIn-app modal is materially incomplete and inconsistent.
    ThemeYesNoNoImplemented in Settings menu; undocumented.
    ZoomYesNoNoImplemented in View menu; undocumented.
    Terminal shell selectionYesNoNoImplemented in View menu and terminal UI; undocumented.
    Screen capture settingYesYesMostlyDocumented accurately.
    Auto-ignore .notes-app in GitYesNoNoImplemented in document header; undocumented.

    README Audit

    What is correct

    • Product purpose and overall scope are broadly accurate.
    • Build, test, lint, and packaging command names in README match package.json.
    • Help Center content is loaded from docs/ and exposed in-app.
    • Workspace zip export exists with raw, PDF, and web output modes.

    What is inaccurate or incomplete

    1. README mixes current and stale terminology.

      • User docs and README discuss a notes root / notes folder model, but the actual user-facing menu label is Open Workspace.
      • In-app help is exposed as Help Center, not Help -> Documentation.
    2. Installation guidance is incomplete for end users.

      • No supported-OS matrix.
      • No end-user install instructions.
      • No prerequisites section.
      • No environment setup section for AI, signing, or terminal hardening beyond scattered later sections.
    3. AI provider and model documentation is stale.

      • README lists HuggingFace as an end-user provider concept, but the visible text-provider UI exposes Gemini and Groq while OpenAI and Local LLM are marked unavailable/coming soon.
      • README model lists do not match the current AISettings provider arrays.
    4. Storage details are partly stale.

      • README says .notes-app/settings.json stores workspace-level settings, but the implementation uses .notes-app/app-state.json and .notes-app/app.sqlite for metadata storage.
    5. Several implemented features are missing from README.

      • Embedded terminal
      • Recent workspaces
      • Favorites and landing dashboard
      • Workspace activity panel
      • Reference note preview / insert-reference-link workflows
      • Theme, zoom, density, terminal shell, and git metadata controls
    6. There are no screenshots.

    README verdict

    • Coverage breadth: good
    • Setup/install quality: weak
    • Accuracy against current UI labels: weak
    • Release-readiness for external users: not sufficient

    docs/ Folder Audit

    Strong areas

    • Global search and regex coverage are relatively strong.
    • Workspace export, screen capture, AI setup intent, graph clustering, and task panels are described at a usable high level.
    • Troubleshooting contains relevant real workflows rather than placeholder advice.

    Systemic issues

    1. Terminology drift across nearly every user doc.

      • "File -> Notes Folder" should be updated to Open Workspace.
      • "Help -> Documentation" should be updated to Help -> Help Center.
    2. Documentation claims are spread across too many overlapping pages.

      • README, user-guide, feature-reference, top-tasks, and Help Center all repeat the same foundational workflows.
      • Keyboard references are split across docs/index.md, the keyboard modal, and actual code.
    3. Several major product surfaces are under-documented or absent.

      • Terminal
      • Recent workspaces
      • Favorites/dashboard
      • Workspace activity
      • Conflict Center
      • Theme, zoom, density, terminal shell, git metadata controls
      • Reference-note commands
    4. Top Tasks is no longer a "Top 15" page.

      • It now contains 23 numbered items, including 11b and 19b.
      • The title is obsolete.
    5. Some docs describe workflows that are only partially true.

      • AI docs imply a cleaner provider surface than the actual UI exposes.
      • Some storage descriptions blur workspace metadata, note history, and app-state files.

    Per-document findings

    docs/index.md

    • Accurate that Help Center reads from docs/.
    • Stale label usage: notes folder and Help/Documentation naming.
    • Keyboard section is too small and omits most real shortcuts.

    docs/user-guide.md

    • Good high-level workflow sequencing.
    • Stale workspace terminology.
    • Omits recent workspaces, favorites, terminal, workspace activity, theme, zoom, density, and reference-note features.

    docs/feature-reference.md

    • Broadest end-user reference and the most valuable single page.
    • Contains stale Help and workspace naming.
    • Does not cover terminal, recent workspaces, favorites/dashboard, or git metadata controls.
    • Under-documents settings and over-compresses platform differences.

    docs/top-tasks.md

    • Good procedural format.
    • Title is obsolete.
    • Uses stale menu labels.
    • Omits several daily-use workflows that are more prominent in the UI than some included items.

    docs/feature-availability.md

    • Useful conceptually.
    • Does not mention terminal or settings surfaces.
    • AI setup distinctions are too simplified relative to the current UI.

    docs/data-sync-security.md

    • Good for high-level safety framing.
    • Too light on actual storage specifics, backup expectations, and what P2P telemetry/conflicts look like.

    docs/troubleshooting.md

    • Useful, but missing troubleshooting topics for terminal, workspace export, recent workspaces, graph clustering freshness, and shortcut conflicts.

    docs/ux-writing-guide.md

    • Useful internal style guide.
    • Not a user-facing doc.
    • Should not be treated as part of user help coverage.

    Built-in Help Audit

    Implemented help surfaces:

    • Help Center modal backed by docs/
    • Keyboard Shortcuts modal
    • About dialog
    • Start Here content in docs/index.md
    • Empty states and inline titles/tooltips across components

    Not implemented:

    • Welcome screen
    • Tutorial
    • First-run wizard
    • Tips carousel
    • Contextual walkthroughs

    Findings:

    1. Help delivery architecture is sound.

      • Help metadata is hardcoded in the main process, while markdown body content is loaded from docs/.
    2. Help naming is inconsistent.

      • UI says Help Center.
      • Multiple docs still say Help -> Documentation.
    3. Built-in keyboard help is not trustworthy.

      • The modal contains only seven shortcuts.
      • The implementation contains many more menu and editor bindings.
    4. First-run support is weak.

      • New users get a splash screen and empty states, but no guided onboarding.
    5. Empty states and microcopy quality are generally decent.

      • Examples: DocumentList, DashboardPanels, TasksPanel, P2PStatusPanel, WorkspaceActivityPanel, MediaTab.
      • The product does provide inline guidance, but those surfaces are not covered in documentation strategy.

    Documented well enough:

    • New Note
    • Versions
    • Workspace Graph
    • P2P Status
    • AI Settings
    • Screen Capture

    Undocumented or under-documented menu items:

    • Open Recent
    • Move current folder to Removed
    • Workspace Activity
    • Show Terminal
    • Terminal Shell: Auto / Bash / CMD
    • Theme: System / Light / Dark
    • Density controls
    • Zoom In / Out / Reset
    • Run Sync Self-Test
    • Conflict Center
    • Rotate Workspace Keys
    • How Sync Works
    • Generate Embeddings / Build Relationship Graph / Detect Patterns / Clear Cache
    • Open in VS Code
    • Open Website View
    • Reload from Disk

    Settings Documentation Audit

    Documented:

    • AI settings, at a high level
    • Screen Capture mode

    Missing or incomplete:

    • Theme preference
    • Zoom factor
    • Tile vs Table view mode
    • Comfortable vs Compact density
    • Terminal visibility and shell preference
    • Typo Check toggle
    • Auto-ignore .notes-app in .gitignore
    • Workspace export section modes
    • AI advanced generation controls: max tokens and temperature
    • AI feature toggles: pattern learning, embeddings, relationship discovery

    Documentation quality of settings descriptions: insufficient. The code exposes the controls, but the docs do not explain defaults, impact, or recommended usage for most of them.

    Workflow Documentation Audit

    Well-covered workflows:

    • Create note
    • Edit markdown
    • Find / replace
    • Global search
    • Version recovery
    • Screen capture
    • Mermaid / Excalidraw basics
    • Workspace zip export
    • Task review

    Partially covered workflows:

    • P2P sync pairing and conflict resolution
    • AI setup and use
    • Media cleanup and annotations
    • PDF export

    Missing workflows:

    • Recent workspace reopening
    • Workspace activity review
    • Favorites and dashboard usage
    • Terminal usage and shell switching
    • Reference note preview and insert-reference-link flows
    • Theme / density / zoom customization
    • Remove-to-removed-folder and recovery expectations
    • Git metadata handling for .notes-app

    Missing Documentation by Severity

    Critical

    • Full keyboard shortcut inventory is missing and the current in-app guide is inaccurate.
    • Actual shortcut conflicts are undocumented and unresolved.
    • Core menu/help terminology is stale across user docs.

    High

    • No changelog or release notes.
    • No FAQ.
    • Terminal feature undocumented.
    • Settings coverage incomplete for theme, zoom, density, terminal shell, AI advanced settings, and git metadata controls.
    • Recent workspaces and workspace activity undocumented.

    Medium

    • Dashboard, favorites, and continue-writing surfaces undocumented.
    • Conflict Center and sync self-test workflows undocumented.
    • Workspace export section-mode options undocumented.
    • Reference note preview/link insertion workflows undocumented.
    • First-run onboarding is minimal and undocumented.

    Low

    • Empty states and tooltip strategy are undocumented.
    • Top Tasks title is stale.
    • Some developer docs duplicate or overstate AI capabilities.

    Keyboard Shortcut Audit

    Key findings

    1. The keyboard guide is incomplete.

      • The in-app modal shows 7 shortcuts.
      • The implementation exposes many more.
    2. Three real conflicts exist in the current implementation.

      • Ctrl/Cmd+K is used for both Command Palette and Open AI Palette.
      • Ctrl/Cmd+Shift+F is used for both Global Search and Focus Mode.
      • Ctrl/Cmd+Shift+L is used for both Show Outline and Insert Reference Link.
    3. Platform behavior is not documented.

      • Find and Replace has a Ctrl/Cmd+H accelerator only on non-macOS in the app menu.

    Shortcut table

    ShortcutActionWhere it worksScope / conditionsDocumented?Notes
    Ctrl/Cmd+KOpen Command PaletteGlobal rendererWindow-level keydownPartialDocumented, but conflicts with AI Palette menu accelerator.
    Ctrl/Cmd+KOpen AI PaletteDocument screen menuElectron menu acceleratorNoConflicts with Command Palette.
    Ctrl/Cmd+Shift+FOpen Global SearchGlobal rendererWindow-level keydownPartialDocumented in keyboard modal, but conflicts with Focus Mode.
    Ctrl/Cmd+Shift+FToggle Focus ModeDocument editorWindow-level keydown and View menuPartialDocumented as menu workflow, not as conflicting shortcut.
    Ctrl/Cmd+/Open Keyboard ShortcutsGlobalWindow-level keydown and Help menuYesOne of the few consistent shortcuts.
    F1Open Help CenterGlobalHelp menu acceleratorPartialDocs still say Help -> Documentation.
    Ctrl/Cmd+NNew NoteLanding and documentFile menu and command paletteYesAccurate.
    Ctrl/Cmd+Shift+NOpen WorkspaceLanding and documentFile menu and command paletteNoDocs still describe File -> Notes Folder.
    Ctrl/Cmd+SSave current noteDocumentFile menu and editor keydownPartialExists, but not consistently documented in user docs.
    Ctrl/Cmd+Shift+EExport PDFDocumentFile menuNoUser docs mention note PDF export, not the shortcut.
    Ctrl/Cmd+Shift+EExport Workspace as ZipLandingFile menuNoExport workflow documented, shortcut not.
    Ctrl/Cmd+Shift+HVersionsDocumentFile menuYesAccurate.
    Ctrl/Cmd+Shift+OOpen in VS CodeDocumentFile menuNoUndocumented.
    Ctrl/Cmd+Shift+WOpen Website ViewLanding and documentFile menuNoUndocumented.
    F2Rename NoteDocumentFile menuNoUndocumented.
    Ctrl/Cmd+Shift+RReload from DiskDocumentFile menuNoUndocumented.
    Ctrl/Cmd+DeleteMove Note to RemovedDocumentFile menuNoUndocumented.
    Ctrl/Cmd+Shift+DeleteMove Folder to RemovedLandingFile menuNoUndocumented.
    EscBack to NotesDocumentFile menuPartialBehavior exists, but docs do not describe it.
    Ctrl/Cmd+FFind in Current NoteDocumentEdit menu, CodeMirror keymap, editor hookYesAccurate.
    Ctrl/Cmd+HFind and ReplaceDocumentEdit menu, non-macOS acceleratorPartialKeyboard modal incorrectly implies universal availability.
    Ctrl/Cmd+Shift+LShow OutlineDocumentView menu acceleratorPartialConflicts with Insert Reference Link.
    Ctrl/Cmd+Shift+LInsert Reference LinkDocumentToolbar document keydownNoUndocumented and conflicts with Show Outline.
    Ctrl/Cmd+Shift+KOpen Reference NoteDocumentToolbar document keydownNoUndocumented.
    Ctrl/Cmd+Shift+SCapture Screen AreaDocumentToolbar document keydownYesDocumented procedurally, not in keyboard guide.
    Ctrl/Cmd+ZUndoDocumentCodeMirror keymap and editor hookNoVisible in tooltips, undocumented in guide.
    Ctrl/Cmd+YRedoDocumentCodeMirror keymap and editor hookNoVisible in tooltips, undocumented in guide.
    Ctrl/Cmd+Shift+ZRedoDocumentCodeMirror keymapNoUndocumented.
    Ctrl/Cmd+\\Split PreviewDocumentView menu and editor hookNoUndocumented shortcut.
    Ctrl/Cmd+1Tile NotesLandingView menuNoContext-specific landing shortcut.
    Ctrl/Cmd+2Table NotesLandingView menuNoContext-specific landing shortcut.
    Ctrl/Cmd+3Comfortable DensityLandingView menuNoContext-specific landing shortcut.
    Ctrl/Cmd+4Compact DensityLandingView menuNoContext-specific landing shortcut.
    Ctrl/Cmd+1Edit ModeDocumentEditor hookNoContext-specific document shortcut.
    Ctrl/Cmd+2Split ModeDocumentEditor hookNoContext-specific document shortcut.
    Ctrl/Cmd+3Preview ModeDocumentEditor hookNoContext-specific document shortcut.
    Ctrl/Cmd+=Zoom InLanding and documentView menuNoUndocumented.
    Ctrl/Cmd+-Zoom OutLanding and documentView menuNoUndocumented.
    Ctrl/Cmd+0Reset ZoomLanding and documentView menuNoUndocumented.
    Ctrl/Cmd+Shift+POpen P2P StatusGlobalP2P menuNoUndocumented shortcut.
    Ctrl/Cmd+Shift+,Open AI SettingsGlobalAI menuNoUndocumented shortcut.
    Ctrl/Cmd+Shift+GOpen Workspace GraphGlobalWorkspace menuNoWorkflow documented, shortcut not.
    Ctrl/Cmd+Shift+AOpen Workspace ActivityLanding and documentFile or Workspace menuNoUndocumented.
    EnterNext find matchFind panelFind UI onlyNoTooltip only.
    Shift+EnterPrevious find matchFind panelFind UI onlyNoTooltip only.
    ContextMenu or Shift+F10Open preview context menuMarkdown previewPreview surface onlyNoAccessibility-oriented shortcut, undocumented.
    PlusZoom image inMedia previewImage preview onlyNoUndocumented.
    MinusZoom image outMedia previewImage preview onlyNoUndocumented.
    1 or 0Reset image zoomMedia previewImage preview onlyNoUndocumented.

    Inconsistencies

    1. Code vs docs: workspace naming

      • Docs repeatedly say File -> Notes Folder.
      • UI/menu uses Open Workspace.
    2. Code vs docs: help naming

      • Docs say Help -> Documentation.
      • UI/menu uses Help Center.
    3. Code vs in-app keyboard guide

      • KeyboardShortcutsModal shows only seven shortcuts.
      • Menu and editor implement many more.
    4. Code vs code: shortcut ownership conflicts

      • Ctrl/Cmd+K
      • Ctrl/Cmd+Shift+F
      • Ctrl/Cmd+Shift+L
    5. Code vs README/docs: AI providers and models

      • README and AI README overstate available provider surface.
      • AISettings marks OpenAI and Local as unavailable / coming soon.
    6. Code vs README: storage details

      • README references .notes-app/settings.json.
      • Metadata storage uses .notes-app/app-state.json and .notes-app/app.sqlite.
    7. Code vs docs: menu surface coverage

      • Recent workspaces, terminal, workspace activity, theme, zoom, density, git metadata status, and reference-note flows exist but are not documented.

    Obsolete Documentation

    • docs/top-tasks.md title: no longer "Top 15"
    • docs/index.md: stale notes-folder and Help/Documentation terminology
    • docs/user-guide.md: stale notes-folder and Help/Documentation terminology
    • docs/feature-reference.md: stale Help/Documentation terminology and stale notes-folder terminology
    • docs/top-tasks.md: stale Help/Documentation terminology and stale notes-folder terminology
    • docs/troubleshooting.md: stale notes-folder terminology
    • README.md: storage details partially stale; AI/provider details partially stale; setup/install guidance incomplete
    • src/ai/README.md: overstates available providers and uses Cmd+K AI palette guidance that conflicts with current app behavior

    Documentation Quality Review

    CategoryScore (1-10)Notes
    Completeness7Broad feature coverage exists, but several implemented surfaces are missing.
    Correctness5Too many stale labels and shortcut mismatches.
    Consistency4Terminology and shortcut references are fragmented.
    Readability8Most docs are easy to read.
    Navigation7Help Center structure is usable.
    Discoverability5Important features exist without docs or guided discovery.
    Onboarding quality4Splash + Start Here is not enough for first-time users.
    Troubleshooting quality6Useful but incomplete.
    Searchability7docs/ pages are topic-based and searchable.

    End-User Perspective

    Can a new user install it?

    • Not confidently from current docs. There is no end-user installation guide or platform support section.

    Can they understand the UI?

    • Partially. The docs explain the major note-editing model, but the actual menu and settings labels do not line up with the guide.

    Can they discover features?

    • Only partially. The command palette, terminal, workspace activity, recent workspaces, favorites, and several settings are easy to miss.

    Can they recover from mistakes?

    • Better than average for notes and media. Version history, removed-folder flow, and image restore exist. Documentation of all recovery paths does not.

    Can they learn shortcuts?

    • No. The keyboard guide is materially incomplete and current shortcuts conflict.

    Can they understand settings?

    • Only AI and screen capture at a high level. Most other settings are undocumented.

    Can they troubleshoot issues?

    • Some common cases yes, but not terminal, recent workspace, export, graph freshness, or shortcut conflicts.

    Can they use advanced functionality?

    • Only after experimentation. P2P, AI tuning, terminal, graph refresh, and workspace export options need stronger docs.

    Suggested Improvements

    1. Critical fixes

    • Resolve the three shortcut conflicts in implementation.
    • Generate the keyboard guide from the actual command/accelerator map.
    • Replace all stale menu labels in README and docs.

    2. High-value additions

    • Add release notes / changelog.
    • Add FAQ.
    • Add end-user installation and supported-platform guide.
    • Add settings reference page.

    3. UX improvements

    • Add a first-run onboarding sheet or setup checklist in-app.
    • Add contextual help for terminal, recent workspaces, workspace activity, and reference-note workflows.

    4. Documentation restructuring

    • Reduce duplication across README, user-guide, feature-reference, and top-tasks.
    • Keep README external-facing and concise.
    • Keep docs/ as the canonical in-app help set.

    5. Navigation improvements

    • Add a dedicated shortcut reference page in docs/.
    • Add a settings reference page in docs/.
    • Add an advanced workflows page for P2P, AI, terminal, and export.

    6. Onboarding enhancements

    • Replace "Start Here" with a real first-run path that includes opening a workspace, creating a note, editing, searching, and recovery.

    7. Help system improvements

    • Rename all doc references to Help Center.
    • Surface missing workflows directly from related panels.

    8. Keyboard guide improvements

    • Show scope, platform notes, and conflicts.
    • Split global, editor, media preview, and context-menu shortcuts.
    • Include only real bindings, not aspirational ones.

    Final Scorecard

    SurfaceScore (1-10)
    README6
    User Guide6
    Help System6
    Keyboard Guide2
    Setup Instructions4
    Troubleshooting6
    API / Developer Docs5
    Consistency4
    Completeness7
    Overall Documentation Quality5.8

    Release-Readiness Roadmap

    Before releasing Notely broadly to end users, complete this sequence:

    1. Fix shortcut conflicts in code and replace the hardcoded keyboard modal with generated data.
    2. Normalize all docs to current UI terminology: Open Workspace, Help Center, Help -> Keyboard Shortcuts.
    3. Publish a real install/setup guide and a changelog.
    4. Add missing documentation for terminal, workspace activity, recent workspaces, dashboard/favorites, settings, and reference-note workflows.
    5. Update AI and storage documentation to match the current implementation exactly.
    6. Add lightweight first-run onboarding and link it from the landing empty state and Help Center.

    If those six items are completed, documentation quality would move from internal-tooling grade to a credible end-user release baseline.

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("documentation-audit-2026-07-03.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const documentationAudit20260703 = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + documentationAudit20260703 as default +}; diff --git a/docs-site/.vitepress/.temp/editor_code-blocks.md.js b/docs-site/.vitepress/.temp/editor_code-blocks.md.js new file mode 100644 index 00000000..593052f0 --- /dev/null +++ b/docs-site/.vitepress/.temp/editor_code-blocks.md.js @@ -0,0 +1,22 @@ +import { ssrRenderAttrs, ssrRenderStyle } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Code Blocks","description":"Auto-detect languages, auto-format with Prettier, and edit code in a dedicated popup — all from inside Notely.","frontmatter":{"title":"Code Blocks","description":"Auto-detect languages, auto-format with Prettier, and edit code in a dedicated popup — all from inside Notely.","keywords":"code block, syntax highlighting, auto-format, prettier, code editor, language detection","category":"Editor"},"headers":[],"relativePath":"editor/code-blocks.md","filePath":"editor/code-blocks.md","lastUpdated":1786126353000}'); +const _sfc_main = { name: "editor/code-blocks.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Code Blocks

    Notely provides a rich experience for working with code inside Markdown notes: automatic language detection, one-click formatting with Prettier, and a dedicated full-screen code editor.

    Insert a Code Block

    In Edit mode, use the toolbar Code button or type three backticks followed by a language name:

    markdown
    \`\`\`python
    +def hello(name):
    +    return f"Hello, {name}!"
    +\`\`\`

    Notely renders the block with syntax highlighting in Preview and Split modes.

    Auto-Detect Language

    If you paste a code snippet without a language tag, Notely attempts to detect the language automatically:

    1. Paste code into an empty fenced block (\`\`\` without a language).
    2. Notely inspects the content and adds the correct language tag.
    3. The block re-renders with appropriate highlighting.

    Supported auto-detected languages include JavaScript, TypeScript, Python, HTML, CSS, JSON, YAML, Bash, SQL, Go, Rust, and more.

    Auto-Format with Prettier

    In Preview mode, a toolbar appears on hover above each code block. Click the 🪄 Format button to auto-format the code using Prettier:

    • Applies consistent indentation
    • Normalizes quotes and semicolons
    • Respects the language-appropriate style

    The formatting is written back to the Markdown source automatically.

    You can also trigger formatting from inside the dedicated code editor.

    Dedicated Code Editor

    For a distraction-free editing experience:

    1. Switch to Preview mode.
    2. Hover over any code block — a toolbar appears.
    3. Click the ✎ Edit button.

    The dedicated code editor opens with:

    • Syntax highlighting for the block's language
    • Find and Replace (Ctrl + F)
    • Language selector — switch the code language
    • Line numbers
    • Format button — run Prettier from within the editor

    Click Save to write changes back to the note, or Cancel to discard.

    Code Execution

    You can run code snippets directly from your notes:

    1. Hover over a code block in Preview mode.
    2. If the block is written in a supported language, the ▶ Run button in the hover toolbar will be active.
    3. Supported execution languages include:
      • JavaScript (js, javascript): runs locally via node.
      • Python (py, python): runs locally via system python / python3.
      • Bash (sh, bash): runs shell scripts locally via bash or sh.
      • PowerShell (ps1, powershell): runs scripts via powershell or pwsh.
      • HTML (html): renders live HTML DOM output inside an interactive preview drawer.
    4. Click ▶ Run to execute the script or preview output.
    5. Command outputs (stdout/stderr) are displayed in a collapsible, high-contrast dark terminal output frame beneath the code block.

    You can also execute code from inside the Dedicated Code Editor modal using the Execute button in the top toolbar.

    Security Note

    Running code execution spawns a local process on your machine using your local system environment. Only run code from trusted workspaces and sources.

    Execution Limits & Loops

    Code execution terminates automatically after 10 seconds. If your code hangs or enters an infinite loop, the runner will kill the subprocess safely and report a timeout error. Buffer sizes are capped at 64KB.

    Supported Languages

    Notely supports highlighting for all highlight.js languages, including:

    CategoryExamples
    Webhtml, css, javascript, typescript, jsx, tsx
    Backendpython, go, rust, java, csharp, php, ruby
    Datajson, yaml, toml, xml, sql
    Shellbash, powershell, cmd
    Markupmarkdown, latex
    Confignginx, dockerfile, makefile

    Tips

    Copy Button

    Every code block in Preview mode has a Copy button in the top-right corner. Click it to copy the code contents without the backtick fences.

    Language Tags are Important

    Always specify a language tag for better highlighting and to ensure the auto-formatter chooses the right rules. Example: \`\`\`typescript instead of \`\`\`.

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("editor/code-blocks.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const codeBlocks = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + codeBlocks as default +}; diff --git a/docs-site/.vitepress/.temp/editor_diagrams.md.js b/docs-site/.vitepress/.temp/editor_diagrams.md.js new file mode 100644 index 00000000..d46f767b --- /dev/null +++ b/docs-site/.vitepress/.temp/editor_diagrams.md.js @@ -0,0 +1,40 @@ +import { resolveComponent, useSSRContext } from "vue"; +import { ssrRenderAttrs, ssrRenderStyle, ssrRenderSuspense, ssrRenderComponent } from "vue/server-renderer"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Diagrams","description":"Create flowcharts and visual diagrams in Notely using Mermaid syntax or the Excalidraw visual canvas.","frontmatter":{"title":"Diagrams","description":"Create flowcharts and visual diagrams in Notely using Mermaid syntax or the Excalidraw visual canvas.","keywords":"mermaid, excalidraw, diagrams, flowchart, sequence diagram, gantt, whiteboard, visual editor","category":"Editor"},"headers":[],"relativePath":"editor/diagrams.md","filePath":"editor/diagrams.md","lastUpdated":1786254063000}'); +const _sfc_main = { name: "editor/diagrams.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + const _component_Mermaid = resolveComponent("Mermaid"); + _push(`

    Diagrams

    Notely supports three diagram formats: Mermaid for text-based diagrams written in code, Excalidraw for freehand whiteboard-style drawing, and Draw.io for structured technical schemas and system architectures.

    Mermaid Diagrams

    Mermaid lets you create diagrams using a simple text syntax. Notely renders them live in Preview and Split modes.

    Insert a Mermaid Block

    1. In Edit mode, click Diagram → Mermaid in the toolbar.
    2. A Mermaid code block is inserted at the cursor.
    3. Write your Mermaid syntax inside the block.
    4. Switch to Split or Preview to see the rendered diagram.

    Diagram Types

    markdown
    \`\`\`mermaid
    +graph TD
    +    A[Open workspace] --> B[Create note]
    +    B --> C{Write content}
    +    C --> D[Save note]
    +    D --> E[Commit to Git]
    +\`\`\`
    TypeKeywordUse for
    Flowchartgraph TD / graph LRProcesses, decisions, flows
    SequencesequenceDiagramAPI calls, user interactions
    GanttganttProject timelines
    ClassclassDiagramObject relationships
    StatestateDiagram-v2State machines
    ERerDiagramDatabase schemas
    PiepieData proportions

    Example — Git Workflow

    `); + ssrRenderSuspense(_push, { + default: () => { + _push(ssrRenderComponent(_component_Mermaid, { + id: "mermaid-138", + class: "mermaid", + graph: "graph%20TD%0A%20%20%20%20A%5BEdit%20note%5D%20--%3E%20B%5BStage%20changes%5D%0A%20%20%20%20B%20--%3E%20C%5BWrite%20commit%20message%5D%0A%20%20%20%20C%20--%3E%20D%5BCommit%5D%0A%20%20%20%20D%20--%3E%20E%7BPush%20to%20remote%3F%7D%0A%20%20%20%20E%20--%20Yes%20--%3E%20F%5Bgit%20push%5D%0A%20%20%20%20E%20--%20No%20--%3E%20G%5BStay%20local%5D%0A" + }, null, _parent)); + }, + fallback: () => { + _push(` Loading... `); + }, + _: 1 + }); + _push(`

    Interactive Diagram Actions

    In Preview and Split modes, hovering over any rendered Mermaid diagram reveals the top action bar:

    • Edit: Opens the Mermaid visual editor modal to modify diagram elements visually.
    • Download: Renders and exports the Mermaid diagram as a high-resolution PNG image saved directly to your system Downloads folder.

    Troubleshooting Mermaid

    If your diagram does not render:

    1. Switch to Split mode to see both the source and the error message.
    2. Check for syntax errors — Mermaid is strict about arrow direction (--> not ).
    3. Validate with the Mermaid Live Editor.

    Excalidraw Diagrams

    Excalidraw provides a whiteboard canvas for freehand drawing, annotated shapes, and visual diagrams embedded directly in your notes.

    Insert an Excalidraw Diagram

    1. Click Diagram → Excalidraw in the toolbar.
    2. An Excalidraw block is inserted in the note.
    3. In Preview mode, the Excalidraw canvas opens.
    4. Draw your diagram, then click Save to embed it.
    5. The diagram is stored as a file in your workspace.

    Re-Edit an Existing Diagram

    1. In Preview mode, click the Edit button on the Excalidraw preview.
    2. The canvas reopens with your existing drawing.
    3. Make changes, then click Save.

    Convert an Image to Excalidraw

    You can convert any workspace image into an Excalidraw diagram so you can annotate or draw on top of it:

    1. In Preview mode, right-click on any workspace image.
    2. Select Edit with Excalidraw.
    3. The image is placed on the Excalidraw canvas as a resizable background element.
    4. Draw annotations, arrows, or labels on top.
    5. Click Save to replace the image reference with the Excalidraw diagram.

    Restore the Original Image

    If you converted an image to Excalidraw and want to revert to the original:

    1. In Preview mode, right-click the Excalidraw preview.
    2. Select Restore original image.

    Restore Availability

    The Restore original image option only appears for Excalidraw diagrams that were created from an image conversion. Diagrams created from scratch do not show this option.


    Draw.io Diagrams

    Draw.io (diagrams.net) is integrated into Notely for precise, professional engineering schematics, UML designs, and network/cloud architectures.

    Insert a Draw.io Diagram

    1. Click the Insert Diagram icon () on the toolbar.
    2. Click Draw.io.
    3. In Preview mode, click on the placeholder to open the Draw.io editor.
    4. Build your diagram and click Save Diagram.
    5. The diagram saves XML source metadata to media/draw.io/*.drawio and renders a preview image to media/draw.io/*.png.

    Import Diagrams via Drag and Drop

    Drop any existing .drawio or .drawio.xml file directly into the Markdown Editor. Notely will parse the file, copy it into the workspace media directory, and embed it as an interactive diagram block.


    Choosing a Diagram Tool

    FeatureMermaidExcalidrawDraw.io
    Best forFast text-based flows, timelinesCasual sketching, wireframesEngineering schematics, network charts
    EditingText syntaxVisual canvasVisual canvas
    StoragePlain Markdown textJSON .excalidraw + SVG previewXML .drawio + PNG preview
    Offline
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("editor/diagrams.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const diagrams = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + diagrams as default +}; diff --git a/docs-site/.vitepress/.temp/editor_focus-mode.md.js b/docs-site/.vitepress/.temp/editor_focus-mode.md.js new file mode 100644 index 00000000..1590746a --- /dev/null +++ b/docs-site/.vitepress/.temp/editor_focus-mode.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Focus Mode & Outline","description":"Use Focus Mode to minimize distractions and the Outline panel to navigate long notes by heading.","frontmatter":{"title":"Focus Mode & Outline","description":"Use Focus Mode to minimize distractions and the Outline panel to navigate long notes by heading.","keywords":"focus mode, outline, navigation, heading, distraction-free","category":"Editor"},"headers":[],"relativePath":"editor/focus-mode.md","filePath":"editor/focus-mode.md","lastUpdated":1784865427000}'); +const _sfc_main = { name: "editor/focus-mode.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Focus Mode & Outline

    Outline Panel

    The Outline panel shows a navigation tree of all headings in the current note. Use it to jump quickly between sections in long documents.

    Open the Outline

    • Toolbar: Click View ▾ dropdown → check Document Outline
    • Menu: View → Show Outline
    • Shortcut: Ctrl + Alt + L

    Using the Outline

    • Click any heading in the Outline panel to place a single cursor at that section and scroll the editor directly to it.
    • The Outline updates in real time as you write.
    • The active heading is highlighted based on the editor scroll position.
    • Works seamlessly in Edit, Split, and Preview modes.

    Focus Mode Interaction

    The Outline panel is automatically hidden when Focus Mode is active. Toggle Focus Mode off to use the Outline.


    Focus Mode

    Focus Mode reduces visual distractions by hiding the Outline panel and reducing surrounding chrome.

    Toggle Focus Mode

    • Menu: View → Focus Mode
    • Shortcut: Ctrl + Alt + F

    What Changes in Focus Mode

    ElementState
    Outline panelHidden
    Status bar paddingReduced
    Surrounding UISimplified

    Focus Mode is ideal for extended writing sessions where you want minimal context-switching.

    Exit Focus Mode

    Press Ctrl + Alt + F again or use View → Focus Mode to toggle off.


    Tips

    Combining with Split Mode

    For maximum productivity, combine Split mode (editor + preview) with the Outline panel open. You can read the rendered output on the right while using the outline for navigation on the left.

    Long Notes

    If your note is long enough to need an outline, consider whether it should be split into separate notes linked with Markdown links. The graph view can help you see connections between notes.

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("editor/focus-mode.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const focusMode = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + focusMode as default +}; diff --git a/docs-site/.vitepress/.temp/editor_index.md.js b/docs-site/.vitepress/.temp/editor_index.md.js new file mode 100644 index 00000000..bf36940b --- /dev/null +++ b/docs-site/.vitepress/.temp/editor_index.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Editor Overview","description":"Learn the edit modes, status bar, breadcrumbs, and copy/export actions in the Notely editor.","frontmatter":{"title":"Editor Overview","description":"Learn the edit modes, status bar, breadcrumbs, and copy/export actions in the Notely editor.","keywords":"editor, edit mode, split view, preview, status bar, breadcrumbs, word count","category":"Editor"},"headers":[],"relativePath":"editor/index.md","filePath":"editor/index.md","lastUpdated":1784865427000}'); +const _sfc_main = { name: "editor/index.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Editor Overview

    The Notely editor is the primary workspace for writing and reviewing Markdown notes. It supports four view modes, a rich toolbar, real-time validation, and statistics.

    View Modes

    Switch modes using the mode buttons in the editor header bar.

    ModeDescription
    EditRaw Markdown source editor with syntax highlighting and completions
    SplitEditor on the left, live rendered preview on the right
    PreviewFull-width read-only rendered output
    WebWebsite-style rendering — higher-fidelity preview with full media support

    Split Mode for Writing

    Split mode is the most productive mode for writing. You can edit Markdown on the left while watching the formatted output update in real time on the right.

    Status Bar

    The status bar at the bottom of the editor shows live document statistics:

    StatDescription
    Word countLive count of words in the current content
    Line countTotal lines in the document
    Reading timeEstimated reading time (calculated at 200 wpm)

    Statistics update independently when switching between Edit and other modes.

    The breadcrumb trail in the editor header shows the full folder path to the current note.

    • Click any breadcrumb segment to navigate to that folder.
    • Updates automatically when you switch notes.
    • Useful when working in deeply nested folder structures.

    Copy and Export Actions

    From the editor toolbar you can export note content without leaving the app:

    ActionOutput
    Copy as HTMLFormatted HTML — paste into email clients, Notion, or CMS systems
    Copy as Plain TextPlain text without Markdown syntax

    Both actions show a success notification and copy to the clipboard.

    Right-click any note tab or document list item to select Copy Link Path. This copies a workspace-relative reference link to your clipboard, making it easy to link documents together.

    When viewing notes in Preview or Split modes, hovering over any note link displays a transient popup with two actions:

    • Copy: Copy the link target path to your clipboard.
    • Navigate: Open and jump to the linked note.

    To prevent accidental navigation jumps, clicking a link directly in the preview pane is disabled.

    Validation Indicators

    Notely checks your Markdown as you write:

    • Markdown validation — flags structural issues (unclosed tables, bad heading levels, etc.)
    • Typo checking — underlines suspected spelling errors in prose (skips code blocks). Right-click any flagged word to ignore it or add it to your custom spelling dictionary.
    • Custom spelling dictionary — manage custom spelling dictionary words via the settings menu or the command palette (under "Manage Spelling Dictionary").

    When issues are found, a badge appears in the editor header. Click it to jump to the first problem.

    Typo and Validation Settings

    Tab Context Menu

    Right-click any note tab at the top of the editor pane to access tab actions:

    • Close Actions: Close Tab, Close Other Tabs, Close Tabs to the Right, Close Saved Tabs, Close All Tabs.
    • Reload from Disk: Force-reload the selected note from disk, discarding unsaved memory buffers.
    • System Actions: Open in VS Code, Reveal in File Explorer.
    • Personalization & Linking: Set Icon & Color, Copy Link Path.

    External Disk Change Detection

    If an open note is modified externally on disk by another tool, Notely automatically:

    1. Detects the external file change.
    2. Temporarily disables autosave to prevent overwriting external updates.
    3. Displays a warning banner with a Reload content from disk button.

    Click Reload content from disk, press Ctrl + Shift + R, or right-click the tab and choose Reload from Disk to load the updated content.

    Keyboard Shortcuts

    ActionShortcut
    New NoteCtrl + N
    Reload Current Note from DiskCtrl + Shift + R
    Reload Workspace from DiskCtrl + Alt + R
    Find in noteCtrl + F
    Find and ReplaceCtrl + H
    Show OutlineCtrl + Alt + L
    Focus ModeCtrl + Alt + F
    Version HistoryCtrl + Shift + H
    Screen CaptureCtrl + Shift + S
    Switch to Next TabCtrl + Tab
    Switch to Previous TabCtrl + Shift + Tab

    Full Keyboard Shortcuts

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("editor/index.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + index as default +}; diff --git a/docs-site/.vitepress/.temp/editor_markdown-guide.md.js b/docs-site/.vitepress/.temp/editor_markdown-guide.md.js new file mode 100644 index 00000000..96371751 --- /dev/null +++ b/docs-site/.vitepress/.temp/editor_markdown-guide.md.js @@ -0,0 +1,81 @@ +import { resolveComponent, useSSRContext } from "vue"; +import { ssrRenderAttrs, ssrRenderStyle, ssrRenderComponent } from "vue/server-renderer"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Markdown Guide","description":"Complete Markdown syntax reference for Notely — headings, lists, links, images, tables, code, tasks, and more.","frontmatter":{"title":"Markdown Guide","description":"Complete Markdown syntax reference for Notely — headings, lists, links, images, tables, code, tasks, and more.","keywords":"markdown, syntax, headings, lists, links, images, tables, code blocks, task lists, footnotes, GFM","category":"Editor","difficulty":"Beginner"},"headers":[],"relativePath":"editor/markdown-guide.md","filePath":"editor/markdown-guide.md","lastUpdated":1786041359000}'); +const _sfc_main = { name: "editor/markdown-guide.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + const _component_Info = resolveComponent("Info"); + _push(`

    Markdown Guide

    Notely renders GitHub Flavored Markdown (GFM). This page covers the complete syntax supported by the editor.

    Headings

    markdown
    # Heading 1
    +## Heading 2
    +### Heading 3
    +#### Heading 4
    +##### Heading 5
    +###### Heading 6

    Heading Hierarchy

    Use a single # H1 per note (the note title). Start sections at ## H2. Screen readers and the Outline panel use heading structure to navigate.

    Text Formatting

    FormatSyntaxResult
    Bold**bold** or __bold__bold
    Italic*italic* or _italic_italic
    Bold + Italic***both***both
    Strikethrough~~strike~~strike
    Inline code\`code\`code

    Paragraphs and Line Breaks

    Leave a blank line between paragraphs:

    markdown
    First paragraph.
    +
    +Second paragraph.

    For a line break without a new paragraph, add two spaces at the end of the line or use \\:

    markdown
    Line one  
    +Line two

    Lists

    Unordered

    markdown
    - Item one
    +- Item two
    +  - Nested item
    +  - Another nested item
    +- Item three

    Ordered

    markdown
    1. First step
    +2. Second step
    +3. Third step

    Task Lists

    markdown
    - [ ] Open task
    +- [x] Completed task
    +- [ ] Another open task

    Rendered task checkboxes are interactive in Preview mode — click to toggle state (changes are written back to the Markdown source).

    markdown
    [Link text](https://example.com)
    +[Link with title](https://example.com "Hover title")
    +[Relative link to another note](./other-note.md)

    Images

    markdown
    ![Alt text](./assets/screenshot.png)
    +![Alt text](./assets/screenshot.png "Optional title")

    Use the toolbar Image button to pick a file from your workspace — Notely handles the path automatically.

    Blockquotes & Callouts

    markdown
    > This is a standard blockquote.
    +> 
    +> It can span multiple paragraphs.

    GitHub-Style Callouts (Admonitions)

    Notely supports GitHub-style rich callout boxes using blockquote syntax:

    markdown
    > [!NOTE]
    +> Informational note or context.
    +
    +> [!WARNING]
    +> Warning or caution message.
    +
    +> [!TIP]
    +> Helpful tip or shortcut suggestion.
    +
    +> [!TODO]
    +> Action item or pending task.
    +
    +> [!IMPORTANT]
    +> Important highlight or priority notice.
    +
    +> [!CAUTION]
    +> High-risk action or warning.

    Custom titles can also be appended to the first line:

    markdown
    > [!NOTE] Custom Title Header
    +> Callout body content goes here.

    Quick Insert via Slash Menu

    Type / anywhere in the editor to open the Notion-style Slash Commands menu, or hover/click the Callout icon (`); + _push(ssrRenderComponent(_component_Info, { size: "{16}" }, null, _parent)); + _push(`) in the Markdown toolbar.

    Code Blocks

    Fenced code blocks with syntax highlighting:

    markdown
    \`\`\`javascript
    +function greet(name) {
    +  return \`Hello, \${name}!\`;
    +}
    +\`\`\`

    Supported languages include: js, ts, jsx, tsx, python, rust, go, sql, bash, css, html, json, yaml, markdown, and many more.

    Code Blocks — full guide

    Tables

    markdown
    | Column A | Column B | Column C |
    +|---|---|---|
    +| Row 1 | Data | Data |
    +| Row 2 | Data | Data |

    Column alignment:

    markdown
    | Left | Center | Right |
    +|:---|:---:|---:|
    +| left | center | right |

    Inline Table Editor

    Click inside any table in the editor to open the inline table editor overlay for a spreadsheet-style editing experience.

    Tables — full guide

    Horizontal Rules

    markdown
    ---

    or

    markdown
    ***

    Footnotes

    markdown
    This is a sentence with a footnote.[^1]
    +
    +[^1]: Here is the footnote text.

    HTML

    Notely renders inline HTML in Preview mode when safe HTML is enabled. Use sparingly.

    markdown
    <details>
    +<summary>Click to expand</summary>
    +Hidden content here.
    +</details>

    Escape Characters

    Prefix any Markdown character with a backslash to render it literally:

    markdown
    \\# Not a heading
    +\\*Not italic\\*
    +\\\`Not code\\\`

    Mermaid Diagrams

    Embed flowcharts, sequence diagrams, Gantt charts, and more:

    markdown
    \`\`\`mermaid
    +graph TD
    +    A[Start] --> B[Write notes]
    +    B --> C[Commit to Git]
    +    C --> D[Done]
    +\`\`\`

    Diagrams — full guide

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("editor/markdown-guide.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const markdownGuide = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + markdownGuide as default +}; diff --git a/docs-site/.vitepress/.temp/editor_markdown-toolbar.md.js b/docs-site/.vitepress/.temp/editor_markdown-toolbar.md.js new file mode 100644 index 00000000..d6b3ae32 --- /dev/null +++ b/docs-site/.vitepress/.temp/editor_markdown-toolbar.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Markdown Toolbar Reference","description":"Every toolbar button in the Notely editor explained with keyboard shortcuts and usage notes.","frontmatter":{"title":"Markdown Toolbar Reference","description":"Every toolbar button in the Notely editor explained with keyboard shortcuts and usage notes.","keywords":"toolbar, markdown toolbar, shortcuts, headings, bold, italic, link, image, table, diagram","category":"Editor"},"headers":[],"relativePath":"editor/markdown-toolbar.md","filePath":"editor/markdown-toolbar.md","lastUpdated":1786041359000}'); +const _sfc_main = { name: "editor/markdown-toolbar.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Toolbar Reference

    The Markdown toolbar sits above the editor and provides quick-insert actions for common Markdown elements.

    Formatting Buttons

    ButtonInsertsNotes
    H1H6Heading at cursor levelWraps selection in heading if text is selected
    B**bold**Wraps selection
    I*italic*Wraps selection
    ~~~~strikethrough~~Wraps selection
    \`\`inline code\`Wraps selection
    "> blockquotePrepends to current line
    Info (Callout)Insert Callout BoxOpens hover/click picker (Note, Warning, Tip, Todo, Important, Caution)
    /Slash Menu TriggerType / in editor to trigger Notion-style command menu

    Insert Buttons

    ButtonActionNotes
    LinkInsert [text](url) templateCursor lands on url
    ImageOpen file picker → insert imageUses workspace-relative path
    TableInsert 3×3 table skeletonOpens inline table editor on click
    Ordered listInsert 1. list item
    Unordered listInsert - list item
    TaskInsert - [ ] task
    HRInsert ---

    Diagram Buttons

    ButtonAction
    MermaidInsert fenced Mermaid block
    ExcalidrawInsert Excalidraw diagram block

    Validation and Quality

    ButtonAction
    ValidateRun Markdown validation on the current note
    FormatAuto-format the focused code block using Prettier

    Capture Button (Windows)

    ButtonActionNotes
    📷 ACapture screen area — Auto Insert modeA = Auto Insert
    📷 RCapture screen area — Review Before Insert modeR = Review mode

    The mode badge (A or R) reflects the current setting from Settings → Screen Capture.

    Screen Capture guide

    View Mode Controls

    The mode buttons in the editor header bar (not the toolbar) control which view is shown:

    ButtonMode
    EditRaw Markdown editor
    SplitEditor + live preview
    PreviewRendered output only
    WebWebsite-style rendering

    Tips

    Keyboard Over Mouse

    Most toolbar actions have keyboard alternatives. Open Help → Keyboard Shortcuts (Ctrl + /) for the full list.

    Wrapping Selections

    Most formatting buttons (bold, italic, link, code) wrap the current text selection if one exists. Select text first for faster formatting.

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("editor/markdown-toolbar.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const markdownToolbar = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + markdownToolbar as default +}; diff --git a/docs-site/.vitepress/.temp/editor_tables.md.js b/docs-site/.vitepress/.temp/editor_tables.md.js new file mode 100644 index 00000000..fd58b126 --- /dev/null +++ b/docs-site/.vitepress/.temp/editor_tables.md.js @@ -0,0 +1,23 @@ +import { ssrRenderAttrs, ssrRenderStyle } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Tables","description":"Create and edit Markdown tables using the inline table editor with row/column controls and alignment settings.","frontmatter":{"title":"Tables","description":"Create and edit Markdown tables using the inline table editor with row/column controls and alignment settings.","keywords":"tables, markdown table, inline table editor, columns, rows, alignment","category":"Editor"},"headers":[],"relativePath":"editor/tables.md","filePath":"editor/tables.md","lastUpdated":1786254063000}'); +const _sfc_main = { name: "editor/tables.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Tables

    Notely includes an inline table editor that lets you edit Markdown tables in a spreadsheet-style grid without touching the raw Markdown syntax.

    Create a Table

    Option 1 — Toolbar:

    1. Click the Table button in the editor toolbar.
    2. A basic table skeleton is inserted at the cursor.

    Option 2 — Type Markdown directly:

    markdown
    | Header A | Header B | Header C |
    +|---|---|---|
    +| Cell 1 | Cell 2 | Cell 3 |
    +| Cell 4 | Cell 5 | Cell 6 |

    Open the Inline Table Editor

    When your cursor is inside a Markdown table in Edit mode, the inline table editor opens automatically as an overlay panel.

    Toggle Table Editor in View Menu

    You can enable or disable the Visual Table Editor modal at any time from the View ▾ dropdown menu on the editor toolbar. When disabled, tables can be edited directly as raw Markdown text.

    The table editor shows:

    • Header cells — editable in the top row
    • Data cells — editable in a grid layout
    • Action chips — row and column controls
    • Alignment controls — per-column alignment buttons in the header
    • Maximize / Restore — expand table editor to full screen for large tables

    Edit Cells

    Click any cell in the grid to edit its content. Standard text editing applies — no Markdown needed inside cells.

    Pipe Characters in Cells

    If you need a literal | character inside a cell, use the escaped form \\|. This is handled automatically by the table editor.

    Paste Excel & Web Tables Directly

    You can copy tables directly from Microsoft Excel, Word, or web pages and paste them (Ctrl+V) straight into the editor. Notely automatically converts HTML tabular markup into clean, formatted Markdown table syntax at your cursor.

    Add and Remove Rows

    Use the action chips below the grid:

    ActionResult
    + RowAdds a new row at the bottom
    - RowRemoves the last row
    + ColAdds a column at the right
    - ColRemoves the rightmost column

    After adding or removing rows/columns, the table editor stays active so you can continue editing.

    Column Alignment

    Each header cell has an alignment control:

    ButtonAlignment
    L (left arrow)Left-align the column (default)
    C (center)Center-align the column
    R (right arrow)Right-align the column

    Alignment is written as Markdown column separators:

    markdown
    | Left | Center | Right |
    +|:---|:---:|---:|

    Save and Cancel

    ControlShortcutAction
    Save TableCtrl + EnterWrites the edited table back to Markdown source
    CancelEscDiscards changes and closes the editor
    ClearClears all data cells in the grid

    Background Scroll Lock

    While the table editor is open, background page scrolling is locked. The table content panel has its own scroll when the table is large. This prevents accidental position changes while editing.

    Formatting Preservation

    When you edit a table that already exists in your note, Notely preserves the original Markdown formatting style (column spacing and delimiter style) where the table shape hasn't changed.

    Export Table as Image or CSV

    In Preview mode and Split View, hovering over any rendered Markdown table displays the action bar with direct 1-click export buttons:

    ActionIconResult
    Edit✏️Opens the inline visual table editor modal
    Download Image🖼️Exports the table as a high-resolution, unclipped PNG image with white background and clean padding
    Download CSV📄Exports raw tabular data as a clean UTF-8 encoded .csv file

    Exported tables are saved directly to your system Downloads folder and automatically logged in the Downloads & Export History Manager.

    Tips

    Large Tables & Full Screen Mode

    For very large tables, click the Maximize icon in the table editor header to expand the grid to full window size. Use the header controls to keep column alignment buttons in view.

    Escaped Paths

    Windows file paths (e.g. C:\\Users\\name) are handled safely — backslashes are preserved correctly in cell content.

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("editor/tables.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const tables = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + tables as default +}; diff --git a/docs-site/.vitepress/.temp/export-import.md.js b/docs-site/.vitepress/.temp/export-import.md.js new file mode 100644 index 00000000..0d0981cb --- /dev/null +++ b/docs-site/.vitepress/.temp/export-import.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Export / Import Note Package","description":"","frontmatter":{},"headers":[],"relativePath":"export-import.md","filePath":"export-import.md","lastUpdated":1784345507000}'); +const _sfc_main = { name: "export-import.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Export / Import Note Package

    Notely can package one or more notes — together with all their linked assets — into a single portable .note file that can be shared with other Notely users and imported directly into any workspace.

    Opening the dialog

    Go to File → Export / Import Note Package (or use the app menu from the landing screen).

    The dialog has two tabs:

    TabPurpose
    Export PackageBundle selected notes into a .note file
    Import PackageUnpack a .note file into the current workspace

    Exporting

    1. Select notes — the list shows every .md file in the current workspace. Use Select All / Deselect All or click individual rows. The list scrolls when the workspace is large.
    2. Save location — defaults to the last-used export path with the filename {workspaceName}.note. Click Browse to choose a different destination.
    3. Password (Optional) — set a password to restrict who can import the package. If set, a salted SHA-256 hash of the password is saved securely inside the encrypted metadata.
    4. Click Export Package.

    What gets bundled

    Asset typeWhere it livesIncluded
    Markdown filesanywhere in the workspace
    Images / screenshotsmedia/images/
    Excalidraw diagrams.notes-app/excali-diagrams/
    Draw.io diagrams + thumbnailsmedia/draw.io/
    Package metadatametadata.json inside bundle✅ auto-generated

    Assets that are locked, missing, or inaccessible at export time are silently skipped; the note itself is still exported.

    Security

    • The bundle is AES-256 encrypted using a shared app-level key so it is not readable by generic ZIP tools.
    • Every file in the bundle is SHA-256 hashed and the hashes are stored in metadata.json. On import, Notely verifies each hash and rejects tampered packages.
    • If protected by a password, the manifest contains a salted SHA-256 password signature. Unlocking verification occurs securely in memory during the import sequence before files are written.

    Importing

    1. Switch to the Import Package tab.
    2. Click Browse and pick a .note file.
    3. Click Import Package.
    4. Password Prompts: If the package is password-protected, the app will display a password field. Enter the correct password and click Import Package again to proceed.

    Notely will:

    • Decrypt and verify the integrity of the bundle.
    • Authenticate the password if password protection was configured.
    • Copy notes into the workspace root (or appropriate subfolder).
    • Restore all media assets to their original relative paths.
    • Resolve filename collisions automatically so existing files are never overwritten.
    • Reload the workspace document list so imported notes appear immediately.

    Troubleshooting

    SymptomLikely causeFix
    "Export failed: EPERM"Destination folder is inside an OneDrive-synced path being actively syncedWait a moment and retry, or choose a local (non-OneDrive) folder
    "Import failed: integrity check"The .note file was modified or corrupted in transitRequest a fresh export from the sender
    "Incorrect password" or prompt staysThe password supplied does not match the package hashConfirm the password with the package creator
    Notes appear in workspace root instead of a subfolderPackage was exported from a flat workspaceExpected — the import mirrors the original layout
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("export-import.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const exportImport = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + exportImport as default +}; diff --git a/docs-site/.vitepress/.temp/export-reference.md.js b/docs-site/.vitepress/.temp/export-reference.md.js new file mode 100644 index 00000000..a75686db --- /dev/null +++ b/docs-site/.vitepress/.temp/export-reference.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Export & Import Reference","description":"Complete reference for all Notely export and import features — workspace exports, PDF/HTML rendering, note packages, and workspace bundles.","frontmatter":{"title":"Export & Import Reference","description":"Complete reference for all Notely export and import features — workspace exports, PDF/HTML rendering, note packages, and workspace bundles.","keywords":"export, import, PDF, HTML, workspace, note package, zip, AES-256","category":"User Guide"},"headers":[],"relativePath":"export-reference.md","filePath":"export-reference.md","lastUpdated":1786254063000}'); +const _sfc_main = { name: "export-reference.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Export & Import Reference

    Notely provides three distinct export systems depending on the scope and format needed:

    SystemScopeFormatWhere to find
    Single Note ExportOne notePDF, HTMLFile menu or Toolbar button
    Workspace ExportEntire workspace.zip (Raw, PDF, or Web)File → Export Workspace
    Note PackageSelected notes + assets.note (encrypted bundle)File → Export / Import Note Package

    1. Single Note Export (PDF & HTML)

    Exports the currently active markdown note as a standalone rendered document.

    PDF Export

    • Renders the note through a Headless Chromium window with the active Notely theme CSS applied.
    • Local media resolved: Embedded images and diagrams are referenced via their absolute file:// paths before rendering.
    • Mermaid diagrams and LaTeX equations are rendered as vector SVG and KaTeX HTML inside the PDF.
    • Output path defaults directly to your system Downloads folder (~/Downloads).
    • PDF write failures (EPERM, EBUSY on OneDrive paths) are automatically retried up to 3 times with increasing delays (120ms → 320ms → 700ms).

    HTML Export

    • Produces a self-contained HTML file with inline CSS and resolved media references.
    • Suitable for publishing notes to static web servers or opening in any browser without Notely.

    Block-Level Exports (Tables & Diagrams)

    • Table Image Export (Download Image): Exports any rendered table as a high-resolution, unclipped PNG image with clean padding and solid background styling via ExportManager.
    • Table CSV Export (Download CSV): Exports raw markdown table rows and columns as a clean UTF-8 encoded .csv file with a byte order mark (\\uFEFF) for immediate compatibility with Excel and spreadsheet tools.
    • Mermaid Diagram Export (Download): Converts rendered Mermaid SVG diagrams into high-resolution PNG image files via ExportManager.

    2. Downloads & Export History Manager

    Access via top Workspace → Downloads & Export History menu item or press Ctrl/Cmd + J.

    Notely automatically tracks and logs all file exports and diagram renders to a local workspace database (.notes-app/export-history.db).

    Features & Capabilities

    • Unified Tracking: Tracks PDF exports, .note packages, workspace .zip archives, Excalidraw diagrams, Draw.io diagrams, and exported media files.
    • Category Tabs: Filter by All, Documents, Diagrams, or Media with live item count badges.
    • Instant Actions:
      • Show in Folder: Reveals the exported file directly in OS File Explorer (Windows) or Finder (macOS).
      • Open: Launches the file in its default system application.
      • Downloads Folder: Direct shortcut button to open your system Downloads directory.
    • Live File Status: Automatically detects if an exported file has been moved or deleted from disk.
    • SQLite Persistence: Stored per-workspace in {workspace}/.notes-app/export-history.db using Node's native DatabaseSync (node:sqlite). Reconnects dynamically on workspace switching.

    2. Workspace Export (Full ZIP Bundle)

    Exports the entire active workspace as a .zip archive. Accessed via File → Export Workspace.

    Export Modes

    ModeWhat is exported
    Raw Docs (raw)Plain .md files as-is, preserving original workspace folder structure
    PDF (pdf)Each note rendered to a themed PDF file inside the archive
    Web / HTML (web)Each note rendered to a standalone HTML page

    Content Modes (for PDF & Web)

    Content ModeBehaviour
    CombinedRaw notes and cleansed/structured content merged into one file per note
    SeparateRaw and Cleansed versions saved as separate files per note
    Raw OnlyOnly raw markdown source content
    Cleansed OnlyOnly the structured/processed note content

    Archive Structure

    • The ZIP root folder is named after the workspace (sanitized): {workspaceName}_docs_DD_MM_YYYY.zip.
    • Hidden subsystem directories (.notes-app/, .git/) are excluded from all workspace exports.
    • A progress event stream (workspace-export:progress) reports real-time file count progress to the UI.

    3. Note Package Export & Import (.note Bundle)

    For sharing specific notes between Notely users. Accessed via File → Export / Import Note Package.

    Exporting a Package

    1. Select notes — choose any .md files from the current workspace.
    2. Save location — defaults to {workspaceName}.note. Click Browse to choose a different path.
    3. Password (Optional) — restricts import. Stores a salted SHA-256 password hash in the bundle manifest.
    4. Click Export Package.

    What gets bundled:

    AssetSource PathIncluded
    Markdown notes{workspace}/**/*.md
    Images / screenshotsmedia/images/
    Excalidraw diagrams.notes-app/excali-diagrams/
    Draw.io diagrams + thumbnailsmedia/draw.io/
    Package metadata manifestmetadata.json inside bundle✅ auto-generated

    Assets that are locked, missing, or inaccessible at export time are silently skipped — the note is still exported.

    Security

    • AES-256 encrypted bundle — not readable by generic ZIP tools.
    • Every file in the bundle is SHA-256 hashed and the hashes are verified on import. Tampered packages are rejected.
    • Password protection stores a salted SHA-256 signature in the manifest. The password is verified in memory before any files are written.

    Importing a Package

    1. Switch to the Import Package tab.
    2. Click Browse and select a .note file.
    3. Click Import Package.
    4. Enter the password if prompted.

    Notely will:

    • Decrypt and verify bundle integrity.
    • Authenticate the password against the manifest signature.
    • Copy notes into the workspace root (or appropriate subfolder).
    • Restore all media assets to their original relative paths.
    • Resolve filename collisions automatically — existing files are never overwritten.
    • Reload the workspace document list so imported notes appear immediately.

    Troubleshooting

    SymptomLikely CauseFix
    "Export failed: EPERM"Destination inside an actively syncing OneDrive pathWait a moment and retry, or choose a local (non-OneDrive) folder
    "Import failed: integrity check".note file was modified or corrupted in transitRequest a fresh export from the sender
    "Incorrect password"Password doesn't match package hashConfirm password with the package creator
    Notes appear in workspace rootPackage was exported from a flat workspaceExpected — import mirrors the original layout
    PDF looks wrong on exportNote uses unsupported CSS or external fontsUse built-in Notely themes; avoid @import of remote fonts
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("export-reference.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const exportReference = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + exportReference as default +}; diff --git a/docs-site/.vitepress/.temp/faq.md.js b/docs-site/.vitepress/.temp/faq.md.js new file mode 100644 index 00000000..6dc5c887 --- /dev/null +++ b/docs-site/.vitepress/.temp/faq.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"FAQ","description":"","frontmatter":{},"headers":[],"relativePath":"faq.md","filePath":"faq.md","lastUpdated":1783076990000}'); +const _sfc_main = { name: "faq.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    FAQ

    What is a workspace in Notely?

    A workspace is the folder you open with File -> Open Workspace. It holds your notes, files, and Notely's support data for that set of notes.

    Where does Notely store my data?

    Your notes stay in the workspace folder you choose.

    Notely also keeps a .notes-app/ folder there for note history and other support data.

    Some app-wide preferences, like recent workspaces and theme choice, are stored separately by the app.

    Does Notely work offline?

    Yes for core note-taking features.

    You can create notes, edit them, preview them, manage media, review history, use the terminal, and export workspaces offline.

    Which features require internet?

    AI features need internet access and a working account or key for the service you chose.

    Device-to-device sync usually only needs both devices to reach each other on the same network.

    What is .notes-app?

    .notes-app is Notely's own support folder for things like note history, image notes, and other behind-the-scenes app data.

    Should .notes-app be committed to Git?

    Usually no.

    If your workspace is a Git folder, Notely can help keep .notes-app/ out of version control so private app files do not end up in project history.

    Can I restore deleted or changed notes?

    Yes.

    Use File -> Versions to inspect and restore earlier versions of a note. Notes and folders moved out of the main workspace flow are also handled by Notely's removed-folder flow.

    How do I reopen a workspace quickly?

    Use File -> Open Recent or the command palette entry for recent workspaces.

    Does Notely have a plugin system?

    Not currently. The app does not expose a user plugin or extension mechanism.

    What happens if I configure AI?

    AI requests only run when you use an AI feature. They go to the service you set up in AI -> AI Settings.

    The app keeps its AI working data on your device unless you explicitly move or export it.

    What is the easiest way to learn shortcuts?

    Open Help -> Keyboard Shortcuts (Ctrl/Cmd + /). The in-app guide lists current global, editor, landing, and preview shortcuts.

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("faq.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const faq = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + faq as default +}; diff --git a/docs-site/.vitepress/.temp/feature-availability.md.js b/docs-site/.vitepress/.temp/feature-availability.md.js new file mode 100644 index 00000000..081399af --- /dev/null +++ b/docs-site/.vitepress/.temp/feature-availability.md.js @@ -0,0 +1,42 @@ +import { resolveComponent, useSSRContext } from "vue"; +import { ssrRenderAttrs, ssrRenderComponent } from "vue/server-renderer"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Feature Availability Matrix","description":"View offline compatibility and network requirements for Notely features.","frontmatter":{"title":"Feature Availability Matrix","description":"View offline compatibility and network requirements for Notely features.","keywords":"internet required, offline support, offline setup, capabilities","category":"Reference"},"headers":[],"relativePath":"feature-availability.md","filePath":"feature-availability.md","lastUpdated":1783855203000}'); +const _sfc_main = { name: "feature-availability.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + const _component_FeatureMatrix = resolveComponent("FeatureMatrix"); + _push(`

    Feature Availability

    The matrix below details which features run entirely offline, which require local network settings, and which require internet access.

    `); + _push(ssrRenderComponent(_component_FeatureMatrix, { features: [ + { feature: "Notes Create/Edit", available: true, setup: "No", internet: false }, + { feature: "Folder Organization", available: true, setup: "No", internet: false }, + { feature: "Edit/Split/Preview Modes", available: true, setup: "No", internet: false }, + { feature: "Markdown Validation", available: true, setup: "No", internet: false }, + { feature: "Typo Checking", available: true, setup: "No", internet: false }, + { feature: "Global Search", available: true, setup: "No", internet: false }, + { feature: "Help Center", available: true, setup: "No", internet: false }, + { feature: "Tasks Dashboard", available: true, setup: "No", internet: false }, + { feature: "Version History (Git)", available: true, setup: "No", internet: false }, + { feature: "Media Library", available: true, setup: "No", internet: false }, + { feature: "Embedded Terminal", available: true, setup: "No", internet: false }, + { feature: "Screen Capture (Windows)", available: true, setup: "No", internet: false }, + { feature: "Mermaid Diagrams", available: true, setup: "No", internet: false }, + { feature: "Excalidraw Diagrams", available: true, setup: "No", internet: false }, + { feature: "Workspace Graph", available: true, setup: "No", internet: false }, + { feature: "Sync with other devices", available: false, setup: "Pair Trusted Devices", internet: "Local network" }, + { feature: "AI Chat & Rewriting", available: false, setup: "Setup AI Provider", internet: true }, + { feature: "Meaning-based Search", available: false, setup: "Setup AI Provider", internet: true }, + { feature: "Graph Clustering", available: false, setup: "Setup AI Provider", internet: true } + ] }, null, _parent)); + _push(``); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("feature-availability.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const featureAvailability = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + featureAvailability as default +}; diff --git a/docs-site/.vitepress/.temp/feature-reference.md.js b/docs-site/.vitepress/.temp/feature-reference.md.js new file mode 100644 index 00000000..6fbbb787 --- /dev/null +++ b/docs-site/.vitepress/.temp/feature-reference.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Notely Feature Reference","description":"","frontmatter":{},"headers":[],"relativePath":"feature-reference.md","filePath":"feature-reference.md","lastUpdated":1786126353000}'); +const _sfc_main = { name: "feature-reference.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Notely Feature Reference

    This page explains every major user-facing feature in Notely.

    1. Notes and Workspace

    Workspace selection

    Use File -> Open Workspace to choose the folder where your notes are stored.

    Use File -> Open Recent to reopen a recently used workspace quickly.

    Opening the workspace externally

    On the landing screen, the File menu exposes two shortcuts for working with the workspace folder outside Notely:

    • File -> Open Workspace in VS Code (Ctrl/Cmd + Shift + O) — opens the active workspace folder directly in VS Code. Falls back to the system default app if VS Code is not installed.
    • File -> Reveal Workspace in File Explorer (Ctrl/Cmd + Shift + J) — opens the workspace folder in the native system file browser.

    Opening the website view

    The Web menu provides quick access to the rendered website output:

    • Web -> Open Current Note Website View (Ctrl/Cmd + Shift + W) — available when a note is open; renders the current note as a website preview in the default browser.
    • Web -> Open Project Website (Ctrl/Cmd + Shift + W) — available on the landing screen; opens the project website.

    Project-aware workspace

    You can keep notes grouped by project while still working inside one larger workspace.

    Landing dashboard

    The landing view includes lightweight workspace overview panels so you can resume work quickly:

    • Continue Writing shows the single most recently edited note so you can resume immediately.
    • Recent Notes shows recently changed documents.
    • Favorites collects starred notes.
    • Open Tasks surfaces unchecked tasks across the workspace.

    Note and folder creation

    • Create notes from File -> New Note (Ctrl/Cmd + N).
    • Create folders to group related notes.
    • Customize the icon and color of any folder or note by right-clicking it and selecting "Customize icon & color..." or from the context menu in the open tabs.
    • Rename and delete notes from list actions.

    Trash Recovery Bin

    When folders or notes are deleted, they are moved to a temporary Trash Bin instead of being permanently erased immediately. The Trash Bin recovery drawer (Trash quick action on the landing view) supports:

    • Browsing deleted files and folders with their deletion timestamps.
    • Restoring items back to their original paths.
    • Permanently emptying the trash bin to free up disk space.

    2. Editor and Writing Experience

    Multiple edit modes

    • Edit: write markdown source.
    • Split: source and preview side-by-side.
    • Preview: read-only rendered output.
    • Web Preview: richer rendering for selected notes.

    Markdown toolbar

    Quick insert actions for headings, emphasis, lists, links, tables, diagrams, and validation.

    Inline table editor

    When the cursor is inside a markdown table, Notely opens an inline table editor overlay with focused controls:

    • Edit headers and cells in a grid view.
    • Add/remove rows and columns from contextual action chips.
    • Set per-column alignment (left, center, right) from header actions.
    • Save and cancel explicitly from compact top controls.
    • Background page scrolling is locked while editing to keep interaction scoped to the table editor.

    Code Blocks

    Notely provides a rich experience for working with code snippets:

    • Auto-detection: Paste a snippet without a language tag and Notely will automatically detect it (e.g., JavaScript, Python, HTML).
    • Auto-formatting: Use the 🪄 Format button in the preview hover toolbar or inside the editor to instantly auto-indent and format your code using Prettier.
    • Dedicated Editor: Click the ✎ Edit button on any code block in Preview mode to open a distraction-free Code Editor popup with syntax highlighting, search, and language selection.
    • Code Execution: Click the ▶ Run button in the hover toolbar or inside the popup editor to execute JavaScript (js), Python (py), Bash (sh), PowerShell (ps1), and HTML live-preview snippets locally. Output is displayed in an integrated high-contrast dark terminal output drawer (with exit status and a "Clear" button). Execution times out automatically after 10 seconds to prevent hanging. For unsupported languages, the run button is disabled with a helpful tooltip.

    Find and replace

    Search inside the current note and jump through results quickly.

    Outline navigation

    Use View -> Show Outline to jump between sections in long notes.

    Focus mode

    Use View -> Focus Mode to reduce visual distractions.

    Terminal and workspace tools

    Use View -> Show Terminal to open the embedded terminal.

    Use View -> Terminal Shell to switch between Auto, Bash, and CMD.

    Use Workspace -> Workspace Activity to review recent changes across the active workspace.

    Appearance and layout

    Notely includes view and appearance controls for different working styles:

    • Settings -> Theme: System, Light, or Dark
    • View -> Tile Notes / Table Notes: landing list layout
    • View -> Comfortable Density / Compact Density: landing list density
    • View -> Zoom In / Zoom Out / Reset Zoom: app-scale display controls

    Note statistics

    When editing a note, the status bar displays:

    • Word count: Live count of words in the active tab content (updates as you type).
    • Line count: Total number of lines in the document.
    • Reading time: Estimated reading time in minutes (calculated at 200 words per minute).

    Statistics update independently for Raw and Formal editing modes.

    Copy and export

    Export note content in different formats directly from the toolbar:

    • Copy as HTML: copies a nicely formatted version you can paste into other apps
    • Copy as Plain Text: copies the plain note text

    Both actions show success or error feedback via notifications.

    The editor displays a breadcrumb trail showing the full folder hierarchy leading to the current note:

    • Click any segment to navigate to that folder.
    • Helps you keep track of where the current note lives.
    • Updates dynamically when you switch notes.

    3. Quality and Validation

    Markdown validation

    Notely reports markdown issues while you edit.

    Typo checking & Spelling Dictionary

    Notely flags likely spelling mistakes in real-time as you write (excluding code blocks and raw markdown syntax).

    • Hunspell engine: Powered by Hunspell under the hood for accurate, high-quality dictionary checks.
    • Ignore / Add to dictionary: Right-click on a flagged spelling error in the editor to immediately ignore the word, or click Add to dictionary to add it to your custom workspace spelling dictionary.
    • Spelling Dictionary Manager: Open the command palette (Ctrl/Cmd+P) and run Manage Spelling Dictionary (or click the settings menu option) to view all custom added words, search them, remove individual words, or clear the dictionary completely.

    Quick problem fixing

    When Notely finds a problem, it shows you where it is so you can jump there quickly.

    4. Search and Discovery

    Search by note title, folder, details, and note content across the whole workspace.

    Advanced search patterns

    If you know advanced search patterns, you can turn on advanced matching in global search:

    • Click the .* button in the search bar.
    • Type your search pattern.
    • Notely checks the pattern as you type and tells you if it is invalid.
    • Results update as you type.

    Example use cases:

    • Find function definitions: function\\s+\\w+\\s*\\(
    • Find error patterns: Error: \\[[A-Z0-9_]+\\]
    • Find API routes: \\/api\\/[a-z]+
    • Find imports: import\\s+\\{[\\w\\s,]+\\}

    Limit search results to code blocks only:

    • Click the Code Blocks filter button in the search bar (appears alongside All, Notes, Folders, Current Note).
    • Search now only matches code sections inside notes.
    • Matches appear in code, not normal writing.
    • Works with or without advanced matching turned on.

    Example use case:

    • Search for TypeScript patterns only: Select "Code Blocks" filter, search for interface\\s+\\w+

    Content snippets

    Search results show match context so you can confirm relevance before opening.

    Workspace graph

    Open Workspace -> Workspace Graph to see how notes and files connect to each other.

    Graph capabilities include:

    • Visual note-to-note link mapping
    • Media node visibility (images, videos, PDFs, and more)
    • Interactive zoom, pan, and drag
    • Mini-map for large workspaces

    When AI search data is available, the graph can also group notes that are closely related.

    5. Tasks and Workflow

    Tasks overview

    Task checkboxes from your notes appear in several places:

    • Open Tasks panel: unchecked tasks (- [ ]) only.
    • All Tasks panel: open + closed tasks in one searchable list.
    • Dashboard task summaries: quick counts and drill-down from landing widgets.
    • Note-level task summary: open/closed snapshot for the current note.

    Open Tasks panel

    The Open Tasks panel collects unfinished tasks from all of your notes into one searchable list.

    Opening the Open Tasks panel

    Open the panel using the Command Palette:

    • Press Ctrl/Cmd + K to open the command palette.
    • Search for "Open Tasks Panel" (or type "tasks", "todos", "checkboxes").
    • Press Enter to open.

    Using the Open Tasks panel

    • Filter tasks: Use the search input to filter by task text or source note title.
    • View task count: The header shows the total number of open tasks.
    • Group by source: Tasks stay grouped by the note they came from.
    • Open source note: Click the "Open note" link next to any task to navigate to that note and close the panel.
    • Supported task syntax: Recognizes all markdown task formats:
      • - [ ] Task text (dash)
      • * [ ] Task text (asterisk)
      • + [ ] Task text (plus)

    All Tasks panel

    Use All Tasks when you need both open and completed work in one place.

    • Includes open ([ ]) and closed ([x]) tasks.
    • Supports quick filtering and note-grouped review.
    • Useful for status reviews, audits, and release checklists.

    Use cases

    • Track action items across project notes
    • Get a quick overview of all pending work
    • Find tasks by keyword without opening individual notes
    • Maintain accountability in team workspaces

    6. Git Version Control and History

    Native Git Repository

    Notely integrates native Git versioning to track your document history. Workspaces can be initialized as Git repositories directly from the Version Control panel.

    Compare, Restore, and Tagging

    Open Version Control -> History (Ctrl/Cmd + Shift + H) or click the History button in the note top bar to:

    • Compare commits with word-level difference highlighting.
    • Toggle between rich Markdown Preview Mode and raw Code View for line differences.
    • Restore the active note to an older revision.
    • Add tag references to commits directly from the history timeline.

    Branch, Stash, and Sync Management

    The full Version Control Page includes tabs to switch branches, create tags, push/pull changes to remote repositories, and stash unstaged changes to keep your workspace tidy.

    7. Media Management

    Image and file linking

    Add images and other files to your notes and link to them when needed.

    Media actions

    Rename, replace, annotate, and open media in default apps.

    Screen capture (Windows)

    Notely supports area-based screen capture directly from the editor.

    • Trigger capture from the toolbar screen icon or Ctrl/Cmd + Shift + S.
    • Use Windows snip overlay to select an area.
    • Insert behavior is controlled by Settings -> Screen Capture:
      • Auto Insert: captured image is inserted immediately.
      • Review Before Insert: open review editor first, then save to insert.
    • In review mode, edits are optional; you can save as-is.

    The toolbar capture icon shows current mode:

    • A = Auto Insert
    • R = Review Before Insert

    Media preview tools

    Use zoom and media-aware preview controls to inspect assets.

    Workspace Health media checks

    Notely helps detect and manage:

    • Missing linked files
    • Duplicate media
    • Unused media
    • Preview failures

    You can review where files are used and clean up unused items.

    Image annotation and lifecycle

    Image notes and markups are saved separately from the picture itself, so you can keep editing them later.

    Those notes stay in sync when you replace, rename, or remove an image.

    Original image backup and restore

    Before first edit, Notely stores an original image backup and allows restoring it later.

    This helps recover from aggressive crops or accidental edits.

    8. Diagram Features

    Mermaid diagrams

    • Insert Mermaid blocks from the toolbar.
    • Write Mermaid syntax in markdown.
    • Render in preview modes.

    Excalidraw diagrams

    • Insert Excalidraw diagrams in notes.
    • Edit visually and save.
    • Re-open diagrams from preview for updates.
    • Convert an existing note image to an Excalidraw diagram from image right-click menu (Edit with Excalidraw).
    • Converted diagrams open with the original image already placed underneath so you can trace or mark it up.
    • Excalidraw previews have their own right-click actions.
    • If the diagram started from an image, you can switch back to the original image later.

    9. AI Assistance

    AI settings

    Set up AI services and sign-in details in AI -> AI Settings.

    You can set up:

    • a writing assistant service for chat and rewriting
    • a separate service for smarter search and graph features

    AI chat and commands

    Use AI for writing support, note understanding, and quick content actions.

    Semantic features

    When AI search data is turned on, Notely can find related notes by meaning, not just exact words.

    What each AI service can do

    Not every AI service supports every feature.

    Notely shows capability warnings in settings when a selected provider cannot run a feature.

    You can also choose which AI model to use in AI settings.

    AI operation feedback

    Longer AI actions show progress and completion messages so you know something is happening.

    How recent the AI search data is

    Notely shows whether its AI search data is fresh or getting old.

    10. Peer-to-Peer Sync

    Discovery and pairing

    Pair trusted peers using invite codes from P2P -> P2P Status.

    Sync status and conflicts

    Monitor sync progress and resolve conflicts with built-in conflict tools.

    Security controls

    Trust and access controls help keep shared workspaces safer.

    11. Help and Product Info

    Documentation

    Open Help -> Help Center (F1) for in-app help.

    Keyboard shortcuts

    Open Help -> Keyboard Shortcuts (Ctrl/Cmd + /).

    About dialog

    Open Help -> About Notely to view app identity and version information.

    12. Preview and Export

    Web preview

    Use Web Preview for richer rendered note viewing with media and diagram support.

    PDF export

    Export notes to PDF using the same note preview system used inside the app.

    PDF export keeps image quality options and visible image notes where possible.

    Website-style rendering

    Website-style output is designed to look close to what you see in preview.

    Workspace zip export

    From the landing screen, choose File -> Export Workspace as Zip.

    The workspace export dialog includes:

    • Export format:
      • Notes as-is (markdown + assets)
      • PDF-only workspace bundle
      • Web format static package
    • App data toggle: include the .notes-app folder (off by default)
    • Destination: browse folder and reuse remembered location
    • Filename: default notelyproject.zip, editable before export

    This flow is intended for backups, handoff, archival snapshots, and portable workspace sharing.

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("feature-reference.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const featureReference = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + featureReference as default +}; diff --git a/docs-site/.vitepress/.temp/getting-started_first-note.md.js b/docs-site/.vitepress/.temp/getting-started_first-note.md.js new file mode 100644 index 00000000..f160bce8 --- /dev/null +++ b/docs-site/.vitepress/.temp/getting-started_first-note.md.js @@ -0,0 +1,32 @@ +import { ssrRenderAttrs, ssrRenderStyle } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Your First Note","description":"Step-by-step guide to creating, writing, and saving your first note in Notely.","frontmatter":{"title":"Your First Note","description":"Step-by-step guide to creating, writing, and saving your first note in Notely.","keywords":"create note, first note, markdown, edit, preview","category":"Getting Started","difficulty":"Beginner"},"headers":[],"relativePath":"getting-started/first-note.md","filePath":"getting-started/first-note.md","lastUpdated":1783855203000}'); +const _sfc_main = { name: "getting-started/first-note.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Your First Note

    This guide walks you through creating, writing, and previewing a note from scratch.

    Step 1 — Create a Note

    1. Press Ctrl + N (or go to File → New Note).
    2. Enter a name for your note (e.g., My First Note).
    3. Press Enter to confirm.

    The new note opens in the editor immediately.

    Naming Notes

    Notely uses the filename as the note title. Use clear, descriptive names — avoid special characters like / \\ : * ? " < > |.

    Step 2 — Write in Markdown

    The editor starts in Edit mode. Type your note content using Markdown:

    markdown
    # Meeting Notes — Project Kickoff
    +
    +## Attendees
    +- Alice
    +- Bob
    +- Carol
    +
    +## Action Items
    +- [ ] Share the meeting recording
    +- [ ] Create project timeline by Friday
    +- [x] Set up shared workspace
    +
    +## Notes
    +The project starts **Monday July 14**. First milestone is due in **3 weeks**.

    Quick Markdown Reference

    ElementSyntax
    Heading# H1, ## H2, ### H3
    Bold**bold**
    Italic*italic*
    Task- [ ] open, - [x] done
    Link[text](url)
    Code\`inline\` or \`\`\`fenced\`\`\`

    Full Markdown Guide

    Step 3 — Preview Your Note

    Switch view modes using the mode buttons in the editor header:

    ModeShortcutWhat you see
    EditRaw Markdown source
    SplitEditor + live preview side by side
    PreviewRead-only rendered output

    Try Split view while editing — it shows formatted output as you type.

    Step 4 — Use the Toolbar

    The toolbar above the editor provides quick-insert actions:

    • H1–H6 — Insert heading at cursor
    • B / I — Bold or italic selection
    • Link — Insert link template
    • Image — Pick and insert an image
    • Table — Insert a table skeleton
    • Diagram — Insert Mermaid or Excalidraw block

    Step 5 — Save

    Notely saves your notes automatically as you type. You'll see a status indicator in the note header when the file is being saved.

    Unsaved Changes

    If you close a note with unsaved changes, Notely will prompt you to confirm. Auto-save runs continuously, so this only happens if a write error occurs.

    What's Next?

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("getting-started/first-note.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const firstNote = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + firstNote as default +}; diff --git a/docs-site/.vitepress/.temp/getting-started_index.md.js b/docs-site/.vitepress/.temp/getting-started_index.md.js new file mode 100644 index 00000000..436d0354 --- /dev/null +++ b/docs-site/.vitepress/.temp/getting-started_index.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs, ssrRenderStyle } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Getting Started with Notely","description":"Install Notely, open your first workspace, and understand the key concepts in under 5 minutes.","frontmatter":{"title":"Getting Started with Notely","description":"Install Notely, open your first workspace, and understand the key concepts in under 5 minutes.","keywords":"install, setup, workspace, first launch, getting started","category":"Getting Started"},"headers":[],"relativePath":"getting-started/index.md","filePath":"getting-started/index.md","lastUpdated":1784174884000}'); +const _sfc_main = { name: "getting-started/index.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Getting Started

    Notely is a desktop Markdown notes app for Windows. Your notes live as plain .md files in a folder of your choice — no accounts required, no cloud lock-in.

    Requirements

    RequirementDetails
    PlatformWindows 10 / 11 (x64)
    Storage~120 MB for the application
    NetworkNot required for core features
    GitOptional — required only for Git features

    Download & Install

    1. Go to the latest release on GitHub.
    2. Download the portable .exe file.
    3. Run it — no installer needed.

    Portable App

    Notely is a portable executable. You can run it from any folder, including a USB drive or a synced folder.

    Release Types

    When downloading or building Notely, three package formats are available. Choose the one that fits your workflow:

    1. NSIS Installer (.exe)

    A standard Windows installer that installs Notely on your system, creates Start Menu/desktop shortcuts, and registers file associations.

    • Best for: Long-term installations on a single personal or work computer.
    • Pros: Standard user experience, clean updates, easy shortcut access.

    2. Portable Executable (.exe)

    A single self-contained application file that runs immediately without installation.

    • Best for: Quick testing, running from a USB drive, or on locked-down environments (e.g. corporate laptops) where administrator/install permissions are restricted.
    • Pros: Zero-install footprint; doesn't alter system files.

    3. ZIP Archive (.zip)

    A compressed folder containing the compiled application files and dependencies.

    • Best for: Portable configurations where you want full control over where the application files are kept, or for offline distribution.
    • Pros: Easy to inspect files directly; runs without installation.

    Cons & Limitations of Packaged Electron Applications

    Since Notely is packaged as an Electron desktop application, it inherits a few tradeoffs compared to native Windows apps or web tools:

    1. Large Package Size: The bundle includes both Chromium (browser engine) and Node.js runtime, resulting in a download size of over 100MB+ per package.
    2. Memory Footprint: Each open window launches separate helper processes for the renderer, main processor, and utility threads. This consumes more RAM compared to light text editors (like Notepad).
    3. Windows SmartScreen/Signing Warnings: Unsigned custom builds may trigger Windows Defender SmartScreen warnings on launch. Users will need to click More Info -> Run Anyway to launch the application unless it is signed with a valid Microsoft Developer Certificate.
    4. Native Bindings (e.g., node-pty): Notely compiles binary system dependencies (like the embedded terminal interface) specifically for target operating system architectures (x64). These require corresponding C++ runtimes on the host machine.

    Open Your Workspace

    A workspace is a folder on your computer where your notes live. Notely reads .md files from this folder and its subfolders.

    First launch:

    1. Open Notely.
    2. The workspace picker appears automatically.
    3. Click Open Workspace and select a folder.
    4. Notely loads your notes.

    Subsequent launches:

    Use File → Open Recent or the command palette (Ctrl + K) to reopen a recent workspace instantly.

    Key Concepts

    ConceptWhat it is
    WorkspaceA folder containing your Markdown notes
    NoteA single .md file inside the workspace
    FolderA subfolder for organizing related notes
    .notes-appA hidden folder Notely creates for note history and support data

    What to Do Next

    New to Notely?Create your first note

    Ready to write?Editor overview

    Coming from another tool?Feature Reference

    Need Git integration?Git overview

    Help at Any Time

    ShortcutAction
    F1Open Help Center (in-app)
    Ctrl + /Open Keyboard Shortcuts
    Ctrl + KOpen Command Palette
    Ctrl + Shift + FSearch all notes
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("getting-started/index.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + index as default +}; diff --git a/docs-site/.vitepress/.temp/git_branches.md.js b/docs-site/.vitepress/.temp/git_branches.md.js new file mode 100644 index 00000000..b0d0f3b2 --- /dev/null +++ b/docs-site/.vitepress/.temp/git_branches.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Branches and Remote Repositories","description":"Learn how to manage branches, stash changes, and sync with Git remotes.","frontmatter":{"title":"Branches and Remote Repositories","description":"Learn how to manage branches, stash changes, and sync with Git remotes.","keywords":"git branch, remote, push, pull, stash, origin, sync","category":"Git"},"headers":[],"relativePath":"git/branches.md","filePath":"git/branches.md","lastUpdated":1786126353000}'); +const _sfc_main = { name: "git/branches.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Branches & Remote

    For advanced collaboration, Notely supports branch switching, tag markers, and remote syncing.

    1. Branch Management

    Switch or create branches in the Branch tab of the Version Control page:

    • Select from local branches.
    • Create a new branch from your current HEAD checkpoint.
    • Switch branches to test features or review colleagues' work.

    2. Remote Synchronization (Push/Pull)

    Configure an upstream remote (like GitHub, GitLab, or a self-hosted Git server) to sync notes:

    • Pull: Fetch and merge changes from the remote repository to update your local workspace.
    • Push: Upload your local commits to the remote repository.

    Authentication uses Personal Access Tokens (PAT). When performing remote actions with a PAT, Notely temporarily injects the token into the git remote URL for the operation and immediately restores the clean original URL afterwards, keeping plain-text credentials out of persistent repository settings.


    3. Stashing Changes

    If you need to switch branches but have unstaged edits that you aren't ready to commit:

    • Click Stash Changes to save your work to a temporary shelf.
    • To recover stashed work, navigate to the Stash manager and click Apply Stash.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("git/branches.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const branches = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + branches as default +}; diff --git a/docs-site/.vitepress/.temp/git_commit.md.js b/docs-site/.vitepress/.temp/git_commit.md.js new file mode 100644 index 00000000..8563c007 --- /dev/null +++ b/docs-site/.vitepress/.temp/git_commit.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Committing and Staging Changes","description":"Learn how to stage modified notes and write commits in Notely.","frontmatter":{"title":"Committing and Staging Changes","description":"Learn how to stage modified notes and write commits in Notely.","keywords":"git commit, git stage, diff, modified files","category":"Git"},"headers":[],"relativePath":"git/commit.md","filePath":"git/commit.md","lastUpdated":1783855203000}'); +const _sfc_main = { name: "git/commit.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Commit & Stage

    To save a permanent checkpoint of your notes, you must stage and commit them.

    1. Staging Files

    When you modify or create notes, they appear under the Unstaged Changes section of the Version Control Panel:

    • Stage: Hover over a modified note and click + (Stage) to mark it ready for committing.
    • Stage All: Click the Stage All button to stage all modified files at once.
    • Discard: Click Discard to revert file changes back to their last committed state.

    2. Writing a Commit

    1. Navigate to the commit section in the Version Control Panel.
    2. Enter a clear, descriptive summary (e.g., Update markdown tables and add screenshots).
    3. Optionally add a detailed description explaining the reasoning behind the change.
    4. Click Commit.

    Once committed, these changes are logged in the local Git repository timeline.

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("git/commit.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const commit = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + commit as default +}; diff --git a/docs-site/.vitepress/.temp/git_history.md.js b/docs-site/.vitepress/.temp/git_history.md.js new file mode 100644 index 00000000..e6e2e3c3 --- /dev/null +++ b/docs-site/.vitepress/.temp/git_history.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Note History and Restores","description":"Browse historical versions of notes, compare visual diffs, and restore earlier revisions.","frontmatter":{"title":"Note History and Restores","description":"Browse historical versions of notes, compare visual diffs, and restore earlier revisions.","keywords":"history, rollback, diff viewer, git history, versions, compare","category":"Git"},"headers":[],"relativePath":"git/history.md","filePath":"git/history.md","lastUpdated":1783855203000}'); +const _sfc_main = { name: "git/history.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    History & Restore

    Notely lets you browse the full commit history of any note and compare versions side-by-side.

    1. Opening Revision History

    • Press Ctrl + Shift + H or click the History button in the note top bar.
    • The history sidebar will slide out, displaying a timeline of all commits touching the current note.

    2. Comparing Diffs

    Click on any commit in the history timeline to open the Diff Viewer:

    • Code View: Standard text-based differences, highlighting added and removed lines.
    • Markdown Preview Mode: Shows a visual, word-level comparison of the rendered document, marking insertions in green and deletions in red.

    3. Restoring Notes

    To restore the note to a previous revision:

    1. Select the target commit in the history timeline.
    2. Verify the content in the diff viewer.
    3. Click the Restore button.
    4. Notely will replace the active note contents with the selected version, placing a new restoration commit in your history.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("git/history.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const history = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + history as default +}; diff --git a/docs-site/.vitepress/.temp/git_index.md.js b/docs-site/.vitepress/.temp/git_index.md.js new file mode 100644 index 00000000..46c325c1 --- /dev/null +++ b/docs-site/.vitepress/.temp/git_index.md.js @@ -0,0 +1,34 @@ +import { resolveComponent, useSSRContext } from "vue"; +import { ssrRenderAttrs, ssrRenderSuspense, ssrRenderComponent } from "vue/server-renderer"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Git Version Control Overview","description":"Learn how Git is integrated into Notely to track history, commit changes, and restore notes.","frontmatter":{"title":"Git Version Control Overview","description":"Learn how Git is integrated into Notely to track history, commit changes, and restore notes.","keywords":"git, version control, revision history, commit, rollback","category":"Git"},"headers":[],"relativePath":"git/index.md","filePath":"git/index.md","lastUpdated":1783855203000}'); +const _sfc_main = { name: "git/index.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + const _component_Mermaid = resolveComponent("Mermaid"); + _push(`

    Git Version Control

    Notely features a native, Git-backed version control system to track document changes. Every modification can be versioned, compared, and restored without relying on external Git tools.

    `); + ssrRenderSuspense(_push, { + default: () => { + _push(ssrRenderComponent(_component_Mermaid, { + id: "mermaid-6", + class: "mermaid", + graph: "graph%20LR%0A%20%20%20%20A%5BEdit%20Note%5D%20--%3E%20B%5BStage%20Changes%5D%0A%20%20%20%20B%20--%3E%20C%5BWrite%20Commit%5D%0A%20%20%20%20C%20--%3E%20D%5BSave%20Version%5D%0A%20%20%20%20D%20--%3E%20E%5BTimeline%20History%5D%0A" + }, null, _parent)); + }, + fallback: () => { + _push(` Loading... `); + }, + _: 1 + }); + _push(`

    Why Git?

    Using Git directly under the hood ensures:

    • Portability: Your note history is stored in standard Git format, meaning you can open the folder in any Git client (like GitHub Desktop or VS Code) to view the history.
    • Precision: Fine-grained line-by-line diffs of changes.
    • Safety: Rollback individual files or entire folders to a previous point in time.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("git/index.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + index as default +}; diff --git a/docs-site/.vitepress/.temp/git_setup.md.js b/docs-site/.vitepress/.temp/git_setup.md.js new file mode 100644 index 00000000..b30aeccb --- /dev/null +++ b/docs-site/.vitepress/.temp/git_setup.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Setting Up Git in Notely","description":"Initialize a new Git repository or clone an existing one for your workspace in Notely.","frontmatter":{"title":"Setting Up Git in Notely","description":"Initialize a new Git repository or clone an existing one for your workspace in Notely.","keywords":"git init, git clone, git config, credentials, gitignore","category":"Git"},"headers":[],"relativePath":"git/setup.md","filePath":"git/setup.md","lastUpdated":1783855203000}'); +const _sfc_main = { name: "git/setup.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Git Setup & Repository

    Before tracking changes, your workspace folder must be configured as a Git repository.

    1. Initializing a Repository

    If your opened workspace folder is not currently a Git repository:

    1. Open the Version Control view or click the Git status bar badge.
    2. Select Initialize Git Repository.
    3. Notely will run git init and create a local repository structure.

    2. Cloning a Repository

    To import an existing notes repository:

    1. Open the workspace dialogue on launch.
    2. Select Clone Git Repository.
    3. Input the repository HTTPS URL and destination folder.
    4. Input credentials if the repository is private.

    3. Ignoring App Metadata (.notes-app)

    Notely stores internal editor states, annotations, and caches in the .notes-app subdirectory. It is recommended to keep this out of version control:

    • In Settings → Git Safety, enable Ignore .notes-app.
    • Notely will automatically append .notes-app/ to your workspace .gitignore file.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("git/setup.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const setup = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + setup as default +}; diff --git a/docs-site/.vitepress/.temp/index.md.js b/docs-site/.vitepress/.temp/index.md.js new file mode 100644 index 00000000..79f631e8 --- /dev/null +++ b/docs-site/.vitepress/.temp/index.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Notely — Desktop Markdown Notes","description":"Notely is a desktop Markdown notes app with Git version control, AI writing assistance, and peer-to-peer sync. Works offline. Runs on Windows.","frontmatter":{"layout":"home","title":"Notely — Desktop Markdown Notes","description":"Notely is a desktop Markdown notes app with Git version control, AI writing assistance, and peer-to-peer sync. Works offline. Runs on Windows.","hero":{"name":"Notely","text":"Write. Organize. Remember.","tagline":"A desktop Markdown notes app with Git version control, AI assistance, and offline-first sync.","image":{"src":"/assets/icon.png","alt":"Notely"},"actions":[{"theme":"brand","text":"💻 Download for Windows","link":"https://github.com/WGLabz/notely/releases/latest"},{"theme":"alt","text":"🚀 Getting Started","link":"/getting-started/"},{"theme":"alt","text":"📚 All Documentation","link":"/getting-started/"}]},"features":[{"icon":"📝","title":"Markdown Editor","details":"Edit, Split, and Preview modes. Toolbar shortcuts, inline table editor, code block formatting, Mermaid and Excalidraw diagrams."},{"icon":"🌿","title":"Git Version Control","details":"Native Git integration. Commit, browse history, compare diffs, restore notes, manage branches — all from inside the app."},{"icon":"🤖","title":"AI Writing Assistant","details":"AI chat, AI palette actions, semantic search, and relationship graph powered by your choice of AI provider."},{"icon":"🔍","title":"Powerful Search","details":"Global search across all notes with regex support, code-block filtering, and meaning-based results when AI is configured."},{"icon":"🔒","title":"Works Offline","details":"All core features work without internet. Your notes stay on your device in plain Markdown files."},{"icon":"🔄","title":"P2P Sync","details":"Sync notes across devices over your local network using encrypted peer-to-peer pairing — no cloud required."},{"icon":"📦","title":"Export / Import Note Packages","details":"Bundle notes with all linked assets into an encrypted, integrity-checked `.note` file. Share with others and import directly into any Notely workspace."}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1784310121000}'); +const _sfc_main = { name: "index.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(``); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("index.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + index as default +}; diff --git a/docs-site/.vitepress/.temp/keyboard-shortcuts.md.js b/docs-site/.vitepress/.temp/keyboard-shortcuts.md.js new file mode 100644 index 00000000..1dbb06ae --- /dev/null +++ b/docs-site/.vitepress/.temp/keyboard-shortcuts.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Keyboard Shortcuts","description":"Complete reference of all keyboard shortcuts in Notely.","frontmatter":{"title":"Keyboard Shortcuts","description":"Complete reference of all keyboard shortcuts in Notely.","keywords":"shortcuts, hotkeys, keybinds, keyboard, cheat sheet","category":"Reference"},"headers":[],"relativePath":"keyboard-shortcuts.md","filePath":"keyboard-shortcuts.md","lastUpdated":1786163747000}'); +const _sfc_main = { name: "keyboard-shortcuts.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Keyboard Shortcuts

    Use shortcuts to navigate and edit notes quickly across Notely.

    ActionShortcutScope / Notes
    Open Command PaletteCtrl/Cmd + KGlobal
    Open Global SearchCtrl/Cmd + Shift + FGlobal
    Open Keyboard ShortcutsCtrl/Cmd + /Global
    Open Help CenterF1Global
    Open Markdown GuideCtrl/Cmd + MGlobal
    Open WorkspaceCtrl/Cmd + Shift + NWorkspace
    Open Workspace ActivityCtrl/Cmd + Shift + AWorkspace
    Open Workspace GraphCtrl/Cmd + Shift + GWorkspace
    Open P2P StatusCtrl/Cmd + Shift + PSync
    Switch to Next TabCtrl + TabEditor
    Switch to Previous TabCtrl + Shift + TabEditor

    Note Editor

    ActionShortcutScope / Notes
    Create New NoteCtrl/Cmd + NNotes
    Save Current NoteCtrl/Cmd + SEditor
    Rename Current NoteF2Editor
    Move Note to RemovedCtrl/Cmd + DeleteEditor
    Reload Current Note from DiskCtrl/Cmd + Shift + REditor
    Back to Notes / Close DialogEscEditor / Dialogs
    UndoCtrl/Cmd + ZEditor
    RedoCtrl/Cmd + Y or Ctrl/Cmd + Shift + ZEditor
    Toggle Split PreviewCtrl/Cmd + \\Editor
    Switch to Edit ModeCtrl/Cmd + 1Editor
    Switch to Split ModeCtrl/Cmd + 2Editor
    Switch to Preview ModeCtrl/Cmd + 3Editor
    Toggle Focus ModeCtrl/Cmd + Alt + FEditor
    Toggle Outline PanelCtrl/Cmd + Alt + LEditor
    Open Reference NoteCtrl/Cmd + Shift + KEditor
    Insert Reference LinkCtrl/Cmd + Shift + LEditor

    Search & Find Panel

    ActionShortcutScope / Notes
    Find in Current NoteCtrl/Cmd + FEditor
    Find and Replace in Current NoteCtrl/Cmd + HEditor (Non-macOS menu accelerator)
    Next Find MatchEnterFind Panel
    Previous Find MatchShift + EnterFind Panel

    AI & Features

    ActionShortcutScope / Notes
    Open AI PaletteCtrl/Cmd + Shift + IAI (Document screens)
    Open Downloads & Export HistoryCtrl/Cmd + JGlobal
    Open AI SettingsCtrl/Cmd + Shift + ,AI

    View, Media & Tools

    ActionShortcutScope / Notes
    Open Versions / HistoryCtrl/Cmd + Shift + HEditor
    Export PDFCtrl/Cmd + Shift + EEditor
    Open Note in VS CodeCtrl/Cmd + Shift + OEditor
    Open Website ViewCtrl/Cmd + Shift + WEditor
    Capture Screen Area (Windows)Ctrl/Cmd + Shift + SMedia
    Zoom In / Out / ResetCtrl/Cmd + = / - / 0View
    Open Preview Context MenuShift + F10 / ContextMenuPreview
    Image Zoom In / Out / Reset+ / - / 1 or 0Media Preview
    Landing Tile / Table ViewCtrl/Cmd + 1 / 2Landing View
    Landing Comfortable / Compact DensityCtrl/Cmd + 3 / 4Landing View
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("keyboard-shortcuts.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const keyboardShortcuts = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + keyboardShortcuts as default +}; diff --git a/docs-site/.vitepress/.temp/license.md.js b/docs-site/.vitepress/.temp/license.md.js new file mode 100644 index 00000000..5007f86f --- /dev/null +++ b/docs-site/.vitepress/.temp/license.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"License & Third-Party Notices","description":"Creative Commons License terms and third-party open source notices.","frontmatter":{"title":"License & Third-Party Notices","description":"Creative Commons License terms and third-party open source notices.","keywords":"license, cc-by-nc, legal, third party","category":"Developer"},"headers":[],"relativePath":"license.md","filePath":"license.md","lastUpdated":1783855203000}'); +const _sfc_main = { name: "license.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    License

    Notely is released under the Creative Commons Attribution-NonCommercial 4.0 International (CC-BY-NC-4.0) license.

    Attribution-NonCommercial 4.0 International

    Under these terms, you are free to:

    • Share: Copy and redistribute the material in any medium or format.
    • Adapt: Remix, transform, and build upon the material.

    Under the following conditions:

    • Attribution: You must give appropriate credit and indicate if changes were made.
    • NonCommercial: You may not use the material for commercial purposes.

    → For full terms, see the LICENSE file in the repository.


    Third-Party Open Source Software

    Notely is built using open-source libraries. Key packages include:

    • Electron: System integration framework.
    • React: Frontend UI runtime.
    • CodeMirror: Code and Markdown editing canvas.
    • Simple-Git: Local Git wrapper.
    • VitePress: Documentation toolchain.

    Refer to THIRD_PARTY_NOTICES.txt in the app package for full license transcripts of all dependencies.

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("license.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const license = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + license as default +}; diff --git a/docs-site/.vitepress/.temp/package.json b/docs-site/.vitepress/.temp/package.json new file mode 100644 index 00000000..25d9dcff --- /dev/null +++ b/docs-site/.vitepress/.temp/package.json @@ -0,0 +1 @@ +{ "private": true, "type": "module" } \ No newline at end of file diff --git a/docs-site/.vitepress/.temp/plugin-vue_export-helper.1tPrXgE0.js b/docs-site/.vitepress/.temp/plugin-vue_export-helper.1tPrXgE0.js new file mode 100644 index 00000000..84d1cb56 --- /dev/null +++ b/docs-site/.vitepress/.temp/plugin-vue_export-helper.1tPrXgE0.js @@ -0,0 +1,10 @@ +const _export_sfc = (sfc, props) => { + const target = sfc.__vccOpts || sfc; + for (const [key, val] of props) { + target[key] = val; + } + return target; +}; +export { + _export_sfc as _ +}; diff --git a/docs-site/.vitepress/.temp/release-notes.md.js b/docs-site/.vitepress/.temp/release-notes.md.js new file mode 100644 index 00000000..de9aed67 --- /dev/null +++ b/docs-site/.vitepress/.temp/release-notes.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Release Notes","description":"","frontmatter":{},"headers":[],"relativePath":"release-notes.md","filePath":"release-notes.md","lastUpdated":1784968955000}'); +const _sfc_main = { name: "release-notes.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Release Notes

    2026-07-25 (latest)

    AI Architecture & UI Telemetry

    • 13-Domain Decoupled Facade Subsystem — Reorganized AI domain modules into 13 single-entry point facades (compaction, planner, personas, prompts, context, graph, embeddings, memory, executor, tools, grounding, formatter, testing) orchestrated by AIFlow.js.
    • Zero-Latency Context Compaction Engine — 2-tier sliding window algorithm compresses chat sessions into Executive Memory Summaries, cutting LLM input token usage by ~75-80% with 0ms NLP intent heuristics.
    • Flow Telemetry Timeline Stream — AI Health Page now features a structural 3-column timeline stream displaying 5-stage execution breakdown, latency metrics, persistent session tokens (LogDB), expandable tool call arguments/output, and full flow trace JSON export.

    2026-07-17

    New features

    • Keyboard Tab Switching — switch between open tabs using Ctrl+Tab (next) and Ctrl+Shift+Tab (previous).

    • Copy Link Path — right-click on active tabs or dashboard document list items to copy the workspace-relative path for note referencing.

    • Preview Link Hover overlay — hover over any link in note previews to open a popover with Copy and Navigate options (with icons). Direct link clicks are disabled to prevent accidental navigation jumps.

    • Dismissible Toasts & Undo actions — notification toasts now include an X dismiss button, and applying markdown quick fixes prompts an Undo toast to quickly revert changes.

    • Always-Visible Workspace Sidebar — the dashboard rail containing recent notes, favorites, and open tasks remains visible when navigating workspace subfolders, preventing layout shifts and keeping dashboard information at hand.

    • Improved Contrast on Colored Items — extracted dynamic inline styling into a semantic .custom-colored-item CSS class, ensuring document text, icons, and action chips dynamically scale contrast and remain highly readable when custom card/tab colors are applied.

    • Draw.io Solid Background Exports — saves of Draw.io diagrams now export with a solid white background in PNG files, preventing poorly contrasted layouts under dark theme previews.

    • Modal Corner Radius Standardization — custom modal borders consistently use --radius-lg (6px) to match standard dialog overlays.

    • Centralized CSS Keyframes — common animations like spin and modal-pop are centralized in base.css to reduce code repetition.

    • Double-click to open row — table list items in document dashboard now open immediately on double-click.

    • Validation Banner Auto-Hide — the validation banner at the top of the editor is completely hidden when there are no issues.

    • Spacing Token Normalization — dashboard panels and bars now use design system space tokens (var(--space-4) and var(--space-5)) for consistent alignments.


    2026-07-11

    • Inline markdown table editor — placing the cursor inside a markdown table now opens a focused grid editor for direct cell/header updates.

    Refinements

    • Compact table actions — row/column controls now use labeled compact action chips for quicker recognition and less visual noise.
    • Table edit interaction flow — deleting rows/columns keeps editing context active instead of dropping back to the main editor.
    • Table formatting preservation — same-shape table edits now preserve the original table style (spacing and delimiter style) where possible.

    Fixes

    • Escaped content safety — table parsing now preserves escaped pipes and plain backslashes in cell content (including Windows-style paths).
    • Scroll behavior during table edits — background scrolling is disabled while table editing is active; table content scrolling remains within the editor panel.

    2026-07-03 (latest)

    New features

    • Open Workspace in VS Code — the landing File menu now includes Open Workspace in VS Code (Ctrl/Cmd + Shift + O). Opens the active workspace folder directly in VS Code, or falls back to the system default app.
    • Reveal Workspace in File Explorer — the landing File menu now includes Reveal Workspace in File Explorer (Ctrl/Cmd + Shift + J). Opens the workspace folder in the native system file browser.
    • Web menu — a new top-level Web menu (Ctrl/Cmd + Shift + W) provides one-click access to the project website (landing screen) or the current note's website view (note screen).
    • Custom dropdown controls — all select/dropdown controls across the app have been replaced with a fully custom listbox component. The new control supports grouped options, keyboard navigation (arrow keys, Home, End, Enter, Escape), selected-state checkmarks, and focus-aware close behaviour.

    Refinements

    • Form focus styles — focus indicators across all inputs, selects, and textareas have been softened to a subtle border tint and 2px halo for a more professional desktop feel.
    • Continue Writing panel — now shows only the single most recently edited note instead of a list, making it faster to resume work.
    • Task hover popover — the note-level task summary popover now sizes to the available viewport height before showing a scrollbar.
    • Note detail topbar consistency — breadcrumb chips, task summary, save status, and action controls now use aligned heights and shared corner radius styling for a cleaner, unified row.

    Fixes

    • Workspace switch website refresh — opening project website view after changing workspace now reflects the current workspace immediately instead of reusing stale scope from the previous folder.
    • Task summary accessibility semantics — the topbar task summary trigger now uses button semantics with screen-reader state attributes for improved accessibility.

    2026-07-03

    This release focuses on documentation accuracy, shortcut clarity, and in-app help coverage.

    Documentation updates

    • Updated user docs to match current UI labels such as Open Workspace and Help Center
    • Added a dedicated Settings Reference page
    • Added an FAQ page
    • Added this Release Notes page and a repository CHANGELOG.md

    Shortcut updates

    • Resolved overlapping shortcut definitions for the command palette, AI palette, focus mode, and outline workflows
    • Expanded the in-app keyboard shortcuts guide to include context-specific shortcuts and usage notes

    Help Center updates

    • Added new Help Center entries for settings, FAQ, and release notes
    • Updated task and troubleshooting documentation to cover current workflows more accurately

    Notes for existing users

    • If you learned older menu names such as Notes Folder or Documentation, use Open Workspace and Help Center instead.
    • If you used older overlapping shortcuts, open the keyboard guide once to confirm the current bindings.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("release-notes.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const releaseNotes = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + releaseNotes as default +}; diff --git a/docs-site/.vitepress/.temp/search.md.js b/docs-site/.vitepress/.temp/search.md.js new file mode 100644 index 00000000..d97a87d1 --- /dev/null +++ b/docs-site/.vitepress/.temp/search.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Search in Notely","description":"Learn how to perform global searches, use regex patterns, filter by code blocks, and utilize semantic AI search.","frontmatter":{"title":"Search in Notely","description":"Learn how to perform global searches, use regex patterns, filter by code blocks, and utilize semantic AI search.","keywords":"search, global search, regex, regular expressions, code block search, semantic search, synonyms","category":"Search"},"headers":[],"relativePath":"search.md","filePath":"search.md","lastUpdated":1783855203000}'); +const _sfc_main = { name: "search.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Search

    Search is a first-class feature in Notely. You can search within the current note, across the entire workspace, or filter for specific content types.

    1. Find in Current Note

    Press Ctrl + F to open the in-note search bar:

    • Search by keyword.
    • Jump through matches using Next (F3) and Previous (Shift + F3).
    • Case-sensitivity and whole-word matching toggles are supported.

    Press Ctrl + H to open Find and Replace.


    Press Ctrl + Shift + F to open the Global Search panel:

    • Searches all .md note titles, folders, metadata, and note content.
    • Results update instantly as you type.
    • Matches are shown with content snippets highlighting where the term appeared.

    Synonym & Term Support

    Search matches related concepts even if the exact keyword differs. Searching for:

    • Repository, Repo, Git, Version Control, Commit, History, Diff
    • will all surface related version control documentation and notes.

    3. Regular Expression Search (Regex)

    Enable advanced matching by clicking the .* button in the search bar:

    • Search using standard regular expression patterns.
    • Notely checks your regex syntax live and shows a warning if the pattern is invalid.

    Common Regex Examples:

    • Find functions: function\\s+\\w+\\s*\\(
    • Find issue IDs: Error: \\[[A-Z0-9_]+\\]
    • Find markdown links: \\[([^\\]]+)\\]\\(([^)]+)\\)

    Filter your search results to code snippets only:

    1. Click the Code Blocks filter in the global search panel.
    2. Enter your keyword or regex.
    3. Notely will only return matches found inside fenced code blocks (\`\`\`).

    5. Semantic Search (AI-Powered)

    When AI embeddings are configured, Notely supports meaning-based search:

    • Matches concepts rather than exact words (e.g. searching "backup" finds notes discussing "disaster recovery" or "exporting").
    • Requires the Generate Embeddings toggle to be enabled in AI settings.
    • The status bar displays the freshness state of the search index.

    AI Setup & Embeddings

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("search.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const search = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + search as default +}; diff --git a/docs-site/.vitepress/.temp/settings-reference.md.js b/docs-site/.vitepress/.temp/settings-reference.md.js new file mode 100644 index 00000000..1068a971 --- /dev/null +++ b/docs-site/.vitepress/.temp/settings-reference.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Settings Reference","description":"","frontmatter":{},"headers":[],"relativePath":"settings-reference.md","filePath":"settings-reference.md","lastUpdated":1786126353000}'); +const _sfc_main = { name: "settings-reference.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Settings Reference

    Use this page when you want to understand what each configurable option does in Notely.

    1. Appearance

    Theme

    Open Settings -> Theme.

    • System: follows the operating system theme
    • Light: always uses the light theme
    • Dark: always uses the dark theme

    Default: System

    Use this when you want Notely to stay consistent with your desktop or when you need a fixed light or dark theme.

    Zoom

    Open View -> Zoom In, Zoom Out, or Reset Zoom.

    • Minimum zoom: 75%
    • Default zoom: 80%
    • Maximum zoom: 200%

    Use zoom when UI text or panels feel too small or too large on your display.

    2. Landing View

    View Mode

    Open View -> Tile Notes or View -> Table Notes.

    • Tile Notes: visual cards with previews and summary details
    • Table Notes: denser list-style view for scanning many notes quickly

    Density

    Open View -> Comfortable Density or Compact Density.

    • Comfortable: more whitespace and larger rows
    • Compact: denser rows for large workspaces

    Use compact density when you want to see more notes at once.

    3. Editor and Writing

    Typo Check

    Open Edit -> Enable Typo Check.

    • When enabled, Notely checks note text for spelling and typo issues.
    • It skips code and diagram content so it does not flag technical text unnecessarily.

    Default: On

    Outline

    Open View -> Show Outline.

    • Shows a headings-based side panel for the current note
    • Hidden automatically while Focus Mode is active

    Shortcut: Ctrl/Cmd + Alt + L

    Focus Mode

    Open View -> Focus Mode.

    • Hides the outline and reduces surrounding distractions
    • Useful for concentrated writing sessions

    Shortcut: Ctrl/Cmd + Alt + F

    4. Terminal

    Show Terminal

    Open View -> Show Terminal.

    • Opens or hides the embedded terminal panel
    • Useful for project-local commands while staying in Notely

    Terminal Shell

    Open View -> Terminal Shell.

    • Auto: lets Notely choose the shell
    • Bash: prefers Bash when available
    • CMD: uses Windows Command Prompt

    Use Bash if you prefer a Unix-style command line. Use CMD if you prefer standard Windows commands.

    5. Screen Capture

    Open Settings -> Screen Capture.

    • Auto Insert: inserts the captured image immediately into the note
    • Review Before Insert: opens the review editor before saving and inserting

    Default: Auto Insert

    The toolbar capture button shows the current mode:

    • A = Auto Insert
    • R = Review Before Insert

    6. AI Settings

    Open AI -> AI Settings.

    Provider setup

    • Text provider: choose the LLM service for writing, summarizing, or refactoring text (Google Gemini, Groq, or OpenAI / OpenAI-compatible).
    • OpenAI Compatible: connect to OpenAI (gpt-4o, gpt-4o-mini) or any compatible endpoint by specifying your API key and Base URL.
    • Local ONNX Models: vector embeddings (BGE-small-en-v1.5) and Knowledge Graph extraction (GLiNER2-Relex) run completely on-device and offline via onnxruntime-node.
    • HuggingFace token: optional API token for cloud-based embeddings fallback.
    • Test buttons: verify that your saved credentials and endpoint connections work.

    Feature toggles

    • Learn user patterns: lets the app remember how you use AI so it can be more helpful later
    • Generate embeddings: turns on meaning-based search and related-note features
    • Discover relationships: helps the graph and AI features find links between related notes
    • Graph confidence threshold: controls the minimum confidence score (10% to 95%) required for neural-extracted entities and relationships. Adjusting this slider dynamically filters the Knowledge Graph visualization in real time.

    Advanced generation tuning

    • Max tokens: controls how long AI responses are allowed to be
    • Temperature: controls how safe and predictable, or how varied and creative, the response feels

    Use lower temperature for predictable output. Use higher temperature for brainstorming or variation.

    Data and privacy controls

    • Shows where AI-related app data is stored on your device
    • Lets you clear saved AI working data and learned behavior

    7. Workspace Metadata and Git Safety

    If your workspace is also a Git folder, Notely can help keep its own support files out of version control.

    • Ignore .notes-app: On: automatically keeps .notes-app/ ignored in .gitignore
    • Ignore .notes-app: Off: leaves Git ignore management to you

    Use this when your team stores notes in Git but does not want Notely's private support files committed with them.

    8. Environment Variables

    Notely respects system environment variables for advanced runtime configuration:

    VariableValuesPurpose
    NOTELY_TERMINAL_POLICYpermissive | strictSets execution policy for embedded terminal. strict enforces role and command allowlists.
    NOTELY_TERMINAL_REQUIRED_ROLEdeveloper (default)Required user role when operating in strict terminal policy.
    NOTELY_TERMINAL_ALLOWLISTComma-separated stringsAllowed command executables in strict terminal mode (e.g. git,npm,node).
    NOTELY_BASH_PATHFile pathExplicit path to Bash binary on Windows hosts.
    GIT_BASH_PATHFile pathFallback Git Bash executable path on Windows hosts.
    NOTELY_LOG_LEVELdebug | info | warn | errorSystem logging threshold for LogDB.
    NOTES_ROOTWorkspace pathEnvironment variable override for default workspace directory path.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("settings-reference.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const settingsReference = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + settingsReference as default +}; diff --git a/docs-site/.vitepress/.temp/sync_index.md.js b/docs-site/.vitepress/.temp/sync_index.md.js new file mode 100644 index 00000000..c299a5cb --- /dev/null +++ b/docs-site/.vitepress/.temp/sync_index.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Peer-to-Peer Sync","description":"Sync notes securely between devices using peer-to-peer pairing over local networks.","frontmatter":{"title":"Peer-to-Peer Sync","description":"Sync notes securely between devices using peer-to-peer pairing over local networks.","keywords":"P2P, sync, peer-to-peer, discovery, invite code, conflict resolution","category":"Sync"},"headers":[],"relativePath":"sync/index.md","filePath":"sync/index.md","lastUpdated":1786126353000}'); +const _sfc_main = { name: "sync/index.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    P2P Sync

    Notely includes a native peer-to-peer (P2P) synchronization subsystem (p2pLive.cjs & p2pSyncEngine.cjs), allowing you to replicate notes directly between local devices without cloud servers or third-party storage.


    1. Network Discovery & Transport Security

    • UDP Network Discovery (Port 47653): Devices broadcast periodic UDP discovery packets every 4 seconds across the local network subnet to locate active Notely peers.
    • TLS/TCP Transport: Peer-to-peer payload transfers execute over encrypted TCP connections.
    • AES-256-GCM End-to-End Encryption: Note deltas and workspace data payloads are encrypted using 256-bit AES-GCM with unique 12-byte initialization vectors (iv) and auth tags (tag).
    • Workspace Keys & Key TTL: Pairing generates a 256-bit workspace key stored in global app.sqlite. Workspace key expiration (TTL) is configurable from 1 to 365 days (default 30 days). Expired keys automatically trigger re-authentication.

    2. Pairing Devices & Invite Flow

    1. Open P2P → P2P Status (Ctrl/Cmd + Shift + P) on both devices.
    2. Click Start Discovery to scan the local subnet for peers on port 47653.
    3. On device A, click Generate Invite to create a short-lived, 5-minute invite code (INVITE_TTL_MS = 300000).
    4. On device B, click Pair with Peer, enter the invite code, and confirm authorization.
    5. Once accepted, add the peer to your Trusted Peers whitelist.

    3. Delta Note Merging & Conflict Resolution

    • 3-Way Line Delta Engine: Edits are processed incrementally using line-level note diffs (buildNoteDelta / applyNoteDelta). Small non-overlapping changes merge automatically without prompting.
    • Automatic Retry Policy: Unreachable or interrupted sync requests automatically retry up to 5 times at 2-second intervals (SYNC_RETRY_INTERVAL_MS = 2000).
    • Conflict Snapshot Copying: If simultaneous edits modify the exact same line block on two devices before a delta is applied:
      1. Notely creates a timestamped conflict file: [note-name].sync-conflict-[timestamp].md.
      2. Automated sync halts for that specific note to prevent data corruption.
      3. The P2P Status Panel alerts you to the conflict.
      4. Open the Conflict Resolution Panel to compare versions side-by-side and choose Keep Local, Keep Remote, or Merge Manually.

    4. Key Rotation & Security Controls

    • Rotate Keys: Generate a new 256-bit workspace key at any time from P2P Settings. Rotated keys are pushed securely to connected trusted peers.
    • Revoke Peers: Remove any device from your Trusted Peers list to block future connection handshakes instantly.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("sync/index.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + index as default +}; diff --git a/docs-site/.vitepress/.temp/top-tasks.md.js b/docs-site/.vitepress/.temp/top-tasks.md.js new file mode 100644 index 00000000..587e44fa --- /dev/null +++ b/docs-site/.vitepress/.temp/top-tasks.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Top Common Tasks","description":"","frontmatter":{},"headers":[],"relativePath":"top-tasks.md","filePath":"top-tasks.md","lastUpdated":1783832700000}'); +const _sfc_main = { name: "top-tasks.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Top Common Tasks

    Use this page when you want quick, direct steps.

    1. Open or change workspace

    1. Open File -> Open Workspace.
    2. Select the folder.
    3. Confirm.

    2. Create a new note

    1. Open File -> New Note (Ctrl/Cmd + N).
    2. Enter note name.
    3. Start writing.

    3. Create a folder

    1. Use folder controls in the list view.
    2. Enter folder name.
    3. Save.

    4. Find text in current note

    1. Press Ctrl/Cmd + F.
    2. Enter text.
    3. Use next/previous controls.

    5. Replace text in current note

    1. Open find panel.
    2. Enter find and replace text.
    3. Run replace or replace all.

    6. Switch between Edit, Split, and Preview

    1. Open view mode controls in the editor header.
    2. Choose the mode that fits your task.

    7. Show document outline

    1. Open View -> Show Outline.
    2. Click section headings to jump.

    8. Enable Focus Mode

    1. Open View -> Focus Mode.
    2. Toggle off when done.

    9. Insert an image into a note

    1. Use markdown toolbar image action.
    2. Pick file.
    3. Confirm insertion.

    10. Insert a Mermaid diagram

    1. Use toolbar diagram action.
    2. Select Mermaid.
    3. Add Mermaid syntax.
    4. Check rendering in preview.

    11. Insert an Excalidraw diagram

    1. Use toolbar diagram action.
    2. Select Excalidraw.
    3. Edit and save.

    11b. Convert an image to Excalidraw

    1. In preview, right-click a workspace image.
    2. Choose Edit with Excalidraw.
    3. Draw and resize the base image as needed.
    4. Save diagram.

    12. View or restore note history

    1. Click the History button in the note's top-right toolbar or press Ctrl/Cmd + Shift + H.
    2. Select a commit from the history timeline sidebar.
    3. Compare revisions or click Restore to revert changes.

    13. Search across all notes

    1. Open global search.
    2. Enter keyword.
    3. Open matching result.

    14. Open keyboard shortcuts

    1. Open Help -> Keyboard Shortcuts.
    2. Use it as a quick command reference.

    15. Open troubleshooting

    1. Open Help -> Help Center (F1).
    2. Select Troubleshooting in the left menu.

    16. Run AI setup and test

    1. Open AI -> AI Settings.
    2. Add your sign-in details for the AI service you want to use.
    3. Run the connection test.

    17. Refresh semantic graph data

    1. Open Workspace -> Workspace Graph.
    2. Use graph refresh action.
    3. Verify freshness indicator updates.

    18. Clean unused media

    1. Open media management/health view.
    2. Filter by unused media.
    3. Run bulk delete for confirmed unused files.

    19. Restore original image after edits

    1. Open image editor for a previously edited image.
    2. Choose restore original.
    3. Confirm restore action.

    19b. Restore original image from converted Excalidraw

    1. Right-click an Excalidraw preview that came from image conversion.
    2. Choose Restore original image.

    20. Export a note to PDF

    1. Open note actions for export.
    2. Choose PDF export.
    3. Select destination and confirm.

    21. Capture a screen area into a note

    1. Place cursor in note.
    2. Click toolbar capture icon or press Ctrl/Cmd + Shift + S.
    3. Select area in Windows snip overlay.
    4. If mode is Review, click Save in review dialog.

    Set mode in Settings -> Screen Capture.

    22. Review open and completed tasks across workspace

    1. Open Command Palette (Ctrl/Cmd + K).
    2. Run Open Tasks Panel to review pending tasks.
    3. Run Open All Tasks to review open + completed tasks together.
    4. Open source notes directly from task rows.

    23. Export workspace as zip

    1. Go to landing view.
    2. Open File -> Export Workspace as Zip.
    3. Select format (notes as-is, PDF-only, or web format).
    4. Keep the app data toggle off unless you intentionally need .notes-app data.
    5. Browse destination and adjust filename if needed.
    6. Click Export Zip.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("top-tasks.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const topTasks = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + topTasks as default +}; diff --git a/docs-site/.vitepress/.temp/troubleshooting.md.js b/docs-site/.vitepress/.temp/troubleshooting.md.js new file mode 100644 index 00000000..8d5eef5f --- /dev/null +++ b/docs-site/.vitepress/.temp/troubleshooting.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Notely Troubleshooting","description":"","frontmatter":{},"headers":[],"relativePath":"troubleshooting.md","filePath":"troubleshooting.md","lastUpdated":1783102196000}'); +const _sfc_main = { name: "troubleshooting.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Notely Troubleshooting

    Use this page to quickly fix common issues.

    1. Notes Are Not Showing

    1. Open File -> Open Workspace.
    2. Confirm the selected folder is correct.
    3. Check that the folder contains .md files.

    If still empty, restart the app and re-open the same folder.

    2. Preview Looks Wrong

    1. Switch to Split view.
    2. Check for markdown validation warnings.
    3. Fix heading/list/table syntax first.

    For Mermaid diagrams, validate the Mermaid block syntax before retrying preview.

    3. A Linked File or Image Does Not Open

    1. Check that the file still exists in your workspace.
    2. Verify the path in markdown is correct.
    3. Reinsert the link from toolbar/file picker if needed.

    4. Sync Conflicts Keep Appearing

    1. Open P2P -> P2P Status.
    2. Confirm peers are connected and trusted.
    3. Open conflict tools and resolve each conflict.

    After resolving, refresh the note list and verify final content.

    5. AI Features Are Disabled

    1. Open AI -> AI Settings.
    2. Confirm your AI sign-in details are saved.
    3. Run connection test.

    If a feature still does not appear, the AI service you chose may not support it.

    6. App Feels Slow in Large Workspaces

    • Use folder structure to reduce very large flat note lists.
    • Close unused views (for example, graph or media-heavy previews).
    • Refresh AI search data only when you actually need it.

    7. Quick Support Details to Share

    If you need help from your team, share:

    • App version from Help -> About Notely
    • What you were doing when issue started
    • Exact error message text (if shown)

    8. Screen Capture Mode Looks Incorrect (A/R)

    1. Open Settings -> Screen Capture and choose mode again.
    2. Check toolbar capture icon marker. A means Auto Insert and R means Review Before Insert.
    3. Trigger a fresh capture (Ctrl/Cmd + Shift + S) to confirm behavior.

    If marker and menu differ, restart app once and re-check.

    9. Review Mode Save Appears Unresponsive

    In current flow, review mode Save should work even without making edits.

    If Save still appears blocked:

    1. Ensure review dialog is focused.
    2. Confirm image preview has loaded.
    3. Try keyboard Enter once.
    4. Retry capture from toolbar.

    10. Embedded Terminal Does Not Start

    1. Open View -> Show Terminal again.
    2. Switch shell from View -> Terminal Shell and retry.
    3. If strict terminal policy is configured, confirm your command is allowed.

    If the terminal still fails, capture the exact error text shown in the terminal panel.

    11. Workspace Export Does Not Finish

    1. Retry export from the landing screen.
    2. Confirm the destination folder is writable.
    3. Try Notes as-is first to isolate PDF or web export issues.

    If PDF-only export fails, retry with a smaller workspace to identify a problematic note or asset.

    12. Project Website Shows Notes from an Older Workspace

    1. Confirm workspace was changed from File -> Open Workspace and opened successfully.
    2. Re-open website using Web -> Open Project Website from the landing screen.
    3. If browser tab is pinned, open a new tab/window once.

    If this keeps happening, update to the latest build that includes workspace-switch website scope refresh fixes.

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("troubleshooting.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const troubleshooting = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + troubleshooting as default +}; diff --git a/docs-site/.vitepress/.temp/user-guide.md.js b/docs-site/.vitepress/.temp/user-guide.md.js new file mode 100644 index 00000000..627ea70d --- /dev/null +++ b/docs-site/.vitepress/.temp/user-guide.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Notely User Guide","description":"","frontmatter":{},"headers":[],"relativePath":"user-guide.md","filePath":"user-guide.md","lastUpdated":1783839551000}'); +const _sfc_main = { name: "user-guide.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Notely User Guide

    Use this guide for everyday work in Notely: creating notes, editing safely, finding information quickly, and working with visuals.

    1. Set Up Your Workspace

    1. Open Notely.
    2. Go to File -> Open Workspace.
    3. Select the folder where your notes should live.
    4. Confirm and continue.

    Result: your notes and folders appear in the main list.

    Tip: use File -> Open Recent when you want to jump back into a recently used workspace faster.

    2. Create and Organize Notes

    1. Create a note from File -> New Note (Ctrl/Cmd + N).
    2. Create folders to group related notes.
    3. Use clear titles and optional tags so notes are easier to find later.

    3. Write and Edit Faster

    Choose the view mode that fits your task:

    • Edit: write raw markdown.
    • Split: write and preview side-by-side.
    • Preview: read final output.

    Helpful actions:

    • Find text: Ctrl/Cmd + F
    • Use toolbar buttons for headings, lists, links, tables, and diagrams.
    • Edit markdown tables inline by placing the cursor inside a table and using the popup grid controls.
      • Add/remove rows and columns from compact action chips.
      • Adjust column alignment from header controls.
      • Save with Save, or close/cancel with Cancel or Esc.
    • Format code blocks automatically and use the dedicated code editor popup.
    • Fix issues shown by markdown validation and typo checks.

    4. Recover Changes with Git Version Control

    Notely tracks your document history with a native Git-backed system:

    1. Open Version Control -> History (Ctrl/Cmd + Shift + H) or click the History button in the top menu of an open note.
    2. Select a commit from the timeline list to inspect its details.
    3. Compare commits or restore a note to that version.
    4. Add tags directly to commits to bookmark key milestones.

    Use this to track changes chronologically and recover older revisions of any note.

    5. Work with Images and Files

    You can insert and manage media directly from your notes:

    • Add images and linked files.
    • Rename or replace existing media.
    • Open media in the default app.
    • Use image tools like crop and annotation when needed.

    Tip: keep image names meaningful so teammates can identify assets quickly.

    6. Capture Screen Areas into Notes (Windows)

    1. Place your cursor where you want the screenshot markdown inserted.
    2. Click the toolbar capture icon, or press Ctrl/Cmd + Shift + S.
    3. Select screen area in Windows snip overlay.
    4. If mode is Auto Insert, image is inserted directly.
    5. If mode is Review Before Insert, adjust (optional) and click Save.

    Change mode in Settings -> Screen Capture.

    Tip: capture icon marker shows active mode (A auto, R review).

    7. Use Diagrams (Mermaid and Excalidraw)

    Mermaid

    1. Insert a Mermaid block from the toolbar.
    2. Write Mermaid syntax.
    3. Check rendering in Split or Preview.

    Excalidraw

    1. Insert an Excalidraw diagram.
    2. Edit visually and save.
    3. Re-open from preview to continue editing.

    Convert an image to Excalidraw

    1. In preview, right-click a workspace image.
    2. Select Edit with Excalidraw.
    3. Draw on top of the image (the starting image is resizable on canvas).
    4. Save diagram to replace the markdown image reference.

    Restore original image from converted diagram

    1. Right-click an Excalidraw preview created from an image.
    2. Select Restore original image.

    Note: restore appears only for diagrams that were created from an image conversion flow.

    8. Navigate Large Workspaces

    • View -> Show Outline for quick jumps inside long notes.
    • View -> Split Preview to keep source and output aligned.
    • View -> Focus Mode to reduce distractions.
    • Workspace -> Workspace Graph to explore note and media relationships.

    9. Track Tasks Across Notes

    Use markdown task checkboxes in your notes:

    • Open task: - [ ]
    • Completed task: - [x]

    Then review tasks centrally:

    1. Open Command Palette (Ctrl/Cmd + K).
    2. Run Open Tasks Panel for pending tasks.
    3. Run Open All Tasks to view open + completed tasks.
    4. Open the source note directly from a task row when you need context.

    10. Export Workspace as Zip

    1. Go to the landing screen (notes list view).
    2. Open File -> Export Workspace as Zip.
    3. Choose export format:
      • Notes as-is (Markdown + assets)
      • PDF-only
      • Web format
    4. Choose whether to include Notely app data from .notes-app (default is off).
    5. Select destination folder (Browse is available and last path is remembered).
    6. Confirm or edit filename (default notelyproject.zip).
    7. Click Export Zip.

    11. Get Help Quickly

    • Help -> Help Center (F1) for in-app help.
    • Help -> Keyboard Shortcuts (Ctrl/Cmd + /) for key bindings.
    • Help -> About Notely for app version details.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("user-guide.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const userGuide = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + userGuide as default +}; diff --git a/docs-site/.vitepress/.temp/ux-writing-guide.md.js b/docs-site/.vitepress/.temp/ux-writing-guide.md.js new file mode 100644 index 00000000..da1e2c49 --- /dev/null +++ b/docs-site/.vitepress/.temp/ux-writing-guide.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"UX Writing Guide","description":"","frontmatter":{},"headers":[],"relativePath":"ux-writing-guide.md","filePath":"ux-writing-guide.md","lastUpdated":1783014271000}'); +const _sfc_main = { name: "ux-writing-guide.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    UX Writing Guide

    Purpose: keep labels and messages consistent, clear, and action-oriented.

    Core Rules

    • Use sentence case for buttons, labels, and helper text.
    • Start actions with a verb: Open, Create, Save, Delete, Show, Hide.
    • Keep labels short: prefer 2 to 4 words when possible.
    • Use consistent nouns across UI: note, folder, workspace, command palette.
    • Avoid mixed casing of the same phrase (for example, "AI data" vs "AI Data").

    Buttons and Actions

    • Primary button text: explicit outcome, e.g. "Save", "Export", "Create note".
    • Secondary button text: supportive action, e.g. "Close", "Cancel", "Show details".
    • Destructive actions: include object and consequence, e.g. "Clear AI data".

    Empty, Error, and Status Text

    • Empty states should include a next step.
    • Error states should describe what failed and what to do next.
    • Success states should confirm completion in one short sentence.

    Examples

    • Good: "Search commands and actions"
    • Good: "No matching commands"
    • Good: "Connect providers, tune behavior, and manage local AI data."
    • Avoid: title-case fragments like "Type a command or action" when sentence case is used elsewhere.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("ux-writing-guide.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const uxWritingGuide = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + uxWritingGuide as default +}; diff --git a/docs-site/.vitepress/.temp/virtual_mermaid-config.CM0F1BUC.js b/docs-site/.vitepress/.temp/virtual_mermaid-config.CM0F1BUC.js new file mode 100644 index 00000000..e0ee83b5 --- /dev/null +++ b/docs-site/.vitepress/.temp/virtual_mermaid-config.CM0F1BUC.js @@ -0,0 +1,4 @@ +const _virtual_mermaidConfig = { "securityLevel": "loose", "startOnLoad": false }; +export { + _virtual_mermaidConfig as default +}; diff --git a/docs-site/.vitepress/.temp/web-view.md.js b/docs-site/.vitepress/.temp/web-view.md.js new file mode 100644 index 00000000..b0764080 --- /dev/null +++ b/docs-site/.vitepress/.temp/web-view.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Website View","description":"How the Notely website preview works — live local server, note rendering, project index, and full-text search.","frontmatter":{"title":"Website View","description":"How the Notely website preview works — live local server, note rendering, project index, and full-text search.","keywords":"website view, web preview, local server, note rendering, search index, markdown","category":"User Guide"},"headers":[],"relativePath":"web-view.md","filePath":"web-view.md","lastUpdated":1784644592000}'); +const _sfc_main = { name: "web-view.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Website View

    The Website View renders your workspace notes as a fully navigable, styled static website served locally by Notely. Unlike the in-editor Markdown Preview pane, the website view runs inside your browser and includes a project index, full-text search, and cross-note navigation.


    Opening the Website View

    Access via the Web top-level menu:

    ActionContextShortcut
    Web → Open Project WebsiteLanding screen (no note open)Ctrl/Cmd + Shift + W
    Web → Open Current Note Website ViewWhen a note is activeCtrl/Cmd + Shift + W

    Both actions start the local preview server (if not already running) and open the rendered page in your default browser.


    How It Works

    Local HTTP Server

    Notely starts a local HTTP server (webPreview.cjs) on a random available port. The server binds to 127.0.0.1 only and is never accessible from other devices.

    The server handles five route types:

    RouteWhat it serves
    GET /Project index page — a listing of all workspace notes
    GET /view/{note-path}Individual note rendered as a website page
    GET /pdf/{note-path}Note rendered in PDF-optimised layout
    GET /searchFull-text search results page
    GET /search-index.jsonSearch index JSON (used by the search page)
    GET /raw/{asset-path}Static file passthrough for media assets (images, PDFs, Excalidraw PNGs)

    All responses include Cache-Control: no-store so you always see the latest saved version.

    Live Content Overrides

    When you open the current note's website view while editing, Notely passes the unsaved editor buffer as a content override so you see real-time changes without needing to save first.


    Page Rendering Pipeline (websiteRenderer.cjs)

    Each note is processed through a custom rendering pipeline before being served:

    1. Markdown-It parser with linkify and typographer enabled.
    2. Syntax highlighting (highlight.js) with numbered lines and a one-click copy button on every code block.
    3. Heading slug generation — all headings get deterministic id attributes (deduplicated with counters) enabling anchor links.
    4. Asset path rewriting — relative image/media paths are rewritten to /raw/{path} server routes. Legacy Excalidraw diagram paths are automatically migrated to the current .notes-app/excali-diagrams/ layout.
    5. Markdown link rewriting.md links become /view/{note-path} server routes, enabling seamless cross-note navigation.
    6. HTML injection into websiteTemplate.cjs which adds navigation, project sidebar, and the Notely website stylesheet.

    What renders in website view

    • Standard GFM markdown (headings, lists, tables, blockquotes, task lists)
    • Fenced code blocks with syntax highlighting and line numbers
    • Inline and block images (.png, .jpg, .gif, .svg, .webp)
    • Embedded Excalidraw diagram previews (rendered PNG thumbnails)
    • Embedded PDF documents
    • Cross-note Wikilinks and relative .md links

    NOTE

    Mermaid diagram live rendering is handled client-side via a Mermaid.js script tag injected by websiteTemplate.cjs.


    Project Index Page

    The root / page lists all .md files in the active workspace (or project scope), sorted alphabetically. Notes in excluded directories (.notes-app/, .git/, node_modules/) are omitted.


    The /search page provides client-side full-text search across all workspace notes:

    • The server builds a search index JSON (/search-index.json) by reading and indexing all .md files in scope at request time.
    • The search page fetches this JSON and runs matching in the browser — no external search service required.
    • Results include the note title, matching excerpt, and a direct link to the note's website view.

    Website Scope

    The website scope tracks the active project (or workspace root if no project is open):

    • Switching workspace or project updates the scope — the server scope syncs on the next page load.
    • On scope change, the content override cache is cleared so you don't see stale overrides from a previous workspace.

    Comparison: Website View vs Preview Pane vs PDF Export

    FeaturePreview PaneWebsite ViewPDF Export
    Rendered inElectron app windowYour browserHeadless Chromium
    NavigationSingle note onlyCross-note links, project indexSingle note only
    Full-text search✅ (client-side)
    Live refresh✅ (auto on typing)Manual browser refreshOne-shot render
    Media resolved
    Syntax highlighting✅ (with line numbers)
    Shareable output❌ (local only)✅ (save as file)

    To publish the website view as a static site, use File → Export Workspace → Web Format which packages the full rendered HTML output as a .zip archive you can host on GitHub Pages, Netlify, or any static server. See Export Reference for details.

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("web-view.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const webView = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + webView as default +}; diff --git a/docs-site/.vitepress/.temp/workspace_calendar.md.js b/docs-site/.vitepress/.temp/workspace_calendar.md.js new file mode 100644 index 00000000..4f7af515 --- /dev/null +++ b/docs-site/.vitepress/.temp/workspace_calendar.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Calendar & Scheduling","description":"Guide to using the Calendar workspace, task scheduling, due dates, and visual timeline management in Notely.","frontmatter":{"title":"Calendar & Scheduling","description":"Guide to using the Calendar workspace, task scheduling, due dates, and visual timeline management in Notely.","keywords":"calendar, schedule, due dates, task timeline, month view, week view, day view","category":"Workspace"},"headers":[],"relativePath":"workspace/calendar.md","filePath":"workspace/calendar.md","lastUpdated":1786125015000}'); +const _sfc_main = { name: "workspace/calendar.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Calendar & Scheduling

    Notely includes an integrated Calendar Workspace that turns scheduled Markdown tasks and due dates into a visual timeline. View project deadlines, schedule tasks across days or hours, and track upcoming workloads visually.


    1. Task Scheduling & Due Dates

    Tasks in Notely support both Due Dates and Scheduled Start/End Times:

    • Due Date: Target completion deadline for a task (e.g. 2026-08-15).
    • Scheduled Start / End: Specific time window when work is planned (e.g. 2026-08-15 09:00 - 11:00).
    • All-Day Tasks: Tasks scheduled for an entire day without specific hour constraints.

    2. Calendar Views

    Access the Calendar from the left navigation sidebar or Command Palette (Ctrl + Shift + C). The Calendar supports three main view modes:

    Month View

    Provides a high-level overview of the entire month. Scheduled tasks and due date markers appear inside their respective date cells. Click any date cell to quickly inspect or add tasks for that day.

    Week View

    A 7-day grid showing time slots for hourly scheduled tasks alongside an All-Day Header for day-wide deadlines. Perfect for weekly sprint planning and time-blocking.

    Day View

    A detailed single-day timeline for granular schedule management and hourly focus blocks.


    3. Interactive Drag & Drop Scheduling

    • Reschedule Tasks: Drag tasks across calendar date cells to change their due dates or scheduled days automatically.
    • Time Slot Placement: In Week or Day views, drag tasks onto specific hour slots to assign start and end times.
    • Quick Status Toggle: Click task markers directly within calendar cells to mark them as completed without leaving the calendar view.

    4. Date Filtering & Overdue Tracking

    The Calendar integration automatically categorizes workspace tasks into smart time filters:

    • Due Today: Tasks whose due date matches the current calendar day.
    • Overdue: Open tasks whose due date has passed. Overdue items are highlighted in red for quick visibility.
    • Upcoming: Scheduled tasks occurring over the next 7 to 30 days.
    • Unscheduled Queue: A side panel listing open tasks that haven't been assigned a due date yet, allowing easy drag-and-drop onto the calendar.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("workspace/calendar.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const calendar = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + calendar as default +}; diff --git a/docs-site/.vitepress/.temp/workspace_downloads.md.js b/docs-site/.vitepress/.temp/workspace_downloads.md.js new file mode 100644 index 00000000..e17a9458 --- /dev/null +++ b/docs-site/.vitepress/.temp/workspace_downloads.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Downloads & Export History","description":"Manage and track all note exports, diagram renders, note packages, and workspace zip archives in Notely.","frontmatter":{"title":"Downloads & Export History","description":"Manage and track all note exports, diagram renders, note packages, and workspace zip archives in Notely.","keywords":"downloads, export history, exports, PDF, note package, excalidraw, draw.io, SQLite","category":"Workspace"},"headers":[],"relativePath":"workspace/downloads.md","filePath":"workspace/downloads.md","lastUpdated":1786163747000}'); +const _sfc_main = { name: "workspace/downloads.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Downloads & Export History

    Notely includes a dedicated Downloads & Export History Manager that automatically tracks all document exports, workspace zip bundles, diagram renders, and media files created in your active workspace.

    Access the downloads manager anytime via:

    • Top Workspace → Downloads & Export History menu item
    • Global keyboard shortcut Ctrl/Cmd + J
    • Quick 📥 Download icon button in the title bar
    • Command Palette (Ctrl/Cmd + Shift + P) → search for Open Downloads & Export History

    1. Features & Capabilities

    FeatureDescription
    Automatic TrackingEvery PDF export, .note package, workspace .zip archive, Excalidraw diagram, Draw.io diagram, and exported media file is logged automatically.
    Category TabsFilter exports into All, Documents (PDF, HTML, packages), Diagrams (Excalidraw, Draw.io), or Media (images, video, audio) with live item counter badges.
    Show in FolderOpens the exact file location in Windows File Explorer or macOS Finder.
    Open FileLaunches the exported file directly in your system's default application.
    Downloads DirectoryQuick action button to open your system's default Downloads directory (~/Downloads).
    Disk Status IndicatorAutomatically checks if exported files still exist on disk or have been moved/deleted.

    2. Storage & Database Architecture

    • Export history records are persisted locally per-workspace inside {workspace}/.notes-app/export-history.db.
    • Built on Node 22 native SQLite (node:sqlite DatabaseSync).
    • Dynamic Connection Handling: Automatically opens and queries the active workspace's SQLite database upon switching workspaces.
    • Deduplication: Exporting a note or diagram to the same file path updates the timestamp and metadata without creating duplicate rows.

    3. Supported Export & Download Formats

    Export TypeFile ExtensionSubsystem Category
    Single Note PDF.pdfDocuments
    Single Note HTML.htmlDocuments
    Note Package.note / .nlyDocuments
    Workspace Zip Archive.zipDocuments
    Excalidraw Diagram.pngDiagrams
    Draw.io Diagram.pngDiagrams
    Exported Media Render.png, .jpg, .webpMedia

    4. System Downloads Directory

    By default, all exports and downloads in Notely save directly to your system's Downloads folder (app.getPath("downloads")). You can customize the destination path during export prompts.

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("workspace/downloads.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const downloads = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + downloads as default +}; diff --git a/docs-site/.vitepress/.temp/workspace_export.md.js b/docs-site/.vitepress/.temp/workspace_export.md.js new file mode 100644 index 00000000..316076f2 --- /dev/null +++ b/docs-site/.vitepress/.temp/workspace_export.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Exporting Workspaces","description":"Export your workspace as a zip archive containing raw markdown, PDFs, or a built website package.","frontmatter":{"title":"Exporting Workspaces","description":"Export your workspace as a zip archive containing raw markdown, PDFs, or a built website package.","keywords":"export, zip, backup, pdf bundle, web format","category":"Workspace"},"headers":[],"relativePath":"workspace/export.md","filePath":"workspace/export.md","lastUpdated":1786163747000}'); +const _sfc_main = { name: "workspace/export.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Export

    Notely allows you to bundle and export your entire workspace (or specific selections) as a ZIP archive.

    1. Export Formats

    Open the export window from File → Export Workspace as Zip:

    • Notes As-Is: Bundles your raw Markdown files and the assets/ directory. Perfect for backups or migrating to another Markdown editor (like Obsidian).
    • PDF-Only: Compiles all notes into formatted PDF documents, placing them inside a structured ZIP. Useful for offline reading or client deliverables.
    • Web Format: Generates a static HTML website from your notes, packaged inside a ZIP. You can host this static folder on services like GitHub Pages or Netlify.

    2. Advanced Options

    • App Data Toggle: Choose whether to include the .notes-app support folder (containing version control commits and metadata). Recommended to leave disabled unless creating full recovery backups.
    • Default Location: All exported workspace archives default directly to your system Downloads directory (~/Downloads).
    • History Tracking: View and manage all past workspace exports anytime via Workspace → Downloads & Export History (Ctrl/Cmd + J).
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("workspace/export.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const _export = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + _export as default +}; diff --git a/docs-site/.vitepress/.temp/workspace_graph.md.js b/docs-site/.vitepress/.temp/workspace_graph.md.js new file mode 100644 index 00000000..64123f98 --- /dev/null +++ b/docs-site/.vitepress/.temp/workspace_graph.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Workspace Graph","description":"Explore links and relations between your notes using the visual workspace graph.","frontmatter":{"title":"Workspace Graph","description":"Explore links and relations between your notes using the visual workspace graph.","keywords":"graph, workspace graph, node link, connections, semantic clustering","category":"Workspace"},"headers":[],"relativePath":"workspace/graph.md","filePath":"workspace/graph.md","lastUpdated":1783855203000}'); +const _sfc_main = { name: "workspace/graph.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Workspace Graph

    The Workspace Graph is an interactive visualizer that maps notes and media files, helping you discover connections and trace relationships.

    1. Navigating the Graph

    Open the graph from Workspace → Workspace Graph:

    • Zoom and pan using the mouse wheel/drag.
    • Click and drag nodes to rearrange the visual layout.
    • Hover over nodes to highlight their direct neighbors.
    • Click a note node to open that note directly.

    2. Node Types

    • Note Nodes: Represent Markdown files.
    • Media Nodes: Represent images, PDFs, and assets referenced by notes.
    • Disconnected Nodes: Represent orphan notes containing no links.

    3. Semantic Clustering (AI-Powered)

    When AI features are active, the graph clusters related notes using semantic similarity. If the clustering falls out of date, click Refresh to rebuild the semantic relations.

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("workspace/graph.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const graph = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + graph as default +}; diff --git a/docs-site/.vitepress/.temp/workspace_index.md.js b/docs-site/.vitepress/.temp/workspace_index.md.js new file mode 100644 index 00000000..83f86e8e --- /dev/null +++ b/docs-site/.vitepress/.temp/workspace_index.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Workspace Management","description":"Learn how to manage workspaces, notes, folders, and navigate the dashboard in Notely.","frontmatter":{"title":"Workspace Management","description":"Learn how to manage workspaces, notes, folders, and navigate the dashboard in Notely.","keywords":"workspace, landing screen, folders, sidebar, dashboard, favorites, continue writing","category":"Workspace"},"headers":[],"relativePath":"workspace/index.md","filePath":"workspace/index.md","lastUpdated":1786126353000}'); +const _sfc_main = { name: "workspace/index.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Workspace Overview

    A workspace is the single source of truth for your notes in Notely. It maps to a folder on your local filesystem containing Markdown documents and asset subfolders.

    1. Landing Dashboard

    When you open a workspace, you are greeted by the landing dashboard, which provides quick access to recent work and workspace health:

    • Continue Writing: Shows the single most recently edited note to resume editing instantly.
    • Recent Notes: Displays a chronological list of recent notes.
    • Favorites: Starred notes for immediate access.
    • Open Tasks: Summarizes unchecked tasks across the workspace.

    2. Note and Folder Creation

    • New Note: Create notes from File → New Note (Ctrl + N).
    • New Folder: Create subfolders inside the sidebar list view to group notes logically.
    • Rename & Delete: Available from the note context menu. Deleted files are safely moved to the "Removed" folder pool managed by Notely.

    3. Density & Layout Views

    Customize how you browse your workspace contents:

    • Tile View: Card-style layout showing note content previews.
    • Table View: Compact, grid-based list view for scanning large note lists quickly. Double-click any note row in Table View to open it immediately.
    • Comfortable Density: Added margins and breathing room.
    • Compact Density: High-density display for reviewing many documents at once.

    4. Workspace Tools & Embedded Terminal

    Notely includes integrated workspace utilities for project productivity:


    5. Workspace & Document Reloading

    Keep your workspace and active notes synchronized with external changes on disk:

    • Reload Workspace: Click the Reload button in the landing list controls, select Workspace → Reload Workspace (Ctrl + Alt + R), or run Reload Workspace from Disk in the Command Palette to re-scan all workspace documents, folder structures, open note tabs, and git status.
    • External Change Banner & Reload Note: When an active note is modified externally by another tool or process, Notely detects the change, temporarily disables autosave to prevent overwriting disk state, and displays a warning banner. Click Reload content from disk, select File → Reload Note from Disk (Ctrl + Shift + R), right-click the note tab and choose Reload from Disk, or use the Command Palette to force-load the latest file content from disk.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("workspace/index.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + index as default +}; diff --git a/docs-site/.vitepress/.temp/workspace_media.md.js b/docs-site/.vitepress/.temp/workspace_media.md.js new file mode 100644 index 00000000..eb819d9e --- /dev/null +++ b/docs-site/.vitepress/.temp/workspace_media.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs, ssrRenderStyle } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Media Management","description":"How to manage files, images, PDFs, annotations, and health checks in Notely.","frontmatter":{"title":"Media Management","description":"How to manage files, images, PDFs, annotations, and health checks in Notely.","keywords":"media, assets, images, pdf, workspace health, annotations","category":"Workspace"},"headers":[],"relativePath":"workspace/media.md","filePath":"workspace/media.md","lastUpdated":1783855203000}'); +const _sfc_main = { name: "workspace/media.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Media

    Notely includes an integrated asset library for linking, viewing, and managing media files inside your notes.

    1. Asset Storage

    All inserted files (images, PDFs, documents) are stored inside the assets/ subfolder in your workspace. Markdown links refer to them relatively:

    markdown
    ![My Image](./assets/image.png)

    2. Image Tools & Annotation

    When viewing a note in Preview mode, hover over an image or right-click to access tools:

    • Crop: Recut and trim the image in-app.
    • Annotate: Draw callout lines, arrows, highlights, and text notes on top of the image.
    • Original Restore: Notely stores a backup of the original asset before your first edit, letting you revert changes later.

    3. Workspace Health Checks

    Keep your assets tidy using the Media Health Dashboard:

    • Unused Media: Lists media files in assets/ not referenced by any note. Offers bulk-deletion.
    • Missing Assets: Displays links in notes pointing to files that do not exist.
    • Duplicate Media: Highlights duplicate file contents to save storage.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("workspace/media.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const media = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + media as default +}; diff --git a/docs-site/.vitepress/.temp/workspace_screen-capture.md.js b/docs-site/.vitepress/.temp/workspace_screen-capture.md.js new file mode 100644 index 00000000..0a589d0d --- /dev/null +++ b/docs-site/.vitepress/.temp/workspace_screen-capture.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Screen Capture","description":"Capture areas of your screen and insert them directly into notes (Windows).","frontmatter":{"title":"Screen Capture","description":"Capture areas of your screen and insert them directly into notes (Windows).","keywords":"screen capture, screenshot, windows snip, review mode, auto insert","category":"Workspace"},"headers":[],"relativePath":"workspace/screen-capture.md","filePath":"workspace/screen-capture.md","lastUpdated":1783855203000}'); +const _sfc_main = { name: "workspace/screen-capture.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Screen Capture

    On Windows systems, Notely supports direct screen capture, allowing you to snip visual areas and paste them instantly into your active note.

    1. How to Capture

    1. Position your cursor in the editor where you want the image link placed.
    2. Click the toolbar 📷 Capture button or press Ctrl + Shift + S.
    3. Select the target area using the Windows snip overlay.

    2. Capture Modes

    Configure capture behavior in Settings → Screen Capture:

    • Auto Insert: Inserts the captured image immediately as a Markdown reference. The file is saved automatically under assets/.
    • Review Before Insert: Opens a review editor where you can crop, annotate, or rename the captured image before saving.

    3. Toolbar Indicators

    The toolbar icon shows the current mode:

    • 📷 A: Auto Insert mode active.
    • 📷 R: Review Before Insert mode active.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("workspace/screen-capture.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const screenCapture = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + screenCapture as default +}; diff --git a/docs-site/.vitepress/.temp/workspace_tasks.md.js b/docs-site/.vitepress/.temp/workspace_tasks.md.js new file mode 100644 index 00000000..3ccbd924 --- /dev/null +++ b/docs-site/.vitepress/.temp/workspace_tasks.md.js @@ -0,0 +1,25 @@ +import { ssrRenderAttrs, ssrRenderStyle } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Tasks Management","description":"Comprehensive documentation for task tracking, interactive preview task toggling, task detail modal, bi-directional markdown synchronization, and workspace-wide task management in Notely.","frontmatter":{"title":"Tasks Management","description":"Comprehensive documentation for task tracking, interactive preview task toggling, task detail modal, bi-directional markdown synchronization, and workspace-wide task management in Notely.","keywords":"tasks, checklists, todos, task workspace, task detail modal, bi-directional sync, deduplication","category":"Workspace"},"headers":[],"relativePath":"workspace/tasks.md","filePath":"workspace/tasks.md","lastUpdated":1786125015000}'); +const _sfc_main = { name: "workspace/tasks.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Tasks & Checklists

    Notely turns standard Markdown checklist checkboxes into a workspace-wide task management system. Tasks written inside any note automatically sync in real-time with a SQLite task database, providing bi-directional status updates, detail management, and workspace-wide task views.


    1. Creating Tasks in Notes

    Create tasks inside any note using standard Markdown checklist syntax:

    markdown
    - [ ] Open task
    +- [x] Completed task
    +1. [ ] Numbered list task
    +- [ ] High priority task #work @alex

    Supported Formats

    • Bullet Lists: - [ ], * [ ], + [ ]
    • Numbered Lists: 1. [ ], 2. [ ]
    • Standalone Paragraph Tasks: [ ] Standalone task

    2. Interactive Preview Toggling & Task Modal

    When viewing notes in Preview Mode or Split View:

    • Click to Toggle: Clicking the [ ] checkbox directly toggles its status between Open ([ ]) and Completed ([x]).
    • Interactive Task Modal: Clicking the task text opens the Task Detail Modal where you can manage extended task attributes:
      • Status: Toggle between Open, In Progress, and Completed.
      • Priority: Set priority levels (Low, Medium, High, Urgent).
      • Due Date & Scheduling: Assign due dates, start/end times, and all-day flags.
      • Assignees & Tags: Tag team members or add custom categories.
      • Comments: Add discussion threads to individual tasks.
      • Note Source Link: Jump directly to the exact line number in the source note.

    3. Bi-Directional Markdown Synchronization

    Task statuses update bi-directionally between your Markdown files and the Task Workspace:

    +------------------+         Real-Time IPC         +-------------------+
    +|  Markdown Note   |  <=========================>  | SQLite Task DB &  |
    +| (- [x] Task 1)   |   Pre-Save Buffer Sync    | Task Workspace UI |
    ++------------------+                               +-------------------+
    • Markdown → Task DB: Edits inside the text editor automatically sync to the task database whenever the note is saved.
    • Task DB → Markdown: Updating task status from the Task Workspace or Task Detail Modal writes - [x] or - [ ] directly back into the .md file.
    • Buffer Safety: Active unsaved editor changes are committed to disk before task updates execute, preventing data loss, file watcher hash mismatches, or disk conflict warnings.

    4. Smart Alignment & Deduplication Engine

    Notely uses a 4-pass alignment algorithm to maintain task identity across note refactoring and line shifts:

    1. Pass 1: Exact Hash Match: Matches SHA1(filePath + title + occurrenceIndex).
    2. Pass 2: Line Number Match: Preserves task identity when task titles are edited on the same line index.
    3. Pass 3: Fuzzy Similarity Match: Uses Jaccard word similarity (>0.35 threshold) to track tasks when lines move and title text is tweaked simultaneously.
    4. Pass 4: Orphan Purging: Auto-removes database records when tasks are permanently deleted from a Markdown file.

    5. Note-Level Task Bar & Workspace Dashboard

    Note-Level Task Summary

    When editing any note, the top header displays a live task completion progress indicator (e.g. 2/5 tasks). Clicking this indicator opens the Task Summary Popover, listing all open and completed tasks for that note with direct line-jump buttons.

    Workspace Task Page

    Access the full Task Workspace via the left sidebar or Command Palette (Ctrl + Shift + T):

    • Filter by Note: Focus on tasks from the active note or view tasks across all project notes.
    • Status Tabs: Easily switch between All, Open, In Progress, and Completed.
    • Search & Sort: Filter tasks by title, priority, due date, or assignee.
    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("workspace/tasks.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const tasks = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + tasks as default +}; diff --git a/docs-site/.vitepress/.temp/workspace_terminal.md.js b/docs-site/.vitepress/.temp/workspace_terminal.md.js new file mode 100644 index 00000000..1eb5ac7e --- /dev/null +++ b/docs-site/.vitepress/.temp/workspace_terminal.md.js @@ -0,0 +1,19 @@ +import { ssrRenderAttrs } from "vue/server-renderer"; +import { useSSRContext } from "vue"; +import { _ as _export_sfc } from "./plugin-vue_export-helper.1tPrXgE0.js"; +const __pageData = JSON.parse('{"title":"Embedded Terminal","description":"Work with terminal commands, local scripts, and build tools directly inside Notely.","frontmatter":{"title":"Embedded Terminal","description":"Work with terminal commands, local scripts, and build tools directly inside Notely.","keywords":"terminal, shell, bash, cmd, powershell, pty, node-pty, terminal policy, allowlist","category":"Workspace"},"headers":[],"relativePath":"workspace/terminal.md","filePath":"workspace/terminal.md","lastUpdated":1786126353000}'); +const _sfc_main = { name: "workspace/terminal.md" }; +function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { + _push(`

    Embedded Terminal

    Notely features an integrated, full-featured Embedded Terminal powered by node-pty. Run project-local commands, build scripts, git commands, and shell utilities without leaving your workspace.


    1. Opening & Toggling the Terminal

    • View Menu: Open View → Show Terminal.
    • Command Palette: Press Ctrl/Cmd + K and select Show Terminal.
    • Bottom Panel: Toggle the terminal drawer at the bottom of your workspace layout.

    2. Shell Selection & Configuration

    Select your preferred shell from View → Terminal Shell:

    • Auto: Automatically selects the default shell based on your host operating system.
    • Bash: Prefers Bash when installed (e.g. Git Bash on Windows or native Bash on macOS/Linux).
    • CMD: Uses standard Windows Command Prompt (cmd.exe).
    • PowerShell: Uses PowerShell (powershell.exe or pwsh).

    Custom Shell Path Overrides (Environment Variables)

    On Windows systems, you can override default shell binary paths using environment variables:

    • NOTELY_BASH_PATH: Absolute path to a specific Bash executable.
    • GIT_BASH_PATH: Fallback path to Git Bash executable.

    3. Working Directory & Lifecycle

    • Workspace Alignment: The terminal automatically sets its initial working directory (CWD) to your active project workspace root ({workspace}/).
    • Session Lifecycle: Terminal PTY sessions persist as long as the panel is open. Closing the terminal drawer terminates the PTY subprocess cleanly to free system resources.
    • Resize Behavior: The terminal automatically adjusts its columns and rows dynamically as you resize the panel drawer.

    4. Security Policies & Strict Allowlist Mode

    Notely includes enterprise security controls to restrict terminal command execution when operating in sensitive workspace environments:

    Policy Modes (NOTELY_TERMINAL_POLICY)

    • Permissive Mode (permissive, default): Standard interactive shell access allowing any user command.
    • Strict Mode (strict): Restricts command execution to a pre-approved list of command binaries and enforces user role policies.

    Environment Variable Security Flags

    VariableDescription
    NOTELY_TERMINAL_POLICYSet to strict to enforce command allowlisting.
    NOTELY_TERMINAL_REQUIRED_ROLERequired user role (defaults to developer).
    NOTELY_TERMINAL_ALLOWLISTComma-separated list of allowed command executables (e.g. git,npm,node,dir,ls).

    Strict Policy Enforcement

    When NOTELY_TERMINAL_POLICY=strict is active, any command execution attempt outside the NOTELY_TERMINAL_ALLOWLIST is blocked by IPC security guards before spawning.

    `); +} +const _sfc_setup = _sfc_main.setup; +_sfc_main.setup = (props, ctx) => { + const ssrContext = useSSRContext(); + (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("workspace/terminal.md"); + return _sfc_setup ? _sfc_setup(props, ctx) : void 0; +}; +const terminal = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); +export { + __pageData, + terminal as default +}; diff --git a/electron/lib/export/ExportManager.cjs b/electron/lib/export/ExportManager.cjs index 09ee62b9..c107fc25 100644 --- a/electron/lib/export/ExportManager.cjs +++ b/electron/lib/export/ExportManager.cjs @@ -3,7 +3,7 @@ const fsAsync = require("fs").promises; const path = require("path"); const os = require("os"); const crypto = require("crypto"); -const { pathToFileURL, fileURLToPath } = require("node:url"); +const { pathToFileURL } = require("node:url"); const { ZipFile } = require("yazl"); const PDF_WRITE_RETRY_DELAYS_MS = [120, 320, 700]; @@ -552,7 +552,7 @@ class ExportManager { copyDir(sourceRoot, targetRoot); } - async _exportPdfWorkspace({ notesRoot, stagingRoot, contentMode }) { + async _exportPdfWorkspace({ notesRoot, stagingRoot, _contentMode }) { const markdownFiles = this._walkFiles(notesRoot, { excludeDirs: [".notes-app", "node_modules", ".git", ".artifacts", "dist", "build"], }).filter((filePath) => path.extname(filePath).toLowerCase() === ".md"); @@ -623,7 +623,7 @@ class ExportManager { } } - _exportWebWorkspace({ notesRoot, stagingRoot, contentMode }) { + _exportWebWorkspace({ notesRoot, stagingRoot, _contentMode }) { const allFiles = this._walkFiles(notesRoot, { excludeDirs: [".notes-app", "node_modules", ".git", ".artifacts", "dist", "build"], }); diff --git a/src/components/MarkdownPreview.jsx b/src/components/MarkdownPreview.jsx index 7f34a28d..7e5a3715 100644 --- a/src/components/MarkdownPreview.jsx +++ b/src/components/MarkdownPreview.jsx @@ -1,6 +1,5 @@ import { useEffect, useMemo, useRef, useState, memo } from "react"; -import { createPortal } from "react-dom"; -import { Search, Copy, ExternalLink, Pencil, RefreshCw, Trash2, RotateCcw, Download, FolderOpen } from "lucide-react"; +import { Search, Copy, ExternalLink, Pencil, RefreshCw, Trash2, RotateCcw } from "lucide-react"; import { renderMarkdown, parseDiagramBlocks, @@ -479,117 +478,6 @@ export const MarkdownPreview = memo(function MarkdownPreviewContent({ const [contextMenu, setContextMenu] = useState(null); const handleLinkNavigateRef = useRef(null); - const handleCopyLinkFromPreview = (href) => { - if (!href) return; - navigator.clipboard.writeText(href); - onNotify?.(`Copied link path: ${href}`, "success"); - }; - - const handleDownloadFileFromPreview = (href) => { - if (!href) return; - const resolvedPath = resolveAnyLocalLinkPath(basePath, href) || String(href || "").trim().replace(/^file:\/\/\/?/i, "").split(/[?#]/)[0]; - const ext = resolvedPath.split(".").pop()?.toLowerCase(); - const mediaType = getMediaTypeFromExtension(ext) || "document"; - - if (typeof onMediaClick === "function") { - onMediaClick({ path: resolvedPath, type: mediaType }); - } else if (basePath && typeof openMediaInDefaultApp === "function") { - openMediaInDefaultApp(basePath, resolvedPath).catch((err) => { - onNotify?.(err?.message || "Failed to open file.", "error"); - }); - } - }; - - const handleDirectDownloadFileFromPreview = async (href) => { - if (!href) return; - try { - const resolvedPath = resolveAnyLocalLinkPath(basePath, href) || String(href || "").trim().replace(/^file:\/\/\/?/i, "").split(/[?#]/)[0]; - const filename = resolvedPath.split(/[/\\]/).pop() || "file"; - - let downloadSrc = resolvedPath; - if (basePath && downloadSrc && !/^(https?:|data:|blob:)/i.test(downloadSrc)) { - try { - const loaded = await readImage(basePath, downloadSrc); - if (loaded) downloadSrc = loaded; - } catch { /* keep resolvedPath */ } - } - - let dataUrl; - let srcPath; - - if (typeof downloadSrc === "string" && downloadSrc.startsWith("data:")) { - dataUrl = downloadSrc; - } else if (typeof downloadSrc === "string" && (downloadSrc.startsWith("blob:") || downloadSrc.startsWith("http"))) { - const resp = await fetch(downloadSrc); - const blob = await resp.blob(); - dataUrl = await new Promise((resolve) => { - const reader = new FileReader(); - reader.onloadend = () => resolve(reader.result); - reader.readAsDataURL(blob); - }); - } else { - srcPath = downloadSrc; - } - - const result = await runExport("media", { - dataUrl, - srcPath, - filename, - }); - - if (result?.success) { - onNotify?.(`Downloaded ${result.filename} to Downloads folder`, "success"); - } else { - onNotify?.(result?.error || "Failed to download file.", "error"); - } - } catch (err) { - onNotify?.(err?.message || "Failed to download file.", "error"); - } - }; - - const handleExportTableImage = async (tableWrapper) => { - if (!tableWrapper) return; - try { - const dataUrl = await tableElementToPngDataUrl(tableWrapper); - const result = await runExport("media", { - dataUrl, - filename: "table.png", - customExportType: "image", - category: "media", - }); - if (result?.success) { - onNotify?.(`Table image exported to ${result.filename}`, "success"); - } else { - onNotify?.(result?.error || "Export failed", "error"); - } - } catch (err) { - onNotify?.(`Failed to export table image: ${err?.message || "Unknown error"}`, "error"); - } - }; - - const handleExportTableCsv = async (tableWrapper) => { - if (!tableWrapper) return; - try { - const csvContent = tableElementToCsv(tableWrapper); - if (!csvContent) { - throw new Error("Table content is empty."); - } - const dataUrl = `data:text/csv;charset=utf-8,${encodeURIComponent(csvContent)}`; - const result = await runExport("media", { - dataUrl, - filename: "table.csv", - customExportType: "csv", - category: "document", - }); - if (result?.success) { - onNotify?.(`Table CSV exported to ${result.filename}`, "success"); - } else { - onNotify?.(result?.error || "Export failed", "error"); - } - } catch (err) { - onNotify?.(`Failed to export table CSV: ${err?.message || "Unknown error"}`, "error"); - } - }; const [menuIndex, setMenuIndex] = useState(0); const [cropSaving, setCropSaving] = useState(false); @@ -998,6 +886,117 @@ export const MarkdownPreview = memo(function MarkdownPreviewContent({ } } }; + const handleCopyLinkFromPreview = (href) => { + if (!href) return; + navigator.clipboard.writeText(href); + onNotify?.(`Copied link path: ${href}`, "success"); + }; + + const handleDownloadFileFromPreview = (href) => { + if (!href) return; + const resolvedPath = resolveAnyLocalLinkPath(basePath, href) || String(href || "").trim().replace(/^file:\/\/\/?/i, "").split(/[?#]/)[0]; + const ext = resolvedPath.split(".").pop()?.toLowerCase(); + const mediaType = getMediaTypeFromExtension(ext) || "document"; + + if (typeof onMediaClick === "function") { + onMediaClick({ path: resolvedPath, type: mediaType }); + } else if (basePath && typeof openMediaInDefaultApp === "function") { + openMediaInDefaultApp(basePath, resolvedPath).catch((err) => { + onNotify?.(err?.message || "Failed to open file.", "error"); + }); + } + }; + + const handleDirectDownloadFileFromPreview = async (href) => { + if (!href) return; + try { + const resolvedPath = resolveAnyLocalLinkPath(basePath, href) || String(href || "").trim().replace(/^file:\/\/\/?/i, "").split(/[?#]/)[0]; + const filename = resolvedPath.split(/[/\\]/).pop() || "file"; + + let downloadSrc = resolvedPath; + if (basePath && downloadSrc && !/^(https?:|data:|blob:)/i.test(downloadSrc)) { + try { + const loaded = await readImage(basePath, downloadSrc); + if (loaded) downloadSrc = loaded; + } catch { /* keep resolvedPath */ } + } + + let dataUrl; + let srcPath; + + if (typeof downloadSrc === "string" && downloadSrc.startsWith("data:")) { + dataUrl = downloadSrc; + } else if (typeof downloadSrc === "string" && (downloadSrc.startsWith("blob:") || downloadSrc.startsWith("http"))) { + const resp = await fetch(downloadSrc); + const blob = await resp.blob(); + dataUrl = await new Promise((resolve) => { + const reader = new FileReader(); + reader.onloadend = () => resolve(reader.result); + reader.readAsDataURL(blob); + }); + } else { + srcPath = downloadSrc; + } + + const result = await runExport("media", { + dataUrl, + srcPath, + filename, + }); + + if (result?.success) { + onNotify?.(`Downloaded ${result.filename} to Downloads folder`, "success"); + } else { + onNotify?.(result?.error || "Failed to download file.", "error"); + } + } catch (err) { + onNotify?.(err?.message || "Failed to download file.", "error"); + } + }; + + const handleExportTableImage = async (tableWrapper) => { + if (!tableWrapper) return; + try { + const dataUrl = await tableElementToPngDataUrl(tableWrapper); + const result = await runExport("media", { + dataUrl, + filename: "table.png", + customExportType: "image", + category: "media", + }); + if (result?.success) { + onNotify?.(`Table image exported to ${result.filename}`, "success"); + } else { + onNotify?.(result?.error || "Export failed", "error"); + } + } catch (err) { + onNotify?.(`Failed to export table image: ${err?.message || "Unknown error"}`, "error"); + } + }; + + const handleExportTableCsv = async (tableWrapper) => { + if (!tableWrapper) return; + try { + const csvContent = tableElementToCsv(tableWrapper); + if (!csvContent) { + throw new Error("Table content is empty."); + } + const dataUrl = `data:text/csv;charset=utf-8,${encodeURIComponent(csvContent)}`; + const result = await runExport("media", { + dataUrl, + filename: "table.csv", + customExportType: "csv", + category: "document", + }); + if (result?.success) { + onNotify?.(`Table CSV exported to ${result.filename}`, "success"); + } else { + onNotify?.(result?.error || "Export failed", "error"); + } + } catch (err) { + onNotify?.(`Failed to export table CSV: ${err?.message || "Unknown error"}`, "error"); + } + }; const handleMediaClick = async (event) => { const target = event.target;