Basic documentation mdBook

main
~erin 2023-04-17 17:23:10 -04:00
commit 82a13d8c3d
Signed by untrusted user: erin
GPG Key ID: 9A8E308CEFA37A47
28 changed files with 2637 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
book

28
book.toml Normal file
View File

@ -0,0 +1,28 @@
[book]
authors = ["Erin <contact@the-system.eu.org>"]
description = "Core documentation for the Mercury project"
language = "en"
multilingual = false
src = "src"
title = "Mercury Docs"
[rust]
edition = "2021"
[preprocessor]
[preprocessor.catppuccin]
assets_version = "0.1.1" # DO NOT EDIT: Managed by `mdbook-catppuccin install`
[preprocessor.mermaid]
command = "mdbook-mermaid"
[preprocessor.admonish]
command = "mdbook-admonish"
assets_version = "2.0.0" # do not edit: managed by `mdbook-admonish install`
[output]
[output.html]
additional-css = ["./theme/catppuccin.css", "./theme/catppuccin-highlight.css", "././mdbook-admonish.css"]
additional-js = ["mermaid.min.js", "mermaid-init.js"]

352
mdbook-admonish.css Normal file
View File

@ -0,0 +1,352 @@
@charset "UTF-8";
:root {
--md-admonition-icon--note:
url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z'/></svg>");
--md-admonition-icon--abstract:
url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M17 9H7V7h10m0 6H7v-2h10m-3 6H7v-2h7M12 3a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m7 0h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z'/></svg>");
--md-admonition-icon--info:
url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2z'/></svg>");
--md-admonition-icon--tip:
url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M17.66 11.2c-.23-.3-.51-.56-.77-.82-.67-.6-1.43-1.03-2.07-1.66C13.33 7.26 13 4.85 13.95 3c-.95.23-1.78.75-2.49 1.32-2.59 2.08-3.61 5.75-2.39 8.9.04.1.08.2.08.33 0 .22-.15.42-.35.5-.23.1-.47.04-.66-.12a.58.58 0 0 1-.14-.17c-1.13-1.43-1.31-3.48-.55-5.12C5.78 10 4.87 12.3 5 14.47c.06.5.12 1 .29 1.5.14.6.41 1.2.71 1.73 1.08 1.73 2.95 2.97 4.96 3.22 2.14.27 4.43-.12 6.07-1.6 1.83-1.66 2.47-4.32 1.53-6.6l-.13-.26c-.21-.46-.77-1.26-.77-1.26m-3.16 6.3c-.28.24-.74.5-1.1.6-1.12.4-2.24-.16-2.9-.82 1.19-.28 1.9-1.16 2.11-2.05.17-.8-.15-1.46-.28-2.23-.12-.74-.1-1.37.17-2.06.19.38.39.76.63 1.06.77 1 1.98 1.44 2.24 2.8.04.14.06.28.06.43.03.82-.33 1.72-.93 2.27z'/></svg>");
--md-admonition-icon--success:
url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='m9 20.42-6.21-6.21 2.83-2.83L9 14.77l9.88-9.89 2.83 2.83L9 20.42z'/></svg>");
--md-admonition-icon--question:
url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='m15.07 11.25-.9.92C13.45 12.89 13 13.5 13 15h-2v-.5c0-1.11.45-2.11 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41a2 2 0 0 0-2-2 2 2 0 0 0-2 2H8a4 4 0 0 1 4-4 4 4 0 0 1 4 4 3.2 3.2 0 0 1-.93 2.25M13 19h-2v-2h2M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10c0-5.53-4.5-10-10-10z'/></svg>");
--md-admonition-icon--warning:
url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M13 14h-2V9h2m0 9h-2v-2h2M1 21h22L12 2 1 21z'/></svg>");
--md-admonition-icon--failure:
url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20 6.91 17.09 4 12 9.09 6.91 4 4 6.91 9.09 12 4 17.09 6.91 20 12 14.91 17.09 20 20 17.09 14.91 12 20 6.91z'/></svg>");
--md-admonition-icon--danger:
url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M11 15H6l7-14v8h5l-7 14v-8z'/></svg>");
--md-admonition-icon--bug:
url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M14 12h-4v-2h4m0 6h-4v-2h4m6-6h-2.81a5.985 5.985 0 0 0-1.82-1.96L17 4.41 15.59 3l-2.17 2.17a6.002 6.002 0 0 0-2.83 0L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8z'/></svg>");
--md-admonition-icon--example:
url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M7 13v-2h14v2H7m0 6v-2h14v2H7M7 7V5h14v2H7M3 8V5H2V4h2v4H3m-1 9v-1h3v4H2v-1h2v-.5H3v-1h1V17H2m2.25-7a.75.75 0 0 1 .75.75c0 .2-.08.39-.21.52L3.12 13H5v1H2v-.92L4 11H2v-1h2.25z'/></svg>");
--md-admonition-icon--quote:
url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M14 17h3l2-4V7h-6v6h3M6 17h3l2-4V7H5v6h3l-2 4z'/></svg>");
--md-details-icon:
url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42Z'/></svg>");
}
:is(.admonition) {
display: flow-root;
margin: 1.5625em 0;
padding: 0 1.2rem;
color: var(--fg);
page-break-inside: avoid;
background-color: var(--bg);
border: 0 solid black;
border-inline-start-width: 0.4rem;
border-radius: 0.2rem;
box-shadow: 0 0.2rem 1rem rgba(0, 0, 0, 0.05), 0 0 0.1rem rgba(0, 0, 0, 0.1);
}
@media print {
:is(.admonition) {
box-shadow: none;
}
}
:is(.admonition) > * {
box-sizing: border-box;
}
:is(.admonition) :is(.admonition) {
margin-top: 1em;
margin-bottom: 1em;
}
:is(.admonition) > .tabbed-set:only-child {
margin-top: 0;
}
html :is(.admonition) > :last-child {
margin-bottom: 1.2rem;
}
a.admonition-anchor-link {
display: none;
position: absolute;
left: -1.2rem;
padding-right: 1rem;
}
a.admonition-anchor-link:link, a.admonition-anchor-link:visited {
color: var(--fg);
}
a.admonition-anchor-link:link:hover, a.admonition-anchor-link:visited:hover {
text-decoration: none;
}
a.admonition-anchor-link::before {
content: "§";
}
:is(.admonition-title, summary) {
position: relative;
margin-block: 0;
margin-inline: -1.6rem -1.2rem;
padding-block: 0.8rem;
padding-inline: 4.4rem 1.2rem;
font-weight: 700;
background-color: rgba(68, 138, 255, 0.1);
display: flex;
}
:is(.admonition-title, summary) p {
margin: 0;
}
html :is(.admonition-title, summary):last-child {
margin-bottom: 0;
}
:is(.admonition-title, summary)::before {
position: absolute;
top: 0.625em;
inset-inline-start: 1.6rem;
width: 2rem;
height: 2rem;
background-color: #448aff;
mask-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"></svg>');
-webkit-mask-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"></svg>');
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-size: contain;
content: "";
}
:is(.admonition-title, summary):hover a.admonition-anchor-link {
display: initial;
}
details.admonition > summary.admonition-title::after {
position: absolute;
top: 0.625em;
inset-inline-end: 1.6rem;
height: 2rem;
width: 2rem;
background-color: currentcolor;
mask-image: var(--md-details-icon);
-webkit-mask-image: var(--md-details-icon);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-size: contain;
content: "";
transform: rotate(0deg);
transition: transform 0.25s;
}
details[open].admonition > summary.admonition-title::after {
transform: rotate(90deg);
}
:is(.admonition):is(.note) {
border-color: #448aff;
}
:is(.note) > :is(.admonition-title, summary) {
background-color: rgba(68, 138, 255, 0.1);
}
:is(.note) > :is(.admonition-title, summary)::before {
background-color: #448aff;
mask-image: var(--md-admonition-icon--note);
-webkit-mask-image: var(--md-admonition-icon--note);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.abstract, .summary, .tldr) {
border-color: #00b0ff;
}
:is(.abstract, .summary, .tldr) > :is(.admonition-title, summary) {
background-color: rgba(0, 176, 255, 0.1);
}
:is(.abstract, .summary, .tldr) > :is(.admonition-title, summary)::before {
background-color: #00b0ff;
mask-image: var(--md-admonition-icon--abstract);
-webkit-mask-image: var(--md-admonition-icon--abstract);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.info, .todo) {
border-color: #00b8d4;
}
:is(.info, .todo) > :is(.admonition-title, summary) {
background-color: rgba(0, 184, 212, 0.1);
}
:is(.info, .todo) > :is(.admonition-title, summary)::before {
background-color: #00b8d4;
mask-image: var(--md-admonition-icon--info);
-webkit-mask-image: var(--md-admonition-icon--info);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.tip, .hint, .important) {
border-color: #00bfa5;
}
:is(.tip, .hint, .important) > :is(.admonition-title, summary) {
background-color: rgba(0, 191, 165, 0.1);
}
:is(.tip, .hint, .important) > :is(.admonition-title, summary)::before {
background-color: #00bfa5;
mask-image: var(--md-admonition-icon--tip);
-webkit-mask-image: var(--md-admonition-icon--tip);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.success, .check, .done) {
border-color: #00c853;
}
:is(.success, .check, .done) > :is(.admonition-title, summary) {
background-color: rgba(0, 200, 83, 0.1);
}
:is(.success, .check, .done) > :is(.admonition-title, summary)::before {
background-color: #00c853;
mask-image: var(--md-admonition-icon--success);
-webkit-mask-image: var(--md-admonition-icon--success);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.question, .help, .faq) {
border-color: #64dd17;
}
:is(.question, .help, .faq) > :is(.admonition-title, summary) {
background-color: rgba(100, 221, 23, 0.1);
}
:is(.question, .help, .faq) > :is(.admonition-title, summary)::before {
background-color: #64dd17;
mask-image: var(--md-admonition-icon--question);
-webkit-mask-image: var(--md-admonition-icon--question);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.warning, .caution, .attention) {
border-color: #ff9100;
}
:is(.warning, .caution, .attention) > :is(.admonition-title, summary) {
background-color: rgba(255, 145, 0, 0.1);
}
:is(.warning, .caution, .attention) > :is(.admonition-title, summary)::before {
background-color: #ff9100;
mask-image: var(--md-admonition-icon--warning);
-webkit-mask-image: var(--md-admonition-icon--warning);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.failure, .fail, .missing) {
border-color: #ff5252;
}
:is(.failure, .fail, .missing) > :is(.admonition-title, summary) {
background-color: rgba(255, 82, 82, 0.1);
}
:is(.failure, .fail, .missing) > :is(.admonition-title, summary)::before {
background-color: #ff5252;
mask-image: var(--md-admonition-icon--failure);
-webkit-mask-image: var(--md-admonition-icon--failure);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.danger, .error) {
border-color: #ff1744;
}
:is(.danger, .error) > :is(.admonition-title, summary) {
background-color: rgba(255, 23, 68, 0.1);
}
:is(.danger, .error) > :is(.admonition-title, summary)::before {
background-color: #ff1744;
mask-image: var(--md-admonition-icon--danger);
-webkit-mask-image: var(--md-admonition-icon--danger);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.bug) {
border-color: #f50057;
}
:is(.bug) > :is(.admonition-title, summary) {
background-color: rgba(245, 0, 87, 0.1);
}
:is(.bug) > :is(.admonition-title, summary)::before {
background-color: #f50057;
mask-image: var(--md-admonition-icon--bug);
-webkit-mask-image: var(--md-admonition-icon--bug);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.example) {
border-color: #7c4dff;
}
:is(.example) > :is(.admonition-title, summary) {
background-color: rgba(124, 77, 255, 0.1);
}
:is(.example) > :is(.admonition-title, summary)::before {
background-color: #7c4dff;
mask-image: var(--md-admonition-icon--example);
-webkit-mask-image: var(--md-admonition-icon--example);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.quote, .cite) {
border-color: #9e9e9e;
}
:is(.quote, .cite) > :is(.admonition-title, summary) {
background-color: rgba(158, 158, 158, 0.1);
}
:is(.quote, .cite) > :is(.admonition-title, summary)::before {
background-color: #9e9e9e;
mask-image: var(--md-admonition-icon--quote);
-webkit-mask-image: var(--md-admonition-icon--quote);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
.navy :is(.admonition) {
background-color: var(--sidebar-bg);
}
.ayu :is(.admonition), .coal :is(.admonition) {
background-color: var(--theme-hover);
}
.rust :is(.admonition) {
background-color: var(--sidebar-bg);
color: var(--sidebar-fg);
}
.rust .admonition-anchor-link:link, .rust .admonition-anchor-link:visited {
color: var(--sidebar-fg);
}

1
mermaid-init.js Normal file
View File

@ -0,0 +1 @@
mermaid.initialize({startOnLoad:true});

1282
mermaid.min.js vendored Normal file

File diff suppressed because one or more lines are too long

13
src/README.md Normal file
View File

@ -0,0 +1,13 @@
# Introduction
Welcome to the documentation for the **Mercury** project!
This is the main user-facing documentation for the project as a whole.
It consists of docs for [Developers](/development/index.md), as well as [end-users](/user/index.md).
If you would like to use the operating system, or help with development, this is where to get your information!
## Status
Right now, **Mercury** is mainly in the planning stage.
We're still setting things up, learning, and planning out how we're going to do this.
Actual code development is likely not going to take place for a while, but feel free to come back later to help with that!

22
src/SUMMARY.md Normal file
View File

@ -0,0 +1,22 @@
# Summary
[Introduction](README.md)
- [Development](development/README.md)
- [Understanding the Design Goals](development/design/README.md)
- [Actor System](development/design/actor.md)
- [Security Features](development/design/security.md)
- [Microkernel](development/design/kernel.md)
- [GUI](development/design/gui.md)
- [Filesystem](development/filesystem.md)
- [Configuring a Build Environment](development/environment.md)
- [Development Workflow](development/workflow.md)
- [Running Tests](development/tests.md)
- [Using the OS](user/README.md)
- [Running in a Virtual Machine](user/virtual-machine.md)
- [Running on Baremetal](user/baremetal.md)
- [General Use](user/use/README.md)
- [Working in the Shell](user/use/shell.md)
- [Navigating the GUI](user/use/gui.md)
- [Configuring the System](user/use/config.md)
- [Working with Actors](user/use/actors.md)

34
src/development/README.md Normal file
View File

@ -0,0 +1,34 @@
# Development
If you're wanting to help develop **Mercury**, you've come to the right place!
Again, right now we're a heavy work-in-progress. But eventually this will be useful!
## Contributor Agreements
By submitting resources to this project (code, art, writing, etc.), you must agree to the following terms:
1. Resources will be licensed under the [CNPLv7+](https://thufie.lain.haus/NPL.html) license
2. You *must* follow the [Code of Conduct](conduct.md)
3. You should follow the [Design Goals](/development/design/index.md) and [Best Practices](#best-practices) when possible
Otherwise, feel free to start contributing!
## Best Practices
These are various "best practices" for code written for the **Mercury** project.
They should be followed when reasonable, to the best of your ability/understanding.
Feel free to [contact](https://mercury.the-system.eu.org/contribute/) a maintainer with questions!
- No compromises will be made for compatibility. If there is a better, if unusual, way to do things, it should be done that way.
- Everything must be fully accessible. Everything else can be sacrificed for this.
- `unsafe` code should be avoided when possible.
- Everything should be documented as it is written.
- Nesting should be avoided as much as possible.
- `cargo fmt` must be used before each commit.
- If something can be excluded from the main `kernel`, it should be. It's a `microkernel`!
- While binary size should be kept down and optimized, it should not be done at the cost of performance.
- Features should be *opt-in* rather than *opt-out*.
- Releases should ideally contain no compiler or `clippy` warnings.
## Source Code
All of the source code for **Mercury** is on a self-hosted [Gitea](https://git.lavender.software/mercury), courtesy of [Lavender Software](https://lavender.software).
Sign up there, and contact one of the maintainers to get access to the repositories.
The source for this site, and our [website](https://mercury.the-system.eu.org) is available there as well.

View File

@ -0,0 +1,39 @@
# Understanding the Design Goals
**Mercury** has several new and novel design decisions that make it radically different from other general Operating Systems.
```admonish warning
A lot of these designs will likely change and shift as work get's done on the project.
```
First off, it's written in [Rust](https://www.rust-lang.org/), which allows for several nice features, including:
- Memory safety
- Easy dependency and build management with `cargo`
- Great performance and reliability
- Several compilation targets, with simple cross-compilation
It also uses [microkernel](https://doc.redox-os.org/book/ch04-01-microkernels.html) architecture - this allows for us to keep the base kernel code small, and have additional features be modular, and easy to integrate into other projects.
This also allows for a smaller attack surface, less bloat, smaller code, etc.
Additionally, **Mercury** is designed for `ARM`/`RISC-V` architecture machines.
This is not only because they are simpler, but also because I believe they are the future of computing.
For the future, I do not see myself wanting or attempting to implement `x86` functionality.
Further design decisions are gone into detail in the next few chapters.
## Code Organization
```admonish info
These names and layout are all **WIP**.
```
All of the code will take place in seperate repositories.
Information on actually commiting, pulling, etc. is in the [Workflow](/development/workflow.md) chapter.
Most of the code will be implemented as libraries, enabling for them to be used across systems, and worked on separately.
- [ferrite](https://git.lavender.software/mercury/ferrite-kernel) - The core microkernel code
- [hermes]() - The package manager
- [meteor]() - The [actors](/development/design/actor.md) library/implementation
- [gravitas]() - The library for working with [storage](/development/filesystem.md)
- [pulsar]() - Networking code
- [photon]() - GUI library

View File

@ -0,0 +1 @@
# Actor System

View File

@ -0,0 +1 @@
# GUI

View File

@ -0,0 +1 @@
# Microkernel

View File

@ -0,0 +1 @@
# Security Features

View File

@ -0,0 +1,21 @@
# Configuring a Build Environment
```admonish info
All of this build information is for `Linux` right now, as I don't want to mess around with getting stuff working on `Windows`.
Just use `WSL` if you want.
`BSD` should work similarly, but if not, please let us know!
```
Of course, first you will need to install `Rust`. The best way to do this is through [rustup](https://www.rust-lang.org/tools/install).
Additionally, you will need to install [clippy](https://doc.rust-lang.org/nightly/clippy/installation.html) and [rustfmt](https://github.com/rust-lang/rustfmt).
You probably will also want to install `sccache` from your distribution's package manager, and export the `RUSTC_WRAPPER='sccache'` environment variable however your shell does it.
Then, you'll want to `git clone` whatever repository you're wanting to work on.
## Building
**TODO:** Figure out how building actually works.
When you're just testing, `cargo` will use the `dev` profile.
This will allow for debugging, and faster compilation speeds.
However, all releases will be using the `release` profile, which is much slower, but better optimized.
It's unlikely you'll want to use this on your computer.

View File

@ -0,0 +1 @@
# Filesystem

1
src/development/tests.md Normal file
View File

@ -0,0 +1 @@
# Running Tests

View File

@ -0,0 +1,30 @@
# Development Workflow
## 1. Pull Down Code
`git clone` the repository of whatever code you're wanting to work on.
Make a new branch for the feature you want to do.
Maybe it's a new feature, or fixing a bug *(please file it in the issue tracker!)*.
## 2. Do Coding
Work on your code however you do it, make sure to `cargo fmt` before each commit, sign your commits, and commit fairly often.
## 3. Test
### Clippy
Run this `clippy` command, and try and ensure there are no warnings:
```bash
cargo clippy -- -W clippy::pedantic -W clippy::suspicious -W clippy::complexity -W clippy::perf -W clippy::cargo -W clippy::nursery -W clippy::unwrap_used -D warnings
```
### Automated Tests
Run `cargo test` to ensure all of the [tests](https://doc.rust-lang.org/book/ch11-00-testing.html) still pass.
If needed, add your own tests for your new code.
### Run
Of course, manually run the code in a [VM](/user/virtual-machine.md) and see if everything works how it should.
## 3. Document
Use inline [rustdoc](https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html) to document your code.
## 4. Push
Push the code to a new branch in the repository.
If it's ready and fully working, make a pull request to merge it into `main`.

1
src/user/README.md Normal file
View File

@ -0,0 +1 @@
# Using the OS

1
src/user/baremetal.md Normal file
View File

@ -0,0 +1 @@
# Running on Baremetal

1
src/user/use/README.md Normal file
View File

@ -0,0 +1 @@
# General Use

1
src/user/use/actors.md Normal file
View File

@ -0,0 +1 @@
# Working with Actors

1
src/user/use/config.md Normal file
View File

@ -0,0 +1 @@
# Configuring the System

1
src/user/use/gui.md Normal file
View File

@ -0,0 +1 @@
# Navigating the GUI

1
src/user/use/shell.md Normal file
View File

@ -0,0 +1 @@
# Working in the Shell

View File

@ -0,0 +1 @@
# Running in a Virtual Machine

View File

@ -0,0 +1,359 @@
.mocha code,
.mocha .hljs {
background: #181825;
}
.mocha code .hljs-attr,
.mocha code .hljs-string {
color: #a6e3a1;
}
.mocha code .hljs-tag {
color: #f38ba8;
}
.mocha code .hljs-name {
color: #f2cdcd;
}
.mocha pre .hljs {
background: #181825 !important;
}
.mocha pre .hljs-params {
color: #f38ba8 !important;
}
.mocha pre .hljs-built_in,
.mocha pre .hljs-selector-tag,
.mocha pre .hljs-section,
.mocha pre .hljs-link {
color: #74c7ec !important;
}
.mocha pre .hljs-keyword {
color: #cba6f7 !important;
}
.mocha pre .hljs,
.mocha pre .hljs-subst {
color: #a6adc8 !important;
}
.mocha pre .hljs-title {
color: #89b4fa !important;
}
.mocha pre .hljs-attr,
.mocha pre .hljs-meta-keyword {
color: #a6e3a1 !important;
}
.mocha pre .hljs-type {
color: #89b4fa !important;
}
.mocha pre .hljs-string {
color: #a6e3a1 !important;
}
.mocha pre .hljs-tag {
color: #f38ba8 !important;
}
.mocha pre .hljs-meta,
.mocha pre .hljs-name,
.mocha pre .hljs-symbol,
.mocha pre .hljs-bullet,
.mocha pre .hljs-addition,
.mocha pre .hljs-variable,
.mocha pre .hljs-template-tag,
.mocha pre .hljs-template-variable {
color: #f2cdcd !important;
}
.mocha pre .hljs-addition {
background-color: #181825 !important;
color: #a6e3a1 !important;
}
.mocha pre .hljs-deletion {
background-color: #181825 !important;
color: #f38ba8 !important;
}
.mocha pre .hljs-comment,
.mocha pre .hljs-quote {
color: #585b70 !important;
}
.mocha pre .hljs-keyword,
.mocha pre .hljs-selector-tag,
.mocha pre .hljs-literal,
.mocha pre .hljs-title,
.mocha pre .hljs-section,
.mocha pre .hljs-doctag,
.mocha pre .hljs-type,
.mocha pre .hljs-name,
.mocha pre .hljs-strong {
font-weight: bold !important;
}
.mocha pre .hljs-literal,
.mocha pre .hljs-number {
color: #fab387 !important;
}
.mocha pre .hljs-emphasis {
font-style: italic !important;
}
.macchiato code,
.macchiato .hljs {
background: #1e2030;
}
.macchiato code .hljs-attr,
.macchiato code .hljs-string {
color: #a6da95;
}
.macchiato code .hljs-tag {
color: #ed8796;
}
.macchiato code .hljs-name {
color: #f0c6c6;
}
.macchiato pre .hljs {
background: #1e2030 !important;
}
.macchiato pre .hljs-params {
color: #ed8796 !important;
}
.macchiato pre .hljs-built_in,
.macchiato pre .hljs-selector-tag,
.macchiato pre .hljs-section,
.macchiato pre .hljs-link {
color: #7dc4e4 !important;
}
.macchiato pre .hljs-keyword {
color: #c6a0f6 !important;
}
.macchiato pre .hljs,
.macchiato pre .hljs-subst {
color: #a5adcb !important;
}
.macchiato pre .hljs-title {
color: #8aadf4 !important;
}
.macchiato pre .hljs-attr,
.macchiato pre .hljs-meta-keyword {
color: #a6da95 !important;
}
.macchiato pre .hljs-type {
color: #8aadf4 !important;
}
.macchiato pre .hljs-string {
color: #a6da95 !important;
}
.macchiato pre .hljs-tag {
color: #ed8796 !important;
}
.macchiato pre .hljs-meta,
.macchiato pre .hljs-name,
.macchiato pre .hljs-symbol,
.macchiato pre .hljs-bullet,
.macchiato pre .hljs-addition,
.macchiato pre .hljs-variable,
.macchiato pre .hljs-template-tag,
.macchiato pre .hljs-template-variable {
color: #f0c6c6 !important;
}
.macchiato pre .hljs-addition {
background-color: #1e2030 !important;
color: #a6da95 !important;
}
.macchiato pre .hljs-deletion {
background-color: #1e2030 !important;
color: #ed8796 !important;
}
.macchiato pre .hljs-comment,
.macchiato pre .hljs-quote {
color: #5b6078 !important;
}
.macchiato pre .hljs-keyword,
.macchiato pre .hljs-selector-tag,
.macchiato pre .hljs-literal,
.macchiato pre .hljs-title,
.macchiato pre .hljs-section,
.macchiato pre .hljs-doctag,
.macchiato pre .hljs-type,
.macchiato pre .hljs-name,
.macchiato pre .hljs-strong {
font-weight: bold !important;
}
.macchiato pre .hljs-literal,
.macchiato pre .hljs-number {
color: #f5a97f !important;
}
.macchiato pre .hljs-emphasis {
font-style: italic !important;
}
.frappe code,
.frappe .hljs {
background: #292c3c;
}
.frappe code .hljs-attr,
.frappe code .hljs-string {
color: #a6d189;
}
.frappe code .hljs-tag {
color: #e78284;
}
.frappe code .hljs-name {
color: #eebebe;
}
.frappe pre .hljs {
background: #292c3c !important;
}
.frappe pre .hljs-params {
color: #e78284 !important;
}
.frappe pre .hljs-built_in,
.frappe pre .hljs-selector-tag,
.frappe pre .hljs-section,
.frappe pre .hljs-link {
color: #85c1dc !important;
}
.frappe pre .hljs-keyword {
color: #ca9ee6 !important;
}
.frappe pre .hljs,
.frappe pre .hljs-subst {
color: #a5adce !important;
}
.frappe pre .hljs-title {
color: #8caaee !important;
}
.frappe pre .hljs-attr,
.frappe pre .hljs-meta-keyword {
color: #a6d189 !important;
}
.frappe pre .hljs-type {
color: #8caaee !important;
}
.frappe pre .hljs-string {
color: #a6d189 !important;
}
.frappe pre .hljs-tag {
color: #e78284 !important;
}
.frappe pre .hljs-meta,
.frappe pre .hljs-name,
.frappe pre .hljs-symbol,
.frappe pre .hljs-bullet,
.frappe pre .hljs-addition,
.frappe pre .hljs-variable,
.frappe pre .hljs-template-tag,
.frappe pre .hljs-template-variable {
color: #eebebe !important;
}
.frappe pre .hljs-addition {
background-color: #292c3c !important;
color: #a6d189 !important;
}
.frappe pre .hljs-deletion {
background-color: #292c3c !important;
color: #e78284 !important;
}
.frappe pre .hljs-comment,
.frappe pre .hljs-quote {
color: #626880 !important;
}
.frappe pre .hljs-keyword,
.frappe pre .hljs-selector-tag,
.frappe pre .hljs-literal,
.frappe pre .hljs-title,
.frappe pre .hljs-section,
.frappe pre .hljs-doctag,
.frappe pre .hljs-type,
.frappe pre .hljs-name,
.frappe pre .hljs-strong {
font-weight: bold !important;
}
.frappe pre .hljs-literal,
.frappe pre .hljs-number {
color: #ef9f76 !important;
}
.frappe pre .hljs-emphasis {
font-style: italic !important;
}
.latte code,
.latte .hljs {
background: #e6e9ef;
}
.latte code .hljs-attr,
.latte code .hljs-string {
color: #40a02b;
}
.latte code .hljs-tag {
color: #d20f39;
}
.latte code .hljs-name {
color: #dd7878;
}
.latte pre .hljs {
background: #e6e9ef !important;
}
.latte pre .hljs-params {
color: #d20f39 !important;
}
.latte pre .hljs-built_in,
.latte pre .hljs-selector-tag,
.latte pre .hljs-section,
.latte pre .hljs-link {
color: #209fb5 !important;
}
.latte pre .hljs-keyword {
color: #8839ef !important;
}
.latte pre .hljs,
.latte pre .hljs-subst {
color: #6c6f85 !important;
}
.latte pre .hljs-title {
color: #1e66f5 !important;
}
.latte pre .hljs-attr,
.latte pre .hljs-meta-keyword {
color: #40a02b !important;
}
.latte pre .hljs-type {
color: #1e66f5 !important;
}
.latte pre .hljs-string {
color: #40a02b !important;
}
.latte pre .hljs-tag {
color: #d20f39 !important;
}
.latte pre .hljs-meta,
.latte pre .hljs-name,
.latte pre .hljs-symbol,
.latte pre .hljs-bullet,
.latte pre .hljs-addition,
.latte pre .hljs-variable,
.latte pre .hljs-template-tag,
.latte pre .hljs-template-variable {
color: #dd7878 !important;
}
.latte pre .hljs-addition {
background-color: #e6e9ef !important;
color: #40a02b !important;
}
.latte pre .hljs-deletion {
background-color: #e6e9ef !important;
color: #d20f39 !important;
}
.latte pre .hljs-comment,
.latte pre .hljs-quote {
color: #acb0be !important;
}
.latte pre .hljs-keyword,
.latte pre .hljs-selector-tag,
.latte pre .hljs-literal,
.latte pre .hljs-title,
.latte pre .hljs-section,
.latte pre .hljs-doctag,
.latte pre .hljs-type,
.latte pre .hljs-name,
.latte pre .hljs-strong {
font-weight: bold !important;
}
.latte pre .hljs-literal,
.latte pre .hljs-number {
color: #fe640b !important;
}
.latte pre .hljs-emphasis {
font-style: italic !important;
}

123
theme/catppuccin.css Normal file
View File

@ -0,0 +1,123 @@
.mocha {
--bg: #1e1e2e;
--fg: #cdd6f4;
--sidebar-bg: #181825;
--sidebar-fg: #cdd6f4;
--sidebar-non-existant: #6c7086;
--sidebar-active: #f5e0dc;
--sidebar-spacer: #6c7086;
--scrollbar: #6c7086;
--icons: #6c7086;
--icons-hover: #7f849c;
--links: #89b4fa;
--inline-code-color: #fab387;
--theme-popup-bg: #181825;
--theme-popup-border: #6c7086;
--theme-hover: #6c7086;
--quote-bg: #181825;
--quote-border: #11111b;
--table-border-color: #11111b;
--table-header-bg: #181825;
--table-alternate-bg: #11111b;
--searchbar-border-color: #11111b;
--searchbar-bg: #181825;
--searchbar-fg: #cdd6f4;
--searchbar-shadow-color: #11111b;
--searchresults-header-fg: #cdd6f4;
--searchresults-border-color: #11111b;
--searchresults-li-bg: #1e1e2e;
--search-mark-bg: #fab387;
}
.macchiato {
--bg: #24273a;
--fg: #cad3f5;
--sidebar-bg: #1e2030;
--sidebar-fg: #cad3f5;
--sidebar-non-existant: #6e738d;
--sidebar-active: #f4dbd6;
--sidebar-spacer: #6e738d;
--scrollbar: #6e738d;
--icons: #6e738d;
--icons-hover: #8087a2;
--links: #8aadf4;
--inline-code-color: #f5a97f;
--theme-popup-bg: #1e2030;
--theme-popup-border: #6e738d;
--theme-hover: #6e738d;
--quote-bg: #1e2030;
--quote-border: #181926;
--table-border-color: #181926;
--table-header-bg: #1e2030;
--table-alternate-bg: #181926;
--searchbar-border-color: #181926;
--searchbar-bg: #1e2030;
--searchbar-fg: #cad3f5;
--searchbar-shadow-color: #181926;
--searchresults-header-fg: #cad3f5;
--searchresults-border-color: #181926;
--searchresults-li-bg: #24273a;
--search-mark-bg: #f5a97f;
}
.frappe {
--bg: #303446;
--fg: #c6d0f5;
--sidebar-bg: #292c3c;
--sidebar-fg: #c6d0f5;
--sidebar-non-existant: #737994;
--sidebar-active: #f2d5cf;
--sidebar-spacer: #737994;
--scrollbar: #737994;
--icons: #737994;
--icons-hover: #838ba7;
--links: #8caaee;
--inline-code-color: #ef9f76;
--theme-popup-bg: #292c3c;
--theme-popup-border: #737994;
--theme-hover: #737994;
--quote-bg: #292c3c;
--quote-border: #232634;
--table-border-color: #232634;
--table-header-bg: #292c3c;
--table-alternate-bg: #232634;
--searchbar-border-color: #232634;
--searchbar-bg: #292c3c;
--searchbar-fg: #c6d0f5;
--searchbar-shadow-color: #232634;
--searchresults-header-fg: #c6d0f5;
--searchresults-border-color: #232634;
--searchresults-li-bg: #303446;
--search-mark-bg: #ef9f76;
}
.latte {
--bg: #eff1f5;
--fg: #4c4f69;
--sidebar-bg: #e6e9ef;
--sidebar-fg: #4c4f69;
--sidebar-non-existant: #9ca0b0;
--sidebar-active: #dc8a78;
--sidebar-spacer: #9ca0b0;
--scrollbar: #9ca0b0;
--icons: #9ca0b0;
--icons-hover: #8c8fa1;
--links: #1e66f5;
--inline-code-color: #fe640b;
--theme-popup-bg: #e6e9ef;
--theme-popup-border: #9ca0b0;
--theme-hover: #9ca0b0;
--quote-bg: #e6e9ef;
--quote-border: #dce0e8;
--table-border-color: #dce0e8;
--table-header-bg: #e6e9ef;
--table-alternate-bg: #dce0e8;
--searchbar-border-color: #dce0e8;
--searchbar-bg: #e6e9ef;
--searchbar-fg: #4c4f69;
--searchbar-shadow-color: #dce0e8;
--searchresults-header-fg: #4c4f69;
--searchresults-border-color: #dce0e8;
--searchresults-li-bg: #eff1f5;
--search-mark-bg: #fe640b;
}

318
theme/index.hbs Normal file
View File

@ -0,0 +1,318 @@
<!DOCTYPE HTML>
<html lang="{{ language }}" class="sidebar-visible no-js {{ default_theme }}">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>{{ title }}</title>
{{#if is_print }}
<meta name="robots" content="noindex" />
{{/if}}
{{#if base_url}}
<base href="{{ base_url }}">
{{/if}}
<!-- Custom HTML head -->
{{> head}}
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="{{ description }}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
{{#if favicon_svg}}
<link rel="icon" href="{{ path_to_root }}favicon.svg">
{{/if}}
{{#if favicon_png}}
<link rel="shortcut icon" href="{{ path_to_root }}favicon.png">
{{/if}}
<link rel="stylesheet" href="{{ path_to_root }}css/variables.css">
<link rel="stylesheet" href="{{ path_to_root }}css/general.css">
<link rel="stylesheet" href="{{ path_to_root }}css/chrome.css">
{{#if print_enable}}
<link rel="stylesheet" href="{{ path_to_root }}css/print.css" media="print">
{{/if}}
<!-- Fonts -->
<link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
{{#if copy_fonts}}
<link rel="stylesheet" href="{{ path_to_root }}fonts/fonts.css">
{{/if}}
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="{{ path_to_root }}highlight.css">
<link rel="stylesheet" href="{{ path_to_root }}tomorrow-night.css">
<link rel="stylesheet" href="{{ path_to_root }}ayu-highlight.css">
<!-- Custom theme stylesheets -->
{{#each additional_css}}
<link rel="stylesheet" href="{{ ../path_to_root }}{{ this }}">
{{/each}}
{{#if mathjax_support}}
<!-- MathJax -->
<script async type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
{{/if}}
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "{{ path_to_root }}";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('{{ default_theme }}')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
{{#toc}}{{/toc}}
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
{{> header}}
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">{{ theme_option "Light" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">{{ theme_option "Rust" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">{{ theme_option "Coal" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">{{ theme_option "Navy" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">{{ theme_option "Ayu" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="latte">{{ theme_option "Latte" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="frappe">{{ theme_option "Frappé" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="macchiato">{{ theme_option "Macchiato" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="mocha">{{ theme_option "Mocha" }}</button></li>
</ul>
{{#if search_enabled}}
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
{{/if}}
</div>
<h1 class="menu-title">{{ book_title }}</h1>
<div class="right-buttons">
{{#if print_enable}}
<a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
{{/if}}
{{#if git_repository_url}}
<a href="{{git_repository_url}}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa {{git_repository_icon}}"></i>
</a>
{{/if}}
{{#if git_repository_edit_url}}
<a href="{{git_repository_edit_url}}" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
{{/if}}
</div>
</div>
{{#if search_enabled}}
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
{{/if}}
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
{{{ content }}}
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
{{#previous}}
<a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
{{/previous}}
{{#next}}
<a rel="next" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
{{/next}}
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
{{#previous}}
<a rel="prev" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
{{/previous}}
{{#next}}
<a rel="next" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
{{/next}}
</nav>
</div>
{{#if live_reload_endpoint}}
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsAddress = wsProtocol + "//" + location.host + "/" + "{{{live_reload_endpoint}}}";
const socket = new WebSocket(wsAddress);
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
{{/if}}
{{#if google_analytics}}
<!-- Google Analytics Tag -->
<script type="text/javascript">
var localAddrs = ["localhost", "127.0.0.1", ""];
// make sure we don't activate google analytics if the developer is
// inspecting the book locally...
if (localAddrs.indexOf(document.location.hostname) === -1) {
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', '{{google_analytics}}', 'auto');
ga('send', 'pageview');
}
</script>
{{/if}}
{{#if playground_line_numbers}}
<script type="text/javascript">
window.playground_line_numbers = true;
</script>
{{/if}}
{{#if playground_copyable}}
<script type="text/javascript">
window.playground_copyable = true;
</script>
{{/if}}
{{#if playground_js}}
<script src="{{ path_to_root }}ace.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}editor.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}mode-rust.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}theme-dawn.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}theme-tomorrow_night.js" type="text/javascript" charset="utf-8"></script>
{{/if}}
{{#if search_js}}
<script src="{{ path_to_root }}elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}searcher.js" type="text/javascript" charset="utf-8"></script>
{{/if}}
<script src="{{ path_to_root }}clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
{{#each additional_js}}
<script type="text/javascript" src="{{ ../path_to_root }}{{this}}"></script>
{{/each}}
{{#if is_print}}
{{#if mathjax_support}}
<script type="text/javascript">
window.addEventListener('load', function() {
MathJax.Hub.Register.StartupHook('End', function() {
window.setTimeout(window.print, 100);
});
});
</script>
{{else}}
<script type="text/javascript">
window.addEventListener('load', function() {
window.setTimeout(window.print, 100);
});
</script>
{{/if}}
{{/if}}
</body>
</html>