<!DOCTYPE html>
<html lang="{{ lang_code }}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary_large_image" />
<!-- Page title -->
{% if scrap %}
{% set title_var=[ scrap.title,title ] | join(sep=" - ") %}
<title>{{ title_var }}</title>
<meta property="og:title" content="{{ title_var }}" />
<meta name="twitter:title" content="{{ title_var }}" />
{% else %}
<title>{{ title }}</title>
<meta property="og:title" content="{{ title }}" />
<meta name="twitter:title" content="{{ title }}" />
{% endif %}
<!-- Page description -->
{% if description %}
<meta name="description" content="{{ description }}" />
<meta property="og:description" content="{{ description }}" />
<meta name="twitter:description" content="{{ description }}" />
{% endif %}
<!-- Page favicon -->
{% if favicon %}
<link rel="icon" type="image/png" href="{{ favicon }}" />
{% endif %}
<!-- Rubik and Noto Sans JP fonts -->
<link rel="stylesheet" href="{{ base_url }}fonts/fonts.css?v={{ scraps_version }}">
<!-- Style sheet -->
<link rel="stylesheet" href="{{ base_url }}main.css">
{% block head %}
{% endblock head %}
</head>
<body>
<div class="shell">
<aside class="sidebar">
<div class="brand-block">
<a class="brand" href="{{ base_url }}">
<span class="mark">[[ ]]</span>
<span class="name">{{ title }}</span>
</a>
{% if has_readme %}
{% if view == "about" %}<span class="about active">about</span>{% else %}<a class="about" href="{{ base_url }}about/">about</a>{% endif %}
{% endif %}
</div>
{% if build_search_index == true %}
<div class="search">
<input
type="search"
id="search-input"
onkeyup="doSearch()"
placeholder="Search by title..."
autocomplete="off"
/>
<ul id="search-results"></ul>
</div>
{% endif %}
<nav class="scopes" aria-label="Scopes">
{% for scope in nav_scopes %}
{% if loop.index == 2 %}<p class="nav-label">tags</p>{% endif %}
<a class="item{% if scope.depth > 0 %} nested{% endif %}" href="{{ base_url }}{{ scope.url_path }}" data-counts="{{ scope.counts | json_encode() }}"{% if scope.title %} title="{{ scope.title }}"{% endif %}{% if scope.active %} aria-current="page"{% endif %} style="--depth: {{ scope.depth }}">{% if scope.title %}<span class="tag-name"><span class="syntax">#[[</span>{{ scope.name }}<span class="syntax">]]</span></span>{% else %}<span class="scope-name">{{ scope.name }}</span>{% endif %}<span class="count">{{ scope.counts.total }}</span></a>
{% endfor %}
</nav>
<p class="version">scraps v{{ scraps_version }}</p>
</aside>
<div class="main-wrap">
<main>
{% block main %}
{% endblock main %}
</main>
<footer class="status-bar">
<span class="left">{% block status_left %}{{ scrap_count }} scraps indexed{% endblock status_left %}</span>
<span class="right">Generated by <a href="https://github.com/boykush/scraps" target="_blank" rel="noopener noreferrer">Scraps</a></span>
</footer>
</div>
</div>
<!-- Code syntax highlight -->
<script src="{{ base_url }}js/highlight.min.js?v={{ scraps_version }}"></script>
<script>hljs.highlightAll();</script>
<!-- Mermaid -->
<script type="module">
// Mermaid outweighs the rest of the page many times over, so only
// a page that draws a diagram fetches it. Its browser build is a
// classic script that defines a global, which import() cannot load.
if (document.querySelector('code.mermaid')) {
await new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = '{{ base_url }}js/mermaid.min.js?v={{ scraps_version }}';
script.onload = resolve;
script.onerror = reject;
document.head.append(script);
});
// A diagram carries its own colours, so it has to be told which
// scheme the page resolved to; left on the default it draws dark
// strokes onto the dark ground and the edges disappear.
const prefersDark = matchMedia('(prefers-color-scheme: dark)');
const isDark = () => {
const declared = getComputedStyle(document.documentElement).colorScheme;
return declared === 'dark' || (declared !== 'light' && prefersDark.matches);
};
const draw = () => {
mermaid.initialize({ startOnLoad: false, theme: isDark() ? 'dark' : 'default' });
document.querySelectorAll('code.mermaid').forEach((node) => {
node.textContent = node.dataset.source ??= node.textContent;
node.removeAttribute('data-processed');
});
mermaid.run({ querySelector: 'code.mermaid' });
};
draw();
prefersDark.addEventListener('change', draw);
}
</script>
{% if build_search_index == true %}
<!-- For search scraps -->
<!--
fuse.js@7+ ships as ESM only; loading it through a classic <script src>
fails to evaluate the `export` and leaves window.Fuse undefined. Import it
from a module script and re-expose it as a global so the classic
doSearch() handler below can call `new Fuse(...)`.
-->
<script type="module">
import Fuse from "{{ base_url }}js/fuse.min.js?v={{ scraps_version }}";
window.Fuse = Fuse;
fetch('{{ base_url }}search_index.json')
.then(response => response.json())
.then(data => {
const fuseOptions = {
minMatchCharLength: 3,
keys: ["title"]
};
const fuse = new Fuse(data, fuseOptions);
window.search = function (query, numResults) {
return fuse.search(query).slice(0, numResults).map(result => [result.item.title, result.item.url]);
};
})
</script>
<script>
function doSearch() {
const value = document.getElementById("search-input").value;
const results = search(value, 5);
const ul = document.getElementById("search-results");
ul.innerHTML = "";
results.forEach((result) => {
const li = document.createElement("li");
const [title, url] = result;
const link = document.createElement("a");
link.textContent = title;
link.setAttribute("href", url);
li.appendChild(link);
ul.appendChild(li);
});
}
</script>
{% endif %}
{% block script %}
{% endblock script %}
</body>
</html>