83 lines
2.4 KiB
HTML
83 lines
2.4 KiB
HTML
</div><!-- end doc-container -->
|
|||
|
|
</main>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
mermaid.initialize({
|
||
|
|
startOnLoad: true,
|
||
|
|
theme: 'base',
|
||
|
|
themeVariables: {
|
||
|
|
primaryColor: '#e3f2fd',
|
||
|
|
primaryTextColor: '#1e293b',
|
||
|
|
primaryBorderColor: '#1976d2',
|
||
|
|
lineColor: '#64748b',
|
||
|
|
secondaryColor: '#fff3e0',
|
||
|
|
tertiaryColor: '#f4f1eb',
|
||
|
|
fontFamily: 'Inter, sans-serif',
|
||
|
|
fontSize: '14px',
|
||
|
|
},
|
||
|
|
flowchart: { curve: 'basis', padding: 15 },
|
||
|
|
securityLevel: 'loose',
|
||
|
|
});
|
||
|
|
|
||
|
|
// ── Progress bar ──
|
||
|
|
const bar = document.getElementById('progress-bar');
|
||
|
|
function updateProgress() {
|
||
|
|
const h = document.documentElement;
|
||
|
|
const pct = ((h.scrollTop) / (h.scrollHeight - h.clientHeight)) * 100;
|
||
|
|
bar.style.width = Math.min(100, pct) + '%';
|
||
|
|
}
|
||
|
|
window.addEventListener('scroll', updateProgress);
|
||
|
|
|
||
|
|
// ── Topbar title ──
|
||
|
|
const topbarTitle = document.getElementById('topbar-title');
|
||
|
|
const headings = document.querySelectorAll('.doc-container h1[id], .doc-container h2[id], .doc-container h3[id], .doc-container h4[id]');
|
||
|
|
function updateTopbar() {
|
||
|
|
let current = '';
|
||
|
|
headings.forEach(h => {
|
||
|
|
if (h.getBoundingClientRect().top <= 120) current = h.textContent;
|
||
|
|
});
|
||
|
|
if (current) topbarTitle.textContent = current;
|
||
|
|
}
|
||
|
|
window.addEventListener('scroll', updateTopbar);
|
||
|
|
|
||
|
|
// ── TOC active state ──
|
||
|
|
const tocLinks = document.querySelectorAll('.toc-item');
|
||
|
|
function updateToc() {
|
||
|
|
let activeId = '';
|
||
|
|
headings.forEach(h => {
|
||
|
|
if (h.getBoundingClientRect().top <= 120) activeId = h.id;
|
||
|
|
});
|
||
|
|
tocLinks.forEach(link => {
|
||
|
|
link.classList.toggle('active', link.getAttribute('href') === '#' + activeId);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
window.addEventListener('scroll', updateToc);
|
||
|
|
|
||
|
|
// ── Collapsible TOC groups ──
|
||
|
|
document.querySelectorAll('.toc-toggle').forEach(btn => {
|
||
|
|
btn.addEventListener('click', () => {
|
||
|
|
const kids = btn.nextElementSibling;
|
||
|
|
const arr = btn.querySelector('.arr');
|
||
|
|
btn.classList.toggle('active');
|
||
|
|
kids.classList.toggle('open');
|
||
|
|
arr.classList.toggle('open');
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
// ── TOC search ──
|
||
|
|
const tocSearch = document.getElementById('toc-search');
|
||
|
|
tocSearch.addEventListener('input', () => {
|
||
|
|
const q = tocSearch.value.toLowerCase();
|
||
|
|
document.querySelectorAll('.toc-item, .toc-toggle').forEach(item => {
|
||
|
|
item.style.display = (!q || item.textContent.toLowerCase().includes(q)) ? '' : 'none';
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
// ── Initial ──
|
||
|
|
updateProgress();
|
||
|
|
updateTopbar();
|
||
|
|
updateToc();
|
||
|
|
</script>
|
||
|
|
</body>
|
||
|
|
</html>
|