import { useCallback, useEffect, useState } from 'react'
import Link from 'next/link'
import { useRouter } from 'next/router'
import clsx from 'clsx'
import { Logo } from '@/components/Logo'
import { Prose } from '@/components/Prose'
import {HeroPattern} from "@/components/HeroPattern";
import {NavigationDocs} from "@/components/NavigationDocs";
import {Header} from "@/components/Header";
import {NavigationAPI} from "@/components/NavigationAPI";
import {motion} from "framer-motion";
import {Footer} from "@/components/Footer";
const navigation = [
{
title: 'Introduction',
links: [
{ title: 'Getting started', href: '/' },
{ title: 'Installation', href: '/installation' },
],
},
{
title: 'Core concepts',
links: [
{ title: 'Understanding caching', href: '/understanding-caching' },
{
title: 'Predicting user behavior',
href: '/predicting-user-behavior',
},
{ title: 'Basics of time-travel', href: '/basics-of-time-travel' },
{
title: 'Introduction to string theory',
href: '/introduction-to-string-theory',
},
{ title: 'The butterfly effect', href: '/the-butterfly-effect' },
],
},
{
title: 'Advanced guides',
links: [
{ title: 'Writing plugins', href: '/writing-plugins' },
{ title: 'Neuralink integration', href: '/neuralink-integration' },
{ title: 'Temporal paradoxes', href: '/temporal-paradoxes' },
{ title: 'Testing', href: '/testing' },
{ title: 'Compile-time caching', href: '/compile-time-caching' },
{
title: 'Predictive data generation',
href: '/predictive-data-generation',
},
],
},
{
title: 'API reference',
links: [
{ title: 'CacheAdvance.predict()', href: '/cacheadvance-predict' },
{ title: 'CacheAdvance.flush()', href: '/cacheadvance-flush' },
{ title: 'CacheAdvance.revert()', href: '/cacheadvance-revert' },
{ title: 'CacheAdvance.regret()', href: '/cacheadvance-regret' },
],
},
{
title: 'Contributing',
links: [
{ title: 'How to contribute', href: '/how-to-contribute' },
{ title: 'Architecture guide', href: '/architecture-guide' },
{ title: 'Design principles', href: '/design-principles' },
],
},
]
function GitHubIcon(props) {
return (
)
}
function useTableOfContents(tableOfContents) {
let [currentSection, setCurrentSection] = useState(tableOfContents[0]?.id)
let getHeadings = useCallback((tableOfContents) => {
return tableOfContents
.flatMap((node) => [node.id, ...node.children.map((child) => child.id)])
.map((id) => {
let el = document.getElementById(id)
if (!el) return
let style = window.getComputedStyle(el)
let scrollMt = parseFloat(style.scrollMarginTop)
let top = window.scrollY + el.getBoundingClientRect().top - scrollMt
return { id, top }
})
}, [])
useEffect(() => {
if (tableOfContents.length === 0) return
let headings = getHeadings(tableOfContents)
function onScroll() {
let top = window.scrollY
let current = headings[0]?.id
for (let heading of headings) {
if (top >= heading?.top) {
current = heading?.id
} else {
break
}
}
setCurrentSection(current)
}
window.addEventListener('scroll', onScroll, { passive: true })
onScroll()
return () => {
window.removeEventListener('scroll', onScroll)
}
}, [getHeadings, tableOfContents])
return currentSection
}
export function Layout({ children, title, tableOfContents }) {
let router = useRouter()
let isHomePage = router.pathname === '/'
let allLinks = navigation.flatMap((section) => section.links)
let linkIndex = allLinks.findIndex((link) => link.href === router.pathname)
let previousPage = allLinks[linkIndex - 1]
let nextPage = allLinks[linkIndex + 1]
let section = navigation.find((section) =>
section.links.find((link) => link.href === router.pathname)
)
let currentSection = useTableOfContents(tableOfContents)
function isActive(section) {
if (section.id === currentSection) {
return true
}
if (!section.children) {
return false
}
return section.children.findIndex(isActive) > -1
}
return (
<>