ObsiGate/frontend/index.html
Bruno Charest 9f00455064
Some checks failed
CI / lint (push) Failing after 7s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / security (push) Successful in 10s
docs: guide d'utilisation enrichi + navigation clavier — sections Tabs, Édition, Graphe, Palette, Partage, Sauvegardes, Sécurité
2026-06-02 15:25:08 -04:00

1449 lines
83 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="fr" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ObsiGate</title>
<!-- PWA Meta Tags -->
<meta name="description" content="Porte d'entrée web pour vos vaults Obsidian - Accédez, naviguez et recherchez dans toutes vos notes">
<meta name="theme-color" content="#2563eb">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="ObsiGate">
<!-- PWA Manifest -->
<link rel="manifest" href="/static/manifest.json">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" sizes="152x152" href="/static/icons/icon-152x152.svg">
<link rel="apple-touch-icon" sizes="192x192" href="/static/icons/icon-192x192.svg">
<!-- Favicon -->
<link rel="icon" type="image/svg+xml" href="/static/icons/icon-72x72.svg">
<link rel="icon" type="image/png" sizes="192x192" href="/static/icons/icon-192x192.svg">
<link rel="stylesheet" href="/static/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css" id="hljs-theme-dark">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css" id="hljs-theme-light" disabled>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<script src="https://unpkg.com/lucide@0.344.0/dist/umd/lucide.min.js"></script>
<script type="importmap">
{
"imports": {
"@codemirror/state": "https://esm.sh/@codemirror/state@6.2.0"
}
}
</script>
<!-- CodeMirror 6 -->
<script type="module">
import { EditorView, keymap, lineNumbers, highlightActiveLineGutter, highlightSpecialChars, drawSelection, dropCursor, rectangularSelection, crosshairCursor, highlightActiveLine } from "https://esm.sh/@codemirror/view@6.9.0?external=@codemirror/state";
import { EditorState } from "@codemirror/state";
import { defaultHighlightStyle, syntaxHighlighting, indentOnInput, bracketMatching, foldGutter, foldKeymap } from "https://esm.sh/@codemirror/language@6.6.0?external=@codemirror/state";
import { defaultKeymap, history, historyKeymap } from "https://esm.sh/@codemirror/commands@6.2.3?external=@codemirror/state";
import { searchKeymap, highlightSelectionMatches } from "https://esm.sh/@codemirror/search@6.3.0?external=@codemirror/state";
import { autocompletion, completionKeymap, closeBrackets, closeBracketsKeymap } from "https://esm.sh/@codemirror/autocomplete@6.5.0?external=@codemirror/state";
import { markdown } from "https://esm.sh/@codemirror/lang-markdown@6.1.0?external=@codemirror/state";
import { python } from "https://esm.sh/@codemirror/lang-python@6.1.3?external=@codemirror/state";
import { javascript } from "https://esm.sh/@codemirror/lang-javascript@6.1.7?external=@codemirror/state";
import { html } from "https://esm.sh/@codemirror/lang-html@6.4.3?external=@codemirror/state";
import { css } from "https://esm.sh/@codemirror/lang-css@6.2.0?external=@codemirror/state";
import { json } from "https://esm.sh/@codemirror/lang-json@6.0.1?external=@codemirror/state";
import { xml } from "https://esm.sh/@codemirror/lang-xml@6.0.2?external=@codemirror/state";
import { sql } from "https://esm.sh/@codemirror/lang-sql@6.5.0?external=@codemirror/state";
import { php } from "https://esm.sh/@codemirror/lang-php@6.0.1?external=@codemirror/state";
import { cpp } from "https://esm.sh/@codemirror/lang-cpp@6.0.2?external=@codemirror/state";
import { java } from "https://esm.sh/@codemirror/lang-java@6.0.1?external=@codemirror/state";
import { rust } from "https://esm.sh/@codemirror/lang-rust@6.0.1?external=@codemirror/state";
import { oneDark } from "https://esm.sh/@codemirror/theme-one-dark@6.1.0?external=@codemirror/state";
const basicSetup = [
lineNumbers(),
highlightActiveLineGutter(),
highlightSpecialChars(),
history(),
foldGutter(),
drawSelection(),
dropCursor(),
EditorState.allowMultipleSelections.of(true),
indentOnInput(),
syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
bracketMatching(),
closeBrackets(),
autocompletion(),
rectangularSelection(),
crosshairCursor(),
highlightActiveLine(),
highlightSelectionMatches(),
keymap.of([
...closeBracketsKeymap,
...defaultKeymap,
...searchKeymap,
...historyKeymap,
...foldKeymap,
...completionKeymap,
])
];
window.CodeMirror = { EditorView, EditorState, basicSetup, markdown, python, javascript, html, css, json, xml, sql, php, cpp, java, rust, oneDark, keymap };
</script>
</head>
<body>
<div class="search-progress-bar" id="search-progress-bar"><div class="search-progress-bar__fill"></div></div>
<!-- Login Screen (hidden by default, shown when auth is required) -->
<div id="login-screen" class="login-screen hidden">
<div class="login-card">
<div class="login-header">
<div class="login-logo">
<span class="login-logo-icon">📖</span>
<span class="login-logo-text">ObsiGate</span>
</div>
<p class="login-subtitle">Accès sécurisé à vos vaults</p>
</div>
<form id="login-form" class="login-form" autocomplete="on">
<div class="form-group">
<label for="login-username">Nom d'utilisateur</label>
<input type="text" id="login-username" name="username" autocomplete="username" placeholder="utilisateur" required autofocus />
</div>
<div class="form-group">
<label for="login-password">Mot de passe</label>
<div class="password-input-wrapper">
<input type="password" id="login-password" name="password" autocomplete="current-password" placeholder="••••••••" required />
<button type="button" id="toggle-password" class="password-toggle" aria-label="Afficher le mot de passe">👁</button>
</div>
</div>
<div class="form-group form-group--inline">
<label class="checkbox-label">
<input type="checkbox" id="remember-me" name="remember_me" />
<span>Se souvenir de moi (30 jours)</span>
</label>
</div>
<div id="login-error" class="login-error hidden"></div>
<button type="submit" id="login-btn" class="btn-login">
<span class="btn-text">Se connecter</span>
<span class="btn-spinner hidden"></span>
</button>
</form>
</div>
</div>
<!-- Main Application (wrapped for show/hide) -->
<div id="app" class="app-container">
<!-- Header -->
<header class="header">
<div class="header-left">
<button class="hamburger-btn" id="hamburger-btn" title="Menu">
<i data-lucide="menu" style="width:20px;height:20px"></i>
</button>
<button class="sidebar-toggle-btn" id="sidebar-toggle-btn" title="Afficher/Masquer la sidebar">
<i data-lucide="sidebar" style="width:20px;height:20px"></i>
</button>
<div class="header-logo" id="header-logo">
<i data-lucide="book-open" style="width:20px;height:20px"></i>
ObsiGate
</div>
<span class="sync-badge sync-badge--disconnected" id="sync-badge" title="Synchronisation"></span>
</div>
<div class="header-center">
<div class="search-wrapper">
<i data-lucide="search" class="search-icon" style="width:16px;height:16px"></i>
<div class="search-input-wrapper">
<input type="text" id="search-input" placeholder="Rechercher dans tous les fichiers..." autocomplete="off">
<div class="search-actions">
<button class="search-btn tog" id="search-case-btn" type="button" title="Respecter la casse (Alt-C)">Aa</button>
<button class="search-btn tog" id="search-word-btn" type="button" title="Mot entier (Alt-W)">wd</button>
<button class="search-btn tog" id="search-regex-btn" type="button" title="Expression régulière (Alt-R)">.*</button>
<span class="search-sep"></span>
<button class="search-btn icon-only" id="search-filter-btn" type="button" title="Filtres de chemin (Alt-F)">
<i data-lucide="filter" style="width:14px;height:14px"></i>
</button>
<span class="search-sep"></span>
<span class="search-count" id="search-match-count">0/0</span>
<button class="search-btn icon-only" id="search-prev-btn" type="button" title="Résultat précédent">&#8593;</button>
<button class="search-btn icon-only" id="search-next-btn" type="button" title="Résultat suivant">&#8595;</button>
<button class="search-btn icon-only" id="search-clear-btn" type="button" title="Effacer" aria-label="Effacer la recherche">
<i data-lucide="x" style="width:14px;height:14px"></i>
</button>
</div>
</div>
<!-- Path filter row -->
<div class="search-filter-row" id="search-filter-row" style="display:none">
<input type="text" class="search-filter-input" id="search-include-input" placeholder="Inclure: **/*.md, notes/**">
<input type="text" class="search-filter-input" id="search-exclude-input" placeholder="Exclure: vendor/*, *.lock">
</div>
<!-- Advanced search autocomplete dropdown -->
<div class="search-dropdown" id="search-dropdown" role="listbox" aria-label="Suggestions de recherche" hidden>
<div class="search-dropdown__section search-dropdown__section--history" id="search-dropdown-history">
<div class="search-dropdown__section-header">
<span>Historique</span>
<button class="search-dropdown__clear-btn" id="search-dropdown-clear-history" type="button" title="Effacer l'historique">
<i data-lucide="trash-2" style="width:12px;height:12px"></i>
</button>
</div>
<ul class="search-dropdown__list" id="search-dropdown-history-list"></ul>
</div>
<div class="search-dropdown__section search-dropdown__section--titles" id="search-dropdown-titles">
<div class="search-dropdown__section-header"><span>Fichiers</span></div>
<ul class="search-dropdown__list" id="search-dropdown-titles-list"></ul>
</div>
<div class="search-dropdown__section search-dropdown__section--tags" id="search-dropdown-tags">
<div class="search-dropdown__section-header"><span>Tags</span></div>
<ul class="search-dropdown__list" id="search-dropdown-tags-list"></ul>
</div>
<div class="search-dropdown__empty" id="search-dropdown-empty" hidden>
Aucune suggestion
</div>
</div>
<!-- Active search filter chips -->
<div class="search-chips" id="search-chips" hidden></div>
</div>
</div>
<div class="header-right">
<div class="vault-context-indicator" id="vault-context-indicator" title="Contexte vault actif">
<i data-lucide="database" style="width:14px;height:14px"></i>
<span id="vault-context-text">All</span>
</div>
<!-- User menu (visible when logged in) -->
<div class="user-menu" id="user-menu"></div>
<div class="header-menu">
<button class="header-menu-btn" id="header-menu-btn" title="Options">
<i data-lucide="settings" style="width:18px;height:18px"></i>
</button>
<div class="header-menu-dropdown" id="header-menu-dropdown">
<div class="menu-list" role="menu" aria-label="Options">
<label class="menu-list-row menu-list-select-row hidden" for="vault-filter">
<span class="menu-list-icon" aria-hidden="true">
<i data-lucide="folders" style="width:17px;height:17px"></i>
</span>
<span class="menu-list-content">
<span class="menu-list-title">Vault</span>
<div class="custom-dropdown" id="vault-filter-dropdown">
<button class="custom-dropdown-trigger" type="button" aria-haspopup="listbox" aria-expanded="false">
<span class="custom-dropdown-selected">Tous les vaults</span>
<i data-lucide="chevron-down" style="width:14px;height:14px"></i>
</button>
<ul class="custom-dropdown-menu" role="listbox" id="vault-filter-options">
<li role="option" data-value="all" class="custom-dropdown-option selected">Tous les vaults</li>
</ul>
<input type="hidden" id="vault-filter" value="all">
</div>
</span>
</label>
<button class="menu-list-row menu-list-button" id="theme-toggle" type="button" role="menuitem">
<span class="menu-list-icon" aria-hidden="true">
<i data-lucide="sun" style="width:17px;height:17px"></i>
</span>
<span class="menu-list-content">
<span class="menu-list-title">Thème</span>
<span class="menu-list-subtitle" id="theme-label">Clair</span>
</span>
</button>
<button class="menu-list-row menu-list-button hidden" id="admin-menu-row" type="button" role="menuitem">
<span class="menu-list-icon" aria-hidden="true">
<i data-lucide="shield" style="width:17px;height:17px"></i>
</span>
<span class="menu-list-content">
<span class="menu-list-title">Administration</span>
<span class="menu-list-subtitle">Gérer les utilisateurs</span>
</span>
</button>
<button class="menu-list-row menu-list-button" id="config-open-btn" type="button" role="menuitem">
<span class="menu-list-icon" aria-hidden="true">
<i data-lucide="settings" style="width:17px;height:17px"></i>
</span>
<span class="menu-list-content">
<span class="menu-list-title">Configurations</span>
<span class="menu-list-subtitle">Paramètres de l'application</span>
</span>
</button>
<button class="menu-list-row menu-list-button" id="help-open-btn" type="button" role="menuitem">
<span class="menu-list-icon" aria-hidden="true">
<i data-lucide="book-open" style="width:17px;height:17px"></i>
</span>
<span class="menu-list-content">
<span class="menu-list-title">Guide d'utilisation</span>
<span class="menu-list-subtitle">Ouvrir l'aide</span>
</span>
</button>
</div>
</div>
</div>
</div>
</header>
<!-- Main -->
<div class="main-body">
<!-- Mobile overlay -->
<div class="sidebar-overlay" id="sidebar-overlay"></div>
<!-- Sidebar -->
<aside class="sidebar" id="sidebar" role="navigation" aria-label="Navigation des vaults">
<!-- Sidebar filter -->
<div class="sidebar-filter">
<div class="sidebar-filter-input-wrapper">
<i data-lucide="filter" class="sidebar-filter-icon" style="width:14px;height:14px"></i>
<input type="text" id="sidebar-filter-input" placeholder="Filtrer fichiers..." autocomplete="off">
<div class="sidebar-filter-actions">
<button class="sidebar-filter-btn" id="sidebar-filter-case-btn" type="button" title="Respecter la casse" aria-label="Respecter la casse">
<span>Aa</span>
</button>
<button class="sidebar-filter-btn" id="sidebar-filter-clear-btn" type="button" title="Effacer le filtrage" aria-label="Effacer le filtrage">
<i data-lucide="x" style="width:14px;height:14px"></i>
</button>
</div>
</div>
</div>
<!-- Tab bar -->
<div class="sidebar-tabs" role="tablist" aria-label="Sections sidebar">
<button class="sidebar-tab active" id="sidebar-tab-vaults" role="tab"
aria-selected="true" aria-controls="sidebar-panel-vaults" data-tab="vaults" title="Vaults">
<i data-lucide="folder-tree" style="width:18px;height:18px"></i>
</button>
<button class="sidebar-tab" id="sidebar-tab-tags" role="tab"
aria-selected="false" aria-controls="sidebar-panel-tags" data-tab="tags" title="Tags">
<i data-lucide="tag" style="width:18px;height:18px"></i>
</button>
<button class="sidebar-tab" id="sidebar-tab-recent" role="tab"
aria-selected="false" aria-controls="sidebar-panel-recent" data-tab="recent" title="Récent">
<i data-lucide="clock" style="width:18px;height:18px"></i>
</button>
<button class="sidebar-tab" id="sidebar-tab-saved" role="tab"
aria-selected="false" aria-controls="sidebar-panel-saved" data-tab="saved" title="Sauvegardes">
<i data-lucide="bookmark" style="width:18px;height:18px"></i>
</button>
</div>
<!-- Vaults panel -->
<div class="sidebar-tab-panel active" id="sidebar-panel-vaults" role="tabpanel" aria-labelledby="sidebar-tab-vaults">
<div class="custom-dropdown sidebar-dropdown" id="vault-quick-select-dropdown">
<button class="custom-dropdown-trigger" type="button" aria-haspopup="listbox" aria-expanded="false">
<span class="custom-dropdown-selected">Tous les vaults</span>
<i data-lucide="chevron-down" style="width:14px;height:14px"></i>
</button>
<ul class="custom-dropdown-menu" role="listbox" id="vault-quick-select-options">
<li role="option" data-value="all" class="custom-dropdown-option selected">Tous les vaults</li>
</ul>
<input type="hidden" id="vault-quick-select" value="all">
</div>
<div id="vault-tree" role="tree" aria-label="Arborescence des fichiers"></div>
</div>
<!-- Tags panel -->
<div class="sidebar-tab-panel" id="sidebar-panel-tags" role="tabpanel" aria-labelledby="sidebar-tab-tags">
<div class="tag-cloud" id="tag-cloud"></div>
</div>
<!-- Recent panel -->
<div class="sidebar-tab-panel" id="sidebar-panel-recent" role="tabpanel" aria-labelledby="sidebar-tab-recent">
<div class="recent-filter-bar">
<select id="recent-vault-filter">
<option value="">Tous les vaults</option>
</select>
</div>
<div id="recent-list" class="recent-list"></div>
<div id="recent-empty" class="recent-empty hidden">
<i data-lucide="inbox" style="width:32px;height:32px"></i>
<span>Aucun fichier récent</span>
</div>
</div>
<!-- Saved Searches panel -->
<div class="sidebar-tab-panel" id="sidebar-panel-saved" role="tabpanel" aria-labelledby="sidebar-tab-saved">
<div id="saved-searches-list" class="recent-list"></div>
<div id="saved-searches-empty" class="recent-empty">
<i data-lucide="bookmark" style="width:32px;height:32px"></i>
<span>Aucune recherche sauvegardée</span>
</div>
</div>
</aside>
<!-- Sidebar resize handle -->
<div class="sidebar-resize-handle" id="sidebar-resize-handle"></div>
<!-- Content Wrapper (tab bar + content area) -->
<div class="content-wrapper">
<!-- Tab bar -->
<div class="tab-bar" id="tab-bar" hidden>
<div class="tab-list" id="tab-list"></div>
</div>
<!-- Content -->
<main class="content-area" id="content-area" aria-label="Contenu principal">
<div id="dashboard-home" class="dashboard-home" role="region" aria-label="Tableau de bord">
<!-- Dashboard Tabs -->
<div class="dashboard-tabs">
<button class="dashboard-tab active" data-tab="stats">
<i data-lucide="bar-chart-3" style="width:14px;height:14px"></i> Statistiques
</button>
<button class="dashboard-tab" data-tab="bookmarks">
<i data-lucide="bookmark" style="width:14px;height:14px"></i> Bookmarks
</button>
<button class="dashboard-tab" data-tab="recent">
<i data-lucide="clock" style="width:14px;height:14px"></i> Récents
</button>
<button class="dashboard-tab" data-tab="shared">
<i data-lucide="share-2" style="width:14px;height:14px"></i> Partagés
</button>
</div>
<!-- Stats Panel -->
<div id="dashboard-panel-stats" class="dashboard-panel active">
<div id="dashboard-stats-grid" class="dashboard-stats-grid">
<div class="dashboard-stats-loading">Chargement...</div>
</div>
<div id="dashboard-conflicts-container" style="margin-top:16px"></div>
</div>
<!-- Bookmarks Panel -->
<div id="dashboard-panel-bookmarks" class="dashboard-panel">
<div id="dashboard-bookmarks-grid" class="dashboard-recent-grid"></div>
<div id="dashboard-bookmarks-empty" class="dashboard-recent-empty">
<i data-lucide="pin"></i>
<span>Aucun bookmark</span>
<p>Épinglez des fichiers pour les retrouver ici.</p>
</div>
</div>
<!-- Recent Panel -->
<div id="dashboard-panel-recent" class="dashboard-panel">
<div class="dashboard-header">
<div class="dashboard-title-row">
<span id="dashboard-count" class="dashboard-badge"></span>
</div>
</div>
<div id="dashboard-recent-grid" class="dashboard-recent-grid"></div>
<div id="dashboard-loading" class="dashboard-loading">
<div class="skeleton-card"></div><div class="skeleton-card"></div><div class="skeleton-card"></div>
<div class="skeleton-card"></div><div class="skeleton-card"></div><div class="skeleton-card"></div>
</div>
<div id="dashboard-recent-empty" class="dashboard-recent-empty hidden">
<i data-lucide="inbox"></i>
<span>Aucun fichier récent</span>
<p>Ouvrez un fichier pour le voir apparaître ici</p>
</div>
</div>
<!-- Shared Panel -->
<div id="dashboard-panel-shared" class="dashboard-panel">
<div id="dashboard-shared-grid" class="dashboard-recent-grid"></div>
<div id="dashboard-shared-empty" class="dashboard-recent-empty">
<i data-lucide="share-2"></i>
<span>Aucun document partagé</span>
<p>Partagez un document pour le voir apparaître ici</p>
</div>
</div>
</div>
</main>
</div><!-- /content-wrapper -->
<!-- Right sidebar resize handle -->
<div class="right-sidebar-resize-handle" id="right-sidebar-resize-handle"></div>
<!-- Right Sidebar (Outline/TOC) -->
<aside class="right-sidebar" id="right-sidebar" role="complementary" aria-label="Table des matières">
<div class="right-sidebar-header">
<h2 class="right-sidebar-title">SUR CETTE PAGE</h2>
<button class="right-sidebar-toggle-btn" id="right-sidebar-toggle-btn" type="button" title="Masquer le panneau" aria-label="Masquer le panneau">
<i data-lucide="chevron-right" style="width:16px;height:16px"></i>
</button>
</div>
<div class="outline-panel" id="outline-panel">
<nav class="outline-list" id="outline-list" role="navigation" aria-label="Navigation dans le document">
<!-- Outline items will be injected here -->
</nav>
<div class="outline-empty" id="outline-empty" hidden>
<i data-lucide="list" style="width:24px;height:24px;opacity:0.3"></i>
<span>Aucun titre dans ce document</span>
</div>
</div>
<div class="reading-progress" id="reading-progress">
<div class="reading-progress-bar">
<div class="reading-progress-fill" id="reading-progress-fill"></div>
</div>
<div class="reading-progress-text" id="reading-progress-text">0%</div>
</div>
</aside>
</div>
</div>
<!-- Editor Modal -->
<div class="editor-modal" id="editor-modal">
<div class="editor-container">
<div class="editor-header">
<div class="editor-title" id="editor-title">Édition</div>
<div class="editor-actions">
<button class="editor-btn danger" id="editor-delete" title="Supprimer" aria-label="Supprimer">
<i data-lucide="trash-2" style="width:16px;height:16px"></i>
</button>
<button class="editor-btn" id="editor-cancel" title="Annuler" aria-label="Annuler">
<i data-lucide="x" style="width:16px;height:16px"></i>
</button>
<button class="editor-btn primary" id="editor-save" title="Sauvegarder" aria-label="Sauvegarder">
<i data-lucide="check" style="width:16px;height:16px"></i>
</button>
</div>
</div>
<div class="editor-body" id="editor-body">
<div id="ai-toolbar-container"></div>
</div>
</div>
</div>
<!-- Configurations Modal -->
<div class="editor-modal" id="config-modal">
<div class="editor-container">
<div class="editor-header">
<div class="editor-title">Configurations</div>
<div class="editor-actions">
<button class="editor-btn" id="config-close" title="Fermer" aria-label="Fermer">
<i data-lucide="x" style="width:16px;height:16px"></i>
</button>
</div>
</div>
<div class="editor-body" id="config-body">
<div class="config-content">
<!-- Performance Settings - Frontend -->
<section class="config-section">
<h2>Paramètres de recherche</h2>
<p class="config-description">Ces paramètres s'appliquent immédiatement côté client.</p>
<div class="config-row">
<label class="config-label" for="cfg-debounce">Délai debounce (ms)</label>
<input type="number" id="cfg-debounce" class="config-input config-input--num" min="100" max="2000" step="50" value="300">
<span class="config-hint">Délai avant exécution de la recherche (100-2000)</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-results-per-page">Résultats par page</label>
<input type="number" id="cfg-results-per-page" class="config-input config-input--num" min="10" max="200" step="10" value="50">
<span class="config-hint">Nombre de résultats affichés par page (10-200)</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-min-query">Longueur min. requête</label>
<input type="number" id="cfg-min-query" class="config-input config-input--num" min="1" max="5" step="1" value="2">
<span class="config-hint">Nombre minimum de caractères avant recherche (1-5)</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-timeout">Timeout recherche (ms)</label>
<input type="number" id="cfg-timeout" class="config-input config-input--num" min="5000" max="120000" step="5000" value="30000">
<span class="config-hint">Annuler la recherche après ce délai (5000-120000)</span>
</div>
</section>
<!-- Historique récent -->
<section class="config-section">
<h2>📋 Historique récent <span class="config-badge-restart">Redémarrage non requis</span></h2>
<div class="config-row">
<label class="config-label" for="cfg-recent-limit">Nombre de fichiers dans l'historique</label>
<input type="number" id="cfg-recent-limit" class="config-input config-input--num" min="5" max="100" step="5" value="20">
<span class="config-hint">Entre 5 et 100 fichiers (sauvegardé sur le serveur)</span>
</div>
</section>
<!-- Performance Settings - Backend -->
<section class="config-section">
<h2>Paramètres backend <span class="config-badge-restart">Redémarrage requis</span></h2>
<p class="config-description">Ces paramètres sont sauvegardés sur le serveur. Certains nécessitent un redémarrage ou une réindexation.</p>
<div class="config-row">
<label class="config-label" for="cfg-workers">Workers de recherche</label>
<input type="number" id="cfg-workers" class="config-input config-input--num" min="1" max="8" step="1" value="2">
<span class="config-hint">Threads dédiés à la recherche (1-8)</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-max-content">Taille max contenu (octets)</label>
<input type="number" id="cfg-max-content" class="config-input config-input--num" min="10000" max="1000000" step="10000" value="100000">
<span class="config-hint">Contenu indexé par fichier (10K-1M). Réindexation requise.</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-title-boost">Boost titre</label>
<input type="number" id="cfg-title-boost" class="config-input config-input--num" min="0" max="10" step="0.5" value="3.0">
<span class="config-hint">Multiplicateur de pertinence pour les correspondances dans le titre</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-tag-boost">Boost tags</label>
<input type="number" id="cfg-tag-boost" class="config-input config-input--num" min="0" max="10" step="0.5" value="2.0">
<span class="config-hint">Multiplicateur de pertinence pour les correspondances dans les tags</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-prefix-exp">Expansions préfixe max</label>
<input type="number" id="cfg-prefix-exp" class="config-input config-input--num" min="10" max="200" step="10" value="50">
<span class="config-hint">Nombre max de tokens élargis par préfixe (10-200)</span>
</div>
<div class="config-actions-row">
<button class="config-btn-save" id="cfg-save-backend">Sauvegarder</button>
<button class="config-btn-secondary" id="cfg-reindex">Forcer réindexation</button>
<button class="config-btn-secondary" id="cfg-reset-defaults">Réinitialiser</button>
</div>
</section>
<!-- Tag Filtering (existing) -->
<section class="config-section">
<h2>Filtrage de tags</h2>
<p class="config-description">Définissez les patterns de tags à masquer dans la sidebar. Vous pouvez utiliser des wildcards pour cibler les tags de template.</p>
<div class="config-filters-list" id="config-filters-list"></div>
<div class="config-add-pattern">
<input type="text" id="config-pattern-input" placeholder="Ex: #&lt;% ... %&gt; ou #{{ ... }}" class="config-input">
<button id="config-add-btn" class="config-btn-add">Ajouter</button>
</div>
<div class="config-regex-preview" id="config-regex-preview" style="display:none;">
<small>Regex : <code id="config-regex-code"></code></small>
</div>
</section>
<!-- Watcher / Synchronisation -->
<section class="config-section">
<h2>Synchronisation automatique</h2>
<p class="config-description">Surveillance des fichiers en temps réel via watchdog. Les modifications sont détectées automatiquement et l'index est mis à jour sans redémarrage.</p>
<div class="config-row">
<label class="config-label" for="cfg-watcher-enabled">Activer la surveillance</label>
<label class="config-toggle">
<input type="checkbox" id="cfg-watcher-enabled" checked>
<span class="config-toggle-slider"></span>
</label>
<span class="config-hint">Activer/désactiver la surveillance automatique des fichiers</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-watcher-polling">Mode polling (fallback)</label>
<label class="config-toggle">
<input type="checkbox" id="cfg-watcher-polling">
<span class="config-toggle-slider"></span>
</label>
<span class="config-hint">Forcer le mode polling au lieu de inotify natif (utile si le mode natif ne fonctionne pas)</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-watcher-interval">Intervalle polling (s)</label>
<input type="number" id="cfg-watcher-interval" class="config-input config-input--num" min="1" max="30" step="1" value="5">
<span class="config-hint">Intervalle de scrutation en mode polling (1-30 secondes)</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-watcher-debounce">Debounce (s)</label>
<input type="number" id="cfg-watcher-debounce" class="config-input config-input--num" min="0.5" max="10" step="0.5" value="2">
<span class="config-hint">Délai avant traitement des changements groupés (0.5-10 secondes)</span>
</div>
</section>
<!-- Hidden Files/Folders Configuration -->
<section class="config-section">
<h2>🗂️ Fichiers cachés</h2>
<p class="config-description">Contrôlez l'affichage des fichiers/dossiers cachés (commençant par <code>.</code>) par vault.</p>
<p class="config-hint" style="margin-bottom: 12px; padding: 8px; background: var(--background-secondary); border-radius: 4px;">
i <strong>Note :</strong> Tous les fichiers sont toujours indexés et cherchables. Ce paramètre contrôle uniquement leur visibilité dans l'interface.
</p>
<div id="hidden-files-vault-list">
<!-- Vault-specific settings will be injected here -->
</div>
<div class="config-actions-row" style="margin-top: 16px;">
<button class="config-btn-save" id="cfg-save-hidden-files">💾 Sauvegarder</button>
</div>
</section>
<!-- Diagnostics -->
<section class="config-section">
<h2>Diagnostics</h2>
<p class="config-description">Statistiques de l'index et du moteur de recherche.</p>
<div id="config-diagnostics" class="config-diagnostics">
<div class="config-diag-loading">Chargement...</div>
</div>
<button class="config-btn-secondary" id="cfg-refresh-diag" style="margin-top:8px">Rafraîchir</button>
</section>
<!-- À propos -->
<section class="config-section">
<h2>📦 À propos</h2>
<div id="config-about" class="config-diagnostics">
<div class="config-diag-loading">Chargement...</div>
</div>
</section>
<!-- Webhooks -->
<section class="config-section">
<h2>🔔 Webhooks</h2>
<p class="config-description">Notifications HTTP vers des services externes lors des changements de fichiers.</p>
<div id="webhooks-list"></div>
<div class="config-add-row">
<input type="text" id="webhook-name-input" placeholder="Nom" class="config-input" style="width:100px">
<input type="text" id="webhook-url-input" placeholder="https://..." class="config-input" style="flex:1">
<button id="webhook-add-btn" class="config-btn config-btn-add">Ajouter</button>
</div>
</section>
<!-- Partages publics -->
<section class="config-section">
<h2>📤 Partages publics</h2>
<p class="config-description">Liens de partage publics pour des documents (lecture seule, sans authentification).</p>
<div id="shares-list"></div>
</section>
</div>
</div>
</div>
</div>
<!-- Graph View Modal -->
<div class="editor-modal" id="graph-modal">
<div class="editor-container" style="max-width:95vw;width:1000px;height:85vh;display:flex;flex-direction:column;">
<!-- Header: 2 lignes — nav+titre+contrôles | recherche -->
<div class="editor-header" style="display:flex;flex-direction:column;gap:6px;padding:8px 12px;border-bottom:1px solid var(--border-color)">
<!-- Line 1: nav + title + controls -->
<div style="display:flex;align-items:center;gap:6px;min-width:0">
<button class="editor-btn" id="graph-nav-back" title="Retour" style="font-size:0.75rem;padding:2px 4px;opacity:0.3;flex-shrink:0;min-width:22px" disabled></button>
<button class="editor-btn" id="graph-nav-fwd" title="Avancer" style="font-size:0.75rem;padding:2px 4px;opacity:0.3;flex-shrink:0;min-width:22px" disabled></button>
<button class="editor-btn" id="graph-nav-up" title="Dossier parent" style="font-size:0.65rem;padding:2px 5px;flex-shrink:0;display:none"></button>
<div class="editor-title" id="graph-title" style="font-weight:600;font-size:0.85rem;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">Vue Graphique</div>
<button class="editor-btn" id="graph-full-vault" title="Vue complète du vault" style="font-size:0.65rem;padding:3px 6px;flex-shrink:0">🌐 Tout</button>
<span style="font-size:0.6rem;color:var(--text-muted);flex-shrink:0">Prof.</span>
<input type="range" id="graph-depth" min="0" max="3" value="1" style="width:40px;flex-shrink:0" title="Profondeur">
<button class="editor-btn" id="graph-zoom-out" title="Zoom arrière" style="flex-shrink:0"><i data-lucide="zoom-out" style="width:14px;height:14px"></i></button>
<button class="editor-btn" id="graph-zoom-in" title="Zoom avant" style="flex-shrink:0"><i data-lucide="zoom-in" style="width:14px;height:14px"></i></button>
<button class="editor-btn" id="graph-reset" title="Réinitialiser" style="flex-shrink:0"><i data-lucide="maximize" style="width:14px;height:14px"></i></button>
<button class="editor-btn" id="graph-export" title="Exporter PNG" style="flex-shrink:0"><i data-lucide="download" style="width:14px;height:14px"></i></button>
<button class="editor-btn" id="graph-fullscreen" title="Plein écran" style="flex-shrink:0"><i data-lucide="expand" style="width:14px;height:14px"></i></button>
<button class="editor-btn" id="graph-close" title="Fermer" style="flex-shrink:0"><i data-lucide="x" style="width:15px;height:15px"></i></button>
</div>
<!-- Line 2: centered search -->
<div style="display:flex;justify-content:center">
<div style="position:relative;width:100%;max-width:450px">
<i data-lucide="search" style="position:absolute;left:10px;top:50%;transform:translateY(-50%);width:14px;height:14px;color:var(--text-muted);pointer-events:none"></i>
<input type="text" id="graph-search" placeholder="Rechercher ou #tag..." style="width:100%;font-size:0.78rem;padding:5px 12px 5px 30px;border-radius:8px;border:none;background:var(--bg-secondary);color:var(--text-primary);outline:none;box-shadow:inset 0 1px 3px rgba(0,0,0,0.2)">
<span style="position:absolute;right:10px;top:50%;transform:translateY(-50%);font-size:0.6rem;color:var(--text-muted);opacity:0.4;pointer-events:none">Ctrl+survol</span>
</div>
</div>
</div>
<div class="editor-body" style="flex:1;overflow:hidden;position:relative;padding:0">
<canvas id="graph-canvas" style="width:100%;height:100%;cursor:grab"></canvas>
<!-- Info panel: top-right, shows on hover, stays until closed -->
<div id="graph-info-panel" style="display:none;position:absolute;top:10px;left:10px;max-width:320px;background:var(--bg-primary);border:1px solid rgba(255,255,255,0.08);border-radius:8px;padding:12px 14px;font-size:0.78rem;color:var(--text-primary);z-index:10;box-shadow:0 4px 16px rgba(0,0,0,0.4)">
<button id="graph-info-close" style="position:absolute;top:6px;right:8px;background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:1rem;line-height:1;padding:2px" title="Fermer"></button>
<div id="graph-info-content"></div>
</div>
<!-- Preview panel: right sidebar, full height, shows on Ctrl+hover, stays until closed -->
<div id="graph-preview-panel" style="display:none;position:absolute;top:0;right:0;width:380px;height:100%;background:var(--bg-primary);border-left:1px solid var(--border-color);z-index:9;overflow-y:auto;font-size:0.8rem;color:var(--text-primary);box-shadow:-4px 0 16px rgba(0,0,0,0.3)">
<button id="graph-preview-close" style="position:sticky;top:0;float:right;background:var(--bg-primary);border:1px solid var(--border-color);border-radius:4px;color:var(--text-muted);cursor:pointer;font-size:0.9rem;padding:2px 8px;z-index:1;margin-bottom:-24px" title="Fermer">✕ Fermer</button>
<div id="graph-preview-content" style="padding:16px;padding-top:8px"></div>
</div>
<!-- Status bar + legend -->
<div style="position:absolute;bottom:0;left:0;right:0;display:flex;align-items:center;justify-content:space-between;padding:4px 12px;background:var(--bg-primary);border-top:1px solid var(--border-color);font-size:0.7rem;color:var(--text-muted)">
<span id="graph-status"></span>
<div style="display:flex;align-items:center;gap:10px">
<label style="cursor:pointer;display:flex;align-items:center;gap:3px"><input type="checkbox" id="graph-filter-dir" checked> 🟦 Dossier</label>
<label style="cursor:pointer;display:flex;align-items:center;gap:3px"><input type="checkbox" id="graph-filter-md" checked> 🟩 .md</label>
<label style="cursor:pointer;display:flex;align-items:center;gap:3px"><input type="checkbox" id="graph-filter-other" checked> ⬜ Autre</label>
<span style="opacity:0.5"></span>
<span>── Parent</span>
<span style="color:var(--accent-color,#2563eb)">┅┅ Wikilink</span>
<span style="color:#e74c3c">← Backlink</span>
</div>
</div>
</div>
</div>
</div>
<!-- Help Modal -->
<div class="editor-modal" id="help-modal">
<div class="editor-container help-container">
<div class="editor-header">
<div class="editor-title" id="help-title">Guide d'utilisation ObsiGate</div>
<div class="editor-actions">
<button class="editor-btn" id="help-close" title="Fermer l'aide" aria-label="Fermer l'aide">
<i data-lucide="x" style="width:16px;height:16px"></i>
</button>
</div>
</div>
<div class="editor-body help-body" id="help-body">
<nav class="help-nav" id="help-nav">
<div class="help-nav-title">Sommaire</div>
<ul class="help-nav-list">
<li><a href="#help-intro" class="help-nav-link">📘 Introduction</a></li>
<li><a href="#help-interface" class="help-nav-link">🧭 Interface</a></li>
<li><a href="#help-navigation" class="help-nav-link">🗺️ Navigation</a></li>
<li><a href="#help-tabs" class="help-nav-link">📑 Onglets</a></li>
<li><a href="#help-recherche" class="help-nav-link">🔍 Recherche</a></li>
<li><a href="#help-tags" class="help-nav-link">🏷️ Tags</a></li>
<li><a href="#help-fichiers" class="help-nav-link">📁 Fichiers</a></li>
<li><a href="#help-edition" class="help-nav-link">✏️ Édition</a></li>
<li><a href="#help-graphe" class="help-nav-link">🗺️ Graphe</a></li>
<li><a href="#help-ia" class="help-nav-link">🤖 IA Éditeur</a></li>
<li><a href="#help-palette" class="help-nav-link">⌨️ Palette</a></li>
<li><a href="#help-raccourcis" class="help-nav-link">⌨️ Raccourcis</a></li>
<li><a href="#help-partage" class="help-nav-link">🔗 Partage</a></li>
<li><a href="#help-sauvegardes" class="help-nav-link">💾 Sauvegardes</a></li>
<li><a href="#help-securite" class="help-nav-link">🛡️ Sécurité</a></li>
<li><a href="#help-personnalisation" class="help-nav-link">🎨 Personnalisation</a></li>
<li><a href="#help-astuces" class="help-nav-link">💡 Astuces</a></li>
</ul>
</nav>
<div class="help-content">
<section class="help-section help-hero" id="help-intro">
<div class="help-hero-copy">
<div class="help-kicker">Guide officiel</div>
<h1>📘 Bienvenue dans ObsiGate</h1>
<p class="help-lead">ObsiGate est votre porte d'entrée web vers vos vaults Obsidian. Accédez, naviguez et recherchez dans toutes vos notes depuis n'importe quel appareil via une interface moderne et responsive.</p>
<div class="help-badges">
<span class="help-badge">⚡ Navigation rapide</span>
<span class="help-badge">🗂️ Multi-vault</span>
<span class="help-badge">🏷️ Tags intelligents</span>
<span class="help-badge">📝 Lecture et édition</span>
<span class="help-badge">🔍 Recherche TF-IDF</span>
</div>
</div>
<div class="help-hero-visual" aria-hidden="true">
<div class="help-stat-card">
<span class="help-stat-label">Expérience</span>
<strong>Simple</strong>
</div>
<div class="help-stat-card">
<span class="help-stat-label">Recherche</span>
<strong>Instantanée</strong>
</div>
<div class="help-stat-card">
<span class="help-stat-label">Accès</span>
<strong>Multi-vault</strong>
</div>
</div>
</section>
<section class="help-section" id="help-interface">
<h2>🧭 Interface utilisateur</h2>
<h3>En-tête</h3>
<p>La barre supérieure contient les éléments essentiels :</p>
<ul>
<li><strong>Bouton menu hamburger</strong> (mobile) : Affiche/masque la sidebar</li>
<li><strong>Bouton toggle sidebar</strong> (desktop) : Masque la sidebar pour plus d'espace</li>
<li><strong>Logo ObsiGate</strong> : Retour à l'accueil</li>
<li><strong>Barre de recherche</strong> : Recherche globale avec autocomplétion</li>
<li><strong>Indicateur de vault</strong> : Affiche le contexte actif (All, vault1, etc.)</li>
<li><strong>Menu Options</strong> : Accès aux paramètres, thème, aide</li>
</ul>
<h3>Sidebar (barre latérale)</h3>
<p>La sidebar est divisée en deux onglets :</p>
<ul>
<li><strong>Vaults</strong> : Arborescence des fichiers et dossiers</li>
<li><strong>Tags</strong> : Nuage de tags cliquables</li>
</ul>
<p>Fonctionnalités de la sidebar :</p>
<ul>
<li><strong>Filtrage</strong> : Barre de recherche pour filtrer fichiers/tags</li>
<li><strong>Sélection rapide</strong> : Dropdown pour changer de vault</li>
<li><strong>Redimensionnement</strong> : Glissez le bord droit pour ajuster la largeur</li>
<li><strong>Masquage</strong> : Cliquez sur l'icône sidebar dans le header</li>
</ul>
<h3>Zone de contenu</h3>
<p>La zone centrale affiche :</p>
<ul>
<li><strong>Breadcrumb</strong> : Chemin du fichier (cliquable pour repositionner la sidebar)</li>
<li><strong>Titre et tags</strong> : Métadonnées du fichier</li>
<li><strong>Boutons d'action</strong> : Copier, Source, Télécharger, Éditer, Ouvrir dans nouvelle fenêtre</li>
<li><strong>Contenu rendu</strong> : Markdown avec wikilinks et images</li>
</ul>
</section>
<section class="help-section" id="help-navigation">
<h2>🗺️ Navigation</h2>
<h3>Arborescence des vaults</h3>
<p>Cliquez sur un vault pour l'ouvrir et voir son contenu. Les dossiers affichent un chevron et un badge avec le nombre d'éléments.</p>
<ul>
<li><strong>Développer/Réduire</strong> : Cliquez sur un dossier</li>
<li><strong>Ouvrir un fichier</strong> : Cliquez sur le nom du fichier</li>
<li><strong>Icônes</strong> : Chaque type de fichier a son icône (markdown, code, etc.)</li>
</ul>
<h3>Filtrage de la sidebar</h3>
<p>Utilisez la barre de filtrage en haut de la sidebar pour rechercher rapidement :</p>
<ul>
<li><strong>Recherche instantanée</strong> : Tapez pour filtrer fichiers et dossiers</li>
<li><strong>Case-sensitive</strong> : Bouton "Aa" pour respecter la casse</li>
<li><strong>Effacer</strong> : Bouton "×" pour réinitialiser le filtre</li>
<li><strong>Résultats groupés</strong> : Affichage par vault avec chemins complets</li>
</ul>
<h3>Breadcrumb et repositionnement</h3>
<p>Le chemin affiché au-dessus du contenu est interactif :</p>
<ul>
<li><strong>Cliquez sur le vault</strong> : Focus sur le vault dans la sidebar</li>
<li><strong>Cliquez sur un segment</strong> : Navigation vers ce dossier</li>
<li><strong>Auto-scroll</strong> : La sidebar se positionne automatiquement</li>
</ul>
<h3>Sélection de vault</h3>
<p>Changez de contexte pour filtrer l'affichage :</p>
<ul>
<li><strong>Menu header</strong> : Dropdown "Vault" dans le menu Options</li>
<li><strong>Sidebar dropdown</strong> : Sélection rapide en haut de l'onglet Vaults</li>
<li><strong>Tous les vaults</strong> : Vue globale de tous vos contenus</li>
<li><strong>Vault spécifique</strong> : Focus sur un seul vault</li>
</ul>
</section>
<section class="help-section" id="help-tabs">
<h2>📑 Gestion des onglets</h2>
<p>ObsiGate supporte l'ouverture de plusieurs fichiers simultanément dans des onglets.</p>
<h3>Ouverture d'onglets</h3>
<ul>
<li><strong>Simple clic</strong> : Ouvre le fichier dans un onglet temporaire (aperçu, italique)</li>
<li><strong>Double clic</strong> : Ouvre le fichier dans un onglet persistant</li>
<li><strong>Navigation récente</strong> : L'onglet "Récent" dans la sidebar liste vos derniers fichiers</li>
</ul>
<h3>Navigation entre onglets</h3>
<ul>
<li><strong>Clic sur un onglet</strong> : Active l'onglet</li>
<li><strong>Ctrl+Tab</strong> : Onglet suivant</li>
<li><strong>Ctrl+Shift+Tab</strong> : Onglet précédent</li>
<li><strong>Ctrl+W</strong> : Fermer l'onglet actif</li>
<li><strong>Bouton ✕</strong> : Ferme l'onglet (sauf s'il est seul)</li>
</ul>
<h3>Fonctionnalités</h3>
<ul>
<li><strong>Barre d'onglets</strong> : Affichage horizontal avec le nom du fichier et son icône</li>
<li><strong>Onglet actif</strong> : Surligné en couleur d'accentuation</li>
<li><strong>Prévisualisation</strong> : Un onglet temporaire (italique) est remplacé par le prochain clic</li>
<li><strong>Onglets persistants</strong> : Restent ouverts jusqu'à fermeture manuelle</li>
</ul>
</section>
<section class="help-section" id="help-recherche">
<h2>🔍 Recherche</h2>
<h3>Recherche simple</h3>
<p>Tapez dans la barre de recherche en haut pour lancer une recherche fulltext :</p>
<ul>
<li><strong>Recherche dans tout</strong> : Titre, contenu, tags, chemins</li>
<li><strong>Scoring intelligent</strong> : Résultats classés par pertinence TF-IDF</li>
<li><strong>Snippets surlignés</strong> : Extraits avec termes en surbrillance</li>
<li><strong>Pagination</strong> : Navigation par pages de 50 résultats</li>
</ul>
<h3>Opérateurs avancés</h3>
<p>Utilisez des opérateurs pour affiner votre recherche :</p>
<ul>
<li><code>tag:docker</code> ou <code>#docker</code> : Filtrer par tag</li>
<li><code>vault:IT</code> : Rechercher dans un vault spécifique</li>
<li><code>title:kubernetes</code> : Chercher dans les titres uniquement</li>
<li><code>path:recettes/soupes</code> : Filtrer par chemin</li>
<li><code>ext:md</code> : Filtrer par type de fichier</li>
<li><code>"phrase exacte"</code> : Recherche de phrase entre guillemets</li>
</ul>
<p><strong>Exemples</strong> : <code>ext:sh</code> recherche dans les scripts bash, <code>ext:py</code> dans les scripts Python, <code>ext:md</code> dans les fichiers Markdown.</p>
<p><strong>Exemple combiné</strong> : <code>tag:linux vault:IT ext:md serveur web</code> recherche "serveur web" dans les fichiers Markdown du vault IT avec le tag linux.</p>
<h3>Autocomplétion</h3>
<p>L'autocomplétion vous aide à trouver rapidement :</p>
<ul>
<li><strong>Historique</strong> : Les 50 dernières recherches (localStorage)</li>
<li><strong>Fichiers</strong> : Suggestions de titres de fichiers</li>
<li><strong>Tags</strong> : Suggestions de tags avec compteurs</li>
<li><strong>Navigation clavier</strong> : ↑/↓ pour naviguer, Enter pour sélectionner</li>
</ul>
<h3>Chips de filtres actifs</h3>
<p>Les opérateurs utilisés s'affichent sous forme de chips colorés :</p>
<ul>
<li><strong>Visualisation</strong> : Voir d'un coup d'œil les filtres actifs</li>
<li><strong>Suppression</strong> : Cliquez sur "×" pour retirer un filtre</li>
<li><strong>Couleurs</strong> : Chaque type d'opérateur a sa couleur</li>
</ul>
<h3>Facettes et tri</h3>
<p>Les résultats incluent des facettes pour affiner :</p>
<ul>
<li><strong>Facettes tags</strong> : Compteurs par tag dans les résultats</li>
<li><strong>Facettes vaults</strong> : Compteurs par vault</li>
<li><strong>Tri par pertinence</strong> : Score TF-IDF (défaut)</li>
<li><strong>Tri par date</strong> : Dernière modification</li>
</ul>
</section>
<section class="help-section" id="help-tags">
<h2>🏷️ Tags</h2>
<h3>Tag cloud</h3>
<p>L'onglet Tags de la sidebar affiche un nuage de tags :</p>
<ul>
<li><strong>Tous les tags</strong> : Extraits des frontmatters YAML et inline (#tag)</li>
<li><strong>Cliquable</strong> : Cliquez pour filtrer les résultats</li>
<li><strong>Filtrage</strong> : Utilisez la barre de filtrage pour chercher un tag</li>
<li><strong>Contexte vault</strong> : Les tags s'adaptent au vault sélectionné</li>
</ul>
<h3>Tags inline vs frontmatter</h3>
<p>ObsiGate supporte deux types de tags :</p>
<ul>
<li><strong>Frontmatter YAML</strong> : <code>tags: [docker, linux]</code> ou <code>tags: docker, linux</code></li>
<li><strong>Inline</strong> : <code>#docker</code> dans le contenu markdown</li>
<li><strong>Fusion automatique</strong> : Les deux types sont combinés</li>
</ul>
<h3>Filtrage de tags template</h3>
<p>Dans les Configurations, vous pouvez masquer les tags de template :</p>
<ul>
<li><strong>Patterns wildcards</strong> : Ex: <code>#&lt;% ... %&gt;</code> ou <code>#{{ ... }}</code></li>
<li><strong>Regex générée</strong> : Aperçu de la regex appliquée</li>
<li><strong>Ajout/Suppression</strong> : Gérez vos patterns de filtrage</li>
</ul>
</section>
<section class="help-section" id="help-fichiers">
<h2>📄 Fichiers</h2>
<h3>Visualisation</h3>
<p>Les fichiers markdown sont rendus avec :</p>
<ul>
<li><strong>Wikilinks cliquables</strong> : <code>[[lien]]</code> et <code>[[lien|texte]]</code></li>
<li><strong>Images Obsidian</strong> : Support de <code>![[image.png]]</code></li>
<li><strong>Syntax highlighting</strong> : Coloration des blocs de code</li>
<li><strong>Tables, listes, quotes</strong> : Rendu complet du markdown</li>
</ul>
<h3>Actions sur fichiers</h3>
<p>Boutons disponibles au-dessus du contenu :</p>
<ul>
<li><strong>Copier</strong> : Copie le contenu source dans le presse-papiers</li>
<li><strong>Source</strong> : Affiche/masque le markdown brut</li>
<li><strong>Télécharger</strong> : Télécharge le fichier</li>
<li><strong>Éditer</strong> : Ouvre l'éditeur CodeMirror</li>
<li><strong>Ouvrir dans nouvelle fenêtre</strong> : Ouvre le fichier dans un nouvel onglet</li>
</ul>
<h3>Édition avec CodeMirror 6</h3>
<p>L'éditeur intégré offre :</p>
<ul>
<li><strong>Coloration syntaxique</strong> : Support de nombreux langages</li>
<li><strong>Numéros de ligne</strong> : Navigation facile</li>
<li><strong>Autocomplétion</strong> : Suggestions contextuelles</li>
<li><strong>Recherche</strong> : Ctrl+F pour chercher dans le fichier</li>
<li><strong>Sauvegarde</strong> : Bouton ✓ pour enregistrer</li>
<li><strong>Suppression</strong> : Bouton corbeille pour supprimer</li>
</ul>
<h3>Types de fichiers supportés</h3>
<p>ObsiGate indexe et affiche :</p>
<ul>
<li><strong>Markdown</strong> : .md (rendu complet)</li>
<li><strong>Code</strong> : .py, .js, .ts, .jsx, .tsx, .java, .c, .cpp, .rs, .go, etc.</li>
<li><strong>Config</strong> : .json, .yaml, .yml, .toml, .xml, .ini, .env</li>
<li><strong>Scripts</strong> : .sh, .bash, .ps1, .bat</li>
<li><strong>Web</strong> : .html, .css, .scss</li>
<li><strong>Autres</strong> : .txt, .log, .sql, .csv</li>
</ul>
</section>
<!-- ✏️ Édition -->
<section class="help-section" id="help-edition">
<h2>✏️ Édition avancée</h2>
<h3>Éditeur CodeMirror 6</h3>
<p>L'éditeur intégré offre une expérience complète d'édition :</p>
<ul>
<li><strong>Coloration syntaxique</strong> : Python, JS, HTML, CSS, Java, C++, Rust, Go et bien d'autres</li>
<li><strong>Numéros de ligne</strong> : Navigation facilitée dans les fichiers longs</li>
<li><strong>Find in page</strong> : Ctrl+F pour chercher dans le fichier (casse, regex, mot entier)</li>
<li><strong>Sauvegarde automatique</strong> : Auto-save silencieux après 2s d'inactivité, flash vert de confirmation</li>
<li><strong>Bouton ✓</strong> : Sauvegarde manuelle</li>
<li><strong>Bouton 🗑️</strong> : Suppression du fichier</li>
<li><strong>Barre d'outils AI</strong> : Complétion, réécriture, traduction (voir section <a href="#help-ia">IA</a>)</li>
</ul>
</section>
<!-- 🗺️ Graphe -->
<section class="help-section" id="help-graphe">
<h2>🗺️ Vue Graphe</h2>
<p>La vue graphe offre une visualisation interactive des connexions entre vos notes via les wikilinks.</p>
<h3>Ouverture</h3>
<ul>
<li><strong>Menu contextuel</strong> : Clic droit sur un vault ou dossier → Vue Graphique</li>
<li><strong>Bouton dédié</strong> : Dans la barre d'outils (le cas échéant)</li>
</ul>
<h3>Interaction</h3>
<ul>
<li><strong>Zoom/Pan</strong> : Molette pour zoomer, cliquer-glisser pour se déplacer</li>
<li><strong>Slider de profondeur</strong> : Contrôle la profondeur d'exploration (0-3)</li>
<li><strong>Filtre par tag</strong> : N'affiche que les nœuds avec un tag spécifique</li>
<li><strong>Filtre par type</strong> : Inclut/exclut fichiers, dossiers, markdown, autres</li>
<li><strong>Recherche visuelle</strong> : Barre de recherche pour surligner des nœuds</li>
<li><strong>Mode focus</strong> : Centre la vue sur un nœud spécifique</li>
<li><strong>Navigation ← → ↑</strong> : Historique de navigation entre les nœuds</li>
</ul>
<h3>Affichage</h3>
<ul>
<li><strong>Nœuds</strong> : Fichiers (carrés) et dossiers (cercles) avec icônes</li>
<li><strong>Arêtes</strong> : Wikilinks sortants (bleu) et backlinks entrants (vert)</li>
<li><strong>Panneau d'info</strong> : Métadonnées du nœud (tags, liens, chemin)</li>
<li><strong>Ctrl+survol</strong> : Aperçu du contenu de la note sans naviguer</li>
<li><strong>Plein écran</strong> : Bouton pour agrandir la vue</li>
<li><strong>Export PNG</strong> : Sauvegardez le graphe en image</li>
</ul>
<h3>Performance</h3>
<p>La vue utilise l'algorithme Barnes-Hut pour calculer la disposition en O(n log n), garantissant des performances fluides même avec des centaines de nœuds.</p>
</section>
<section class="help-section" id="help-personnalisation">
<h2>🎨 Personnalisation</h2>
<h3>Thème clair/sombre</h3>
<p>Basculez entre les thèmes :</p>
<ul>
<li><strong>Menu Options</strong> : Cliquez sur "Thème" dans le menu</li>
<li><strong>Raccourci</strong> : <code>Ctrl+T</code></li>
<li><strong>Persistance</strong> : Votre choix est sauvegardé en localStorage</li>
<li><strong>Highlight.js</strong> : Les blocs de code s'adaptent au thème</li>
</ul>
<h3>Redimensionnement de la sidebar</h3>
<p>Sur desktop, ajustez la largeur de la sidebar :</p>
<ul>
<li><strong>Handle de redimensionnement</strong> : Bordure droite de la sidebar</li>
<li><strong>Glisser-déposer</strong> : Cliquez et glissez pour ajuster</li>
<li><strong>Limites</strong> : Min 200px, Max 500px</li>
<li><strong>Persistance</strong> : La largeur est sauvegardée</li>
</ul>
<h3>Configuration avancée</h3>
<p>Le modal Configurations (menu Options) permet de :</p>
<ul>
<li><strong>Paramètres de recherche</strong> : Délai debounce, résultats par page, timeout</li>
<li><strong>Paramètres backend</strong> : Workers, boosts TF-IDF, expansions préfixe</li>
<li><strong>Filtrage de tags</strong> : Patterns pour masquer les tags template</li>
<li><strong>Diagnostics</strong> : Stats index, mémoire, moteur de recherche</li>
<li><strong>Réindexation</strong> : Forcer un rescan des vaults</li>
</ul>
</section>
<!-- ⌨️ Palette de commandes -->
<section class="help-section" id="help-palette">
<h2>⌨️ Palette de commandes</h2>
<p>La palette de commandes permet d'accéder rapidement aux fichiers et aux actions sans utiliser la souris.</p>
<h3>Ouverture</h3>
<ul>
<li><strong>Ctrl+Shift+Espace</strong> : Palette de fichiers (recherche par titre)</li>
<li><strong>Ctrl+Alt+Espace</strong> : Palette de commandes (liste d'actions)</li>
<li><strong>Tab</strong> : Bascule entre mode fichiers et mode commandes</li>
</ul>
<h3>Mode fichiers</h3>
<p>Tapez le nom d'un fichier pour le trouver rapidement. La recherche utilise l'API <code>/api/suggest</code> pour des suggestions instantanées. Appuyez sur <kbd>Enter</kbd> pour ouvrir le fichier sélectionné.</p>
<h3>Mode commandes</h3>
<p>Tapez <code>&gt;</code> (ou Ctrl+Alt+Espace) pour voir la liste des actions disponibles :</p>
<ul>
<li>🏠 <strong>Accueil</strong> : Retour à l'accueil</li>
<li>✏️ <strong>Éditer fichier courant</strong> : Ouvre l'éditeur sur l'onglet actif</li>
<li>🪟 <strong>Pop-out</strong> : Ouvre le document dans une fenêtre détachée</li>
<li>📄 <strong>Créer fichier markdown</strong> : Crée un nouveau fichier .md et l'ouvre dans l'éditeur</li>
<li>🗑️ <strong>Supprimer fichier courant</strong> : Supprime le fichier de l'onglet actif</li>
<li>📁 <strong>Créer répertoire</strong> : Crée un nouveau dossier</li>
<li>🗑️ <strong>Supprimer répertoire</strong> : Supprime un dossier et son contenu</li>
<li>🌓 <strong>Changer le thème</strong> : Bascule clair/sombre</li>
<li>🔄 <strong>Réindexer</strong> : Force la réindexation complète</li>
<li><strong>Aide</strong> : Ouvre ce guide</li>
<li>⚙️ <strong>Configuration</strong> : Ouvre les paramètres</li>
</ul>
<h3>Navigation</h3>
<ul>
<li><kbd></kbd> <kbd></kbd> : Se déplacer dans la liste</li>
<li><kbd>Enter</kbd> : Ouvrir/sélectionner</li>
<li><kbd>Esc</kbd> : Fermer la palette</li>
<li><kbd>Tab</kbd> : Basculer entre fichiers et commandes</li>
</ul>
</section>
<section class="help-section" id="help-raccourcis">
<h2>⌨️ Raccourcis clavier</h2>
<h3>Navigation</h3>
<ul>
<li><code>Ctrl+K</code> ou <code>Cmd+K</code> : Focaliser la barre de recherche</li>
<li><code>/</code> : Focaliser la recherche (hors champ texte)</li>
<li><code>Escape</code> : Fermer les suggestions / quitter la recherche</li>
</ul>
<h3>Recherche et autocomplétion</h3>
<ul>
<li><code></code> / <code></code> : Naviguer dans les suggestions</li>
<li><code>Enter</code> : Sélectionner la suggestion active ou lancer la recherche</li>
<li><code>Escape</code> : Fermer le dropdown de suggestions</li>
</ul>
<h3>Interface</h3>
<ul>
<li><code>Ctrl+T</code> : Basculer le thème clair/sombre</li>
<li><code>Ctrl+Shift+Espace</code> : Palette de fichiers</li>
<li><code>Ctrl+Alt+Espace</code> : Palette de commandes</li>
<li><code>Escape</code> : Fermer la palette / les suggestions</li>
</ul>
<h3>Onglets</h3>
<ul>
<li><code>Ctrl+W</code> : Fermer l'onglet actif</li>
<li><code>Ctrl+Tab</code> : Onglet suivant</li>
<li><code>Ctrl+Shift+Tab</code> : Onglet précédent</li>
</ul>
<h3>Éditeur CodeMirror</h3>
<ul>
<li><code>Ctrl+F</code> : Rechercher dans le fichier</li>
<li><code>Ctrl+Z</code> : Annuler</li>
<li><code>Ctrl+Y</code> : Refaire</li>
<li><code>Ctrl+S</code> : Sauvegarder (si configuré)</li>
</ul>
</section>
<section class="help-section" id="help-ai">
<h2>🤖 Intelligence Artificielle dans l'Éditeur</h2>
<p>ObsiGate intègre un assistant IA directement dans l'éditeur de texte. Pour l'activer, configurez au moins un provider AI dans le fichier <code>.env</code> (DeepSeek, OpenRouter ou Gemini).</p>
<h3>Activation</h3>
<ol>
<li>Ajoutez votre clé API dans <code>.env</code> : <code>DEEPSEEK_API_KEY=sk-...</code></li>
<li>Redémarrez le conteneur : <code>docker compose down && docker compose up -d --build</code></li>
<li>Ouvrez un fichier en mode Édition (bouton ✏️ Éditer)</li>
<li>La barre d'outils AI apparaît sous le titre de l'éditeur</li>
</ol>
<h3>Barre d'outils AI</h3>
<p>La barre d'outils contient les boutons suivants :</p>
<ul>
<li><strong>✦ AI</strong> — Complétion inline (<kbd>Ctrl+J</kbd>). Complète automatiquement le texte là où se trouve le curseur.</li>
<li><strong>Éditer ▾</strong> — Menu de modification du texte sélectionné :
<ul>
<li>🪄 <strong>Improve writing</strong> : Améliore la qualité, la clarté et le flux du texte</li>
<li>🔤 <strong>Fix spelling & grammar</strong> : Corrige les fautes d'orthographe et de grammaire</li>
<li>📏 <strong>Make shorter</strong> : Rend le texte plus concis tout en préservant l'information</li>
<li>📐 <strong>Make longer</strong> : Ajoute des détails, exemples ou explications</li>
<li>📋 <strong>Simplify language</strong> : Simplifie le langage, évite le jargon</li>
</ul>
</li>
<li><strong>Ton ▾</strong> — Change le ton du texte :
<ul>
<li>💼 <strong>Professional</strong> : Ton formel et professionnel</li>
<li>💬 <strong>Casual</strong> : Ton décontracté et conversationnel</li>
</ul>
</li>
<li><strong>Traduire ▾</strong> — Traduit le texte sélectionné vers une autre langue :
<ul>
<li>🇬🇧 English · 🇨🇳 Chinese · 🇯🇵 Japanese · 🇩🇪 German · 🇫🇷 French · 🇪🇸 Spanish</li>
</ul>
</li>
<li><strong>Générer ▾</strong> — Génère du contenu à partir de la sélection :
<ul>
<li> <strong>Explain this</strong> : Explique le texte sélectionné de façon claire</li>
<li>📝 <strong>Summarize</strong> : Résume le texte de façon concise</li>
<li>✏️ <strong>Continue writing</strong> : Continue l'écriture à partir du texte</li>
</ul>
</li>
<li><strong>💬 Réécrire</strong> — Réécrit le texte selon vos instructions personnalisées. Une boîte de dialogue vous demande votre instruction.</li>
<li><strong>🧰 Boîte ▾</strong> — Outils de conversion :
<ul>
<li>📋 <strong>Convert to list</strong> : Transforme le texte en liste Markdown</li>
<li>📊 <strong>Convert to table</strong> : Transforme en tableau Markdown</li>
<li>⚙️ <strong>Generate frontmatter</strong> : Génère un bloc YAML frontmatter</li>
<li>🔷 <strong>Convert to canvas</strong> : Convertit en diagramme Mermaid.js</li>
</ul>
</li>
</ul>
<h3>Indicateurs visuels</h3>
<ul>
<li>Pendant une requête AI, un toast <strong>⏳ AI: traitement en cours...</strong> s'affiche</li>
<li>Une fois terminé, <strong>AI: texte traité ✓</strong> confirme le succès</li>
<li>En cas d'erreur de clé API : <strong>AI: clé API invalide</strong></li>
</ul>
<h3>Sauvegarde automatique</h3>
<p>L'éditeur sauvegarde automatiquement après 2 secondes d'inactivité. Le bouton de sauvegarde <strong>flashe en vert</strong> brièvement pour confirmer.</p>
<h3>Providers supportés</h3>
<table>
<tr><th>Provider</th><th>Variable .env</th><th>Modèle par défaut</th></tr>
<tr><td>DeepSeek</td><td><code>DEEPSEEK_API_KEY</code></td><td><code>deepseek-chat</code></td></tr>
<tr><td>OpenRouter</td><td><code>OPENROUTER_API_KEY</code></td><td><code>openai/gpt-4o-mini</code></td></tr>
<tr><td>Gemini</td><td><code>GEMINI_API_KEY</code></td><td><code>gemini-2.0-flash</code></td></tr>
</table>
<p>Pour changer de provider par défaut : <code>AI_DEFAULT_PROVIDER=openrouter</code></p>
</section>
<!-- 🔗 Partage -->
<section class="help-section" id="help-partage">
<h2>🔗 Partage et Webhooks</h2>
<h3>Publication publique</h3>
<p>ObsiGate permet de partager des documents via un lien public temporaire.</p>
<ul>
<li><strong>Bouton Partager</strong> : Dans les actions du fichier, génère un lien unique</li>
<li><strong>Token unique</strong> : 64 caractères hexadécimaux, impossible à deviner</li>
<li><strong>Expiration configurable</strong> : Durée de vie en heures</li>
<li><strong>Lecture seule</strong> : La vue publique n'affiche que le contenu sans édition</li>
<li><strong>Gestion des liens</strong> : Liste et révocation dans les Configurations</li>
<li><strong>Export PDF</strong> : Téléchargement du document partagé en PDF via <code>/s/{token}/pdf</code></li>
</ul>
<h3>Webhooks</h3>
<p>Les webhooks notifient des services externes lors des changements de fichiers.</p>
<ul>
<li><strong>Événements</strong> : Création, modification, suppression, renommage</li>
<li><strong>Format</strong> : POST JSON avec détails complets de l'événement</li>
<li><strong>Signature HMAC-SHA256</strong> : Optionnelle pour vérifier l'origine</li>
<li><strong>Configuration</strong> : Gestion via le modal Configurations</li>
</ul>
</section>
<!-- 💾 Sauvegardes -->
<section class="help-section" id="help-sauvegardes">
<h2>💾 Sauvegardes et Audits</h2>
<h3>Backup automatique</h3>
<p>ObsiGate crée automatiquement des sauvegardes avant chaque modification destructive.</p>
<ul>
<li><strong>Avant écriture</strong> : Sauvegarde du contenu original dans <code>.obsigate-backup/</code></li>
<li><strong>Timestamp</strong> : Chaque backup est horodaté</li>
<li><strong>Répertoire dédié</strong> : <code>.obsigate-backup/</code> dans le répertoire de la vault</li>
</ul>
<h3>Audit log</h3>
<p>Toutes les opérations sensibles sont tracées dans un journal.</p>
<ul>
<li><strong>Journal</strong> : Fichier <code>data/audit.log</code> au format JSON lines</li>
<li><strong>Événements tracés</strong> : Écritures, suppressions, changements de configuration</li>
<li><strong>Rotation</strong> : Rotation automatique à 10 Mo</li>
</ul>
</section>
<!-- 🛡️ Sécurité -->
<section class="help-section" id="help-securite">
<h2>🛡️ Sécurité</h2>
<h3>Authentification</h3>
<ul>
<li><strong>JWT + Argon2id</strong> : Tokens JWT avec mots de passe hachés Argon2id</li>
<li><strong>Contrôle d'accès par vault</strong> : Chaque utilisateur voit uniquement ses vaults</li>
<li><strong>Refresh tokens</strong> : Cookies HttpOnly avec rotation automatique</li>
<li><strong>Rate limiting</strong> : 10 tentatives / 15 min par IP + verrouillage compte</li>
<li><strong>Compte admin</strong> : Créé automatiquement au premier démarrage</li>
</ul>
<h3>Protection</h3>
<ul>
<li><strong>Secret redactor</strong> : Masque JWT, clés API, tokens GitHub dans les aperçus</li>
<li><strong>Path traversal</strong> : Validation des chemins contre les attaques <code>../</code></li>
<li><strong>Headers CSP</strong> : Content-Security-Policy, X-Frame-Options, XSS-Protection</li>
<li><strong>Atomic writes</strong> : Écriture via fichier temporaire + renommage atomique</li>
<li><strong>Non-root Docker</strong> : Conteneur tourne avec UID 1000</li>
</ul>
</section>
<section class="help-section" id="help-astuces">
<h2>💡 Astuces et bonnes pratiques</h2>
<h3>Workflow recommandé</h3>
<ol>
<li><strong>Sélectionnez un contexte</strong> : Choisissez un vault pour réduire le bruit</li>
<li><strong>Explorez l'arborescence</strong> : Naviguez dans les dossiers</li>
<li><strong>Utilisez les tags</strong> : Filtrez par tags pour affiner</li>
<li><strong>Recherchez intelligemment</strong> : Combinez opérateurs et texte libre</li>
<li><strong>Profitez de l'historique</strong> : Réutilisez vos recherches fréquentes</li>
</ol>
<h3>Optimisations</h3>
<ul>
<li><strong>Masquez la sidebar</strong> : Plus d'espace pour le contenu</li>
<li><strong>Utilisez le filtrage sidebar</strong> : Plus rapide que la recherche globale pour trouver un fichier</li>
<li><strong>Favorisez les opérateurs</strong> : <code>tag:</code> et <code>vault:</code> accélèrent la recherche</li>
<li><strong>Breadcrumb cliquable</strong> : Repositionnez rapidement la sidebar</li>
</ul>
<h3>Trucs et astuces</h3>
<ul>
<li><strong>Navigation visuelle</strong> : Le breadcrumb repositionne automatiquement la sidebar</li>
<li><strong>Gestion de l'espace</strong> : Réduisez les sections Vaults/Tags selon vos besoins</li>
<li><strong>Confort de lecture</strong> : Ajustez la largeur de la sidebar</li>
<li><strong>Mobile-friendly</strong> : Utilisez le bouton hamburger sur mobile</li>
<li><strong>Wikilinks</strong> : Naviguez entre notes comme dans Obsidian</li>
<li><strong>Images</strong> : Support complet des syntaxes Obsidian</li>
</ul>
<h3>Cas d'usage avancés</h3>
<ul>
<li><strong>Recherche multi-critères</strong> : <code>tag:docker tag:linux vault:IT nginx</code></li>
<li><strong>Exploration par tags</strong> : Cliquez sur un tag dans une note pour voir toutes les notes similaires</li>
<li><strong>Édition rapide</strong> : Ouvrez l'éditeur, modifiez, sauvegardez</li>
<li><strong>Export</strong> : Téléchargez des fichiers pour backup ou partage</li>
<li><strong>Multi-fenêtres</strong> : Ouvrez plusieurs notes dans des onglets séparés</li>
</ul>
</section>
<div class="help-footer">
<p><strong>ObsiGate v1.7.0</strong> - Porte d'entrée web pour vos vaults Obsidian</p>
<p>Pour plus d'informations, consultez le <a href="https://git.dracodev.net/Projets/ObsiGate" target="_blank">dépôt du projet</a>.</p>
</div>
</div>
</div>
</div>
</div>
<!-- Find in Page Bar -->
<div class="find-in-page-bar" id="find-in-page-bar" hidden>
<div class="find-in-page-content">
<i data-lucide="search" class="find-icon"></i>
<input type="text" id="find-input" placeholder="Rechercher..." autocomplete="off" aria-label="Rechercher dans la page">
<span class="find-counter" id="find-counter" aria-live="polite">0 occurrence</span>
<div class="find-nav-buttons">
<button class="find-btn" id="find-prev" title="Précédent (Shift+Enter)" aria-label="Résultat précédent" disabled>
<i data-lucide="chevron-up" style="width:14px;height:14px"></i>
</button>
<button class="find-btn" id="find-next" title="Suivant (Enter)" aria-label="Résultat suivant" disabled>
<i data-lucide="chevron-down" style="width:14px;height:14px"></i>
</button>
</div>
<div class="find-options">
<button class="find-btn find-option-btn" id="find-case-sensitive" title="Respecter la casse" aria-label="Respecter la casse" aria-pressed="false">
<span class="find-option-text">Aa</span>
</button>
<button class="find-btn find-option-btn" id="find-whole-word" title="Mot entier" aria-label="Mot entier" aria-pressed="false">
<span class="find-option-text">abc</span>
</button>
<button class="find-btn find-option-btn" id="find-regex" title="Expression régulière" aria-label="Expression régulière" aria-pressed="false">
<span class="find-option-text">.*</span>
</button>
</div>
<button class="find-btn find-close" id="find-close" title="Fermer (Escape)" aria-label="Fermer la recherche">
<i data-lucide="x" style="width:16px;height:16px"></i>
</button>
</div>
<div class="find-error" id="find-error" hidden></div>
</div>
<script type="module" src="/static/js/app.js"></script>
</body>
</html>