<details
  open
  id="TOCView"
  class="toc-right mt-0 overflow-y-auto overscroll-contain bf-scrollbar rounded-lg -ms-5 ps-5 pe-2 hidden lg:block">
  <summary
    class="block py-1 text-lg font-semibold cursor-pointer bg-neutral-100 text-neutral-800 -ms-5 ps-5 dark:bg-neutral-700 dark:text-neutral-100 lg:hidden">
    {{ i18n "article.table_of_contents" }}
  </summary>
  <div
    class="min-w-[220px] py-2 border-dotted border-s-1 -ms-5 ps-5 dark:border-neutral-600">
    {{ .TableOfContents | emojify }}
  </div>
</details>
<details class="toc-inside mt-0 overflow-hidden rounded-lg -ms-5 ps-5 lg:hidden">
  <summary
    class="py-1 text-lg font-semibold cursor-pointer bg-neutral-100 text-neutral-800 -ms-5 ps-5 dark:bg-neutral-700 dark:text-neutral-100 lg:hidden">
    {{ i18n "article.table_of_contents" }}
  </summary>
  <div
    class="py-2 border-dotted border-neutral-300 border-s-1 -ms-5 ps-5 dark:border-neutral-600">
    {{ .TableOfContents | emojify }}
  </div>
</details>

{{ if or .Site.Params.smartTOC .Site.Params.article.smartTOC }}
<script>
  (function () {
    'use strict'

    const SCROLL_OFFSET_RATIO = 0.33
    const TOC_SELECTOR = '#TableOfContents'
    const ANCHOR_SELECTOR = '.anchor'
    const TOC_LINK_SELECTOR = 'a[href^="#"]'
    const NESTED_LIST_SELECTOR = 'li ul'
    const ACTIVE_CLASS = 'active'
    let isJumpingToAnchor = false

    function getActiveAnchorId(anchors, offsetRatio) {
      const threshold = window.scrollY + window.innerHeight * offsetRatio
      const tocLinks = [...document.querySelectorAll('#TableOfContents a[href^="#"]')]
      const tocIds = new Set(tocLinks.map(link => link.getAttribute('href').substring(1)))

      if (isJumpingToAnchor) {
        for (let i = 0; i < anchors.length; i++) {
          const anchor = anchors[i]
          if (!tocIds.has(anchor.id)) continue
          const top = anchor.getBoundingClientRect().top + window.scrollY
          if (Math.abs(window.scrollY - top) < 100) {
            return anchor.id
          }
        }
      }

      for (let i = anchors.length - 1; i >= 0; i--) {
        const top = anchors[i].getBoundingClientRect().top + window.scrollY
        if (top <= threshold && tocIds.has(anchors[i].id)) {
          return anchors[i].id
        }
      }
      return anchors.find(anchor => tocIds.has(anchor.id))?.id || ''
    }

    function updateTOC({ tocs, anchors, links, scrollOffset, collapseInactive }) {
      const activeId = getActiveAnchorId(anchors, scrollOffset)
      if (!activeId) return

      links.forEach(link => {
        const isActive = link.getAttribute('href') === `#${activeId}`
        link.classList.toggle(ACTIVE_CLASS, isActive)

        if (collapseInactive) {
          const ul = link.closest('li')?.querySelector('ul')
          if (ul) ul.style.display = isActive ? '' : 'none'
        }
      })

      if (collapseInactive) {
        tocs.forEach(toc => {
          const activeLink = toc.querySelector(`a[href="#${CSS.escape(activeId)}"]`)
          let el = activeLink
          while (el && el !== toc) {
            if (el.tagName === 'UL') el.style.display = ''
            if (el.tagName === 'LI') el.querySelector('ul')?.style.setProperty('display', '')
            el = el.parentElement
          }
        })
      }
    }

    function initTOC() {
      const tocs = document.querySelectorAll(TOC_SELECTOR)
      if (tocs.length === 0) return

      const collapseInactive = {{ if or site.Params.smartTOCHideUnfocusedChildren site.Params.article.smartTOCHideUnfocusedChildren }}true{{ else }}false{{ end }}
      const anchors = [...document.querySelectorAll(ANCHOR_SELECTOR)]
      const links = []
      tocs.forEach(toc => links.push(...toc.querySelectorAll(TOC_LINK_SELECTOR)))

      if (collapseInactive) {
        tocs.forEach(toc => {
          toc.querySelectorAll(NESTED_LIST_SELECTOR).forEach(ul => ul.style.display = 'none')
        })
      }

      links.forEach(link => {
        link.addEventListener('click', () => {
          isJumpingToAnchor = true
        })
      })

      const config = {
        tocs,
        anchors,
        links,
        scrollOffset: SCROLL_OFFSET_RATIO,
        collapseInactive
      }

      window.addEventListener('scroll', () => updateTOC(config), { passive: true })
      window.addEventListener('hashchange', () => updateTOC(config), { passive: true })

      updateTOC(config)
    }

    document.readyState === 'loading'
      ? document.addEventListener('DOMContentLoaded', initTOC)
      : initTOC()
  })()
</script>
{{ end }}
