Files
thgtoa/code/index.html
T

1617 lines
56 KiB
HTML

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="How to contribute to the Hitchhiker's Guide — building, signing, releasing, and writing.">
<meta name="author" content="Anonymous Planet">
<link rel="canonical" href="https://anonymousplanet.net/code/">
<link rel="prev" href="../guide/">
<link rel="next" href="../contribute/">
<link rel="icon" href="../media/profile.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.2">
<title>Content Contributions - The Hitchhiker's Guide</title>
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.ab4e12ef.min.css">
<link rel="stylesheet" href="../stylesheets/hacker.css">
<link rel="stylesheet" href="../stylesheets/hacker-extra.css">
<link rel="stylesheet" href="../stylesheets/going-dark.css">
<link rel="stylesheet" href="../stylesheets/toggle.css">
<link rel="stylesheet" href="../stylesheets/navigation.css">
<link rel="stylesheet" href="../stylesheets/footer.css">
<link rel="stylesheet" href="../stylesheets/accessibility.css">
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<link href="https://ioc.exchange/@unknown" rel="me">
<link rel="icon" id="ap-favicon" href="../media/profile.png" sizes="any">
<link rel="icon" type="image/
</script>
<meta property="og:type" content="website" />
<meta property="og:title" content="Content Contributions - The Hitchhiker's Guide" />
<meta property="og:description" content="How to contribute to the Hitchhiker's Guide — building, signing, releasing, and writing." />
<meta property="og:image" content="https://anonymousplanet.net/assets/images/social/code/index.png" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:url" content="https://anonymousplanet.net/code/" />
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:title" content="Content Contributions - The Hitchhiker's Guide" />
<meta property="twitter:description" content="How to contribute to the Hitchhiker's Guide — building, signing, releasing, and writing." />
<meta property="twitter:image" content="https://anonymousplanet.net/assets/images/social/code/index.png" />
</head>
<body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="hacker" data-md-color-accent="green">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#setup" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="The Hitchhiker&#39;s Guide" class="md-header__button md-logo" aria-label="The Hitchhiker's Guide" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m23 11.5-3.05-1.13c-.26-1.15-.91-1.81-.91-1.81a4.19 4.19 0 0 0-5.93 0l-1.48 1.48L5 3c-1 4 0 8 2.45 11.22L2 19.5s8.89 2 14.07-2.05c2.76-2.16 3.38-3.42 3.77-4.75zm-5.29.22c-.39.39-1.03.39-1.42 0a.996.996 0 0 1 0-1.41c.39-.39 1.03-.39 1.42 0s.39 1.02 0 1.41"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
The Hitchhiker's Guide
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Content Contributions
</span>
</div>
</div>
</div>
<div class="toggle-container toggle-container--header" id="ap-palette-toggle">
<div class="toggle-wrap">
<input type="checkbox" class="toggle-input" id="ap-toggle-input" aria-label="Turn the monitor on or off">
<label for="ap-toggle-input" class="toggle-track">
<div class="holo-glow"></div>
<div class="track-lines"><div class="track-line"></div></div>
<div class="toggle-thumb">
<div class="thumb-core"></div>
<div class="thumb-inner"></div>
<div class="thumb-scan"></div>
<div class="thumb-particles">
<div class="thumb-particle"></div>
<div class="thumb-particle"></div>
<div class="thumb-particle"></div>
<div class="thumb-particle"></div>
<div class="thumb-particle"></div>
</div>
</div>
<div class="energy-rings">
<div class="energy-ring"></div>
<div class="energy-ring"></div>
<div class="energy-ring"></div>
</div>
<div class="toggle-data">
<div class="data-text off">On</div>
<div class="data-text on">Off</div>
</div>
<div class="toggle-status-dot off"></div>
<div class="toggle-status-dot on"></div>
<div class="interface-lines">
<div class="interface-line"></div>
<div class="interface-line"></div>
<div class="interface-line"></div>
<div class="interface-line"></div>
<div class="interface-line"></div>
<div class="interface-line"></div>
</div>
<div class="toggle-reflection"></div>
</label>
</div>
</div>
<script>
(function () {
var KEY = "__palette";
var input = document.getElementById("ap-toggle-input");
if (!input) return;
function currentScheme() {
return document.body.getAttribute("data-md-color-scheme") || "slate";
}
function applyScheme(scheme) {
document.body.setAttribute("data-md-color-scheme", scheme);
var stored = { index: scheme === "default" ? 1 : 0 };
try {
localStorage.setItem(KEY, JSON.stringify(stored));
} catch (e) {
/* storage unavailable, fail silently */
}
}
input.checked = currentScheme() === "default";
input.addEventListener("change", function () {
applyScheme(input.checked ? "default" : "slate");
});
})();
</script>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/Anon-Planet/thgtoa" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
</div>
<div class="md-source__repository">
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href=".." class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item">
<a href="../verify/" class="md-tabs__link">
Verify
</a>
</li>
<li class="md-tabs__item">
<a href="../guide/" class="md-tabs__link">
Guide
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="./" class="md-tabs__link">
Code
</a>
</li>
<li class="md-tabs__item">
<a href="../contribute/" class="md-tabs__link">
Donations
</a>
</li>
<li class="md-tabs__item">
<a href="../constitution/" class="md-tabs__link">
A Constitution
</a>
</li>
<li class="md-tabs__item">
<a href="../mirrors/" class="md-tabs__link">
Mirrors
</a>
</li>
<li class="md-tabs__item">
<a href="../changelog/" class="md-tabs__link">
Changelog
</a>
</li>
<li class="md-tabs__item">
<a href="../about/" class="md-tabs__link">
Anonymous Planet
</a>
</li>
<li class="md-tabs__item">
<a href="../pgp/" class="md-tabs__link">
PGP
</a>
</li>
</ul>
</div>
</nav>
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" hidden>
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href=".." title="The Hitchhiker&#39;s Guide" class="md-nav__button md-logo" aria-label="The Hitchhiker's Guide" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m23 11.5-3.05-1.13c-.26-1.15-.91-1.81-.91-1.81a4.19 4.19 0 0 0-5.93 0l-1.48 1.48L5 3c-1 4 0 8 2.45 11.22L2 19.5s8.89 2 14.07-2.05c2.76-2.16 3.38-3.42 3.77-4.75zm-5.29.22c-.39.39-1.03.39-1.42 0a.996.996 0 0 1 0-1.41c.39-.39 1.03-.39 1.42 0s.39 1.02 0 1.41"/></svg>
</a>
The Hitchhiker's Guide
</label>
<div class="md-nav__source">
<a href="https://github.com/Anon-Planet/thgtoa" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
</div>
<div class="md-source__repository">
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../verify/" class="md-nav__link">
<span class="md-ellipsis">
Verify
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../guide/" class="md-nav__link">
<span class="md-ellipsis">
Guide
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Code
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Code
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#setup" class="md-nav__link">
<span class="md-ellipsis">
Setup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#layout" class="md-nav__link">
<span class="md-ellipsis">
Repository Layout
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#build" class="md-nav__link">
<span class="md-ellipsis">
Building Locally
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#contributing" class="md-nav__link">
<span class="md-ellipsis">
Contributing Content
</span>
</a>
<nav class="md-nav" aria-label="Contributing Content">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#commit-types" class="md-nav__link">
<span class="md-ellipsis">
Commit Types
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#rules" class="md-nav__link">
<span class="md-ellipsis">
Rules
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#pipeline" class="md-nav__link">
<span class="md-ellipsis">
Release Pipeline
</span>
</a>
<nav class="md-nav" aria-label="Release Pipeline">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#release-tags" class="md-nav__link">
<span class="md-ellipsis">
Release Tags
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#triggering-each-step" class="md-nav__link">
<span class="md-ellipsis">
Triggering Each Step
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#verify" class="md-nav__link">
<span class="md-ellipsis">
Verifying a Release
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#troubleshooting" class="md-nav__link">
<span class="md-ellipsis">
Troubleshooting
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../contribute/" class="md-nav__link">
<span class="md-ellipsis">
Donations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../constitution/" class="md-nav__link">
<span class="md-ellipsis">
A Constitution
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../mirrors/" class="md-nav__link">
<span class="md-ellipsis">
Mirrors
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../changelog/" class="md-nav__link">
<span class="md-ellipsis">
Changelog
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../about/" class="md-nav__link">
<span class="md-ellipsis">
Anonymous Planet
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../pgp/" class="md-nav__link">
<span class="md-ellipsis">
PGP
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" hidden>
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#setup" class="md-nav__link">
<span class="md-ellipsis">
Setup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#layout" class="md-nav__link">
<span class="md-ellipsis">
Repository Layout
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#build" class="md-nav__link">
<span class="md-ellipsis">
Building Locally
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#contributing" class="md-nav__link">
<span class="md-ellipsis">
Contributing Content
</span>
</a>
<nav class="md-nav" aria-label="Contributing Content">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#commit-types" class="md-nav__link">
<span class="md-ellipsis">
Commit Types
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#rules" class="md-nav__link">
<span class="md-ellipsis">
Rules
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#pipeline" class="md-nav__link">
<span class="md-ellipsis">
Release Pipeline
</span>
</a>
<nav class="md-nav" aria-label="Release Pipeline">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#release-tags" class="md-nav__link">
<span class="md-ellipsis">
Release Tags
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#triggering-each-step" class="md-nav__link">
<span class="md-ellipsis">
Triggering Each Step
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#verify" class="md-nav__link">
<span class="md-ellipsis">
Verifying a Release
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#troubleshooting" class="md-nav__link">
<span class="md-ellipsis">
Troubleshooting
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<div class="hero-block">
<div class="hero-eyebrow">Open source. Every PR matters.</div>
<h1 class="hero-title">Contribute<span class="hero-subtitle">Help us improve the Hitchhiker's Guide..</span></h1>
<p class="hero-tagline">
Contributions range from fixing a typo to writing entire new sections.
</p>
<div class="hero-cta-row">
<a href="https://github.com/Anon-Planet/thgtoa/issues/new" class="hero-cta hero-cta--primary">Open an Issue</a>
<a href="#pipeline" class="hero-cta hero-cta--secondary">Release Pipeline</a>
</div>
</div>
<hr />
<h2 id="setup">Setup<a class="headerlink" href="#setup" title="Permanent link">λ</a></h2>
<p>Install these before anything else.</p>
<div class="tabbed-set tabbed-alternate" data-tabs="1:2"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Linux / macOS</label><label for="__tabbed_1_2">Windows</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="c1"># Python 3.11+</span>
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>python3<span class="w"> </span>--version
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a>
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a><span class="c1"># poppler (pdftoppm) and qpdf</span>
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a>sudo<span class="w"> </span>apt<span class="w"> </span>install<span class="w"> </span>poppler-utils<span class="w"> </span>qpdf<span class="w"> </span><span class="c1"># Debian/Ubuntu</span>
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a>brew<span class="w"> </span>install<span class="w"> </span>poppler<span class="w"> </span>qpdf<span class="w"> </span><span class="c1"># macOS</span>
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a>
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a><span class="c1"># GPG</span>
<a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a>sudo<span class="w"> </span>apt<span class="w"> </span>install<span class="w"> </span>gnupg<span class="w"> </span><span class="c1"># Debian/Ubuntu</span>
<a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a>brew<span class="w"> </span>install<span class="w"> </span>gnupg<span class="w"> </span><span class="c1"># macOS</span>
<a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a>
<a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a><span class="c1"># Python dependencies</span>
<a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a>pip<span class="w"> </span>install<span class="w"> </span><span class="s2">&quot;mkdocs-material[imaging]&quot;</span><span class="w"> </span>pillow<span class="w"> </span>numpy
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="c"># Python 3.11+ from https://python.org</span>
<a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a>
<a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a><span class="c"># poppler: https://github.com/oschwartz10612/poppler-windows/releases</span>
<a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a><span class="c"># Extract and add the bin\ folder to PATH</span>
<a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a>
<a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a><span class="c"># qpdf: https://github.com/qpdf/qpdf/releases</span>
<a id="__codelineno-1-7" name="__codelineno-1-7" href="#__codelineno-1-7"></a><span class="c"># Extract and add the bin\ folder to PATH</span>
<a id="__codelineno-1-8" name="__codelineno-1-8" href="#__codelineno-1-8"></a>
<a id="__codelineno-1-9" name="__codelineno-1-9" href="#__codelineno-1-9"></a><span class="c"># GPG: https://gpg4win.org</span>
<a id="__codelineno-1-10" name="__codelineno-1-10" href="#__codelineno-1-10"></a>
<a id="__codelineno-1-11" name="__codelineno-1-11" href="#__codelineno-1-11"></a><span class="c"># Python dependencies</span>
<a id="__codelineno-1-12" name="__codelineno-1-12" href="#__codelineno-1-12"></a><span class="n">pip</span> <span class="n">install</span> <span class="s2">&quot;mkdocs-material[imaging]&quot;</span> <span class="n">pillow</span> <span class="n">numpy</span>
</code></pre></div>
</div>
</div>
</div>
<p>You also need <strong>Google Chrome</strong> or <strong>Microsoft Edge</strong> installed for the light-mode PDF build (headless Chromium).</p>
<hr />
<h2 id="layout">Repository Layout<a class="headerlink" href="#layout" title="Permanent link">λ</a></h2>
<div class="highlight"><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a>.github/
<a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a> workflows/
<a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a> 01-build.yml # builds PDFs, uploads artifact
<a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a> 02-sign.yml # hashes + GPG signs, uploads signatures artifact
<a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a> 03-release.yml # publishes GitHub Release with all assets
<a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a> 04-changelog.yml # prepends a new entry to docs/changelog/index.md
<a id="__codelineno-2-7" name="__codelineno-2-7" href="#__codelineno-2-7"></a> publish.yml # deploys MkDocs site to GitHub Pages
<a id="__codelineno-2-8" name="__codelineno-2-8" href="#__codelineno-2-8"></a>docs/
<a id="__codelineno-2-9" name="__codelineno-2-9" href="#__codelineno-2-9"></a> guide/index.md # the guide (single Markdown file)
<a id="__codelineno-2-10" name="__codelineno-2-10" href="#__codelineno-2-10"></a> changelog/ # release notes
<a id="__codelineno-2-11" name="__codelineno-2-11" href="#__codelineno-2-11"></a> code/ # this page
<a id="__codelineno-2-12" name="__codelineno-2-12" href="#__codelineno-2-12"></a>export/ # PDF output (PDFs gitignored; .sha256, .b2sum, .asc tracked)
<a id="__codelineno-2-13" name="__codelineno-2-13" href="#__codelineno-2-13"></a>pgp/ # public signing keys
<a id="__codelineno-2-14" name="__codelineno-2-14" href="#__codelineno-2-14"></a>scripts/
<a id="__codelineno-2-15" name="__codelineno-2-15" href="#__codelineno-2-15"></a> build_guide_pdf.py # MkDocs + Chromium PDF builder
<a id="__codelineno-2-16" name="__codelineno-2-16" href="#__codelineno-2-16"></a> convert.py # pixel-based dark mode PDF converter
<a id="__codelineno-2-17" name="__codelineno-2-17" href="#__codelineno-2-17"></a> install_fonts.py # install fonts locally
<a id="__codelineno-2-18" name="__codelineno-2-18" href="#__codelineno-2-18"></a> update_changelog.py # auto-generates changelog entries from git log
<a id="__codelineno-2-19" name="__codelineno-2-19" href="#__codelineno-2-19"></a> setup_workflow.py # GitHub Secrets setup assistant
<a id="__codelineno-2-20" name="__codelineno-2-20" href="#__codelineno-2-20"></a> verify_pdf.py # signature verification helper
<a id="__codelineno-2-21" name="__codelineno-2-21" href="#__codelineno-2-21"></a> archived/
<a id="__codelineno-2-22" name="__codelineno-2-22" href="#__codelineno-2-22"></a> tag_release.py # ARCHIVED — GPG tag helper (not used in current flow)
</code></pre></div>
<hr />
<h2 id="build">Building Locally<a class="headerlink" href="#build" title="Permanent link">λ</a></h2>
<div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a>python<span class="w"> </span>scripts/build_guide_pdf.py<span class="w"> </span>--both
</code></pre></div>
<p>Builds the MkDocs site, renders it to <code>export/thgtoa.pdf</code> via headless Chromium, then produces <code>export/thgtoa-dark.pdf</code>.</p>
<table>
<thead>
<tr>
<th>Flag</th>
<th>Effect</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--both</code></td>
<td>Light PDF then dark PDF</td>
</tr>
<tr>
<td><em>(none)</em></td>
<td>Light PDF only</td>
</tr>
<tr>
<td><code>--dark</code></td>
<td>Dark PDF only (light PDF must already exist)</td>
</tr>
</tbody>
</table>
<p>Build only the dark PDF from an existing light:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a>python<span class="w"> </span>scripts/convert.py<span class="w"> </span>export/thgtoa.pdf<span class="w"> </span>export/thgtoa-dark.pdf
</code></pre></div>
<table>
<thead>
<tr>
<th>Flag</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--dpi</code></td>
<td><code>200</code></td>
<td>Rasterization DPI</td>
</tr>
<tr>
<td><code>--batch-size</code></td>
<td><code>50</code></td>
<td>Pages per batch — reduce if OOM</td>
</tr>
<tr>
<td><code>--bg</code></td>
<td><code>1f1f31</code></td>
<td>Background colour (hex)</td>
</tr>
<tr>
<td><code>--text</code></td>
<td><code>e0e0e0</code></td>
<td>Body text colour (hex)</td>
</tr>
<tr>
<td><code>--link</code></td>
<td><code>5e8bde</code></td>
<td>Link colour (hex)</td>
</tr>
</tbody>
</table>
<p>Preview the site:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a>mkdocs<span class="w"> </span>serve
<a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a><span class="c1"># Opens at http://127.0.0.1:8000</span>
</code></pre></div>
<hr />
<h2 id="contributing">Contributing Content<a class="headerlink" href="#contributing" title="Permanent link">λ</a></h2>
<div class="index-grid">
<div class="index-card">
<h3 class="index-card__title">Use a Topic Branch</h3>
<p class="index-card__body">Never commit directly to <code>main</code>. Use a topic branch per change so PRs stay reviewable and independent.</p>
</div>
<div class="index-card">
<h3 class="index-card__title">Small PRs</h3>
<p class="index-card__body">Split large changes into multiple PRs — one for new content, one for fixes, one for style. Big PRs block merges and create review debt.</p>
</div>
<div class="index-card">
<h3 class="index-card__title">Conventional Commits</h3>
<p class="index-card__body">All commits must follow <code>&lt;type&gt;(&lt;scope&gt;): &lt;description&gt;</code> format. Enforced by the <code>commitizen</code> pre-commit hook.</p>
</div>
<div class="index-card">
<h3 class="index-card__title">Describe Your Changes</h3>
<p class="index-card__body">Never leave a PR description blank. Include what changed, why, and any context a reviewer needs. Link related issues.</p>
</div>
</div>
<h3 id="commit-types">Commit Types<a class="headerlink" href="#commit-types" title="Permanent link">λ</a></h3>
<table>
<thead>
<tr>
<th>Type</th>
<th>Changelog bucket</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>feat</code>, <code>feature</code>, <code>add</code></td>
<td>Added</td>
</tr>
<tr>
<td><code>fix</code>, <code>bugfix</code>, <code>revert</code>, <code>security</code></td>
<td>Fixed</td>
</tr>
<tr>
<td><code>perf</code>, <code>refactor</code>, <code>change</code>, <code>chore</code>, <code>ci</code>, <code>docs</code>, <code>style</code>, <code>test</code>, <code>build</code></td>
<td>Changed</td>
</tr>
</tbody>
</table>
<p>Examples:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a>feat:<span class="w"> </span>add<span class="w"> </span>dark-mode<span class="w"> </span>PDF<span class="w"> </span><span class="nb">export</span>
<a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a>fix<span class="o">(</span>scripts<span class="o">)</span>:<span class="w"> </span>handle<span class="w"> </span>locked<span class="w"> </span>PDF<span class="w"> </span>on<span class="w"> </span>Windows
<a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a>docs:<span class="w"> </span>update<span class="w"> </span>developer<span class="w"> </span>workflow<span class="w"> </span>guide
<a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a>chore<span class="o">(</span>ci<span class="o">)</span>:<span class="w"> </span>pin<span class="w"> </span>Chrome<span class="w"> </span>version<span class="w"> </span>to<span class="w"> </span><span class="m">120</span>
</code></pre></div>
<h3 id="rules">Rules<a class="headerlink" href="#rules" title="Permanent link">λ</a></h3>
<ul>
<li><strong>Do</strong> target PRs at the <code>main</code> branch</li>
<li><strong>Do</strong> write "WIP" or open a draft PR for unfinished work</li>
<li><strong>Do</strong> follow the <a href="http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html">50/72 rule</a> for commit messages</li>
<li><strong>Don't</strong> make mass search/replace changes without context-checking every instance</li>
<li><strong>Don't</strong> abandon a PR mid-review — stay responsive</li>
<li><strong>Don't</strong> modify a PR directly while it's under active review — submit changes to the review branch instead</li>
</ul>
<p>For an example of what <em>not</em> to do, see <a href="https://github.com/Anon-Planet/thgtoa/pull/51">PR #51</a>.</p>
<div class="admonition warning">
<p class="admonition-title">Before you push</p>
<ul>
<li>Make sure the working tree is clean (<code>git status</code>)</li>
<li>Run <code>mkdocs build</code> locally if you changed <code>docs/</code> to catch broken links</li>
<li>If you added footnotes, verify each has both a definition <code>[^N]:</code> and at least one inline citation <code>[^N]</code></li>
</ul>
</div>
<hr />
<h2 id="pipeline">Release Pipeline<a class="headerlink" href="#pipeline" title="Permanent link">λ</a></h2>
<p>The pipeline is fully manual after the initial build — no step triggers the next automatically. This prevents version mismatches between what was built, what was signed, and what gets released.</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a>push to main (or manual trigger)
<a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a>
<a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a>
<a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a> 01-build.yml
<a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a> Builds thgtoa.pdf + thgtoa-dark.pdf.
<a id="__codelineno-7-6" name="__codelineno-7-6" href="#__codelineno-7-6"></a> Uploads artifact: pdfs — note the run ID.
<a id="__codelineno-7-7" name="__codelineno-7-7" href="#__codelineno-7-7"></a>
<a id="__codelineno-7-8" name="__codelineno-7-8" href="#__codelineno-7-8"></a> │ manually trigger 02-sign.yml with the build run ID
<a id="__codelineno-7-9" name="__codelineno-7-9" href="#__codelineno-7-9"></a>
<a id="__codelineno-7-10" name="__codelineno-7-10" href="#__codelineno-7-10"></a> 02-sign.yml
<a id="__codelineno-7-11" name="__codelineno-7-11" href="#__codelineno-7-11"></a> Hashes (SHA-256 + BLAKE2b) and GPG-signs all files.
<a id="__codelineno-7-12" name="__codelineno-7-12" href="#__codelineno-7-12"></a> Commits export/ back to main.
<a id="__codelineno-7-13" name="__codelineno-7-13" href="#__codelineno-7-13"></a> Uploads: signatures, pdfs-signed — note the run ID.
<a id="__codelineno-7-14" name="__codelineno-7-14" href="#__codelineno-7-14"></a>
<a id="__codelineno-7-15" name="__codelineno-7-15" href="#__codelineno-7-15"></a> │ manually trigger 03-release.yml with the sign run ID
<a id="__codelineno-7-16" name="__codelineno-7-16" href="#__codelineno-7-16"></a>
<a id="__codelineno-7-17" name="__codelineno-7-17" href="#__codelineno-7-17"></a> 03-release.yml
<a id="__codelineno-7-18" name="__codelineno-7-18" href="#__codelineno-7-18"></a> Runs VirusTotal. Creates GitHub Release tagged release-YYYYMMDD-&lt;short-sha&gt;.
<a id="__codelineno-7-19" name="__codelineno-7-19" href="#__codelineno-7-19"></a>
<a id="__codelineno-7-20" name="__codelineno-7-20" href="#__codelineno-7-20"></a> │ manually trigger 04-changelog.yml with the version string
<a id="__codelineno-7-21" name="__codelineno-7-21" href="#__codelineno-7-21"></a>
<a id="__codelineno-7-22" name="__codelineno-7-22" href="#__codelineno-7-22"></a> 04-changelog.yml
<a id="__codelineno-7-23" name="__codelineno-7-23" href="#__codelineno-7-23"></a> Prepends a new ## [vX.Y.Z] entry to docs/changelog/index.md and commits.
</code></pre></div>
<h3 id="release-tags">Release Tags<a class="headerlink" href="#release-tags" title="Permanent link">λ</a></h3>
<p>Tags use the format <code>release-YYYYMMDD-&lt;short-sha&gt;</code>, e.g. <code>release-20260527-abc1234</code>. No version decision is needed at release time — the tag is always unique and traceable to the exact commit.</p>
<p>The version string (e.g. <code>v1.2.4</code>) is a separate, human-assigned label that lives only in the changelog.</p>
<h3 id="triggering-each-step">Triggering Each Step<a class="headerlink" href="#triggering-each-step" title="Permanent link">λ</a></h3>
<p><strong>Build:</strong> Push to <code>main</code> or go to <strong>Actions → Build PDFs → Run workflow</strong>. Note the run ID.</p>
<p><strong>Sign:</strong> <strong>Actions → Sign PDFs → Run workflow</strong>, enter the build run ID. Note the run ID.</p>
<p><strong>Release:</strong> <strong>Actions → Release → Run workflow</strong>, enter the sign run ID.</p>
<p><strong>Changelog:</strong> <strong>Actions → Update Changelog → Run workflow</strong>, enter the version string. Use <code>dry_run: true</code> to preview.</p>
<hr />
<h2 id="verify">Verifying a Release<a class="headerlink" href="#verify" title="Permanent link">λ</a></h2>
<div class="highlight"><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="c1"># Import the release signing key</span>
<a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a>gpg<span class="w"> </span>--import<span class="w"> </span>pgp/anonymousplanet.asc
<a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a>
<a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a><span class="c1"># Verify the PDFs</span>
<a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a>gpg<span class="w"> </span>--verify<span class="w"> </span>thgtoa.pdf.asc<span class="w"> </span>thgtoa.pdf
<a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a>gpg<span class="w"> </span>--verify<span class="w"> </span>thgtoa-dark.pdf.asc<span class="w"> </span>thgtoa-dark.pdf
<a id="__codelineno-8-7" name="__codelineno-8-7" href="#__codelineno-8-7"></a>
<a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a><span class="c1"># Verify the hash files</span>
<a id="__codelineno-8-9" name="__codelineno-8-9" href="#__codelineno-8-9"></a>gpg<span class="w"> </span>--verify<span class="w"> </span>sha256sums.txt.asc<span class="w"> </span>sha256sums.txt
<a id="__codelineno-8-10" name="__codelineno-8-10" href="#__codelineno-8-10"></a>gpg<span class="w"> </span>--verify<span class="w"> </span>b2sums.txt.asc<span class="w"> </span>b2sums.txt
<a id="__codelineno-8-11" name="__codelineno-8-11" href="#__codelineno-8-11"></a>
<a id="__codelineno-8-12" name="__codelineno-8-12" href="#__codelineno-8-12"></a><span class="c1"># Check the PDF hashes match</span>
<a id="__codelineno-8-13" name="__codelineno-8-13" href="#__codelineno-8-13"></a>sha256sum<span class="w"> </span>-c<span class="w"> </span>sha256sums.txt
<a id="__codelineno-8-14" name="__codelineno-8-14" href="#__codelineno-8-14"></a>b2sum<span class="w"> </span>-c<span class="w"> </span>b2sums.txt
</code></pre></div>
<p>Expected output:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a>gpg: Signature made Sun 31 May 2026 03:23:26 AM EDT
<a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a>gpg: using EDDSA key C3023DBEA3FB38C438BA1EEDCEC60AEDE8B992A2
<a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a>gpg: Good signature from &quot;Anonymous Planet Release Signing Key&quot; [ultimate]
<a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a>Primary key fingerprint: C302 3DBE A3FB 38C4 38BA 1EED CEC6 0AED E8B9 92A2
</code></pre></div>
<p>You can safely ignore GitHub/Codeberg warnings like "The email in this signature doesn't match the committer email."</p>
<hr />
<h2 id="troubleshooting">Troubleshooting<a class="headerlink" href="#troubleshooting" title="Permanent link">λ</a></h2>
<p><strong><code>cairosvg</code> missing during MkDocs build</strong>
<code>pip install "mkdocs-material[imaging]"</code> — required by the <code>social</code> plugin.</p>
<p><strong><code>KeyError: 'JPEG'</code> in convert.py</strong>
<code>sudo apt install libjpeg-dev &amp;&amp; pip install --force-reinstall pillow</code></p>
<p><strong><code>qpdf: can't find PDF header</code></strong>
qpdf only accepts PDF inputs — ensure you are on the current version of <code>convert.py</code>.</p>
<p><strong>GPG signing fails — <code>No secret key</code></strong>
Re-export: <code>gpg --armor --export-secret-keys &lt;fingerprint&gt;</code> and re-paste the full block including headers into the <code>GPG_PRIVATE_KEY</code> secret.</p>
<p><strong>GPG signing fails — <code>Bad passphrase</code></strong>
The <code>GPG_PASSPHRASE</code> secret has a trailing space or newline. Re-paste without surrounding whitespace.</p>
<p><strong><code>03-release.yml</code> fails on VirusTotal</strong>
<code>VT_API_KEY</code> is missing, invalid, or over the 500 req/day free-tier limit. Re-run after a few minutes.</p>
<p><strong><code>02-sign.yml</code> fails downloading PDF artifact</strong>
Wrong <code>build_run_id</code>, or the artifact expired (90-day retention). Trigger a new build.</p>
<p><strong>Changelog already contains version X</strong>
<code>update_changelog.py</code> errors if the version is already present. Choose the next version string.</p>
<p><strong>Footnote warnings — <code>link '#fnref:N' has no anchor</code></strong>
A definition <code>[^N]:</code> exists without a matching inline citation. Add the citation or remove the orphaned definition.</p>
<!-- Abbreviation definitions. No prose. -->
<!-- markdownlint-disable MD041 -->
</article>
</div>
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
&copy; 2023-2026 Anonymous Planet & contributors &mdash; licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="license">CC BY-SA 4.0</a>.
</div>
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
<div class="md-social">
<a href="https://ioc.exchange/@unknown" target="_blank" rel="noopener me" title="Mastodon" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38q.398-.092.786-.213c.585-.184 1.27-.39 1.774-.753a.06.06 0 0 0 .023-.043v-1.809a.05.05 0 0 0-.02-.041.05.05 0 0 0-.046-.01 20.3 20.3 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.6 5.6 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422q.059-.011.11-.024c2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545m-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102q0-1.965 1.011-3.12c.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164q1.012 1.155 1.012 3.12z"/></svg>
</a>
<a href="https://x.com/anonplanetorg" target="_blank" rel="noopener" title="X" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14.234 10.162 22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299-.929-1.329L3.076 1.56h3.182l5.965 8.532.929 1.329 7.754 11.09h-3.182z"/></svg>
</a>
<a href="http://wmj5kiic7b6kjplpbvwadnht2nh2qnkbnqtcv3dyvpqtz7ssbssftxid.onion/" target="_blank" rel="noopener" title="0xacab" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m23.6 9.593-.033-.086L20.3.98a.85.85 0 0 0-.336-.405.875.875 0 0 0-1 .054.88.88 0 0 0-.29.44L16.47 7.818H7.537L5.333 1.07a.86.86 0 0 0-.29-.441.875.875 0 0 0-1-.054.86.86 0 0 0-.336.405L.433 9.502l-.032.086a6.066 6.066 0 0 0 2.012 7.01l.01.009.03.021 4.977 3.727 2.462 1.863 1.5 1.132a1.01 1.01 0 0 0 1.22 0l1.499-1.132 2.461-1.863 5.006-3.75.013-.01a6.07 6.07 0 0 0 2.01-7.002"/></svg>
</a>
<a href="http://it7otdanqu7ktntxzm427cba6i53w6wlanlh23v5i3siqmos47pzhvyd.onion/anonypla" target="_blank" rel="noopener" title="Darktea" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4.209 4.603c-.247 0-.525.02-.84.088-.333.07-1.28.283-2.054 1.027C-.403 7.25.035 9.685.089 10.052c.065.446.263 1.687 1.21 2.768 1.749 2.141 5.513 2.092 5.513 2.092s.462 1.103 1.168 2.119c.955 1.263 1.936 2.248 2.89 2.367 2.406 0 7.212-.004 7.212-.004s.458.004 1.08-.394c.535-.324 1.013-.893 1.013-.893s.492-.527 1.18-1.73c.21-.37.385-.729.538-1.068 0 0 2.107-4.471 2.107-8.823-.042-1.318-.367-1.55-.443-1.627-.156-.156-.366-.153-.366-.153s-4.475.252-6.792.306c-.508.011-1.012.023-1.512.027v4.474l-.634-.301c0-1.39-.004-4.17-.004-4.17-1.107.016-3.405-.084-3.405-.084s-5.399-.27-5.987-.324c-.187-.011-.401-.032-.648-.032zm.354 1.832h.111s.271 2.269.6 3.597C5.549 11.147 6.22 13 6.22 13s-.996-.119-1.641-.348c-.99-.324-1.409-.714-1.409-.714s-.73-.511-1.096-1.52C1.444 8.73 2.021 7.7 2.021 7.7s.32-.859 1.47-1.145c.395-.106.863-.12 1.072-.12m8.33 2.554c.26.003.509.127.509.127l.868.422-.529 1.075a.69.69 0 0 0-.614.359.69.69 0 0 0 .072.756l-.939 1.924a.69.69 0 0 0-.66.527.69.69 0 0 0 .347.763.686.686 0 0 0 .867-.206.69.69 0 0 0-.069-.882l.916-1.874a.7.7 0 0 0 .237-.02.66.66 0 0 0 .271-.137 9 9 0 0 1 1.016.512.76.76 0 0 1 .286.282c.073.21-.073.569-.073.569-.087.29-.702 1.55-.702 1.55a.69.69 0 0 0-.676.477.681.681 0 1 0 1.157-.252c.073-.141.141-.282.214-.431.19-.397.515-1.16.515-1.16.035-.066.218-.394.103-.814-.095-.435-.48-.638-.48-.638-.467-.301-1.116-.58-1.116-.58s0-.156-.042-.27a.7.7 0 0 0-.148-.241l.516-1.062 2.89 1.401s.48.218.583.619c.073.282-.019.534-.069.657-.24.587-2.1 4.317-2.1 4.317s-.232.554-.748.588a1.1 1.1 0 0 1-.393-.045l-.202-.08-4.31-2.1s-.417-.218-.49-.596c-.083-.31.104-.691.104-.691l2.073-4.272s.183-.37.466-.497a.9.9 0 0 1 .35-.077"/></svg>
</a>
<a href="https://github.com/anon-planet" target="_blank" rel="noopener" title="Github" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
</a>
<a href="https://gitlab.com/anonymousplanetorg" target="_blank" rel="noopener" title="Gitlab" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m23.6 9.593-.033-.086L20.3.98a.85.85 0 0 0-.336-.405.875.875 0 0 0-1 .054.88.88 0 0 0-.29.44L16.47 7.818H7.537L5.333 1.07a.86.86 0 0 0-.29-.441.875.875 0 0 0-1-.054.86.86 0 0 0-.336.405L.433 9.502l-.032.086a6.066 6.066 0 0 0 2.012 7.01l.01.009.03.021 4.977 3.727 2.462 1.863 1.5 1.132a1.01 1.01 0 0 0 1.22 0l1.499-1.132 2.461-1.863 5.006-3.75.013-.01a6.07 6.07 0 0 0 2.01-7.002"/></svg>
</a>
<a href="https://codeberg.org/anonymousplanet" target="_blank" rel="noopener" title="Codeberg" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.999.747A11.974 11.974 0 0 0 0 12.75c0 2.254.635 4.465 1.833 6.376L11.837 6.19c.072-.092.251-.092.323 0l4.178 5.402h-2.992l.065.239h3.113l.882 1.138h-3.674l.103.374h3.86l.777 1.003h-4.358l.135.483h4.593l.695.894h-5.038l.165.589h5.326l.609.785h-5.717l.182.65h6.038l.562.727h-6.397l.183.65h6.717A12 12 0 0 0 24 12.75 11.977 11.977 0 0 0 11.999.747m3.654 19.104.182.65h5.326c.173-.204.353-.433.513-.65zm.385 1.377.18.65h3.563c.233-.198.485-.428.712-.65zm.383 1.377.182.648h1.203c.356-.204.685-.412 1.042-.648z"/></svg>
</a>
<a href="https://gitlab.torproject.org/anonymousplanet/the-hitchhikers-guide" target="_blank" rel="noopener" title="Gitlab at Tor Project" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 21.82v-1.46A8.36 8.36 0 0 0 20.36 12 8.36 8.36 0 0 0 12 3.64V2.18A9.83 9.83 0 0 1 21.82 12 9.83 9.83 0 0 1 12 21.82m0-5.09A4.74 4.74 0 0 0 16.73 12 4.74 4.74 0 0 0 12 7.27V5.82A6.17 6.17 0 0 1 18.18 12 6.17 6.17 0 0 1 12 18.18zm0-7.27A2.54 2.54 0 0 1 14.55 12 2.54 2.54 0 0 1 12 14.54zM0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0 12 12 0 0 0 0 12"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["navigation.instant", "navigation.instant.prefetch", "navigation.tabs", "navigation.sections", "navigation.path", "navigation.top", "search.suggest", "search.highlight", "content.tabs.link", "content.code.annotation", "content.code.copy"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
</body>
</html>