327 lines
20 KiB
Plaintext
327 lines
20 KiB
Plaintext
<!--
|
|
---------------------------------------------------------------
|
|
docmd : the zero-config documentation engine.
|
|
@website https://docmd.io
|
|
[docmd-source] - Please do not remove this header.
|
|
---------------------------------------------------------------
|
|
-->
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="<%= (locals.activeLocale && locals.activeLocale.id) ? locals.activeLocale.id : 'en' %>"<%= (locals.activeLocale && locals.activeLocale.dir && locals.activeLocale.dir !== 'ltr') ? ' dir="' + locals.activeLocale.dir + '"' : '' %>>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="generator" content="docmd v<%= coreVersion %>">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<%- themeInitScript %>
|
|
<style>
|
|
html {
|
|
visibility: hidden;
|
|
}
|
|
</style>
|
|
<% let versionRoot='/' ; let siteRoot=relativePathToRoot;
|
|
const _locPfx = (typeof localePrefix !== 'undefined' && localePrefix) ? localePrefix : '';
|
|
if (config.versions?.current && config._activeVersion?.id) {
|
|
const isSubVersion=config.versions.current !==config._activeVersion.id;
|
|
versionRoot= '/' + _locPfx + (isSubVersion ? config._activeVersion.id + '/' : '');
|
|
if (isSubVersion) { siteRoot=(relativePathToRoot==='./' ? '' :
|
|
relativePathToRoot) + '../' ; } } else if (_locPfx) { versionRoot = '/' + _locPfx; }
|
|
if (locals.isOfflineMode) { versionRoot='' ;
|
|
}
|
|
%>
|
|
<script>
|
|
var root = "<%= relativePathToRoot %>";
|
|
if (root && !root.endsWith('/')) root += '/';
|
|
if (root === '') root = './';
|
|
window.DOCMD_ROOT = root;
|
|
|
|
window.DOCMD_SITE_ROOT = "<%= siteRootAbs %>";
|
|
|
|
window.DOCMD_APPEARANCE = "<%= appearance %>";
|
|
window.DOCMD_VERSION_ROOT = "<%= versionRoot || '/' %>";
|
|
window.DOCMD_BASE = "<%= config.base || '/' %>";
|
|
window.DOCMD_LOCALE = "<%= (locals.activeLocale && locals.activeLocale.id) ? locals.activeLocale.id : '' %>";
|
|
window.DOCMD_DEFAULT_LOCALE = "<%= locals.defaultLocale || '' %>";
|
|
</script>
|
|
<title>
|
|
<%= pageTitle %><% if (siteTitle && pageTitle !== siteTitle && !(frontmatter && frontmatter.titleAppend === false)) { %> : <%= siteTitle %><% } %>
|
|
</title>
|
|
|
|
<base href="<%= siteRootAbs %>">
|
|
<%- faviconLinkHtml || '' %>
|
|
<link rel="stylesheet" href="<%= relativePathToRoot %>assets/css/docmd-main.css?v=<%= buildHash %>">
|
|
<% if (config.theme?.codeHighlight !==false) { const isDarkDefault=appearance==='dark' ; %>
|
|
<link rel="stylesheet" href="<%= relativePathToRoot %>assets/css/docmd-highlight-light.css?v=<%= buildHash %>" id="hljs-light" <%=isDarkDefault ? 'disabled' : '' %>>
|
|
<link rel="stylesheet" href="<%= relativePathToRoot %>assets/css/docmd-highlight-dark.css?v=<%= buildHash %>" id="hljs-dark" <%=isDarkDefault ? '' : 'disabled' %>>
|
|
<% } %>
|
|
<%- pluginHeadScriptsHtml || '' %>
|
|
<% (customCssFiles || []).forEach(cssFile=> { %>
|
|
<link rel="stylesheet" href="<%= relativePathToRoot %><%= cssFile.startsWith('/') ? cssFile.substring(1) : cssFile %>?v=<%= buildHash %>">
|
|
<% }); %>
|
|
<%- themeInitScript %>
|
|
</head>
|
|
<body
|
|
class="<%= sidebarConfig?.enabled === false ? 'no-sidebar' : (sidebarConfig?.collapsible ? 'sidebar-collapsible' : 'sidebar-not-collapsible') %><%= (locals.menubarConfig && menubarConfig?.enabled !== false) ? ' has-menubar has-menubar-' + (menubarConfig.position || 'top') : '' %><%= headerConfig?.enabled === false ? ' no-header' : '' %>"
|
|
data-default-collapsed="<%= sidebarConfig?.defaultCollapsed %>"
|
|
data-copy-code-enabled="<%= config.copyCode === true %>" data-spa-enabled="<%= config.layout?.spa !== false %>"<% if (locals.sourceFile) { %> data-source-file="<%= sourceFile %>"<% } %>>
|
|
|
|
<a href="#main-content" class="skip-link"><%= typeof t === 'function' ? t('skipToContent') : 'Skip to content' %></a>
|
|
|
|
<% if (locals.menubarConfig && menubarConfig?.enabled !==false && menubarConfig.position !=='header' ) { %>
|
|
<%- await include('partials/menubar', {
|
|
menubarConfig, relativePathToRoot, renderIcon, optionsMenu: locals.optionsMenu, t: typeof t === 'function' ? t : null
|
|
}) %>
|
|
<% } %>
|
|
<% if (sidebarConfig?.enabled !==false) { %>
|
|
<aside class="sidebar">
|
|
<div class="sidebar-header">
|
|
<% if (logo && logo.light && logo.dark) { %>
|
|
<a href="<%= logo.href || relativePathToRoot %>" class="logo-link">
|
|
<img
|
|
src="<%= relativePathToRoot %><%= logo.light.startsWith('/') ? logo.light.substring(1) : logo.light %>"
|
|
alt="<%= logo.alt || siteTitle %>" class="logo-light" <% if (logo.height) { %>style="height: <%=
|
|
logo.height %>;"<% } %>>
|
|
<img
|
|
src="<%= relativePathToRoot %><%= logo.dark.startsWith('/') ? logo.dark.substring(1) : logo.dark %>"
|
|
alt="<%= logo.alt || siteTitle %>" class="logo-dark" <% if (logo.height) { %>style="height: <%=
|
|
logo.height %>;"<% } %>>
|
|
</a>
|
|
<% } else { %>
|
|
<h1><a href="<%= relativePathToRoot %>">
|
|
<%= siteTitle %>
|
|
</a></h1>
|
|
<% } %>
|
|
<span class="mobile-view sidebar-menu-button float-right">
|
|
<%- renderIcon("menu") %>
|
|
</span>
|
|
</div>
|
|
<div class="sidebar-top-group">
|
|
<% if (locals.workspace && workspace.switcher.enabled && workspace.switcher.position === 'sidebar-top') { %>
|
|
<div class="sidebar-project-switcher-wrapper">
|
|
<%- await include('partials/project-switcher', { workspace, config, renderIcon, compact: false, t: typeof t === 'function' ? t : null }) %>
|
|
</div>
|
|
<% } %>
|
|
<% if (locals.optionsMenu && optionsMenu.position==='sidebar-top' ) { %>
|
|
<div class="sidebar-options-wrapper">
|
|
<%- await include('partials/options-menu', { optionsMenu, allLocales: locals.allLocales, activeLocale: locals.activeLocale, defaultLocale: locals.defaultLocale, config: locals.config, renderIcon, currentPagePath: locals.currentPagePath, localePrefix: locals.localePrefix, workspace, t: typeof t === 'function' ? t : null }) %>
|
|
</div>
|
|
<% } %>
|
|
<% if (config.versions && config.versions.position==='sidebar-top' ) { %>
|
|
<div class="sidebar-version-wrapper">
|
|
<%- await include('partials/version-dropdown', { versions: config.versions, activeVersion:
|
|
config._activeVersion, relativePathToRoot, localePrefix: locals.localePrefix, config, t: typeof t === 'function' ? t : null }) %>
|
|
</div>
|
|
<% } %>
|
|
<% if (locals.allLocales && allLocales && allLocales.length > 1 && config.i18n && config.i18n.position === 'sidebar-top') { %>
|
|
<div class="sidebar-language-wrapper">
|
|
<%- await include('partials/language-switcher', { allLocales, activeLocale: locals.activeLocale, defaultLocale: locals.defaultLocale, config, renderIcon, compact: false, currentPagePath: locals.currentPagePath, localePrefix: locals.localePrefix, t: typeof t === 'function' ? t : null }) %>
|
|
</div>
|
|
<% } %>
|
|
</div>
|
|
<%- navigationHtml %>
|
|
<div class="sidebar-bottom-group mt-auto">
|
|
<% if (config.versions && config.versions.position==='sidebar-bottom' ) { %>
|
|
<div class="sidebar-version-wrapper">
|
|
<%- await include('partials/version-dropdown', { versions: config.versions, activeVersion:
|
|
config._activeVersion, relativePathToRoot, localePrefix: locals.localePrefix, config, t: typeof t === 'function' ? t : null }) %>
|
|
</div>
|
|
<% } %>
|
|
<% if (locals.allLocales && allLocales && allLocales.length > 1 && config.i18n && config.i18n.position === 'sidebar-bottom') { %>
|
|
<div class="sidebar-language-wrapper">
|
|
<%- await include('partials/language-switcher', { allLocales, activeLocale: locals.activeLocale, defaultLocale: locals.defaultLocale, config, renderIcon, compact: false, currentPagePath: locals.currentPagePath, localePrefix: locals.localePrefix, t: typeof t === 'function' ? t : null }) %>
|
|
</div>
|
|
<% } %>
|
|
<% if (locals.workspace && workspace.switcher.enabled && workspace.switcher.position === 'sidebar-bottom') { %>
|
|
<div class="sidebar-project-switcher-wrapper">
|
|
<%- await include('partials/project-switcher', { workspace, config, renderIcon, compact: false, t: typeof t === 'function' ? t : null }) %>
|
|
</div>
|
|
<% } %>
|
|
<% if (locals.optionsMenu && optionsMenu.position==='sidebar-bottom' ) { %>
|
|
<div class="sidebar-options-wrapper">
|
|
<%- await include('partials/options-menu', { optionsMenu, allLocales: locals.allLocales, activeLocale: locals.activeLocale, defaultLocale: locals.defaultLocale, config: locals.config, renderIcon, currentPagePath: locals.currentPagePath, localePrefix: locals.localePrefix, workspace, t: typeof t === 'function' ? t : null }) %>
|
|
</div>
|
|
<% } %>
|
|
</div>
|
|
</aside>
|
|
<% } %>
|
|
<%# Site-wide announcement banner (new in 0.8.7). Sits above the menubar. %>
|
|
<% if (locals.config && config.layout && config.layout.banner) { %>
|
|
<%- await include('partials/banner', { config, relativePathToRoot, renderIcon, t: typeof t === 'function' ? t : null }) %>
|
|
<% } %>
|
|
<div class="main-content-wrapper">
|
|
<% if (locals.menubarConfig && menubarConfig?.enabled !==false && menubarConfig.position==='header' ) { %>
|
|
<%- await include('partials/menubar', { menubarConfig, relativePathToRoot, renderIcon, optionsMenu:
|
|
locals.optionsMenu, t: typeof t === 'function' ? t : null }) %>
|
|
<% } %>
|
|
<% if (headerConfig?.enabled !==false) { %>
|
|
<header class="page-header">
|
|
<div class="header-left">
|
|
<% if (sidebarConfig?.collapsible) { %>
|
|
<button id="sidebar-toggle-button" class="sidebar-toggle-button"
|
|
aria-label="<%= typeof t === 'function' ? t('toggleSidebar') : 'Toggle sidebar' %>">
|
|
<%- renderIcon('chevron-left') %>
|
|
</button>
|
|
<% } %>
|
|
<div class="header-titles-wrapper">
|
|
<span class="header-title">
|
|
<%= pageTitle %>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="header-right">
|
|
<% if (optionsMenu?.position==='header' ) { %>
|
|
<%- await include('partials/options-menu', { optionsMenu, allLocales: locals.allLocales, activeLocale: locals.activeLocale, defaultLocale: locals.defaultLocale, config: locals.config, renderIcon, currentPagePath: locals.currentPagePath, localePrefix: locals.localePrefix, workspace, t: typeof t === 'function' ? t : null }) %>
|
|
<% } %>
|
|
</div>
|
|
</header>
|
|
<% } %>
|
|
<div class="content-theme-cover">
|
|
<main class="content-area" id="main-content">
|
|
<div class="content-layout">
|
|
<div class="main-content">
|
|
<div class="docmd-breadcrumbs-row">
|
|
<div id="docmd-raw-markdown" data-content="<%= encodeURIComponent(rawMarkdown) %>" style="display: none;"></div>
|
|
<% if (config.layout?.breadcrumbs !== false && locals.breadcrumbs && breadcrumbs.length > 0) { %>
|
|
<nav aria-label="<%= typeof t === 'function' ? t('breadcrumb') : 'Breadcrumb' %>" class="docmd-breadcrumbs">
|
|
<ol>
|
|
<% const _bcPrefix = (typeof outputPrefix !== 'undefined' && outputPrefix) ? outputPrefix : ''; %>
|
|
<% breadcrumbs.forEach((crumb, index) => { %>
|
|
<li class="breadcrumb-item <%= index === breadcrumbs.length - 1 ? 'active' : '' %>" <%= index === breadcrumbs.length - 1 ? 'aria-current="page"' : '' %>>
|
|
<% if (crumb.path && index < breadcrumbs.length - 1) { %>
|
|
<a href="<%= relativePathToRoot %><%= _bcPrefix %><%= crumb.path.startsWith('/') ? crumb.path.substring(1) : crumb.path %>"><%= crumb.title %></a>
|
|
<% } else { %>
|
|
<span><%= crumb.title %></span>
|
|
<% } %>
|
|
<% if (index < breadcrumbs.length - 1) { %>
|
|
<span class="breadcrumb-separator"><%- renderIcon('chevron-right') %></span>
|
|
<% } %>
|
|
</li>
|
|
<% }) %>
|
|
</ol>
|
|
</nav>
|
|
<% } else { %>
|
|
<div class="docmd-breadcrumbs-spacer"></div>
|
|
<% } %>
|
|
|
|
<% if (config.theme?.copyWidgets?.enabled !== false) { %>
|
|
<div class="docmd-copy-widgets">
|
|
<% if (config.theme?.copyWidgets?.raw !== false) { %>
|
|
<button class="docmd-copy-btn docmd-copy-raw-btn" data-copied="<%= typeof t === 'function' ? t('copiedToClipboard') : 'Copied!' %>" title="<%= typeof t === 'function' ? t('copyMarkdown') : 'Copy Markdown' %>" aria-label="<%= typeof t === 'function' ? t('copyMarkdown') : 'Copy Markdown' %>">
|
|
<span class="docmd-btn-icon"><%- renderIcon('copy') %></span>
|
|
</button>
|
|
<% } %>
|
|
<% if (config.theme?.copyWidgets?.context !== false) { %>
|
|
<button class="docmd-copy-btn docmd-copy-context-btn" data-copied="<%= typeof t === 'function' ? t('copiedToClipboard') : 'Copied!' %>" title="<%= typeof t === 'function' ? t('copyContext') : 'Copy Context' %>">
|
|
<span class="docmd-btn-icon"><%- renderIcon('message-square') || renderIcon('copy') %></span>
|
|
<span class="docmd-btn-text"><%= typeof t === 'function' ? t('copyContext') : 'Copy Context' %></span>
|
|
</button>
|
|
<% } %>
|
|
</div>
|
|
<% } %>
|
|
</div>
|
|
<% if (headerConfig?.enabled===false) { %>
|
|
<h1>
|
|
<%= pageTitle %>
|
|
</h1>
|
|
<% } %>
|
|
<%- content %>
|
|
<% if (config.pageNavigation && (prevPage || nextPage)) { %>
|
|
<div class="page-navigation">
|
|
<% if (prevPage) { %>
|
|
<a href="<%= prevPage.url %>" class="prev-page">
|
|
<%- renderIcon('arrow-left', { class: 'page-nav-icon' }) %>
|
|
<span><small><%= typeof t === 'function' ? t('previous') : 'Previous' %></small><strong>
|
|
<%= prevPage.title %>
|
|
</strong></span>
|
|
</a>
|
|
<% } else { %>
|
|
<div class="prev-page-placeholder">
|
|
</div>
|
|
<% } %>
|
|
<% if (nextPage) { %>
|
|
<a href="<%= nextPage.url %>" class="next-page">
|
|
<span><small><%= typeof t === 'function' ? t('next') : 'Next' %></small>
|
|
<strong>
|
|
<%= nextPage.title %>
|
|
</strong></span>
|
|
<%- renderIcon('arrow-right', { class: 'page-nav-icon' }) %>
|
|
</a>
|
|
<% } else { %>
|
|
<div class="next-page-placeholder">
|
|
</div>
|
|
<% } %>
|
|
</div>
|
|
<% } %>
|
|
</div>
|
|
<div class="toc-sidebar">
|
|
<%- await include('toc', { content, headings, navigationHtml, isActivePage, t: typeof t === 'function' ? t : null }) %>
|
|
</div>
|
|
</div>
|
|
<div class="page-footer-actions">
|
|
<%# Git Plugin: Last updated timestamp (core plugin, always inject) %>
|
|
<% if (locals.frontmatter && locals.frontmatter._git && locals.frontmatter._git.lastUpdatedTimestamp) { %>
|
|
<span class="git-last-updated" data-timestamp="<%= locals.frontmatter._git.lastUpdatedTimestamp %>">
|
|
<svg class="git-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<circle cx="12" cy="12" r="10"></circle>
|
|
<polyline points="12 6 12 12 16 14"></polyline>
|
|
</svg>
|
|
<span class="git-label"><%= typeof t === 'function' ? t('lastUpdated') : 'Last updated' %>:</span>
|
|
<span class="git-time" data-timestamp="<%= locals.frontmatter._git.lastUpdatedTimestamp %>"></span>
|
|
<% if (locals.frontmatter._git.commits && locals.frontmatter._git.commits.length > 0) { %>
|
|
<div class="git-commit-tooltip" role="tooltip">
|
|
<div class="git-tooltip-title"><%= typeof t === 'function' ? t('recentCommits') : 'Recent commits' %></div>
|
|
<ul class="git-commit-list">
|
|
<% locals.frontmatter._git.commits.slice(0, 6).forEach(function(commit) { %>
|
|
<li class="git-commit-item">
|
|
<div class="git-commit-avatar" title="<%= commit.author %>">
|
|
<% if (commit.avatarUrl) { %>
|
|
<img src="<%= commit.avatarUrl %>" alt="<%= commit.author %>">
|
|
<% } else { %>
|
|
<%= commit.author.split(' ').map(n => n[0]).join('').substring(0, 2).toUpperCase() %>
|
|
<% } %>
|
|
</div>
|
|
<div class="git-commit-details">
|
|
<div class="git-commit-message" title="<%= commit.message %>"><%= commit.message.length > 40 ? commit.message.substring(0, 37) + '...' : commit.message %></div>
|
|
<div class="git-commit-meta">
|
|
<span class="git-commit-author"><%= commit.author %></span>
|
|
<span class="git-commit-date" data-timestamp="<%= commit.timestamp %>"></span>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<% }); %>
|
|
</ul>
|
|
</div>
|
|
<% } %>
|
|
</span>
|
|
<% } %>
|
|
<span class="git-spacer"></span>
|
|
<% if (locals.editUrl) { %>
|
|
<a href="<%= editUrl %>" target="_blank" rel="noopener noreferrer" class="edit-link">
|
|
<%- renderIcon('pencil') %>
|
|
<%= editLinkText %>
|
|
</a>
|
|
<% } %>
|
|
</div>
|
|
</main>
|
|
<%- await include('partials/footer', { footerConfig, config, relativePathToRoot, logo, siteTitle,
|
|
footerHtml, t: typeof t === 'function' ? t : null }) %>
|
|
</div>
|
|
</div>
|
|
<% if (locals.allLocales && allLocales && allLocales.length > 1) { %>
|
|
<script src="<%= relativePathToRoot %>assets/js/docmd-i18n-manifest.js?v=<%= buildHash %>"></script>
|
|
<% } %>
|
|
<script src="<%= relativePathToRoot %>assets/js/docmd-main.js?v=<%= buildHash %>"></script>
|
|
<%# Git Plugin core JS (injected directly since git is a core plugin) %>
|
|
<script src="<%= relativePathToRoot %>assets/js/docmd-git.js?v=<%= buildHash %>"></script>
|
|
<%- pluginBodyScriptsHtml || '' %>
|
|
<% (customJsFiles || []).forEach(jsFile=> {
|
|
if (jsFile && jsFile.trim() !== '') { %>
|
|
<script
|
|
src="<%= relativePathToRoot %><%= jsFile.startsWith('/') ? jsFile.substring(1) : jsFile %>?v=<%= buildHash %>"></script>
|
|
<% }
|
|
}); %>
|
|
<%# Cookie consent dialog (new in 0.8.7). Rendered only when config.cookie is set. %>
|
|
<% if (locals.config && config.cookie && config.cookie.enabled !== false) { %>
|
|
<%- await include('partials/cookie-consent', { config, relativePathToRoot, renderIcon, t: typeof t === 'function' ? t : null }) %>
|
|
<% } %>
|
|
</body>
|
|
</html> |