Compare commits

5 Commits
main ... next

Author SHA1 Message Date
Ralf Zerres
a96159a27b lib.rs: update annotations
* image path
* translation hints
* unicode icons
2024-10-21 12:08:03 +02:00
Ralf Zerres
21db004362 [next]: Rendered initial english version 2024-10-17 18:01:12 +02:00
Ralf Zerres
8529021733 Document chapter 02
* Install a self hosted instance of element-call
* As a container instances or pods
* Via OS native packages
2024-10-17 18:01:12 +02:00
Ralf Zerres
36bb3d6b8a Document chapter 01
* the routing structure
* the building blocks inside Element-Call
2024-10-17 18:01:07 +02:00
Ralf Zerres
aec8acee46 Update title-page 2024-10-17 17:34:48 +02:00
97 changed files with 32231 additions and 92 deletions

View File

@@ -1,11 +1,14 @@
# element-call-book # element-call-book
![Welcome to the element-call book.][element_call_book] Welcome to the Element-Call book.
[element_call_book]: https://gitea.networkx.de/rzerres/element-call-book/src/branch/main/src/img/element-call-webui.png "Element-Call UI"
![Element-Call book][element_call_book]
This repository contains the text source for "The Element-Call" book. This repository contains the text source for "The Element-Call" book.
We will further reference to it as the `Element-Call Book`. We will further reference to it as the `Element-Call Book`.
[element_call_book]: https://gitea.networkx.de/rzerres/element-call-book/src/branch/main/src/img/element-call-webui.png
<!-- <!--
WIP: once it is ready to be shipped WIP: once it is ready to be shipped
[The book is available in dead-tree form from No Starch Press][nostarch]. [The book is available in dead-tree form from No Starch Press][nostarch].
@@ -25,7 +28,7 @@ We will further reference to it as the `Element-Call Book`.
[releases]: https://element.io/element-call/book/releases [releases]: https://element.io/element-call/book/releases
--> -->
#### Requirements #### Requirements
##### mdBook ##### mdBook
Building the book requires [mdBook] and its helper tools. The used Building the book requires [mdBook] and its helper tools. The used
@@ -98,7 +101,7 @@ $ cargo readme > README.md
[mdBook localization]: https://github.com/Nutomic/mdBook/tree/localization [mdBook localization]: https://github.com/Nutomic/mdBook/tree/localization
[rust-mdbook]: https://github.com/rust-lang/rust/blob/master/src/tools/rustbook/Cargo.toml [rust-mdbook]: https://github.com/rust-lang/rust/blob/master/src/tools/rustbook/Cargo.toml
#### Building #### Building
##### Building the book ##### Building the book
@@ -173,7 +176,7 @@ on Matrix, featuring real humans!
<!-- <!--
WIP: once it is ready to be shipped WIP: once it is ready to be shipped
#### Code of Conduct #### 🌻 Code of Conduct
We are committed to providing a friendly, safe and welcoming We are committed to providing a friendly, safe and welcoming
environment. Read more about our policy in the [code-of-conduct][coc] page. environment. Read more about our policy in the [code-of-conduct][coc] page.
@@ -186,21 +189,17 @@ environment. Read more about our policy in the [code-of-conduct][coc] page.
[element-call-room-matrix]: https://matrix.to/#/#element-call-dev:matrix.org>`_` [element-call-room-matrix]: https://matrix.to/#/#element-call-dev:matrix.org>`_`
--> -->
##### Translations #### 🌐 Translations
We'd love help to translate the book! See the [Translations] label We'd love help to translate the book! See the [Translations] label
to join in efforts that are currently in progress. Open a new to join in efforts that are currently in progress. Open a new
issue to start working on a new language! We're waiting on [mdbook issue to start working on a new language!
support] for multiple languages to be finalized, but feel free to
start! A [pull request] looks promising. The mainline version (we
do depend on v0.4.12) is capable to render the existing versions
where sources are installed in the intended final structure.
[Translations]: https://gitea.networkx.de/rzerres/element-call/book/issues?q=is%3Aopen+is%3Aissue+label%3ATranslations [Translations]: https://gitea.networkx.de/rzerres/element-call/book/issues?q=is%3Aopen+is%3Aissue+label%3ATranslations
[mdbook support]: https://github.com/rust-lang-nursery/mdBook/issues/5 [mdbook support]: https://github.com/rust-lang-nursery/mdBook/issues/5
[pull request]: https://github.com/rust-lang/mdBook/pull/1306 [pull request]: https://github.com/rust-lang/mdBook/pull/1306
#### Spellchecking #### Spellchecking
To scan source files for spelling errors, you can use the `spellcheck.sh` To scan source files for spelling errors, you can use the `spellcheck.sh`
script. It needs a dictionary of valid words, which is provided in script. It needs a dictionary of valid words, which is provided in
@@ -208,7 +207,7 @@ script. It needs a dictionary of valid words, which is provided in
`BTreeMap` which the script considers invalid), you need to add this word to `BTreeMap` which the script considers invalid), you need to add this word to
`dictionary.txt` (keep the sorted order for consistency). `dictionary.txt` (keep the sorted order for consistency).
#### License #### License
<!-- License source --> <!-- License source -->
[Logo-CC_BY]: https://i.creativecommons.org/l/by/4.0/88x31.png "Creative Common Logo" [Logo-CC_BY]: https://i.creativecommons.org/l/by/4.0/88x31.png "Creative Common Logo"

1
book_en/html/.nojekyll Normal file
View File

@@ -0,0 +1 @@
This file makes sure that Github Pages doesn't process mdBook's output.

234
book_en/html/404.html Normal file
View File

@@ -0,0 +1,234 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Page not found - The Element-Call Book</title>
<base href="/">
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<p>M# Document not found (404)</p>
<p>This URL is invalid, sorry. Try the search instead!</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

1
book_en/html/CNAME Normal file
View File

@@ -0,0 +1 @@
element-call-book.rs

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

43
book_en/html/ace.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,248 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Appendix - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item expanded "><a href="appendix-00.html" class="active"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/appendix-00.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h1 id="element-call-appendix"><a class="header" href="#element-call-appendix">Element-Call Appendix</a></h1>
<p>This is WIP</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="ch09-01-element-call-hello.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="appendix-01-keywords.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="ch09-01-element-call-hello.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="appendix-01-keywords.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

View File

@@ -0,0 +1,248 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>A - Keywords - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item expanded "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="appendix-01-keywords.html" class="active"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/appendix-01-keywords.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h1 id="element-call-appendix---keywords"><a class="header" href="#element-call-appendix---keywords">Element-Call Appendix - Keywords</a></h1>
<p>This is WIP</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="appendix-00.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="appendix-02-operators.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="appendix-00.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="appendix-02-operators.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

View File

@@ -0,0 +1,248 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>B - Operators and Symbols - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item expanded "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item expanded "><a href="appendix-02-operators.html" class="active"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/appendix-02-operators.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h1 id="element-call-appendix---operators"><a class="header" href="#element-call-appendix---operators">Element-Call Appendix - Operators</a></h1>
<p>This is WIP</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="appendix-01-keywords.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="appendix-03-derivable-traits.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="appendix-01-keywords.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="appendix-03-derivable-traits.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

View File

@@ -0,0 +1,248 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>C - Derivable Traits - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item expanded "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item expanded "><a href="appendix-03-derivable-traits.html" class="active"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/appendix-03-derivable-traits.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h1 id="element-call-appendix---derivable-traits"><a class="header" href="#element-call-appendix---derivable-traits">Element-CAll Appendix - Derivable Traits</a></h1>
<p>This is WIP</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="appendix-02-operators.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="appendix-04-translation.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="appendix-02-operators.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="appendix-04-translation.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

View File

@@ -0,0 +1,250 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>D - Translations of the Book - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item expanded "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item expanded "><a href="appendix-04-translation.html" class="active"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/appendix-04-translation.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h1 id="appendix-d-translations-of-the-book"><a class="header" href="#appendix-d-translations-of-the-book">Appendix D: Translations of the Book</a></h1>
<p>For resources in languages other than English. This is work in progress; see
<a href="https://gitea.networkx.de/ralf.zerres/element-call-book/issues?q=is%3Aopen+is%3Aissue+label%3ATranslations">the Translations label</a> to help or let us know about a new translation!</p>
<ul>
<li><a href="https://gitea.networkx.de/rzerres/element-call-book">Deutsch</a></li>
</ul>
<!---
- [Deutsch](https://github.com/element.io/element-call/book/book-de)
- [Français](https://github.com/element.io/element-call/book/book-fr)
-->
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="appendix-03-derivable-traits.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="appendix-03-derivable-traits.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

View File

@@ -0,0 +1,78 @@
/*
Based off of the Ayu theme
Original by Dempfi (https://github.com/dempfi/ayu)
*/
.hljs {
display: block;
overflow-x: auto;
background: #191f26;
color: #e6e1cf;
}
.hljs-comment,
.hljs-quote {
color: #5c6773;
font-style: italic;
}
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-attr,
.hljs-regexp,
.hljs-link,
.hljs-selector-id,
.hljs-selector-class {
color: #ff7733;
}
.hljs-number,
.hljs-meta,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #ffee99;
}
.hljs-string,
.hljs-bullet {
color: #b8cc52;
}
.hljs-title,
.hljs-built_in,
.hljs-section {
color: #ffb454;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-symbol {
color: #ff7733;
}
.hljs-name {
color: #36a3d9;
}
.hljs-tag {
color: #00568d;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-addition {
color: #91b362;
}
.hljs-deletion {
color: #d96c75;
}

697
book_en/html/book.js Normal file
View File

@@ -0,0 +1,697 @@
"use strict";
// Fix back button cache problem
window.onunload = function () { };
// Global variable, shared between modules
function playground_text(playground, hidden = true) {
let code_block = playground.querySelector("code");
if (window.ace && code_block.classList.contains("editable")) {
let editor = window.ace.edit(code_block);
return editor.getValue();
} else if (hidden) {
return code_block.textContent;
} else {
return code_block.innerText;
}
}
(function codeSnippets() {
function fetch_with_timeout(url, options, timeout = 6000) {
return Promise.race([
fetch(url, options),
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout))
]);
}
var playgrounds = Array.from(document.querySelectorAll(".playground"));
if (playgrounds.length > 0) {
fetch_with_timeout("https://play.rust-lang.org/meta/crates", {
headers: {
'Content-Type': "application/json",
},
method: 'POST',
mode: 'cors',
})
.then(response => response.json())
.then(response => {
// get list of crates available in the rust playground
let playground_crates = response.crates.map(item => item["id"]);
playgrounds.forEach(block => handle_crate_list_update(block, playground_crates));
});
}
function handle_crate_list_update(playground_block, playground_crates) {
// update the play buttons after receiving the response
update_play_button(playground_block, playground_crates);
// and install on change listener to dynamically update ACE editors
if (window.ace) {
let code_block = playground_block.querySelector("code");
if (code_block.classList.contains("editable")) {
let editor = window.ace.edit(code_block);
editor.addEventListener("change", function (e) {
update_play_button(playground_block, playground_crates);
});
// add Ctrl-Enter command to execute rust code
editor.commands.addCommand({
name: "run",
bindKey: {
win: "Ctrl-Enter",
mac: "Ctrl-Enter"
},
exec: _editor => run_rust_code(playground_block)
});
}
}
}
// updates the visibility of play button based on `no_run` class and
// used crates vs ones available on https://play.rust-lang.org
function update_play_button(pre_block, playground_crates) {
var play_button = pre_block.querySelector(".play-button");
// skip if code is `no_run`
if (pre_block.querySelector('code').classList.contains("no_run")) {
play_button.classList.add("hidden");
return;
}
// get list of `extern crate`'s from snippet
var txt = playground_text(pre_block);
var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
var snippet_crates = [];
var item;
while (item = re.exec(txt)) {
snippet_crates.push(item[1]);
}
// check if all used crates are available on play.rust-lang.org
var all_available = snippet_crates.every(function (elem) {
return playground_crates.indexOf(elem) > -1;
});
if (all_available) {
play_button.classList.remove("hidden");
} else {
play_button.classList.add("hidden");
}
}
function run_rust_code(code_block) {
var result_block = code_block.querySelector(".result");
if (!result_block) {
result_block = document.createElement('code');
result_block.className = 'result hljs language-bash';
code_block.append(result_block);
}
let text = playground_text(code_block);
let classes = code_block.querySelector('code').classList;
let edition = "2015";
if(classes.contains("edition2018")) {
edition = "2018";
} else if(classes.contains("edition2021")) {
edition = "2021";
}
var params = {
version: "stable",
optimize: "0",
code: text,
edition: edition
};
if (text.indexOf("#![feature") !== -1) {
params.version = "nightly";
}
result_block.innerText = "Running...";
fetch_with_timeout("https://play.rust-lang.org/evaluate.json", {
headers: {
'Content-Type': "application/json",
},
method: 'POST',
mode: 'cors',
body: JSON.stringify(params)
})
.then(response => response.json())
.then(response => {
if (response.result.trim() === '') {
result_block.innerText = "No output";
result_block.classList.add("result-no-output");
} else {
result_block.innerText = response.result;
result_block.classList.remove("result-no-output");
}
})
.catch(error => result_block.innerText = "Playground Communication: " + error.message);
}
// Syntax highlighting Configuration
hljs.configure({
tabReplace: ' ', // 4 spaces
languages: [], // Languages used for auto-detection
});
let code_nodes = Array
.from(document.querySelectorAll('code'))
// Don't highlight `inline code` blocks in headers.
.filter(function (node) {return !node.parentElement.classList.contains("header"); });
if (window.ace) {
// language-rust class needs to be removed for editable
// blocks or highlightjs will capture events
code_nodes
.filter(function (node) {return node.classList.contains("editable"); })
.forEach(function (block) { block.classList.remove('language-rust'); });
code_nodes
.filter(function (node) {return !node.classList.contains("editable"); })
.forEach(function (block) { hljs.highlightBlock(block); });
} else {
code_nodes.forEach(function (block) { hljs.highlightBlock(block); });
}
// Adding the hljs class gives code blocks the color css
// even if highlighting doesn't apply
code_nodes.forEach(function (block) { block.classList.add('hljs'); });
Array.from(document.querySelectorAll("code.hljs")).forEach(function (block) {
var lines = Array.from(block.querySelectorAll('.boring'));
// If no lines were hidden, return
if (!lines.length) { return; }
block.classList.add("hide-boring");
var buttons = document.createElement('div');
buttons.className = 'buttons';
buttons.innerHTML = "<button class=\"fa fa-eye\" title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>";
// add expand button
var pre_block = block.parentNode;
pre_block.insertBefore(buttons, pre_block.firstChild);
pre_block.querySelector('.buttons').addEventListener('click', function (e) {
if (e.target.classList.contains('fa-eye')) {
e.target.classList.remove('fa-eye');
e.target.classList.add('fa-eye-slash');
e.target.title = 'Hide lines';
e.target.setAttribute('aria-label', e.target.title);
block.classList.remove('hide-boring');
} else if (e.target.classList.contains('fa-eye-slash')) {
e.target.classList.remove('fa-eye-slash');
e.target.classList.add('fa-eye');
e.target.title = 'Show hidden lines';
e.target.setAttribute('aria-label', e.target.title);
block.classList.add('hide-boring');
}
});
});
if (window.playground_copyable) {
Array.from(document.querySelectorAll('pre code')).forEach(function (block) {
var pre_block = block.parentNode;
if (!pre_block.classList.contains('playground')) {
var buttons = pre_block.querySelector(".buttons");
if (!buttons) {
buttons = document.createElement('div');
buttons.className = 'buttons';
pre_block.insertBefore(buttons, pre_block.firstChild);
}
var clipButton = document.createElement('button');
clipButton.className = 'fa fa-copy clip-button';
clipButton.title = 'Copy to clipboard';
clipButton.setAttribute('aria-label', clipButton.title);
clipButton.innerHTML = '<i class=\"tooltiptext\"></i>';
buttons.insertBefore(clipButton, buttons.firstChild);
}
});
}
// Process playground code blocks
Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) {
// Add play button
var buttons = pre_block.querySelector(".buttons");
if (!buttons) {
buttons = document.createElement('div');
buttons.className = 'buttons';
pre_block.insertBefore(buttons, pre_block.firstChild);
}
var runCodeButton = document.createElement('button');
runCodeButton.className = 'fa fa-play play-button';
runCodeButton.hidden = true;
runCodeButton.title = 'Run this code';
runCodeButton.setAttribute('aria-label', runCodeButton.title);
buttons.insertBefore(runCodeButton, buttons.firstChild);
runCodeButton.addEventListener('click', function (e) {
run_rust_code(pre_block);
});
if (window.playground_copyable) {
var copyCodeClipboardButton = document.createElement('button');
copyCodeClipboardButton.className = 'fa fa-copy clip-button';
copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>';
copyCodeClipboardButton.title = 'Copy to clipboard';
copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title);
buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild);
}
let code_block = pre_block.querySelector("code");
if (window.ace && code_block.classList.contains("editable")) {
var undoChangesButton = document.createElement('button');
undoChangesButton.className = 'fa fa-history reset-button';
undoChangesButton.title = 'Undo changes';
undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
buttons.insertBefore(undoChangesButton, buttons.firstChild);
undoChangesButton.addEventListener('click', function () {
let editor = window.ace.edit(code_block);
editor.setValue(editor.originalCode);
editor.clearSelection();
});
}
});
})();
(function themes() {
var html = document.querySelector('html');
var themeToggleButton = document.getElementById('theme-toggle');
var themePopup = document.getElementById('theme-list');
var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
var stylesheets = {
ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"),
highlight: document.querySelector("[href$='highlight.css']"),
};
function showThemes() {
themePopup.style.display = 'block';
themeToggleButton.setAttribute('aria-expanded', true);
themePopup.querySelector("button#" + get_theme()).focus();
}
function updateThemeSelected() {
themePopup.querySelectorAll('.theme-selected').forEach(function (el) {
el.classList.remove('theme-selected');
});
themePopup.querySelector("button#" + get_theme()).classList.add('theme-selected');
}
function hideThemes() {
themePopup.style.display = 'none';
themeToggleButton.setAttribute('aria-expanded', false);
themeToggleButton.focus();
}
function get_theme() {
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
if (theme === null || theme === undefined) {
return default_theme;
} else {
return theme;
}
}
function set_theme(theme, store = true) {
let ace_theme;
if (theme == 'coal' || theme == 'navy') {
stylesheets.ayuHighlight.disabled = true;
stylesheets.tomorrowNight.disabled = false;
stylesheets.highlight.disabled = true;
ace_theme = "ace/theme/tomorrow_night";
} else if (theme == 'ayu') {
stylesheets.ayuHighlight.disabled = false;
stylesheets.tomorrowNight.disabled = true;
stylesheets.highlight.disabled = true;
ace_theme = "ace/theme/tomorrow_night";
} else {
stylesheets.ayuHighlight.disabled = true;
stylesheets.tomorrowNight.disabled = true;
stylesheets.highlight.disabled = false;
ace_theme = "ace/theme/dawn";
}
setTimeout(function () {
themeColorMetaTag.content = getComputedStyle(document.documentElement).backgroundColor;
}, 1);
if (window.ace && window.editors) {
window.editors.forEach(function (editor) {
editor.setTheme(ace_theme);
});
}
var previousTheme = get_theme();
if (store) {
try { localStorage.setItem('mdbook-theme', theme); } catch (e) { }
}
html.classList.remove(previousTheme);
html.classList.add(theme);
updateThemeSelected();
}
// Set theme
var theme = get_theme();
set_theme(theme, false);
themeToggleButton.addEventListener('click', function () {
if (themePopup.style.display === 'block') {
hideThemes();
} else {
showThemes();
}
});
themePopup.addEventListener('click', function (e) {
var theme;
if (e.target.className === "theme") {
theme = e.target.id;
} else if (e.target.parentElement.className === "theme") {
theme = e.target.parentElement.id;
} else {
return;
}
set_theme(theme);
});
themePopup.addEventListener('focusout', function(e) {
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) {
hideThemes();
}
});
// Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
document.addEventListener('click', function(e) {
if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) {
hideThemes();
}
});
document.addEventListener('keydown', function (e) {
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
if (!themePopup.contains(e.target)) { return; }
switch (e.key) {
case 'Escape':
e.preventDefault();
hideThemes();
break;
case 'ArrowUp':
e.preventDefault();
var li = document.activeElement.parentElement;
if (li && li.previousElementSibling) {
li.previousElementSibling.querySelector('button').focus();
}
break;
case 'ArrowDown':
e.preventDefault();
var li = document.activeElement.parentElement;
if (li && li.nextElementSibling) {
li.nextElementSibling.querySelector('button').focus();
}
break;
case 'Home':
e.preventDefault();
themePopup.querySelector('li:first-child button').focus();
break;
case 'End':
e.preventDefault();
themePopup.querySelector('li:last-child button').focus();
break;
}
});
})();
(function sidebar() {
var body = document.querySelector("body");
var sidebar = document.getElementById("sidebar");
var sidebarLinks = document.querySelectorAll('#sidebar a');
var sidebarToggleButton = document.getElementById("sidebar-toggle");
var sidebarResizeHandle = document.getElementById("sidebar-resize-handle");
var firstContact = null;
function showSidebar() {
body.classList.remove('sidebar-hidden')
body.classList.add('sidebar-visible');
Array.from(sidebarLinks).forEach(function (link) {
link.setAttribute('tabIndex', 0);
});
sidebarToggleButton.setAttribute('aria-expanded', true);
sidebar.setAttribute('aria-hidden', false);
try { localStorage.setItem('mdbook-sidebar', 'visible'); } catch (e) { }
}
var sidebarAnchorToggles = document.querySelectorAll('#sidebar a.toggle');
function toggleSection(ev) {
ev.currentTarget.parentElement.classList.toggle('expanded');
}
Array.from(sidebarAnchorToggles).forEach(function (el) {
el.addEventListener('click', toggleSection);
});
function hideSidebar() {
body.classList.remove('sidebar-visible')
body.classList.add('sidebar-hidden');
Array.from(sidebarLinks).forEach(function (link) {
link.setAttribute('tabIndex', -1);
});
sidebarToggleButton.setAttribute('aria-expanded', false);
sidebar.setAttribute('aria-hidden', true);
try { localStorage.setItem('mdbook-sidebar', 'hidden'); } catch (e) { }
}
// Toggle sidebar
sidebarToggleButton.addEventListener('click', function sidebarToggle() {
if (body.classList.contains("sidebar-hidden")) {
var current_width = parseInt(
document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
if (current_width < 150) {
document.documentElement.style.setProperty('--sidebar-width', '150px');
}
showSidebar();
} else if (body.classList.contains("sidebar-visible")) {
hideSidebar();
} else {
if (getComputedStyle(sidebar)['transform'] === 'none') {
hideSidebar();
} else {
showSidebar();
}
}
});
sidebarResizeHandle.addEventListener('mousedown', initResize, false);
function initResize(e) {
window.addEventListener('mousemove', resize, false);
window.addEventListener('mouseup', stopResize, false);
body.classList.add('sidebar-resizing');
}
function resize(e) {
var pos = (e.clientX - sidebar.offsetLeft);
if (pos < 20) {
hideSidebar();
} else {
if (body.classList.contains("sidebar-hidden")) {
showSidebar();
}
pos = Math.min(pos, window.innerWidth - 100);
document.documentElement.style.setProperty('--sidebar-width', pos + 'px');
}
}
//on mouseup remove windows functions mousemove & mouseup
function stopResize(e) {
body.classList.remove('sidebar-resizing');
window.removeEventListener('mousemove', resize, false);
window.removeEventListener('mouseup', stopResize, false);
}
document.addEventListener('touchstart', function (e) {
firstContact = {
x: e.touches[0].clientX,
time: Date.now()
};
}, { passive: true });
document.addEventListener('touchmove', function (e) {
if (!firstContact)
return;
var curX = e.touches[0].clientX;
var xDiff = curX - firstContact.x,
tDiff = Date.now() - firstContact.time;
if (tDiff < 250 && Math.abs(xDiff) >= 150) {
if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300))
showSidebar();
else if (xDiff < 0 && curX < 300)
hideSidebar();
firstContact = null;
}
}, { passive: true });
})();
(function chapterNavigation() {
document.addEventListener('keydown', function (e) {
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
if (window.search && window.search.hasFocus()) { return; }
var html = document.querySelector('html');
function next() {
var nextButton = document.querySelector('.nav-chapters.next');
if (nextButton) {
window.location.href = nextButton.href;
}
}
function prev() {
var previousButton = document.querySelector('.nav-chapters.previous');
if (previousButton) {
window.location.href = previousButton.href;
}
}
switch (e.key) {
case 'ArrowRight':
e.preventDefault();
if (html.dir == 'rtl') {
prev();
} else {
next();
}
break;
case 'ArrowLeft':
e.preventDefault();
if (html.dir == 'rtl') {
next();
} else {
prev();
}
break;
}
});
})();
(function clipboard() {
var clipButtons = document.querySelectorAll('.clip-button');
function hideTooltip(elem) {
elem.firstChild.innerText = "";
elem.className = 'fa fa-copy clip-button';
}
function showTooltip(elem, msg) {
elem.firstChild.innerText = msg;
elem.className = 'fa fa-copy tooltipped';
}
var clipboardSnippets = new ClipboardJS('.clip-button', {
text: function (trigger) {
hideTooltip(trigger);
let playground = trigger.closest("pre");
return playground_text(playground, false);
}
});
Array.from(clipButtons).forEach(function (clipButton) {
clipButton.addEventListener('mouseout', function (e) {
hideTooltip(e.currentTarget);
});
});
clipboardSnippets.on('success', function (e) {
e.clearSelection();
showTooltip(e.trigger, "Copied!");
});
clipboardSnippets.on('error', function (e) {
showTooltip(e.trigger, "Clipboard error!");
});
})();
(function scrollToTop () {
var menuTitle = document.querySelector('.menu-title');
menuTitle.addEventListener('click', function () {
document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' });
});
})();
(function controllMenu() {
var menu = document.getElementById('menu-bar');
(function controllPosition() {
var scrollTop = document.scrollingElement.scrollTop;
var prevScrollTop = scrollTop;
var minMenuY = -menu.clientHeight - 50;
// When the script loads, the page can be at any scroll (e.g. if you reforesh it).
menu.style.top = scrollTop + 'px';
// Same as parseInt(menu.style.top.slice(0, -2), but faster
var topCache = menu.style.top.slice(0, -2);
menu.classList.remove('sticky');
var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster
document.addEventListener('scroll', function () {
scrollTop = Math.max(document.scrollingElement.scrollTop, 0);
// `null` means that it doesn't need to be updated
var nextSticky = null;
var nextTop = null;
var scrollDown = scrollTop > prevScrollTop;
var menuPosAbsoluteY = topCache - scrollTop;
if (scrollDown) {
nextSticky = false;
if (menuPosAbsoluteY > 0) {
nextTop = prevScrollTop;
}
} else {
if (menuPosAbsoluteY > 0) {
nextSticky = true;
} else if (menuPosAbsoluteY < minMenuY) {
nextTop = prevScrollTop + minMenuY;
}
}
if (nextSticky === true && stickyCache === false) {
menu.classList.add('sticky');
stickyCache = true;
} else if (nextSticky === false && stickyCache === true) {
menu.classList.remove('sticky');
stickyCache = false;
}
if (nextTop !== null) {
menu.style.top = nextTop + 'px';
topCache = nextTop;
}
prevScrollTop = scrollTop;
}, { passive: true });
})();
(function controllBorder() {
function updateBorder() {
if (menu.offsetTop === 0) {
menu.classList.remove('bordered');
} else {
menu.classList.add('bordered');
}
}
updateBorder();
document.addEventListener('scroll', updateBorder, { passive: true });
})();
})();

View File

@@ -0,0 +1,301 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Introduction - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html" class="active">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/ch00-00-introduction.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h1 id="introduction"><a class="header" href="#introduction">Introduction</a></h1>
<!--
> WIP: to be uncommented, once it is done
> Note: This edition of the book is the same as [The Orbital Widget Toolkit]
> [nsprust] available in print and ebook format from [No Starch Press][nsporbtk].
[nsporbtk]: https://nostarch.com/orbtk
[nsp]: https://nostarch.com/
-->
<p><a href="img/element-call-webui.png"><img src="img/element-call-webui.png" width="720"/></a></p>
<p>Welcome to <code>Element-Call</code>, an introductory book about the Matrix based
video conferencing subsystem.</p>
<div class="warning">
<p>Warning: This book is incomplete. Documenting everything and
rewriting outdated parts take a while.
See the <a href="https://https://gitea.networkx.de/rzerres/element-call/book/issues">issue tracker</a> to check whats missing or outdated. If there
are any mistakes or ideas that havent been reported, feel free to
open a new issue there.</p>
</div>
<p><code>Element-Call</code> fully embraces the potential of MatrixRTC. All
supported clients will connect via the genreric API, though selecting
their prefered mode (standalone- vs. widget-view).</p>
<p><a href="img/element-call-modes.png"><img src="img/element-call-modes.png" width="720"/></a></p>
<h2 id="features"><a class="header" href="#features">Features</a></h2>
<ul>
<li>Modern WebRTC API (powered by LifeKit)</li>
<li>Custom widgets</li>
<li>WebBrowser suport</li>
<li>Custom theming engine</li>
<li>Localization</li>
</ul>
<h2 id="supported-backend-platforms"><a class="header" href="#supported-backend-platforms">Supported Backend Platforms</a></h2>
<ul>
<li>Linux (native)</li>
</ul>
<!--
* macOS (native)
* Windows (native)
* openBSD (not tested, but should work)
* Web (cargo-node)
* Android (native planned | cargo-node)
* iOS (native planned | cargo-node planned)
-->
<h2 id="supported-client-platforms"><a class="header" href="#supported-client-platforms">Supported Client Platforms</a></h2>
<ul>
<li>Matrix clients (e.g. Element X, ShildiNext)</li>
<li>WebBrouwsers (e.g. Brave, Chrome, Edge, Firefox)</li>
</ul>
<h2 id="who-element-call-book-is-for"><a class="header" href="#who-element-call-book-is-for">Who Element-Call Book Is For</a></h2>
<p>The intention of <code>Element-Call</code> book is to help interested developers and administrators to get familiar with the structure and the componets choosen to implement a fully functional decentralized video conferencing solution. It will offer the needed in depth information to get in touch with the codebase. It will also aid an administrator to set up the needed software components to build up a self hosted installation.</p>
<h2 id="source-code"><a class="header" href="#source-code">Source Code</a></h2>
<p>The source files of the book are maintained as a git submodule found at <a href="https://gitea.networkx.de/rzerres/element-call-book/book_en"><code>Element-Call book</code></a>.</p>
<!--
[element-call_book_en_stable]: https://element.io/element-call/stable/book/
-->
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="foreword.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ch01-00-getting-started.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="foreword.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ch01-00-getting-started.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

View File

@@ -0,0 +1,253 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Getting Started - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item expanded "><a href="ch01-00-getting-started.html" class="active"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/ch01-00-getting-started.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h1 id="getting-started"><a class="header" href="#getting-started">Getting Started</a></h1>
<p>Lets start your Element-Call journey! Theres a lot to learn, but every journey starts
somewhere. In this chapter, well discuss:</p>
<ul>
<li>The building blocks of Element-Call</li>
<li>Installing Element-Call</li>
</ul>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="ch00-00-introduction.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ch01-01-building-blocks.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="ch00-00-introduction.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ch01-01-building-blocks.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

View File

@@ -0,0 +1,272 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>The building blocks - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item expanded "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch01-01-building-blocks.html" class="active"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/ch01-01-building-blocks.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h2 id="building-blocks"><a class="header" href="#building-blocks">Building blocks</a></h2>
<p>Historically <code>Elememnt-Call</code> did implement an infrastructure, where
all participants were fully meshed. That means all participants had a
direct peer to each other. This structure does work quite well with a
low number of call partners (e.g 1:1 sessions). Clearly this structure
is totally inefficient and collapsing, as soon as the number of
participants rises: The needed number of streams that have to be
synchronized are increasing exponentionally.</p>
<p>Most commercial solutions overcome this bottleneck utilizing a
MCU-structure: Each participant of the call is directly connected to
the controlling MCU (the head).</p>
<p>MCU routing has disadvantages and shortcommings too.</p>
<ul>
<li>You cant assign different egress parameters from the MCU to
individual participant streams</li>
<li>A single MCU cant handle distributed structure</li>
</ul>
<p>Since the nature of Matrix based communication makes use of a
distributed infrasturcture, MatrixRTC need to handle this aspect. It
is implemented with an SFU backend.</p>
<p>The following image visualize the differences inside the available
<img src="./img/voip_routing_structures.png" alt="voip routing structures" /></p>
<h3 id="backend"><a class="header" href="#backend">Backend</a></h3>
<p>The MatrixRTC functionality is handled via <a href="https://github.com/livekit">LiveKit</a>.</p>
<h3 id="frontend"><a class="header" href="#frontend">Frontend</a></h3>
<p><img src="https://gitea.networkx.de/rzerres/element-call/book/blob/main/src/img/element-call_building_blocks.png" alt="Building blocks" /></p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="ch01-00-getting-started.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ch01-02-element-call-hello.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="ch01-00-getting-started.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ch01-02-element-call-hello.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

View File

@@ -0,0 +1,365 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Hello Element-Call! - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item expanded "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item expanded "><a href="ch01-02-element-call-hello.html" class="active"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/ch01-02-element-call-hello.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h2 id="hello-element-call"><a class="header" href="#hello-element-call">Hello ELement-Call!</a></h2>
<!--
[<img src="img/element-call.png" width="720"/>](img/element-call-webui.png)
-->
<p><img src="https://gitea.networkx.de/rzerres/element-call-book/src/branch/main/src/img/element-call-webui.png" alt="Welcome to the element-call book." /></p>
<p>Now that youve installed the needed building blocks, lets adapt the
Frontend.</p>
<h3 id="writing-and-running-the-element-call-frontend"><a class="header" href="#writing-and-running-the-element-call-frontend">Writing and Running the ELement-Call frontend</a></h3>
<p>First, we make a new project using <em>Cargo</em>. With its <em>.toml</em> file we
allow Rust to declare the various dependencies and metadata. That
ensures that youll always get a repeatable output of the build.</p>
<p>Go ahead like so:</p>
<pre><code class="language-console">$ cargo new element-call
$ cd element-call
</code></pre>
<p>The first command, <code>cargo new</code>, takes the name of the project
(“<code>element-call</code>”) as the first argument. The second command changes to
the new projects directory.</p>
<p>Look at the generated <em>Cargo.toml</em> file:</p>
<p><span class="filename">Filename: Cargo.toml</span></p>
<pre><code class="language-toml">[package]
name = "element_call_hello_example"
version = "0.1.0"
authors = ["Your Name &lt;you@example.com&gt;"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
</code></pre>
<p><span class="caption">Listing 1-1: Default metadata “element_call_hello”</span></p>
<p>With <code>cargo new</code>, a default project structure is created. Maybe the
author information is already exchanged if <em>Cargo</em> could obtain a definition
from your environment. <em>Cargo</em> also generated source code for a “Hello, world!”
program. Lets Check out the corresponding <em>src/main.rs</em> file:</p>
<p><span class="filename">Filename: src/main.rs</span></p>
<pre><pre class="playground"><code class="language-rust edition2021">fn main() {
println!("Hello, world!");
}</code></pre></pre>
<p><span class="caption">Listing 1-2: Default source file “main.rs”</span></p>
<p>No need to compile that stage with <code>cargo run</code>, since we are going to
exchange the project metadata, as well as the element-call source code right
away.</p>
<h4 id="update-cargotoml"><a class="header" href="#update-cargotoml">Update Cargo.toml</a></h4>
<p>First reopen the <em>Cargo.toml</em> file and enter the Code in Listing 1-1 into <em>Cargo.toml</em></p>
<p><span class="filename">Filename: Cargo.toml</span></p>
<pre><code class="language-toml ignore">[package]
name = "element_call_hello"
version = "0.0.1"
authors = [
"Ralf Zerres &lt;ralf.zerres.de@gmail.com&gt;",
]
description = "The Element-Call - Training project"
documentation = "https://docs.rs/orbtk"
repository = "https://github.com/redox-os/orbtk"
readme = "README.md"
license = "MIT"
keywords = [
"element-call",
"matrix",
"matrixrtc",
]
edition = "2021"
[profile.dev]
opt-level = 1
[dependencies]
#element-call = { git = "https://gitea.networkx.de/rzerres/element-call-book.git", branch = "develop" }
[[bin]]
name = "element_call_hello"
path = "src/main.rs"
</code></pre>
<p><span class="caption">Listing 1-1: Project metadata “Element-Call”</span></p>
<p>You may wonder, why the <em>name</em> property inside the <em>Cargo.toml</em> is
formatted like <code>element_call</code>.</p>
<pre><code class="language-toml ignore">name = "element_call_hello"
</code></pre>
<p>It is a good habit to follow rusts
naming convention, that encourages you to use <a href="https://rust-lang.github.io/api-guidelines/naming.html">snake_case</a>
naming. While expanding the <em>Element-Call</em> example sources, we will keep
the grouping prefix <code>element-call</code>. That way we end up to call our first target
binary <code>element-call_hello</code>.</p>
<h4 id="update-mainrs"><a class="header" href="#update-mainrs">Update main.rs</a></h4>
<p>All of the <em>Element-Call</em> specific code that is needed to build our first
example “Hello Element-Call!” is shown in Listing 1-2. It goes to
<em>src/main.rs</em>.</p>
<p><span class="filename">Filename: src/main.rs</span></p>
<pre><code class="language-rust ignore">use element-call::prelude::*;
fn main() {
element-call::initialize();
.run();
}</code></pre>
<p><span class="caption">Listing 1-2: Code that creates a Window and
prints “Hey Element-Call!”</span></p>
<p>Save the file and go back to your terminal window. Enter the following
commands to compile and run the file:</p>
<pre><code class="language-console">$ cargo run --release element_call_hello
</code></pre>
<h3 id="compiling-and-running-are-separate-steps"><a class="header" href="#compiling-and-running-are-separate-steps">Compiling and Running Are Separate Steps</a></h3>
<p>Before running an Element-Call application, you must compile its source code. A typical
Element-Call project will generate the executable binary code using cargo and place the
result in the target subfolder of the project.</p>
<p>Profiles may be used to configure compiler options such as optimization levels
and debug settings. By default the <code>dev</code> or <code>test</code> profiles are used. If the
<code>--release</code> flag is given, then the release or bench profiles are used.</p>
<pre><code class="language-console">$ cargo build --release --bin element-call-hello.rs
$ ../target/release/hello_element_call
</code></pre>
<p>On Windows, you need to use <code>backslash</code> as a path delimiter:</p>
<pre><code class="language-powershell">&gt; cargo build --release --bin element-call-hello.rs
&gt; ..\target\release\element_call_hello.exe
</code></pre>
<p>If you like to get debug feedback you can call the build process like this</p>
<pre><code class="language-console">$ cargo build --features debug --bin element-call-hello.rs
</code></pre>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="ch01-01-building-blocks.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ch02-00-installation.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="ch01-01-building-blocks.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ch02-00-installation.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

View File

@@ -0,0 +1,312 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Installation - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item expanded "><a href="ch02-00-installation.html" class="active"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/ch02-00-installation.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h2 id="installation"><a class="header" href="#installation">Installation</a></h2>
<p>The first step is to install Rust. This is described in depth following
<a href="https://github.com/rust-lang/book/blob/master/src/ch01-01-installation.md">Rust book Chapter 1</a></p>
<p>When creating a OrbTk application, we define the needed dependencies to the
OrbTk crates in the Cargo.toml file of our project. The complile process
will resolve the references and download the source as needed.</p>
<blockquote>
<h3 id="command-line-notation"><a class="header" href="#command-line-notation">Command Line Notation</a></h3>
<p>In this chapter and throughout the book, well show some commands used in the
terminal. Lines that you should enter in a terminal all start with <code>$</code>. You
dont need to type in the <code>$</code> character; it indicates the start of each
command. Lines that dont start with <code>$</code> typically show the output of the
previous command. Additionally, PowerShell-specific examples will use <code>&gt;</code>
rather than <code>$</code>.</p>
</blockquote>
<h3 id="troubleshooting"><a class="header" href="#troubleshooting">Troubleshooting</a></h3>
<blockquote>
<p><em><strong>WIP</strong></em>: What are the most common culprits? Can we provide some general, basic solutions</p>
</blockquote>
<h3 id="local-documentation"><a class="header" href="#local-documentation">Local Documentation</a></h3>
<p>OrbTk offers the option to install its documentation locally, so you can read it
offline.</p>
<p>Any time a type, a function, a method or a crate is reference by the toolkit
and youre not sure what it does or how to use it, have a look at its application
programming interface <a href="https://docs.rs/orbtk">API documentation</a> to find out!</p>
<!-- [API documentation]: https://www.redox-os.org/orbtk/doc/en -->
<!-- [API documentation]: https://github.com/redox-os/orbtk -->
<h3 id="install-rust-on-linux-or-macos"><a class="header" href="#install-rust-on-linux-or-macos">Install Rust on Linux or macOS</a></h3>
<p>If you are using Linux or macOS open up an terminal and copy and paste the text below and hit the enter key on your keyboard:</p>
<pre><code class="language-bash">curl https://sh.rustup.rs -sSf | sh
</code></pre>
<h3 id="install-rust-on-windows"><a class="header" href="#install-rust-on-windows">Install Rust on Windows</a></h3>
<p>Download and run the Rust windows installer from https://www.rust-lang.org/tools/install.</p>
<h3 id="install-redoxer-redox-os"><a class="header" href="#install-redoxer-redox-os">Install Redoxer (Redox OS)</a></h3>
<p>If you want build and run your Rust application on a <a href="https://en.wikipedia.org/wiki/Kernel-based_Virtual_Machine">KVM</a> capable OS for Redox you can use <a href="https://gitlab.redox-os.org/redox-os/redoxer">redoxer</a>.</p>
<p>To install Redoxer you have to first install the rust toolchain. After that open up an terminal and copy and paste the text below and hit the enter key on your keyboard:</p>
<pre><code class="language-bash">cargo +nightly install redoxer
</code></pre>
<p>To compile and run your application on Redox OS you should check the Redox OS Book.</p>
<h3 id="editor-and-ide-integration"><a class="header" href="#editor-and-ide-integration">Editor and IDE integration</a></h3>
<p>A wide range of editors and IDEs are providing support for Rust code like</p>
<ul>
<li>like syntax-highlighting</li>
<li>auto-completion</li>
<li>linting</li>
<li>lsp support</li>
</ul>
<h4 id="vs-code"><a class="header" href="#vs-code">VS Code</a></h4>
<p>There is a big community that rely on the visualstudio implementation
to handle their code base. Following are the steps needed to expand
your installation to support <code>VS Code for Rust</code> development:</p>
<ol>
<li>Download VS Code <a href="https://code.visualstudio.com/download">from</a>.</li>
<li>Install <a href="https://marketplace.visualstudio.com/items?itemName=rust-lang.rust">Rust Language Server plugin</a> (the
Rust Language Server).</li>
</ol>
<h4 id="alternative-editors-and-ides"><a class="header" href="#alternative-editors-and-ides">Alternative Editors and IDEs</a></h4>
<p>If you perefer other solution, you will find in depth help inside the
context of this inclomplete links:</p>
<ul>
<li><a href="https://atom.io/packages/language-rust">Atom</a></li>
<li><a href="https://intellij-rust.github.io">Intellij IDEA</a></li>
<li><a href="https://github.com/rust-lang/rust.vim">Vim</a></li>
<li><a href="https://github.com/rust-lang/rust-mode">Emacs</a></li>
<li><a href="https://github.com/eclipse/corrosion">Eclipse</a></li>
</ul>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="ch01-02-element-call-hello.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ch09-00-element-call-examples.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="ch01-02-element-call-hello.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ch09-00-element-call-examples.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

View File

@@ -0,0 +1,256 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Element-Call Examples - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item expanded "><a href="ch09-00-element-call-examples.html" class="active"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/ch09-00-element-call-examples.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h1 id="element-call-example-applications"><a class="header" href="#element-call-example-applications">ELement-Call Example Applications</a></h1>
<p>This section provides <code>Element-Call</code> example apps. We hope to cover
interesting aspects of the API.</p>
<p>Take them as a tutorial, all listings are created as a reference. They
have in mind to serve as an introduction to a specific topic. As
educational content, this apps are marked with in-lined comments and
anchors. If we did well, you can concentrate on the parts we like
to emphasize.</p>
<p>Inside the library, you will find the collection of example code in
the subdirectory <em>examples</em> in crate <a href="https://github.com/element-hq/element-call/tree/develop/element-call/examples"><code>element-call</code></a>.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="ch02-00-installation.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ch09-01-element-call-hello.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="ch02-00-installation.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ch09-01-element-call-hello.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

View File

@@ -0,0 +1,252 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>ELement-Call-Hello! - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item expanded "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch09-01-element-call-hello.html" class="active"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/ch09-01-element-call-hello.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h1 id="hello-element-call"><a class="header" href="#hello-element-call">Hello Element-Call!</a></h1>
<p>We already introduced the source in <a href="https://gitea.networkx.de/element-call-book/src/listings/ch01-02-element-call-hello.html#pdate-cargotoml">Chapter 01</a>.
For the sake of completeness, and since its a habit to begin with … here we go.</p>
<!--
[example_hello-element-call]: https://element-hq.github.io/element-call/book/src/listings/ch01-02-element-call-hello.html#pdate-cargotoml
-->
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="ch09-00-element-call-examples.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="appendix-00.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="ch09-00-element-call-examples.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="appendix-00.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

7
book_en/html/clipboard.min.js vendored Normal file

File diff suppressed because one or more lines are too long

604
book_en/html/css/chrome.css Normal file
View File

@@ -0,0 +1,604 @@
/* CSS for UI elements (a.k.a. chrome) */
html {
scrollbar-color: var(--scrollbar) var(--bg);
}
#searchresults a,
.content a:link,
a:visited,
a > .hljs {
color: var(--links);
}
/*
body-container is necessary because mobile browsers don't seem to like
overflow-x on the body tag when there is a <meta name="viewport"> tag.
*/
#body-container {
/*
This is used when the sidebar pushes the body content off the side of
the screen on small screens. Without it, dragging on mobile Safari
will want to reposition the viewport in a weird way.
*/
overflow-x: clip;
}
/* Menu Bar */
#menu-bar,
#menu-bar-hover-placeholder {
z-index: 101;
margin: auto calc(0px - var(--page-padding));
}
#menu-bar {
position: relative;
display: flex;
flex-wrap: wrap;
background-color: var(--bg);
border-block-end-color: var(--bg);
border-block-end-width: 1px;
border-block-end-style: solid;
}
#menu-bar.sticky,
.js #menu-bar-hover-placeholder:hover + #menu-bar,
.js #menu-bar:hover,
.js.sidebar-visible #menu-bar {
position: -webkit-sticky;
position: sticky;
top: 0 !important;
}
#menu-bar-hover-placeholder {
position: sticky;
position: -webkit-sticky;
top: 0;
height: var(--menu-bar-height);
}
#menu-bar.bordered {
border-block-end-color: var(--table-border-color);
}
#menu-bar i, #menu-bar .icon-button {
position: relative;
padding: 0 8px;
z-index: 10;
line-height: var(--menu-bar-height);
cursor: pointer;
transition: color 0.5s;
}
@media only screen and (max-width: 420px) {
#menu-bar i, #menu-bar .icon-button {
padding: 0 5px;
}
}
.icon-button {
border: none;
background: none;
padding: 0;
color: inherit;
}
.icon-button i {
margin: 0;
}
.right-buttons {
margin: 0 15px;
}
.right-buttons a {
text-decoration: none;
}
.left-buttons {
display: flex;
margin: 0 5px;
}
.no-js .left-buttons button {
display: none;
}
.menu-title {
display: inline-block;
font-weight: 200;
font-size: 2.4rem;
line-height: var(--menu-bar-height);
text-align: center;
margin: 0;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.js .menu-title {
cursor: pointer;
}
.menu-bar,
.menu-bar:visited,
.nav-chapters,
.nav-chapters:visited,
.mobile-nav-chapters,
.mobile-nav-chapters:visited,
.menu-bar .icon-button,
.menu-bar a i {
color: var(--icons);
}
.menu-bar i:hover,
.menu-bar .icon-button:hover,
.nav-chapters:hover,
.mobile-nav-chapters i:hover {
color: var(--icons-hover);
}
/* Nav Icons */
.nav-chapters {
font-size: 2.5em;
text-align: center;
text-decoration: none;
position: fixed;
top: 0;
bottom: 0;
margin: 0;
max-width: 150px;
min-width: 90px;
display: flex;
justify-content: center;
align-content: center;
flex-direction: column;
transition: color 0.5s, background-color 0.5s;
}
.nav-chapters:hover {
text-decoration: none;
background-color: var(--theme-hover);
transition: background-color 0.15s, color 0.15s;
}
.nav-wrapper {
margin-block-start: 50px;
display: none;
}
.mobile-nav-chapters {
font-size: 2.5em;
text-align: center;
text-decoration: none;
width: 90px;
border-radius: 5px;
background-color: var(--sidebar-bg);
}
/* Only Firefox supports flow-relative values */
.previous { float: left; }
[dir=rtl] .previous { float: right; }
/* Only Firefox supports flow-relative values */
.next {
float: right;
right: var(--page-padding);
}
[dir=rtl] .next {
float: left;
right: unset;
left: var(--page-padding);
}
/* Use the correct buttons for RTL layouts*/
[dir=rtl] .previous i.fa-angle-left:before {content:"\f105";}
[dir=rtl] .next i.fa-angle-right:before { content:"\f104"; }
@media only screen and (max-width: 1080px) {
.nav-wide-wrapper { display: none; }
.nav-wrapper { display: block; }
}
/* sidebar-visible */
@media only screen and (max-width: 1380px) {
#sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wide-wrapper { display: none; }
#sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wrapper { display: block; }
}
/* Inline code */
:not(pre) > .hljs {
display: inline;
padding: 0.1em 0.3em;
border-radius: 3px;
}
:not(pre):not(a) > .hljs {
color: var(--inline-code-color);
overflow-x: initial;
}
a:hover > .hljs {
text-decoration: underline;
}
pre {
position: relative;
}
pre > .buttons {
position: absolute;
z-index: 100;
right: 0px;
top: 2px;
margin: 0px;
padding: 2px 0px;
color: var(--sidebar-fg);
cursor: pointer;
visibility: hidden;
opacity: 0;
transition: visibility 0.1s linear, opacity 0.1s linear;
}
pre:hover > .buttons {
visibility: visible;
opacity: 1
}
pre > .buttons :hover {
color: var(--sidebar-active);
border-color: var(--icons-hover);
background-color: var(--theme-hover);
}
pre > .buttons i {
margin-inline-start: 8px;
}
pre > .buttons button {
cursor: inherit;
margin: 0px 5px;
padding: 3px 5px;
font-size: 14px;
border-style: solid;
border-width: 1px;
border-radius: 4px;
border-color: var(--icons);
background-color: var(--theme-popup-bg);
transition: 100ms;
transition-property: color,border-color,background-color;
color: var(--icons);
}
@media (pointer: coarse) {
pre > .buttons button {
/* On mobile, make it easier to tap buttons. */
padding: 0.3rem 1rem;
}
.sidebar-resize-indicator {
/* Hide resize indicator on devices with limited accuracy */
display: none;
}
}
pre > code {
display: block;
padding: 1rem;
}
/* FIXME: ACE editors overlap their buttons because ACE does absolute
positioning within the code block which breaks padding. The only solution I
can think of is to move the padding to the outer pre tag (or insert a div
wrapper), but that would require fixing a whole bunch of CSS rules.
*/
.hljs.ace_editor {
padding: 0rem 0rem;
}
pre > .result {
margin-block-start: 10px;
}
/* Search */
#searchresults a {
text-decoration: none;
}
mark {
border-radius: 2px;
padding-block-start: 0;
padding-block-end: 1px;
padding-inline-start: 3px;
padding-inline-end: 3px;
margin-block-start: 0;
margin-block-end: -1px;
margin-inline-start: -3px;
margin-inline-end: -3px;
background-color: var(--search-mark-bg);
transition: background-color 300ms linear;
cursor: pointer;
}
mark.fade-out {
background-color: rgba(0,0,0,0) !important;
cursor: auto;
}
.searchbar-outer {
margin-inline-start: auto;
margin-inline-end: auto;
max-width: var(--content-max-width);
}
#searchbar {
width: 100%;
margin-block-start: 5px;
margin-block-end: 0;
margin-inline-start: auto;
margin-inline-end: auto;
padding: 10px 16px;
transition: box-shadow 300ms ease-in-out;
border: 1px solid var(--searchbar-border-color);
border-radius: 3px;
background-color: var(--searchbar-bg);
color: var(--searchbar-fg);
}
#searchbar:focus,
#searchbar.active {
box-shadow: 0 0 3px var(--searchbar-shadow-color);
}
.searchresults-header {
font-weight: bold;
font-size: 1em;
padding-block-start: 18px;
padding-block-end: 0;
padding-inline-start: 5px;
padding-inline-end: 0;
color: var(--searchresults-header-fg);
}
.searchresults-outer {
margin-inline-start: auto;
margin-inline-end: auto;
max-width: var(--content-max-width);
border-block-end: 1px dashed var(--searchresults-border-color);
}
ul#searchresults {
list-style: none;
padding-inline-start: 20px;
}
ul#searchresults li {
margin: 10px 0px;
padding: 2px;
border-radius: 2px;
}
ul#searchresults li.focus {
background-color: var(--searchresults-li-bg);
}
ul#searchresults span.teaser {
display: block;
clear: both;
margin-block-start: 5px;
margin-block-end: 0;
margin-inline-start: 20px;
margin-inline-end: 0;
font-size: 0.8em;
}
ul#searchresults span.teaser em {
font-weight: bold;
font-style: normal;
}
/* Sidebar */
.sidebar {
position: fixed;
left: 0;
top: 0;
bottom: 0;
width: var(--sidebar-width);
font-size: 0.875em;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
overscroll-behavior-y: contain;
background-color: var(--sidebar-bg);
color: var(--sidebar-fg);
}
[dir=rtl] .sidebar { left: unset; right: 0; }
.sidebar-resizing {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
.no-js .sidebar,
.js:not(.sidebar-resizing) .sidebar {
transition: transform 0.3s; /* Animation: slide away */
}
.sidebar code {
line-height: 2em;
}
.sidebar .sidebar-scrollbox {
overflow-y: auto;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
padding: 10px 10px;
}
.sidebar .sidebar-resize-handle {
position: absolute;
cursor: col-resize;
width: 0;
right: calc(var(--sidebar-resize-indicator-width) * -1);
top: 0;
bottom: 0;
display: flex;
align-items: center;
}
.sidebar-resize-handle .sidebar-resize-indicator {
width: 100%;
height: 12px;
background-color: var(--icons);
margin-inline-start: var(--sidebar-resize-indicator-space);
}
[dir=rtl] .sidebar .sidebar-resize-handle {
left: calc(var(--sidebar-resize-indicator-width) * -1);
right: unset;
}
.js .sidebar .sidebar-resize-handle {
cursor: col-resize;
width: calc(var(--sidebar-resize-indicator-width) - var(--sidebar-resize-indicator-space));
}
/* sidebar-hidden */
#sidebar-toggle-anchor:not(:checked) ~ .sidebar {
transform: translateX(calc(0px - var(--sidebar-width) - var(--sidebar-resize-indicator-width)));
z-index: -1;
}
[dir=rtl] #sidebar-toggle-anchor:not(:checked) ~ .sidebar {
transform: translateX(calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width)));
}
.sidebar::-webkit-scrollbar {
background: var(--sidebar-bg);
}
.sidebar::-webkit-scrollbar-thumb {
background: var(--scrollbar);
}
/* sidebar-visible */
#sidebar-toggle-anchor:checked ~ .page-wrapper {
transform: translateX(calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width)));
}
[dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper {
transform: translateX(calc(0px - var(--sidebar-width) - var(--sidebar-resize-indicator-width)));
}
@media only screen and (min-width: 620px) {
#sidebar-toggle-anchor:checked ~ .page-wrapper {
transform: none;
margin-inline-start: calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width));
}
[dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper {
transform: none;
}
}
.chapter {
list-style: none outside none;
padding-inline-start: 0;
line-height: 2.2em;
}
.chapter ol {
width: 100%;
}
.chapter li {
display: flex;
color: var(--sidebar-non-existant);
}
.chapter li a {
display: block;
padding: 0;
text-decoration: none;
color: var(--sidebar-fg);
}
.chapter li a:hover {
color: var(--sidebar-active);
}
.chapter li a.active {
color: var(--sidebar-active);
}
.chapter li > a.toggle {
cursor: pointer;
display: block;
margin-inline-start: auto;
padding: 0 10px;
user-select: none;
opacity: 0.68;
}
.chapter li > a.toggle div {
transition: transform 0.5s;
}
/* collapse the section */
.chapter li:not(.expanded) + li > ol {
display: none;
}
.chapter li.chapter-item {
line-height: 1.5em;
margin-block-start: 0.6em;
}
.chapter li.expanded > a.toggle div {
transform: rotate(90deg);
}
.spacer {
width: 100%;
height: 3px;
margin: 5px 0px;
}
.chapter .spacer {
background-color: var(--sidebar-spacer);
}
@media (-moz-touch-enabled: 1), (pointer: coarse) {
.chapter li a { padding: 5px 0; }
.spacer { margin: 10px 0; }
}
.section {
list-style: none outside none;
padding-inline-start: 20px;
line-height: 1.9em;
}
/* Theme Menu Popup */
.theme-popup {
position: absolute;
left: 10px;
top: var(--menu-bar-height);
z-index: 1000;
border-radius: 4px;
font-size: 0.7em;
color: var(--fg);
background: var(--theme-popup-bg);
border: 1px solid var(--theme-popup-border);
margin: 0;
padding: 0;
list-style: none;
display: none;
/* Don't let the children's background extend past the rounded corners. */
overflow: hidden;
}
[dir=rtl] .theme-popup { left: unset; right: 10px; }
.theme-popup .default {
color: var(--icons);
}
.theme-popup .theme {
width: 100%;
border: 0;
margin: 0;
padding: 2px 20px;
line-height: 25px;
white-space: nowrap;
text-align: start;
cursor: pointer;
color: inherit;
background: inherit;
font-size: inherit;
}
.theme-popup .theme:hover {
background-color: var(--theme-hover);
}
.theme-selected::before {
display: inline-block;
content: "✓";
margin-inline-start: -14px;
width: 14px;
}

View File

@@ -0,0 +1,232 @@
/* Base styles and content styles */
:root {
/* Browser default font-size is 16px, this way 1 rem = 10px */
font-size: 62.5%;
color-scheme: var(--color-scheme);
}
html {
font-family: "Open Sans", sans-serif;
color: var(--fg);
background-color: var(--bg);
text-size-adjust: none;
-webkit-text-size-adjust: none;
}
body {
margin: 0;
font-size: 1.6rem;
overflow-x: hidden;
}
code {
font-family: var(--mono-font) !important;
font-size: var(--code-font-size);
direction: ltr !important;
}
/* make long words/inline code not x overflow */
main {
overflow-wrap: break-word;
}
/* make wide tables scroll if they overflow */
.table-wrapper {
overflow-x: auto;
}
/* Don't change font size in headers. */
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
font-size: unset;
}
.left { float: left; }
.right { float: right; }
.boring { opacity: 0.6; }
.hide-boring .boring { display: none; }
.hidden { display: none !important; }
h2, h3 { margin-block-start: 2.5em; }
h4, h5 { margin-block-start: 2em; }
.header + .header h3,
.header + .header h4,
.header + .header h5 {
margin-block-start: 1em;
}
h1:target::before,
h2:target::before,
h3:target::before,
h4:target::before,
h5:target::before,
h6:target::before {
display: inline-block;
content: "»";
margin-inline-start: -30px;
width: 30px;
}
/* This is broken on Safari as of version 14, but is fixed
in Safari Technology Preview 117 which I think will be Safari 14.2.
https://bugs.webkit.org/show_bug.cgi?id=218076
*/
:target {
/* Safari does not support logical properties */
scroll-margin-top: calc(var(--menu-bar-height) + 0.5em);
}
.page {
outline: 0;
padding: 0 var(--page-padding);
margin-block-start: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */
}
.page-wrapper {
box-sizing: border-box;
background-color: var(--bg);
}
.no-js .page-wrapper,
.js:not(.sidebar-resizing) .page-wrapper {
transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */
}
[dir=rtl] .js:not(.sidebar-resizing) .page-wrapper {
transition: margin-right 0.3s ease, transform 0.3s ease; /* Animation: slide away */
}
.content {
overflow-y: auto;
padding: 0 5px 50px 5px;
}
.content main {
margin-inline-start: auto;
margin-inline-end: auto;
max-width: var(--content-max-width);
}
.content p { line-height: 1.45em; }
.content ol { line-height: 1.45em; }
.content ul { line-height: 1.45em; }
.content a { text-decoration: none; }
.content a:hover { text-decoration: underline; }
.content img, .content video { max-width: 100%; }
.content .header:link,
.content .header:visited {
color: var(--fg);
}
.content .header:link,
.content .header:visited:hover {
text-decoration: none;
}
table {
margin: 0 auto;
border-collapse: collapse;
}
table td {
padding: 3px 20px;
border: 1px var(--table-border-color) solid;
}
table thead {
background: var(--table-header-bg);
}
table thead td {
font-weight: 700;
border: none;
}
table thead th {
padding: 3px 20px;
}
table thead tr {
border: 1px var(--table-header-bg) solid;
}
/* Alternate background colors for rows */
table tbody tr:nth-child(2n) {
background: var(--table-alternate-bg);
}
blockquote {
margin: 20px 0;
padding: 0 20px;
color: var(--fg);
background-color: var(--quote-bg);
border-block-start: .1em solid var(--quote-border);
border-block-end: .1em solid var(--quote-border);
}
.warning {
margin: 20px;
padding: 0 20px;
border-inline-start: 2px solid var(--warning-border);
}
.warning:before {
position: absolute;
width: 3rem;
height: 3rem;
margin-inline-start: calc(-1.5rem - 21px);
content: "ⓘ";
text-align: center;
background-color: var(--bg);
color: var(--warning-border);
font-weight: bold;
font-size: 2rem;
}
blockquote .warning:before {
background-color: var(--quote-bg);
}
kbd {
background-color: var(--table-border-color);
border-radius: 4px;
border: solid 1px var(--theme-popup-border);
box-shadow: inset 0 -1px 0 var(--theme-hover);
display: inline-block;
font-size: var(--code-font-size);
font-family: var(--mono-font);
line-height: 10px;
padding: 4px 5px;
vertical-align: middle;
}
:not(.footnote-definition) + .footnote-definition,
.footnote-definition + :not(.footnote-definition) {
margin-block-start: 2em;
}
.footnote-definition {
font-size: 0.9em;
margin: 0.5em 0;
}
.footnote-definition p {
display: inline;
}
.tooltiptext {
position: absolute;
visibility: hidden;
color: #fff;
background-color: #333;
transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */
left: -8px; /* Half of the width of the icon */
top: -35px;
font-size: 0.8em;
text-align: center;
border-radius: 6px;
padding: 5px 8px;
margin: 5px;
z-index: 1000;
}
.tooltipped .tooltiptext {
visibility: visible;
}
.chapter li.part-title {
color: var(--sidebar-fg);
margin: 5px 0px;
font-weight: bold;
}
.result-no-output {
font-style: italic;
}

View File

@@ -0,0 +1,50 @@
#sidebar,
#menu-bar,
.nav-chapters,
.mobile-nav-chapters {
display: none;
}
#page-wrapper.page-wrapper {
transform: none !important;
margin-inline-start: 0px;
overflow-y: initial;
}
#content {
max-width: none;
margin: 0;
padding: 0;
}
.page {
overflow-y: initial;
}
code {
direction: ltr !important;
}
pre > .buttons {
z-index: 2;
}
a, a:visited, a:active, a:hover {
color: #4183c4;
text-decoration: none;
}
h1, h2, h3, h4, h5, h6 {
page-break-inside: avoid;
page-break-after: avoid;
}
pre, code {
page-break-inside: avoid;
white-space: pre-wrap;
}
.fa {
display: none !important;
}

View File

@@ -0,0 +1,279 @@
/* Globals */
:root {
--sidebar-width: 300px;
--sidebar-resize-indicator-width: 8px;
--sidebar-resize-indicator-space: 2px;
--page-padding: 15px;
--content-max-width: 750px;
--menu-bar-height: 50px;
--mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace;
--code-font-size: 0.875em /* please adjust the ace font size accordingly in editor.js */
}
/* Themes */
.ayu {
--bg: hsl(210, 25%, 8%);
--fg: #c5c5c5;
--sidebar-bg: #14191f;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #5c6773;
--sidebar-active: #ffb454;
--sidebar-spacer: #2d334f;
--scrollbar: var(--sidebar-fg);
--icons: #737480;
--icons-hover: #b7b9cc;
--links: #0096cf;
--inline-code-color: #ffb454;
--theme-popup-bg: #14191f;
--theme-popup-border: #5c6773;
--theme-hover: #191f26;
--quote-bg: hsl(226, 15%, 17%);
--quote-border: hsl(226, 15%, 22%);
--warning-border: #ff8e00;
--table-border-color: hsl(210, 25%, 13%);
--table-header-bg: hsl(210, 25%, 28%);
--table-alternate-bg: hsl(210, 25%, 11%);
--searchbar-border-color: #848484;
--searchbar-bg: #424242;
--searchbar-fg: #fff;
--searchbar-shadow-color: #d4c89f;
--searchresults-header-fg: #666;
--searchresults-border-color: #888;
--searchresults-li-bg: #252932;
--search-mark-bg: #e3b171;
--color-scheme: dark;
}
.coal {
--bg: hsl(200, 7%, 8%);
--fg: #98a3ad;
--sidebar-bg: #292c2f;
--sidebar-fg: #a1adb8;
--sidebar-non-existant: #505254;
--sidebar-active: #3473ad;
--sidebar-spacer: #393939;
--scrollbar: var(--sidebar-fg);
--icons: #43484d;
--icons-hover: #b3c0cc;
--links: #2b79a2;
--inline-code-color: #c5c8c6;
--theme-popup-bg: #141617;
--theme-popup-border: #43484d;
--theme-hover: #1f2124;
--quote-bg: hsl(234, 21%, 18%);
--quote-border: hsl(234, 21%, 23%);
--warning-border: #ff8e00;
--table-border-color: hsl(200, 7%, 13%);
--table-header-bg: hsl(200, 7%, 28%);
--table-alternate-bg: hsl(200, 7%, 11%);
--searchbar-border-color: #aaa;
--searchbar-bg: #b7b7b7;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #666;
--searchresults-border-color: #98a3ad;
--searchresults-li-bg: #2b2b2f;
--search-mark-bg: #355c7d;
--color-scheme: dark;
}
.light {
--bg: hsl(0, 0%, 100%);
--fg: hsl(0, 0%, 0%);
--sidebar-bg: #fafafa;
--sidebar-fg: hsl(0, 0%, 0%);
--sidebar-non-existant: #aaaaaa;
--sidebar-active: #1f1fff;
--sidebar-spacer: #f4f4f4;
--scrollbar: #8F8F8F;
--icons: #747474;
--icons-hover: #000000;
--links: #20609f;
--inline-code-color: #301900;
--theme-popup-bg: #fafafa;
--theme-popup-border: #cccccc;
--theme-hover: #e6e6e6;
--quote-bg: hsl(197, 37%, 96%);
--quote-border: hsl(197, 37%, 91%);
--warning-border: #ff8e00;
--table-border-color: hsl(0, 0%, 95%);
--table-header-bg: hsl(0, 0%, 80%);
--table-alternate-bg: hsl(0, 0%, 97%);
--searchbar-border-color: #aaa;
--searchbar-bg: #fafafa;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #666;
--searchresults-border-color: #888;
--searchresults-li-bg: #e4f2fe;
--search-mark-bg: #a2cff5;
--color-scheme: light;
}
.navy {
--bg: hsl(226, 23%, 11%);
--fg: #bcbdd0;
--sidebar-bg: #282d3f;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #505274;
--sidebar-active: #2b79a2;
--sidebar-spacer: #2d334f;
--scrollbar: var(--sidebar-fg);
--icons: #737480;
--icons-hover: #b7b9cc;
--links: #2b79a2;
--inline-code-color: #c5c8c6;
--theme-popup-bg: #161923;
--theme-popup-border: #737480;
--theme-hover: #282e40;
--quote-bg: hsl(226, 15%, 17%);
--quote-border: hsl(226, 15%, 22%);
--warning-border: #ff8e00;
--table-border-color: hsl(226, 23%, 16%);
--table-header-bg: hsl(226, 23%, 31%);
--table-alternate-bg: hsl(226, 23%, 14%);
--searchbar-border-color: #aaa;
--searchbar-bg: #aeaec6;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #5f5f71;
--searchresults-border-color: #5c5c68;
--searchresults-li-bg: #242430;
--search-mark-bg: #a2cff5;
--color-scheme: dark;
}
.rust {
--bg: hsl(60, 9%, 87%);
--fg: #262625;
--sidebar-bg: #3b2e2a;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #505254;
--sidebar-active: #e69f67;
--sidebar-spacer: #45373a;
--scrollbar: var(--sidebar-fg);
--icons: #737480;
--icons-hover: #262625;
--links: #2b79a2;
--inline-code-color: #6e6b5e;
--theme-popup-bg: #e1e1db;
--theme-popup-border: #b38f6b;
--theme-hover: #99908a;
--quote-bg: hsl(60, 5%, 75%);
--quote-border: hsl(60, 5%, 70%);
--warning-border: #ff8e00;
--table-border-color: hsl(60, 9%, 82%);
--table-header-bg: #b3a497;
--table-alternate-bg: hsl(60, 9%, 84%);
--searchbar-border-color: #aaa;
--searchbar-bg: #fafafa;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #666;
--searchresults-border-color: #888;
--searchresults-li-bg: #dec2a2;
--search-mark-bg: #e69f67;
--color-scheme: light;
}
@media (prefers-color-scheme: dark) {
.light.no-js {
--bg: hsl(200, 7%, 8%);
--fg: #98a3ad;
--sidebar-bg: #292c2f;
--sidebar-fg: #a1adb8;
--sidebar-non-existant: #505254;
--sidebar-active: #3473ad;
--sidebar-spacer: #393939;
--scrollbar: var(--sidebar-fg);
--icons: #43484d;
--icons-hover: #b3c0cc;
--links: #2b79a2;
--inline-code-color: #c5c8c6;
--theme-popup-bg: #141617;
--theme-popup-border: #43484d;
--theme-hover: #1f2124;
--quote-bg: hsl(234, 21%, 18%);
--quote-border: hsl(234, 21%, 23%);
--warning-border: #ff8e00;
--table-border-color: hsl(200, 7%, 13%);
--table-header-bg: hsl(200, 7%, 28%);
--table-alternate-bg: hsl(200, 7%, 11%);
--searchbar-border-color: #aaa;
--searchbar-bg: #b7b7b7;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #666;
--searchresults-border-color: #98a3ad;
--searchresults-li-bg: #2b2b2f;
--search-mark-bg: #355c7d;
}
}

29
book_en/html/editor.js Normal file
View File

@@ -0,0 +1,29 @@
"use strict";
window.editors = [];
(function(editors) {
if (typeof(ace) === 'undefined' || !ace) {
return;
}
Array.from(document.querySelectorAll('.editable')).forEach(function(editable) {
let display_line_numbers = window.playground_line_numbers || false;
let editor = ace.edit(editable);
editor.setOptions({
highlightActiveLine: false,
showPrintMargin: false,
showLineNumbers: display_line_numbers,
showGutter: display_line_numbers,
maxLines: Infinity,
fontSize: "0.875em" // please adjust the font size of the code in general.css
});
editor.$blockScrolling = Infinity;
editor.getSession().setMode("ace/mode/rust");
editor.originalCode = editor.getValue();
editors.push(editor);
});
})(window.editors);

10
book_en/html/elasticlunr.min.js vendored Normal file

File diff suppressed because one or more lines are too long

BIN
book_en/html/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

22
book_en/html/favicon.svg Normal file
View File

@@ -0,0 +1,22 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 199.7 184.2">
<style>
@media (prefers-color-scheme: dark) {
svg { fill: white; }
}
</style>
<path d="M189.5,36.8c0.2,2.8,0,5.1-0.6,6.8L153,162c-0.6,2.1-2,3.7-4.2,5c-2.2,1.2-4.4,1.9-6.7,1.9H31.4c-9.6,0-15.3-2.8-17.3-8.4
c-0.8-2.2-0.8-3.9,0.1-5.2c0.9-1.2,2.4-1.8,4.6-1.8H123c7.4,0,12.6-1.4,15.4-4.1s5.7-8.9,8.6-18.4l32.9-108.6
c1.8-5.9,1-11.1-2.2-15.6S169.9,0,164,0H72.7c-1,0-3.1,0.4-6.1,1.1l0.1-0.4C64.5,0.2,62.6,0,61,0.1s-3,0.5-4.3,1.4
c-1.3,0.9-2.4,1.8-3.2,2.8S52,6.5,51.2,8.1c-0.8,1.6-1.4,3-1.9,4.3s-1.1,2.7-1.8,4.2c-0.7,1.5-1.3,2.7-2,3.7c-0.5,0.6-1.2,1.5-2,2.5
s-1.6,2-2.2,2.8s-0.9,1.5-1.1,2.2c-0.2,0.7-0.1,1.8,0.2,3.2c0.3,1.4,0.4,2.4,0.4,3.1c-0.3,3-1.4,6.9-3.3,11.6
c-1.9,4.7-3.6,8.1-5.1,10.1c-0.3,0.4-1.2,1.3-2.6,2.7c-1.4,1.4-2.3,2.6-2.6,3.7c-0.3,0.4-0.3,1.5-0.1,3.4c0.3,1.8,0.4,3.1,0.3,3.8
c-0.3,2.7-1.3,6.3-3,10.8c-1.7,4.5-3.4,8.2-5,11c-0.2,0.5-0.9,1.4-2,2.8c-1.1,1.4-1.8,2.5-2,3.4c-0.2,0.6-0.1,1.8,0.1,3.4
c0.2,1.6,0.2,2.8-0.1,3.6c-0.6,3-1.8,6.7-3.6,11c-1.8,4.3-3.6,7.9-5.4,11c-0.5,0.8-1.1,1.7-2,2.8c-0.8,1.1-1.5,2-2,2.8
s-0.8,1.6-1,2.5c-0.1,0.5,0,1.3,0.4,2.3c0.3,1.1,0.4,1.9,0.4,2.6c-0.1,1.1-0.2,2.6-0.5,4.4c-0.2,1.8-0.4,2.9-0.4,3.2
c-1.8,4.8-1.7,9.9,0.2,15.2c2.2,6.2,6.2,11.5,11.9,15.8c5.7,4.3,11.7,6.4,17.8,6.4h110.7c5.2,0,10.1-1.7,14.7-5.2s7.7-7.8,9.2-12.9
l33-108.6c1.8-5.8,1-10.9-2.2-15.5C194.9,39.7,192.6,38,189.5,36.8z M59.6,122.8L73.8,80c0,0,7,0,10.8,0s28.8-1.7,25.4,17.5
c-3.4,19.2-18.8,25.2-36.8,25.4S59.6,122.8,59.6,122.8z M78.6,116.8c4.7-0.1,18.9-2.9,22.1-17.1S89.2,86.3,89.2,86.3l-8.9,0
l-10.2,30.5C70.2,116.9,74,116.9,78.6,116.8z M75.3,68.7L89,26.2h9.8l0.8,34l23.6-34h9.9l-13.6,42.5h-7.1l12.5-35.4l-24.5,35.4h-6.8
l-0.8-35L82,68.7H75.3z"/>
</svg>
<!-- Original image Copyright Dave Gandy — CC BY 4.0 License -->

After

Width:  |  Height:  |  Size: 1.8 KiB

33
book_en/html/ferries.css Normal file
View File

@@ -0,0 +1,33 @@
body.light .does_not_compile,
body.light .panics,
body.light .not_desired_behavior,
body.rust .does_not_compile,
body.rust .panics,
body.rust .not_desired_behavior {
background: #fff1f1;
}
body.coal .does_not_compile,
body.coal .panics,
body.coal .not_desired_behavior,
body.navy .does_not_compile,
body.navy .panics,
body.navy .not_desired_behavior,
body.ayu .does_not_compile,
body.ayu .panics,
body.ayu .not_desired_behavior {
background: #501f21;
}
.ferris {
position: absolute;
z-index: 99;
right: 5px;
top: 30px;
width: 10%;
height: auto;
}
.ferris-explain {
width: 100px;
}

51
book_en/html/ferries.js Normal file
View File

@@ -0,0 +1,51 @@
var ferrisTypes = [
{
attr: 'does_not_compile',
title: 'This code does not compile!'
},
{
attr: 'panics',
title: 'This code panics!'
},
{
attr: 'unsafe',
title: 'This code block contains unsafe code.'
},
{
attr: 'not_desired_behavior',
title: 'This code does not produce the desired behavior.'
}
]
document.addEventListener('DOMContentLoaded', () => {
for (var ferrisType of ferrisTypes) {
attachFerrises(ferrisType)
}
})
function attachFerrises (type) {
var elements = document.getElementsByClassName(type.attr)
for (var codeBlock of elements) {
var lines = codeBlock.textContent.split(/\r|\r\n|\n/).length - 1;
if (lines >= 4) {
attachFerris(codeBlock, type)
}
}
}
function attachFerris (element, type) {
var a = document.createElement('a')
a.setAttribute('href', 'ch00-00-introduction.html#ferris')
a.setAttribute('target', '_blank')
var img = document.createElement('img')
img.setAttribute('src', 'img/ferris/' + type.attr + '.svg')
img.setAttribute('title', type.title)
img.className = 'ferris'
a.appendChild(img)
element.parentElement.insertBefore(a, element)
}

View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,93 @@
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View File

@@ -0,0 +1,100 @@
/* Open Sans is licensed under the Apache License, Version 2.0. See http://www.apache.org/licenses/LICENSE-2.0 */
/* Source Code Pro is under the Open Font License. See https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL */
/* open-sans-300 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 300;
src: local('Open Sans Light'), local('OpenSans-Light'),
url('open-sans-v17-all-charsets-300.woff2') format('woff2');
}
/* open-sans-300italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 300;
src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'),
url('open-sans-v17-all-charsets-300italic.woff2') format('woff2');
}
/* open-sans-regular - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: local('Open Sans Regular'), local('OpenSans-Regular'),
url('open-sans-v17-all-charsets-regular.woff2') format('woff2');
}
/* open-sans-italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 400;
src: local('Open Sans Italic'), local('OpenSans-Italic'),
url('open-sans-v17-all-charsets-italic.woff2') format('woff2');
}
/* open-sans-600 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 600;
src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'),
url('open-sans-v17-all-charsets-600.woff2') format('woff2');
}
/* open-sans-600italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 600;
src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'),
url('open-sans-v17-all-charsets-600italic.woff2') format('woff2');
}
/* open-sans-700 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 700;
src: local('Open Sans Bold'), local('OpenSans-Bold'),
url('open-sans-v17-all-charsets-700.woff2') format('woff2');
}
/* open-sans-700italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 700;
src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'),
url('open-sans-v17-all-charsets-700italic.woff2') format('woff2');
}
/* open-sans-800 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 800;
src: local('Open Sans ExtraBold'), local('OpenSans-ExtraBold'),
url('open-sans-v17-all-charsets-800.woff2') format('woff2');
}
/* open-sans-800italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 800;
src: local('Open Sans ExtraBold Italic'), local('OpenSans-ExtraBoldItalic'),
url('open-sans-v17-all-charsets-800italic.woff2') format('woff2');
}
/* source-code-pro-500 - latin_vietnamese_latin-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Source Code Pro';
font-style: normal;
font-weight: 500;
src: url('source-code-pro-v11-all-charsets-500.woff2') format('woff2');
}

289
book_en/html/foreword.html Normal file
View File

@@ -0,0 +1,289 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Foreword - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html" class="active">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/foreword.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h1 id="foreword"><a class="header" href="#foreword">Foreword</a></h1>
<p>The history of computer-aided communication, which supports not only
text video and sound goes back to the 1990s. From from todays
perspective, it seems almost grotesque what prices had to be paid for
the had to be paid for the hardware developed at that time. Not only
for the quality and quality of encoded data streams, new formats had
to be invented (CIF (CIF, QCIF). The development of Codex was in its
infancy. infancy. There was a lack of
standardization. Interoperability and and the use of the Internet were
at best distant goals. People were working on very
application-specific solutions and approaches that had the potential
for affordable components for mass production. As an example, the
pioneering manufacturer <a href="https://en.wikipedia.org/wiki/Parallax_Graphics"><code>Parallax Graphics Inc.</code></a>. Founded in 1982 by two graduates of Cornell
University, the company focused on the marketing of the marketing of
<code>high end</code> graphics cards, including for the then popular university
environment at the time. These cards initially cost around €25,000
and supplied ASICS and a codex implemented in implemented in hardware,
which could realize resolutions of up to 1280x1024 pixels could be
realized.</p>
<p>Every commercially available cell phone, tablet, notebook and desktop
PCs currently deliver graphics card performance that can render 2k,
even 4k pixels can render. Encoding and decoding solutions are
decoding solutions have been standardized internationally, which have
significantly reduced the bandwidths to be transmitted and thus and
thus enable billions of uses on the Internet use on the
Internet. One-to-one video telephony has been established for years.
established for years. And everyone will remember the radical upheaval
in the professional use of video conferencing solutions that the COVID
pandemic brought with it in 2022.</p>
<p>Today, the use of video conferencing solutions is ubiquitous. In the
working world, proprietary solutions are often used, to implement work
processes regardless of location. Examples include the products from
the manufacturers <a href="https://en.wikipedia.org/wiki/Cisco"><code>CISCO-&gt;(Webex)</code></a>,
<a href="https://de.wikipedia.org/wiki/Microsoft_Teams"><code>Microsoft-&gt;(Skype,Teams)</code></a>, <a href="https://www.hp.com/de-de/poly.html"><code>HP-&gt;(Poly)</code></a>
and <a href="https://en.wikipedia.org/wiki/Zoom_(software)"><code>Zoom-&gt;(Zoom)</code></a> are listed. But also free software such as
<a href="https://bigbluebutton.org/"><code>BigBlueButton</code></a>, <a href="https://jitsi.org/"><code>Jitsi</code></a> or
<a href="https://nextcloud-talk.readthedocs.io/en/latest/"><code>Nextcloud-&gt;(Talk)</code></a> are enjoying worldwide distribution.</p>
<p>With <code>Element-Call</code> the Matrix ecosystems gains a new approach that
fully embraces the potential of MatrixRTC. Think of participents in
decentralized domains that are to able to dynamicly create and manage
multipoint meetings in an efficiant manner. An Open-Source, that
enables fee choice of any Matrix complient Client. What progress.</p>
<p>— Ralf Zerres</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="title-page.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ch00-00-introduction.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="title-page.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ch00-00-introduction.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Redirecting...</title>
<meta http-equiv="refresh" content="0; URL=configuration/index.html">
<link rel="canonical" href="configuration/index.html">
</head>
<body>
<p>Redirecting to... <a href="configuration/index.html">configuration/index.html</a>.</p>
</body>
</html>

View File

@@ -0,0 +1,82 @@
/*
* An increased contrast highlighting scheme loosely based on the
* "Base16 Atelier Dune Light" theme by Bram de Haan
* (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune)
* Original Base16 color scheme by Chris Kempson
* (https://github.com/chriskempson/base16)
*/
/* Comment */
.hljs-comment,
.hljs-quote {
color: #575757;
}
/* Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #d70025;
}
/* Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #b21e00;
}
/* Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #008200;
}
/* Blue */
.hljs-title,
.hljs-section {
color: #0030f2;
}
/* Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #9d00ec;
}
.hljs {
display: block;
overflow-x: auto;
background: #f6f7f6;
color: #000;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-addition {
color: #22863a;
background-color: #f0fff4;
}
.hljs-deletion {
color: #b31d28;
background-color: #ffeef0;
}

54
book_en/html/highlight.js Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 KiB

269
book_en/html/index.html Normal file
View File

@@ -0,0 +1,269 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>The Element-Call book - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html" class="active">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/title-page.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h1 id="element-call"><a class="header" href="#element-call">Element Call</a></h1>
<p><em>annotated and documented by Ralf Zerres and all contributers</em></p>
<p>This version of the text assumes youre using Element-Call v0.6.7 or later in
conjuction with Rust v1.83.0 or later. <em>Cargo.toml</em> should define
<code>edition="2021"</code>. That enables and uses Rust 2021 Edition idioms in
all derived projects.</p>
<p>See the <a href="https://https://gitea.networkx.de/rzerres/element-call/book/ch02-00-installation.html">“Installation” section of Chapter 2</a>
to install or update Element-Call.</p>
<p>The 2021 Edition of this book is the initial release. It will be
released with the Element-Call version 1.0.0.</p>
<ul>
<li>Appendix A “Keywords”, explains the new raw identifiers.</li>
<li>Appendix D “Translations”, is work in progress. We will release
instances of this book in the target language once they are translated.</li>
</ul>
<p>For online reading, a HTML rendered version is available at
<a href="https://gitea.networkx.de/rzerres/element-call/book/blob/main/src/img/element-call.png">Element-Call book</a>. Alternatively you might want to have it handy
for offline usage. Either you downlaod a rendered <code>pdf</code> or
<code>ebook</code>version or go ahead and download the source. Then kick on
mdbook (the definition of the target location is optional).</p>
<pre><code class="language-console">mdbook build --dest-dir book_en --open
</code></pre>
<!---
This text is available in [paperback and ebook format from No Starch Press][nsprust].
-->
<!--
[element-call_book_en]: https://gitea.networkx.de/rzerres/element-call/book/
[element-call_book_en_stable]: https://element.io/element-call/stable/book/
-->
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="next prefetch" href="foreword.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="next prefetch" href="foreword.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

222
book_en/html/lib.rs Normal file
View File

@@ -0,0 +1,222 @@
#![crate_name = "element_call_book"]
#![crate_type = "lib"]
//! ![Welcome to the element-call book.][element_call_book]
//!
//! This repository contains the text source for "The Element-Call" book.
//! We will further reference to it as the `Element-Call Book`.
//!
//! [element_call_book]: https://gitea.networkx.de/rzerres/element-call-book/src/branch/main/src/img/element-call-webui.png
//! <!--
//! WIP: once it is ready to be shipped
//! [The book is available in dead-tree form from No Starch Press][nostarch].
//!
//! [nostarch]: https://nostarch.com/
//!
//! You can read the book for free online. Please see the book as shipped with
//! the latest [stable], or [develop] ELement-Call releases. Be aware that issues
//! in those versions may have been fixed in this repository already, as those
//! releases are updated less frequently.
//!
//! [stable]: https://element.io/element-call/stable/book/
//! [develop]: https://ekenebt.io/element-call/book/
//!
//! See the [releases] to download just the code of all the code listings that appear in the book.
//!
//! [releases]: https://element.io/element-call/book/releases
//! -->
//!
//! ### Requirements
//!
//! #### mdBook
//! Building the book requires [mdBook] and its helper tools. The used
//! version should be ideally the same that rust-lang/rust uses in
//! [this file][rust-mdbook]. Install this tools with:
//!
//! ```console
//! $ cargo install mdbook mdbook-linkchecker mdbook-mermaid
//! ```
//!
//! This command will grep the latest mdbook version from [crates.io] in
//! combination with the add-on tools mdbook-linkchecker and
//! mdbook-mermaid. With the linkchecker we are able to asure, that
//! the used links inside the markdown source can resolve to valid
//! targets. mkbook-mermaid is a preprocessor for mdbook to add
//! mermaid.js support. We do use it to create graphs that visiulize
//! some process flows.
//!
//! [crates.io]: https://crates.io/crates/cargo-readme
//!
//! If you need a given version of `mdbook`, you may force it's
//! installation the following call:
//!
//! ```rust
//! console $ cargo install mdbook --vers 0.4.40 mdbook-linkchecker mdbook-mermaid
//! ```
//!
//! #### Multilingual version of mdBook
//!
//! The `Element-Call` book aims to make translations as flawless as
//! possible. With [`mdbook-i18n-helpers`][mdbook_i18n_helpers] you gain
//! `Gettext Translation Support` with three extensions.
//!
//! ```console
//! $ cargo install mdbook-i18n-helpers
//! ```
//!
//! It will install three binaries:
//!
//! * mdbook-xgettext: This program extracts the source text. It is an mdbook renderer.
//! * mdbook-gettext: This program translates the book into a target language.
//! It is an mdbook preprocessor.
//! * mdbook-i18n-normalize: This program normalizs a PO file. Use it after breaking changes.
//!
//! Please have a look to the online documentation on howto actually use the Gettext subsystem.
//!
//! [mdbook_i18n_helpers]: https://github.com/google/mdbook-i18n-helpers?tab=readme-ov-file
//! [mdbook_i18n_helpers_usage]: https://github.com/google/mdbook-i18n-helpers/blob/main/i18n-helpers/USAGE.md
//!
//! #### Cargo handled README
//!
//! We do make uses of the crate [cargo-readme]. It resolves rust `doc
//! comments` to generate the README.md file you are reading now. Install the create
//! with the following command if you want to update or regenerate this README yourself.
//!
//! [cargo-readme]: https://github.com/livioribeiro/cargo-readme
//!
//! ```console
//! $ cargo install cargo-readme
//! ```
//!
//! Once the cargo-readme binary is available, you can render the
//! README.md. Change into the document-root and type:
//!
//! ```console
//! $ cargo readme > README.md
//! ```
//!
//! [mdBook]: https://github.com/rust-lang-nursery/mdBook
//! [mdBook localization]: https://github.com/Nutomic/mdBook/tree/localization
//! [rust-mdbook]: https://github.com/rust-lang/rust/blob/master/src/tools/rustbook/Cargo.toml
//!
//! ### Building
//!
//! #### Building the book
//!
//! To build the book with the default language (here: 'en'), change
//! into the root directory of the element-call submodule and type:
//!
//! ```console
//! $ mdbook build --dest-dir book_en
//! ```
//!
//! The rendered HTML output will be placed underneath the
//! `book_en` subdirectory. To check it out, open it in your web
//! browser.
//!
//! _Firefox:_
//! ```console
//! $ firefox book_en/html/index.html # Linux
//! $ open -a "Firefox" book_en/html/index.html # OS X
//! $ Start-Process "firefox.exe" .\book_en\html\index.html # Windows (PowerShell)
//! $ start firefox.exe .\book_en\html\index.html # Windows (Cmd)
//! ```
//!
//! _Chrome:_
//! ```console
//! $ google-chrome book_en/html/index.html # Linux
//! $ open -a "Google Chrome" book_en/html/index.html # OS X
//! $ Start-Process "chrome.exe" .\book_en\html\index.html # Windows (PowerShell)
//! $ start chrome.exe .\book_en\html\index.html # Windows (Cmd)
//! ```
//!
//! Executing `mdbook serve` will have **mdbook** act has a web service
//! which can be accessed opening the following URL: http://localhost:3000.
//!
//! To run the tests:
//!
//! ```console
//! $ mdbook test
//! ```
//!
//! <!--
//! #### Building a language variant of the book
//!
//! WIP: adapt to mdbook-i18n-helpers
//! Translated version of the book will be placed inside the code tree
//! in the subdirectory `src/<language id`.
//!
//! E.g. if you like to render the german version (language id: 'de'), change
//! into Element-Call books root directory and type:
//!
//! ```console
//! $ MDBOOK_BOOK__src=src_de mdbook build --dest-dir book_de --open
//! ```
//!
//! The rendered HTML output will be placed underneath the
//! `book_de` subdirectory. Since we appended the `--open` parameter, your default browser should be fired up and ... tada!
//! !-->
//!
//! ### 🛠️ Development
//! ==================
//!
//! We welcome contributions to the Element-Call book from the community!
//! The best place to get started is our [`guide for contributors`][contributors-guide].
//!
//! This is part of our larger [`documentation][element-documentation],
//! which includes information for Element-Call developers and
//! translaters. We'd love your help! Please see
//! [CONTRIBUTING.md][contrib] to learn about the kinds of contributions
//! we're looking for.
//!
//! Alongside all that, join our [developercommunity][element-call-room-matrix]
//! on Matrix, featuring real humans!
//!
//! <!--
//! WIP: once it is ready to be shipped
//! ### Code of Conduct
//!
//! We are committed to providing a friendly, safe and welcoming
//! environment. Read more about our policy in the [code-of-conduct][coc] page.
//!
//! [coc]: https://element-hq.github.io/element-call/book/policies/code-of-conduct.md
//!
//! [contrib]: https://element-hq.github.io/element-call/book/blob/main/CONTRIBUTING.md
//! [contributors-guide]: https://element-hq.github.io/element-call/book/latest/development/contributing_guide.html
//! [element-documentation]: https://element-hq.github.io/element-call/book/latest>
//! [element-call-room-matrix]: https://matrix.to/#/#element-call-dev:matrix.org>`_`
//! -->
//!
//! #### Translations
//!
//! We'd love help to translate the book! See the [Translations] label
//! to join in efforts that are currently in progress. Open a new
//! issue to start working on a new language! We're waiting on [mdbook
//! support] for multiple languages to be finalized, but feel free to
//! start! A [pull request] looks promising. The mainline version (we
//! do depend on v0.4.12) is capable to render the existing versions
//! where sources are installed in the intended final structure.
//!
//! [Translations]: https://gitea.networkx.de/rzerres/element-call/book/issues?q=is%3Aopen+is%3Aissue+label%3ATranslations
//! [mdbook support]: https://github.com/rust-lang-nursery/mdBook/issues/5
//! [pull request]: https://github.com/rust-lang/mdBook/pull/1306
//!
//! ### Spellchecking
//!
//! To scan source files for spelling errors, you can use the `spellcheck.sh`
//! script. It needs a dictionary of valid words, which is provided in
//! `dictionary.txt`. If the script produces a false positive (say, you used word
//! `BTreeMap` which the script considers invalid), you need to add this word to
//! `dictionary.txt` (keep the sorted order for consistency).
//!
//! ### License
//!
//! <!-- License source -->
//! [Logo-CC_BY]: https://i.creativecommons.org/l/by/4.0/88x31.png "Creative Common Logo"
//! [License-CC_BY]: https://creativecommons.org/licenses/by/4.0/legalcode "Creative Common License"
//!
//! This work is licensed under a [Creative Common License 4.0][License-CC_BY]
//!
//! ![Creative Common Logo][Logo-CC_BY]
//!
//! © 2024 Ralf Zerres

View File

@@ -0,0 +1,5 @@
[workspace]
members = [
"ch01-02-element-call-hello/no-listing-01-02-cargo-new",
]

View File

@@ -0,0 +1,33 @@
# ANCHOR: All
[package]
# ANCHOR: Name
name = "element_call_hello"
# ANCHOR_END: Name
version = "0.0.1"
authors = [
"Ralf Zerres <ralf.zerres.de@gmail.com>",
]
description = "The Element-Call - Training project"
documentation = "https://docs.rs/orbtk"
repository = "https://github.com/redox-os/orbtk"
readme = "README.md"
license = "MIT"
keywords = [
"element-call",
"matrix",
"matrixrtc",
]
edition = "2021"
[profile.dev]
opt-level = 1
[dependencies]
#element-call = { git = "https://gitea.networkx.de/rzerres/element-call-book.git", branch = "develop" }
[[bin]]
# ANCHOR: Name
name = "element_call_hello"
# ANCHOR_END: Name
path = "src/main.rs"
# ANCHOR_END: All

View File

@@ -0,0 +1,17 @@
// ANCHOR: All
// ANCHOR: Use
use element-call::prelude::*;
// ANCHOR_END: Use
// ANCHOR: Main
fn main() {
// ANCHOR_END: Main
// ANCHOR: Initialize
element-call::initialize();
// ANCHOR_END: Initialize
// ANCHOR: Run
.run();
// ANCHOR_END: Run
}
// ANCHOR_END: All

View File

@@ -0,0 +1,9 @@
[package]
name = "element_call_hello_example"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

7
book_en/html/mark.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

618
book_en/html/print.html Normal file
View File

@@ -0,0 +1,618 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>The Element-Call Book</title>
<meta name="robots" content="noindex">
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h1 id="element-call"><a class="header" href="#element-call">Element Call</a></h1>
<p><em>annotated and documented by Ralf Zerres and all contributers</em></p>
<p>This version of the text assumes youre using Element-Call v0.6.7 or later in
conjuction with Rust v1.83.0 or later. <em>Cargo.toml</em> should define
<code>edition="2021"</code>. That enables and uses Rust 2021 Edition idioms in
all derived projects.</p>
<p>See the <a href="https://https://gitea.networkx.de/rzerres/element-call/book/ch02-00-installation.html">“Installation” section of Chapter 2</a>
to install or update Element-Call.</p>
<p>The 2021 Edition of this book is the initial release. It will be
released with the Element-Call version 1.0.0.</p>
<ul>
<li>Appendix A “Keywords”, explains the new raw identifiers.</li>
<li>Appendix D “Translations”, is work in progress. We will release
instances of this book in the target language once they are translated.</li>
</ul>
<p>For online reading, a HTML rendered version is available at
<a href="https://gitea.networkx.de/rzerres/element-call/book/blob/main/src/img/element-call.png">Element-Call book</a>. Alternatively you might want to have it handy
for offline usage. Either you downlaod a rendered <code>pdf</code> or
<code>ebook</code>version or go ahead and download the source. Then kick on
mdbook (the definition of the target location is optional).</p>
<pre><code class="language-console">mdbook build --dest-dir book_en --open
</code></pre>
<!---
This text is available in [paperback and ebook format from No Starch Press][nsprust].
-->
<!--
[element-call_book_en]: https://gitea.networkx.de/rzerres/element-call/book/
[element-call_book_en_stable]: https://element.io/element-call/stable/book/
-->
<div style="break-before: page; page-break-before: always;"></div><h1 id="foreword"><a class="header" href="#foreword">Foreword</a></h1>
<p>The history of computer-aided communication, which supports not only
text video and sound goes back to the 1990s. From from todays
perspective, it seems almost grotesque what prices had to be paid for
the had to be paid for the hardware developed at that time. Not only
for the quality and quality of encoded data streams, new formats had
to be invented (CIF (CIF, QCIF). The development of Codex was in its
infancy. infancy. There was a lack of
standardization. Interoperability and and the use of the Internet were
at best distant goals. People were working on very
application-specific solutions and approaches that had the potential
for affordable components for mass production. As an example, the
pioneering manufacturer <a href="https://en.wikipedia.org/wiki/Parallax_Graphics"><code>Parallax Graphics Inc.</code></a>. Founded in 1982 by two graduates of Cornell
University, the company focused on the marketing of the marketing of
<code>high end</code> graphics cards, including for the then popular university
environment at the time. These cards initially cost around €25,000
and supplied ASICS and a codex implemented in implemented in hardware,
which could realize resolutions of up to 1280x1024 pixels could be
realized.</p>
<p>Every commercially available cell phone, tablet, notebook and desktop
PCs currently deliver graphics card performance that can render 2k,
even 4k pixels can render. Encoding and decoding solutions are
decoding solutions have been standardized internationally, which have
significantly reduced the bandwidths to be transmitted and thus and
thus enable billions of uses on the Internet use on the
Internet. One-to-one video telephony has been established for years.
established for years. And everyone will remember the radical upheaval
in the professional use of video conferencing solutions that the COVID
pandemic brought with it in 2022.</p>
<p>Today, the use of video conferencing solutions is ubiquitous. In the
working world, proprietary solutions are often used, to implement work
processes regardless of location. Examples include the products from
the manufacturers <a href="https://en.wikipedia.org/wiki/Cisco"><code>CISCO-&gt;(Webex)</code></a>,
<a href="https://de.wikipedia.org/wiki/Microsoft_Teams"><code>Microsoft-&gt;(Skype,Teams)</code></a>, <a href="https://www.hp.com/de-de/poly.html"><code>HP-&gt;(Poly)</code></a>
and <a href="https://en.wikipedia.org/wiki/Zoom_(software)"><code>Zoom-&gt;(Zoom)</code></a> are listed. But also free software such as
<a href="https://bigbluebutton.org/"><code>BigBlueButton</code></a>, <a href="https://jitsi.org/"><code>Jitsi</code></a> or
<a href="https://nextcloud-talk.readthedocs.io/en/latest/"><code>Nextcloud-&gt;(Talk)</code></a> are enjoying worldwide distribution.</p>
<p>With <code>Element-Call</code> the Matrix ecosystems gains a new approach that
fully embraces the potential of MatrixRTC. Think of participents in
decentralized domains that are to able to dynamicly create and manage
multipoint meetings in an efficiant manner. An Open-Source, that
enables fee choice of any Matrix complient Client. What progress.</p>
<p>— Ralf Zerres</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="introduction"><a class="header" href="#introduction">Introduction</a></h1>
<!--
> WIP: to be uncommented, once it is done
> Note: This edition of the book is the same as [The Orbital Widget Toolkit]
> [nsprust] available in print and ebook format from [No Starch Press][nsporbtk].
[nsporbtk]: https://nostarch.com/orbtk
[nsp]: https://nostarch.com/
-->
<p><a href="img/element-call-webui.png"><img src="img/element-call-webui.png" width="720"/></a></p>
<p>Welcome to <code>Element-Call</code>, an introductory book about the Matrix based
video conferencing subsystem.</p>
<div class="warning">
<p>Warning: This book is incomplete. Documenting everything and
rewriting outdated parts take a while.
See the <a href="https://https://gitea.networkx.de/rzerres/element-call/book/issues">issue tracker</a> to check whats missing or outdated. If there
are any mistakes or ideas that havent been reported, feel free to
open a new issue there.</p>
</div>
<p><code>Element-Call</code> fully embraces the potential of MatrixRTC. All
supported clients will connect via the genreric API, though selecting
their prefered mode (standalone- vs. widget-view).</p>
<p><a href="img/element-call-modes.png"><img src="img/element-call-modes.png" width="720"/></a></p>
<h2 id="features"><a class="header" href="#features">Features</a></h2>
<ul>
<li>Modern WebRTC API (powered by LifeKit)</li>
<li>Custom widgets</li>
<li>WebBrowser suport</li>
<li>Custom theming engine</li>
<li>Localization</li>
</ul>
<h2 id="supported-backend-platforms"><a class="header" href="#supported-backend-platforms">Supported Backend Platforms</a></h2>
<ul>
<li>Linux (native)</li>
</ul>
<!--
* macOS (native)
* Windows (native)
* openBSD (not tested, but should work)
* Web (cargo-node)
* Android (native planned | cargo-node)
* iOS (native planned | cargo-node planned)
-->
<h2 id="supported-client-platforms"><a class="header" href="#supported-client-platforms">Supported Client Platforms</a></h2>
<ul>
<li>Matrix clients (e.g. Element X, ShildiNext)</li>
<li>WebBrouwsers (e.g. Brave, Chrome, Edge, Firefox)</li>
</ul>
<h2 id="who-element-call-book-is-for"><a class="header" href="#who-element-call-book-is-for">Who Element-Call Book Is For</a></h2>
<p>The intention of <code>Element-Call</code> book is to help interested developers and administrators to get familiar with the structure and the componets choosen to implement a fully functional decentralized video conferencing solution. It will offer the needed in depth information to get in touch with the codebase. It will also aid an administrator to set up the needed software components to build up a self hosted installation.</p>
<h2 id="source-code"><a class="header" href="#source-code">Source Code</a></h2>
<p>The source files of the book are maintained as a git submodule found at <a href="https://gitea.networkx.de/rzerres/element-call-book/book_en"><code>Element-Call book</code></a>.</p>
<!--
[element-call_book_en_stable]: https://element.io/element-call/stable/book/
-->
<div style="break-before: page; page-break-before: always;"></div><h1 id="getting-started"><a class="header" href="#getting-started">Getting Started</a></h1>
<p>Lets start your Element-Call journey! Theres a lot to learn, but every journey starts
somewhere. In this chapter, well discuss:</p>
<ul>
<li>The building blocks of Element-Call</li>
<li>Installing Element-Call</li>
</ul>
<div style="break-before: page; page-break-before: always;"></div><h2 id="building-blocks"><a class="header" href="#building-blocks">Building blocks</a></h2>
<p>Historically <code>Elememnt-Call</code> did implement an infrastructure, where
all participants were fully meshed. That means all participants had a
direct peer to each other. This structure does work quite well with a
low number of call partners (e.g 1:1 sessions). Clearly this structure
is totally inefficient and collapsing, as soon as the number of
participants rises: The needed number of streams that have to be
synchronized are increasing exponentionally.</p>
<p>Most commercial solutions overcome this bottleneck utilizing a
MCU-structure: Each participant of the call is directly connected to
the controlling MCU (the head).</p>
<p>MCU routing has disadvantages and shortcommings too.</p>
<ul>
<li>You cant assign different egress parameters from the MCU to
individual participant streams</li>
<li>A single MCU cant handle distributed structure</li>
</ul>
<p>Since the nature of Matrix based communication makes use of a
distributed infrasturcture, MatrixRTC need to handle this aspect. It
is implemented with an SFU backend.</p>
<p>The following image visualize the differences inside the available
<img src="./img/voip_routing_structures.png" alt="voip routing structures" /></p>
<h3 id="backend"><a class="header" href="#backend">Backend</a></h3>
<p>The MatrixRTC functionality is handled via <a href="https://github.com/livekit">LiveKit</a>.</p>
<h3 id="frontend"><a class="header" href="#frontend">Frontend</a></h3>
<p><img src="https://gitea.networkx.de/rzerres/element-call/book/blob/main/src/img/element-call_building_blocks.png" alt="Building blocks" /></p>
<div style="break-before: page; page-break-before: always;"></div><h2 id="hello-element-call"><a class="header" href="#hello-element-call">Hello ELement-Call!</a></h2>
<!--
[<img src="img/element-call.png" width="720"/>](img/element-call-webui.png)
-->
<p><img src="https://gitea.networkx.de/rzerres/element-call-book/src/branch/main/src/img/element-call-webui.png" alt="Welcome to the element-call book." /></p>
<p>Now that youve installed the needed building blocks, lets adapt the
Frontend.</p>
<h3 id="writing-and-running-the-element-call-frontend"><a class="header" href="#writing-and-running-the-element-call-frontend">Writing and Running the ELement-Call frontend</a></h3>
<p>First, we make a new project using <em>Cargo</em>. With its <em>.toml</em> file we
allow Rust to declare the various dependencies and metadata. That
ensures that youll always get a repeatable output of the build.</p>
<p>Go ahead like so:</p>
<pre><code class="language-console">$ cargo new element-call
$ cd element-call
</code></pre>
<p>The first command, <code>cargo new</code>, takes the name of the project
(“<code>element-call</code>”) as the first argument. The second command changes to
the new projects directory.</p>
<p>Look at the generated <em>Cargo.toml</em> file:</p>
<p><span class="filename">Filename: Cargo.toml</span></p>
<pre><code class="language-toml">[package]
name = "element_call_hello_example"
version = "0.1.0"
authors = ["Your Name &lt;you@example.com&gt;"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
</code></pre>
<p><span class="caption">Listing 1-1: Default metadata “element_call_hello”</span></p>
<p>With <code>cargo new</code>, a default project structure is created. Maybe the
author information is already exchanged if <em>Cargo</em> could obtain a definition
from your environment. <em>Cargo</em> also generated source code for a “Hello, world!”
program. Lets Check out the corresponding <em>src/main.rs</em> file:</p>
<p><span class="filename">Filename: src/main.rs</span></p>
<pre><pre class="playground"><code class="language-rust edition2021">fn main() {
println!("Hello, world!");
}</code></pre></pre>
<p><span class="caption">Listing 1-2: Default source file “main.rs”</span></p>
<p>No need to compile that stage with <code>cargo run</code>, since we are going to
exchange the project metadata, as well as the element-call source code right
away.</p>
<h4 id="update-cargotoml"><a class="header" href="#update-cargotoml">Update Cargo.toml</a></h4>
<p>First reopen the <em>Cargo.toml</em> file and enter the Code in Listing 1-1 into <em>Cargo.toml</em></p>
<p><span class="filename">Filename: Cargo.toml</span></p>
<pre><code class="language-toml ignore">[package]
name = "element_call_hello"
version = "0.0.1"
authors = [
"Ralf Zerres &lt;ralf.zerres.de@gmail.com&gt;",
]
description = "The Element-Call - Training project"
documentation = "https://docs.rs/orbtk"
repository = "https://github.com/redox-os/orbtk"
readme = "README.md"
license = "MIT"
keywords = [
"element-call",
"matrix",
"matrixrtc",
]
edition = "2021"
[profile.dev]
opt-level = 1
[dependencies]
#element-call = { git = "https://gitea.networkx.de/rzerres/element-call-book.git", branch = "develop" }
[[bin]]
name = "element_call_hello"
path = "src/main.rs"
</code></pre>
<p><span class="caption">Listing 1-1: Project metadata “Element-Call”</span></p>
<p>You may wonder, why the <em>name</em> property inside the <em>Cargo.toml</em> is
formatted like <code>element_call</code>.</p>
<pre><code class="language-toml ignore">name = "element_call_hello"
</code></pre>
<p>It is a good habit to follow rusts
naming convention, that encourages you to use <a href="https://rust-lang.github.io/api-guidelines/naming.html">snake_case</a>
naming. While expanding the <em>Element-Call</em> example sources, we will keep
the grouping prefix <code>element-call</code>. That way we end up to call our first target
binary <code>element-call_hello</code>.</p>
<h4 id="update-mainrs"><a class="header" href="#update-mainrs">Update main.rs</a></h4>
<p>All of the <em>Element-Call</em> specific code that is needed to build our first
example “Hello Element-Call!” is shown in Listing 1-2. It goes to
<em>src/main.rs</em>.</p>
<p><span class="filename">Filename: src/main.rs</span></p>
<pre><code class="language-rust ignore">use element-call::prelude::*;
fn main() {
element-call::initialize();
.run();
}</code></pre>
<p><span class="caption">Listing 1-2: Code that creates a Window and
prints “Hey Element-Call!”</span></p>
<p>Save the file and go back to your terminal window. Enter the following
commands to compile and run the file:</p>
<pre><code class="language-console">$ cargo run --release element_call_hello
</code></pre>
<h3 id="compiling-and-running-are-separate-steps"><a class="header" href="#compiling-and-running-are-separate-steps">Compiling and Running Are Separate Steps</a></h3>
<p>Before running an Element-Call application, you must compile its source code. A typical
Element-Call project will generate the executable binary code using cargo and place the
result in the target subfolder of the project.</p>
<p>Profiles may be used to configure compiler options such as optimization levels
and debug settings. By default the <code>dev</code> or <code>test</code> profiles are used. If the
<code>--release</code> flag is given, then the release or bench profiles are used.</p>
<pre><code class="language-console">$ cargo build --release --bin element-call-hello.rs
$ ../target/release/hello_element_call
</code></pre>
<p>On Windows, you need to use <code>backslash</code> as a path delimiter:</p>
<pre><code class="language-powershell">&gt; cargo build --release --bin element-call-hello.rs
&gt; ..\target\release\element_call_hello.exe
</code></pre>
<p>If you like to get debug feedback you can call the build process like this</p>
<pre><code class="language-console">$ cargo build --features debug --bin element-call-hello.rs
</code></pre>
<div style="break-before: page; page-break-before: always;"></div><h2 id="installation"><a class="header" href="#installation">Installation</a></h2>
<p>The first step is to install Rust. This is described in depth following
<a href="https://github.com/rust-lang/book/blob/master/src/ch01-01-installation.md">Rust book Chapter 1</a></p>
<p>When creating a OrbTk application, we define the needed dependencies to the
OrbTk crates in the Cargo.toml file of our project. The complile process
will resolve the references and download the source as needed.</p>
<blockquote>
<h3 id="command-line-notation"><a class="header" href="#command-line-notation">Command Line Notation</a></h3>
<p>In this chapter and throughout the book, well show some commands used in the
terminal. Lines that you should enter in a terminal all start with <code>$</code>. You
dont need to type in the <code>$</code> character; it indicates the start of each
command. Lines that dont start with <code>$</code> typically show the output of the
previous command. Additionally, PowerShell-specific examples will use <code>&gt;</code>
rather than <code>$</code>.</p>
</blockquote>
<h3 id="troubleshooting"><a class="header" href="#troubleshooting">Troubleshooting</a></h3>
<blockquote>
<p><em><strong>WIP</strong></em>: What are the most common culprits? Can we provide some general, basic solutions</p>
</blockquote>
<h3 id="local-documentation"><a class="header" href="#local-documentation">Local Documentation</a></h3>
<p>OrbTk offers the option to install its documentation locally, so you can read it
offline.</p>
<p>Any time a type, a function, a method or a crate is reference by the toolkit
and youre not sure what it does or how to use it, have a look at its application
programming interface <a href="https://docs.rs/orbtk">API documentation</a> to find out!</p>
<!-- [API documentation]: https://www.redox-os.org/orbtk/doc/en -->
<!-- [API documentation]: https://github.com/redox-os/orbtk -->
<h3 id="install-rust-on-linux-or-macos"><a class="header" href="#install-rust-on-linux-or-macos">Install Rust on Linux or macOS</a></h3>
<p>If you are using Linux or macOS open up an terminal and copy and paste the text below and hit the enter key on your keyboard:</p>
<pre><code class="language-bash">curl https://sh.rustup.rs -sSf | sh
</code></pre>
<h3 id="install-rust-on-windows"><a class="header" href="#install-rust-on-windows">Install Rust on Windows</a></h3>
<p>Download and run the Rust windows installer from https://www.rust-lang.org/tools/install.</p>
<h3 id="install-redoxer-redox-os"><a class="header" href="#install-redoxer-redox-os">Install Redoxer (Redox OS)</a></h3>
<p>If you want build and run your Rust application on a <a href="https://en.wikipedia.org/wiki/Kernel-based_Virtual_Machine">KVM</a> capable OS for Redox you can use <a href="https://gitlab.redox-os.org/redox-os/redoxer">redoxer</a>.</p>
<p>To install Redoxer you have to first install the rust toolchain. After that open up an terminal and copy and paste the text below and hit the enter key on your keyboard:</p>
<pre><code class="language-bash">cargo +nightly install redoxer
</code></pre>
<p>To compile and run your application on Redox OS you should check the Redox OS Book.</p>
<h3 id="editor-and-ide-integration"><a class="header" href="#editor-and-ide-integration">Editor and IDE integration</a></h3>
<p>A wide range of editors and IDEs are providing support for Rust code like</p>
<ul>
<li>like syntax-highlighting</li>
<li>auto-completion</li>
<li>linting</li>
<li>lsp support</li>
</ul>
<h4 id="vs-code"><a class="header" href="#vs-code">VS Code</a></h4>
<p>There is a big community that rely on the visualstudio implementation
to handle their code base. Following are the steps needed to expand
your installation to support <code>VS Code for Rust</code> development:</p>
<ol>
<li>Download VS Code <a href="https://code.visualstudio.com/download">from</a>.</li>
<li>Install <a href="https://marketplace.visualstudio.com/items?itemName=rust-lang.rust">Rust Language Server plugin</a> (the
Rust Language Server).</li>
</ol>
<h4 id="alternative-editors-and-ides"><a class="header" href="#alternative-editors-and-ides">Alternative Editors and IDEs</a></h4>
<p>If you perefer other solution, you will find in depth help inside the
context of this inclomplete links:</p>
<ul>
<li><a href="https://atom.io/packages/language-rust">Atom</a></li>
<li><a href="https://intellij-rust.github.io">Intellij IDEA</a></li>
<li><a href="https://github.com/rust-lang/rust.vim">Vim</a></li>
<li><a href="https://github.com/rust-lang/rust-mode">Emacs</a></li>
<li><a href="https://github.com/eclipse/corrosion">Eclipse</a></li>
</ul>
<div style="break-before: page; page-break-before: always;"></div><h1 id="element-call-example-applications"><a class="header" href="#element-call-example-applications">ELement-Call Example Applications</a></h1>
<p>This section provides <code>Element-Call</code> example apps. We hope to cover
interesting aspects of the API.</p>
<p>Take them as a tutorial, all listings are created as a reference. They
have in mind to serve as an introduction to a specific topic. As
educational content, this apps are marked with in-lined comments and
anchors. If we did well, you can concentrate on the parts we like
to emphasize.</p>
<p>Inside the library, you will find the collection of example code in
the subdirectory <em>examples</em> in crate <a href="https://github.com/element-hq/element-call/tree/develop/element-call/examples"><code>element-call</code></a>.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="hello-element-call-1"><a class="header" href="#hello-element-call-1">Hello Element-Call!</a></h1>
<p>We already introduced the source in <a href="https://gitea.networkx.de/element-call-book/src/listings/ch01-02-element-call-hello.html#pdate-cargotoml">Chapter 01</a>.
For the sake of completeness, and since its a habit to begin with … here we go.</p>
<!--
[example_hello-element-call]: https://element-hq.github.io/element-call/book/src/listings/ch01-02-element-call-hello.html#pdate-cargotoml
-->
<div style="break-before: page; page-break-before: always;"></div><h1 id="element-call-appendix"><a class="header" href="#element-call-appendix">Element-Call Appendix</a></h1>
<p>This is WIP</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="element-call-appendix---keywords"><a class="header" href="#element-call-appendix---keywords">Element-Call Appendix - Keywords</a></h1>
<p>This is WIP</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="element-call-appendix---operators"><a class="header" href="#element-call-appendix---operators">Element-Call Appendix - Operators</a></h1>
<p>This is WIP</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="element-call-appendix---derivable-traits"><a class="header" href="#element-call-appendix---derivable-traits">Element-CAll Appendix - Derivable Traits</a></h1>
<p>This is WIP</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="appendix-d-translations-of-the-book"><a class="header" href="#appendix-d-translations-of-the-book">Appendix D: Translations of the Book</a></h1>
<p>For resources in languages other than English. This is work in progress; see
<a href="https://gitea.networkx.de/ralf.zerres/element-call-book/issues?q=is%3Aopen+is%3Aissue+label%3ATranslations">the Translations label</a> to help or let us know about a new translation!</p>
<ul>
<li><a href="https://gitea.networkx.de/rzerres/element-call-book">Deutsch</a></li>
</ul>
<!---
- [Deutsch](https://github.com/element.io/element-call/book/book-de)
- [Français](https://github.com/element.io/element-call/book/book-fr)
-->
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
<script>
window.addEventListener('load', function() {
MathJax.Hub.Register.StartupHook('End', function() {
window.setTimeout(window.print, 100);
});
});
</script>
</div>
</body>
</html>

483
book_en/html/searcher.js Normal file
View File

@@ -0,0 +1,483 @@
"use strict";
window.search = window.search || {};
(function search(search) {
// Search functionality
//
// You can use !hasFocus() to prevent keyhandling in your key
// event handlers while the user is typing their search.
if (!Mark || !elasticlunr) {
return;
}
//IE 11 Compatibility from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
if (!String.prototype.startsWith) {
String.prototype.startsWith = function(search, pos) {
return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search;
};
}
var search_wrap = document.getElementById('search-wrapper'),
searchbar = document.getElementById('searchbar'),
searchbar_outer = document.getElementById('searchbar-outer'),
searchresults = document.getElementById('searchresults'),
searchresults_outer = document.getElementById('searchresults-outer'),
searchresults_header = document.getElementById('searchresults-header'),
searchicon = document.getElementById('search-toggle'),
content = document.getElementById('content'),
searchindex = null,
doc_urls = [],
results_options = {
teaser_word_count: 30,
limit_results: 30,
},
search_options = {
bool: "AND",
expand: true,
fields: {
title: {boost: 1},
body: {boost: 1},
breadcrumbs: {boost: 0}
}
},
mark_exclude = [],
marker = new Mark(content),
current_searchterm = "",
URL_SEARCH_PARAM = 'search',
URL_MARK_PARAM = 'highlight',
teaser_count = 0,
SEARCH_HOTKEY_KEYCODE = 83,
ESCAPE_KEYCODE = 27,
DOWN_KEYCODE = 40,
UP_KEYCODE = 38,
SELECT_KEYCODE = 13;
function hasFocus() {
return searchbar === document.activeElement;
}
function removeChildren(elem) {
while (elem.firstChild) {
elem.removeChild(elem.firstChild);
}
}
// Helper to parse a url into its building blocks.
function parseURL(url) {
var a = document.createElement('a');
a.href = url;
return {
source: url,
protocol: a.protocol.replace(':',''),
host: a.hostname,
port: a.port,
params: (function(){
var ret = {};
var seg = a.search.replace(/^\?/,'').split('&');
var len = seg.length, i = 0, s;
for (;i<len;i++) {
if (!seg[i]) { continue; }
s = seg[i].split('=');
ret[s[0]] = s[1];
}
return ret;
})(),
file: (a.pathname.match(/\/([^/?#]+)$/i) || [,''])[1],
hash: a.hash.replace('#',''),
path: a.pathname.replace(/^([^/])/,'/$1')
};
}
// Helper to recreate a url string from its building blocks.
function renderURL(urlobject) {
var url = urlobject.protocol + "://" + urlobject.host;
if (urlobject.port != "") {
url += ":" + urlobject.port;
}
url += urlobject.path;
var joiner = "?";
for(var prop in urlobject.params) {
if(urlobject.params.hasOwnProperty(prop)) {
url += joiner + prop + "=" + urlobject.params[prop];
joiner = "&";
}
}
if (urlobject.hash != "") {
url += "#" + urlobject.hash;
}
return url;
}
// Helper to escape html special chars for displaying the teasers
var escapeHTML = (function() {
var MAP = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&#34;',
"'": '&#39;'
};
var repl = function(c) { return MAP[c]; };
return function(s) {
return s.replace(/[&<>'"]/g, repl);
};
})();
function formatSearchMetric(count, searchterm) {
if (count == 1) {
return count + " search result for '" + searchterm + "':";
} else if (count == 0) {
return "No search results for '" + searchterm + "'.";
} else {
return count + " search results for '" + searchterm + "':";
}
}
function formatSearchResult(result, searchterms) {
var teaser = makeTeaser(escapeHTML(result.doc.body), searchterms);
teaser_count++;
// The ?URL_MARK_PARAM= parameter belongs inbetween the page and the #heading-anchor
var url = doc_urls[result.ref].split("#");
if (url.length == 1) { // no anchor found
url.push("");
}
// encodeURIComponent escapes all chars that could allow an XSS except
// for '. Due to that we also manually replace ' with its url-encoded
// representation (%27).
var searchterms = encodeURIComponent(searchterms.join(" ")).replace(/\'/g, "%27");
return '<a href="' + path_to_root + url[0] + '?' + URL_MARK_PARAM + '=' + searchterms + '#' + url[1]
+ '" aria-details="teaser_' + teaser_count + '">' + result.doc.breadcrumbs + '</a>'
+ '<span class="teaser" id="teaser_' + teaser_count + '" aria-label="Search Result Teaser">'
+ teaser + '</span>';
}
function makeTeaser(body, searchterms) {
// The strategy is as follows:
// First, assign a value to each word in the document:
// Words that correspond to search terms (stemmer aware): 40
// Normal words: 2
// First word in a sentence: 8
// Then use a sliding window with a constant number of words and count the
// sum of the values of the words within the window. Then use the window that got the
// maximum sum. If there are multiple maximas, then get the last one.
// Enclose the terms in <em>.
var stemmed_searchterms = searchterms.map(function(w) {
return elasticlunr.stemmer(w.toLowerCase());
});
var searchterm_weight = 40;
var weighted = []; // contains elements of ["word", weight, index_in_document]
// split in sentences, then words
var sentences = body.toLowerCase().split('. ');
var index = 0;
var value = 0;
var searchterm_found = false;
for (var sentenceindex in sentences) {
var words = sentences[sentenceindex].split(' ');
value = 8;
for (var wordindex in words) {
var word = words[wordindex];
if (word.length > 0) {
for (var searchtermindex in stemmed_searchterms) {
if (elasticlunr.stemmer(word).startsWith(stemmed_searchterms[searchtermindex])) {
value = searchterm_weight;
searchterm_found = true;
}
};
weighted.push([word, value, index]);
value = 2;
}
index += word.length;
index += 1; // ' ' or '.' if last word in sentence
};
index += 1; // because we split at a two-char boundary '. '
};
if (weighted.length == 0) {
return body;
}
var window_weight = [];
var window_size = Math.min(weighted.length, results_options.teaser_word_count);
var cur_sum = 0;
for (var wordindex = 0; wordindex < window_size; wordindex++) {
cur_sum += weighted[wordindex][1];
};
window_weight.push(cur_sum);
for (var wordindex = 0; wordindex < weighted.length - window_size; wordindex++) {
cur_sum -= weighted[wordindex][1];
cur_sum += weighted[wordindex + window_size][1];
window_weight.push(cur_sum);
};
if (searchterm_found) {
var max_sum = 0;
var max_sum_window_index = 0;
// backwards
for (var i = window_weight.length - 1; i >= 0; i--) {
if (window_weight[i] > max_sum) {
max_sum = window_weight[i];
max_sum_window_index = i;
}
};
} else {
max_sum_window_index = 0;
}
// add <em/> around searchterms
var teaser_split = [];
var index = weighted[max_sum_window_index][2];
for (var i = max_sum_window_index; i < max_sum_window_index+window_size; i++) {
var word = weighted[i];
if (index < word[2]) {
// missing text from index to start of `word`
teaser_split.push(body.substring(index, word[2]));
index = word[2];
}
if (word[1] == searchterm_weight) {
teaser_split.push("<em>")
}
index = word[2] + word[0].length;
teaser_split.push(body.substring(word[2], index));
if (word[1] == searchterm_weight) {
teaser_split.push("</em>")
}
};
return teaser_split.join('');
}
function init(config) {
results_options = config.results_options;
search_options = config.search_options;
searchbar_outer = config.searchbar_outer;
doc_urls = config.doc_urls;
searchindex = elasticlunr.Index.load(config.index);
// Set up events
searchicon.addEventListener('click', function(e) { searchIconClickHandler(); }, false);
searchbar.addEventListener('keyup', function(e) { searchbarKeyUpHandler(); }, false);
document.addEventListener('keydown', function(e) { globalKeyHandler(e); }, false);
// If the user uses the browser buttons, do the same as if a reload happened
window.onpopstate = function(e) { doSearchOrMarkFromUrl(); };
// Suppress "submit" events so the page doesn't reload when the user presses Enter
document.addEventListener('submit', function(e) { e.preventDefault(); }, false);
// If reloaded, do the search or mark again, depending on the current url parameters
doSearchOrMarkFromUrl();
}
function unfocusSearchbar() {
// hacky, but just focusing a div only works once
var tmp = document.createElement('input');
tmp.setAttribute('style', 'position: absolute; opacity: 0;');
searchicon.appendChild(tmp);
tmp.focus();
tmp.remove();
}
// On reload or browser history backwards/forwards events, parse the url and do search or mark
function doSearchOrMarkFromUrl() {
// Check current URL for search request
var url = parseURL(window.location.href);
if (url.params.hasOwnProperty(URL_SEARCH_PARAM)
&& url.params[URL_SEARCH_PARAM] != "") {
showSearch(true);
searchbar.value = decodeURIComponent(
(url.params[URL_SEARCH_PARAM]+'').replace(/\+/g, '%20'));
searchbarKeyUpHandler(); // -> doSearch()
} else {
showSearch(false);
}
if (url.params.hasOwnProperty(URL_MARK_PARAM)) {
var words = decodeURIComponent(url.params[URL_MARK_PARAM]).split(' ');
marker.mark(words, {
exclude: mark_exclude
});
var markers = document.querySelectorAll("mark");
function hide() {
for (var i = 0; i < markers.length; i++) {
markers[i].classList.add("fade-out");
window.setTimeout(function(e) { marker.unmark(); }, 300);
}
}
for (var i = 0; i < markers.length; i++) {
markers[i].addEventListener('click', hide);
}
}
}
// Eventhandler for keyevents on `document`
function globalKeyHandler(e) {
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || e.target.type === 'textarea' || e.target.type === 'text' || !hasFocus() && /^(?:input|select|textarea)$/i.test(e.target.nodeName)) { return; }
if (e.keyCode === ESCAPE_KEYCODE) {
e.preventDefault();
searchbar.classList.remove("active");
setSearchUrlParameters("",
(searchbar.value.trim() !== "") ? "push" : "replace");
if (hasFocus()) {
unfocusSearchbar();
}
showSearch(false);
marker.unmark();
} else if (!hasFocus() && e.keyCode === SEARCH_HOTKEY_KEYCODE) {
e.preventDefault();
showSearch(true);
window.scrollTo(0, 0);
searchbar.select();
} else if (hasFocus() && e.keyCode === DOWN_KEYCODE) {
e.preventDefault();
unfocusSearchbar();
searchresults.firstElementChild.classList.add("focus");
} else if (!hasFocus() && (e.keyCode === DOWN_KEYCODE
|| e.keyCode === UP_KEYCODE
|| e.keyCode === SELECT_KEYCODE)) {
// not `:focus` because browser does annoying scrolling
var focused = searchresults.querySelector("li.focus");
if (!focused) return;
e.preventDefault();
if (e.keyCode === DOWN_KEYCODE) {
var next = focused.nextElementSibling;
if (next) {
focused.classList.remove("focus");
next.classList.add("focus");
}
} else if (e.keyCode === UP_KEYCODE) {
focused.classList.remove("focus");
var prev = focused.previousElementSibling;
if (prev) {
prev.classList.add("focus");
} else {
searchbar.select();
}
} else { // SELECT_KEYCODE
window.location.assign(focused.querySelector('a'));
}
}
}
function showSearch(yes) {
if (yes) {
search_wrap.classList.remove('hidden');
searchicon.setAttribute('aria-expanded', 'true');
} else {
search_wrap.classList.add('hidden');
searchicon.setAttribute('aria-expanded', 'false');
var results = searchresults.children;
for (var i = 0; i < results.length; i++) {
results[i].classList.remove("focus");
}
}
}
function showResults(yes) {
if (yes) {
searchresults_outer.classList.remove('hidden');
} else {
searchresults_outer.classList.add('hidden');
}
}
// Eventhandler for search icon
function searchIconClickHandler() {
if (search_wrap.classList.contains('hidden')) {
showSearch(true);
window.scrollTo(0, 0);
searchbar.select();
} else {
showSearch(false);
}
}
// Eventhandler for keyevents while the searchbar is focused
function searchbarKeyUpHandler() {
var searchterm = searchbar.value.trim();
if (searchterm != "") {
searchbar.classList.add("active");
doSearch(searchterm);
} else {
searchbar.classList.remove("active");
showResults(false);
removeChildren(searchresults);
}
setSearchUrlParameters(searchterm, "push_if_new_search_else_replace");
// Remove marks
marker.unmark();
}
// Update current url with ?URL_SEARCH_PARAM= parameter, remove ?URL_MARK_PARAM and #heading-anchor .
// `action` can be one of "push", "replace", "push_if_new_search_else_replace"
// and replaces or pushes a new browser history item.
// "push_if_new_search_else_replace" pushes if there is no `?URL_SEARCH_PARAM=abc` yet.
function setSearchUrlParameters(searchterm, action) {
var url = parseURL(window.location.href);
var first_search = ! url.params.hasOwnProperty(URL_SEARCH_PARAM);
if (searchterm != "" || action == "push_if_new_search_else_replace") {
url.params[URL_SEARCH_PARAM] = searchterm;
delete url.params[URL_MARK_PARAM];
url.hash = "";
} else {
delete url.params[URL_MARK_PARAM];
delete url.params[URL_SEARCH_PARAM];
}
// A new search will also add a new history item, so the user can go back
// to the page prior to searching. A updated search term will only replace
// the url.
if (action == "push" || (action == "push_if_new_search_else_replace" && first_search) ) {
history.pushState({}, document.title, renderURL(url));
} else if (action == "replace" || (action == "push_if_new_search_else_replace" && !first_search) ) {
history.replaceState({}, document.title, renderURL(url));
}
}
function doSearch(searchterm) {
// Don't search the same twice
if (current_searchterm == searchterm) { return; }
else { current_searchterm = searchterm; }
if (searchindex == null) { return; }
// Do the actual search
var results = searchindex.search(searchterm, search_options);
var resultcount = Math.min(results.length, results_options.limit_results);
// Display search metrics
searchresults_header.innerText = formatSearchMetric(resultcount, searchterm);
// Clear and insert results
var searchterms = searchterm.split(' ');
removeChildren(searchresults);
for(var i = 0; i < resultcount ; i++){
var resultElem = document.createElement('li');
resultElem.innerHTML = formatSearchResult(results[i], searchterms);
searchresults.appendChild(resultElem);
}
// Display results
showResults(true);
}
fetch(path_to_root + 'searchindex.json')
.then(response => response.json())
.then(json => init(json))
.catch(error => { // Try to load searchindex.js if fetch failed
var script = document.createElement('script');
script.src = path_to_root + 'searchindex.js';
script.onload = () => init(window.search);
document.head.appendChild(script);
});
// Exported functions
search.hasFocus = hasFocus;
})(window.search);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
ace.define("ace/theme/dawn",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-dawn",t.cssText=".ace-dawn .ace_gutter {background: #ebebeb;color: #333}.ace-dawn .ace_print-margin {width: 1px;background: #e8e8e8}.ace-dawn {background-color: #F9F9F9;color: #080808}.ace-dawn .ace_cursor {color: #000000}.ace-dawn .ace_marker-layer .ace_selection {background: rgba(39, 95, 255, 0.30)}.ace-dawn.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #F9F9F9;}.ace-dawn .ace_marker-layer .ace_step {background: rgb(255, 255, 0)}.ace-dawn .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgba(75, 75, 126, 0.50)}.ace-dawn .ace_marker-layer .ace_active-line {background: rgba(36, 99, 180, 0.12)}.ace-dawn .ace_gutter-active-line {background-color : #dcdcdc}.ace-dawn .ace_marker-layer .ace_selected-word {border: 1px solid rgba(39, 95, 255, 0.30)}.ace-dawn .ace_invisible {color: rgba(75, 75, 126, 0.50)}.ace-dawn .ace_keyword,.ace-dawn .ace_meta {color: #794938}.ace-dawn .ace_constant,.ace-dawn .ace_constant.ace_character,.ace-dawn .ace_constant.ace_character.ace_escape,.ace-dawn .ace_constant.ace_other {color: #811F24}.ace-dawn .ace_invalid.ace_illegal {text-decoration: underline;font-style: italic;color: #F8F8F8;background-color: #B52A1D}.ace-dawn .ace_invalid.ace_deprecated {text-decoration: underline;font-style: italic;color: #B52A1D}.ace-dawn .ace_support {color: #691C97}.ace-dawn .ace_support.ace_constant {color: #B4371F}.ace-dawn .ace_fold {background-color: #794938;border-color: #080808}.ace-dawn .ace_list,.ace-dawn .ace_markup.ace_list,.ace-dawn .ace_support.ace_function {color: #693A17}.ace-dawn .ace_storage {font-style: italic;color: #A71D5D}.ace-dawn .ace_string {color: #0B6125}.ace-dawn .ace_string.ace_regexp {color: #CF5628}.ace-dawn .ace_comment {font-style: italic;color: #5A525F}.ace-dawn .ace_heading,.ace-dawn .ace_markup.ace_heading {color: #19356D}.ace-dawn .ace_variable {color: #234A97}.ace-dawn .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYLh/5+x/AAizA4hxNNsZAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}); (function() {
ace.require(["ace/theme/dawn"], function(m) {
if (typeof module == "object" && typeof exports == "object" && module) {
module.exports = m;
}
});
})();

View File

@@ -0,0 +1,7 @@
ace.define("ace/theme/tomorrow_night",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-tomorrow-night",t.cssText=".ace-tomorrow-night .ace_gutter {background: #25282c;color: #C5C8C6}.ace-tomorrow-night .ace_print-margin {width: 1px;background: #25282c}.ace-tomorrow-night {background-color: #1D1F21;color: #C5C8C6}.ace-tomorrow-night .ace_cursor {color: #AEAFAD}.ace-tomorrow-night .ace_marker-layer .ace_selection {background: #373B41}.ace-tomorrow-night.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #1D1F21;}.ace-tomorrow-night .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-tomorrow-night .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #4B4E55}.ace-tomorrow-night .ace_marker-layer .ace_active-line {background: #282A2E}.ace-tomorrow-night .ace_gutter-active-line {background-color: #282A2E}.ace-tomorrow-night .ace_marker-layer .ace_selected-word {border: 1px solid #373B41}.ace-tomorrow-night .ace_invisible {color: #4B4E55}.ace-tomorrow-night .ace_keyword,.ace-tomorrow-night .ace_meta,.ace-tomorrow-night .ace_storage,.ace-tomorrow-night .ace_storage.ace_type,.ace-tomorrow-night .ace_support.ace_type {color: #B294BB}.ace-tomorrow-night .ace_keyword.ace_operator {color: #8ABEB7}.ace-tomorrow-night .ace_constant.ace_character,.ace-tomorrow-night .ace_constant.ace_language,.ace-tomorrow-night .ace_constant.ace_numeric,.ace-tomorrow-night .ace_keyword.ace_other.ace_unit,.ace-tomorrow-night .ace_support.ace_constant,.ace-tomorrow-night .ace_variable.ace_parameter {color: #DE935F}.ace-tomorrow-night .ace_constant.ace_other {color: #CED1CF}.ace-tomorrow-night .ace_invalid {color: #CED2CF;background-color: #DF5F5F}.ace-tomorrow-night .ace_invalid.ace_deprecated {color: #CED2CF;background-color: #B798BF}.ace-tomorrow-night .ace_fold {background-color: #81A2BE;border-color: #C5C8C6}.ace-tomorrow-night .ace_entity.ace_name.ace_function,.ace-tomorrow-night .ace_support.ace_function,.ace-tomorrow-night .ace_variable {color: #81A2BE}.ace-tomorrow-night .ace_support.ace_class,.ace-tomorrow-night .ace_support.ace_type {color: #F0C674}.ace-tomorrow-night .ace_heading,.ace-tomorrow-night .ace_markup.ace_heading,.ace-tomorrow-night .ace_string {color: #B5BD68}.ace-tomorrow-night .ace_entity.ace_name.ace_tag,.ace-tomorrow-night .ace_entity.ace_other.ace_attribute-name,.ace-tomorrow-night .ace_meta.ace_tag,.ace-tomorrow-night .ace_string.ace_regexp,.ace-tomorrow-night .ace_variable {color: #CC6666}.ace-tomorrow-night .ace_comment {color: #969896}.ace-tomorrow-night .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}); (function() {
ace.require(["ace/theme/tomorrow_night"], function(m) {
if (typeof module == "object" && typeof exports == "object" && module) {
module.exports = m;
}
});
})();

View File

@@ -0,0 +1,50 @@
/*
Taken from the reference.
Warnings and notes:
Write the <div>s on their own line. E.g.
<div class="warning">
Warning: This is bad!
</div>
*/
main .warning p {
padding: 10px 20px;
margin: 20px 0;
}
main .warning p::before {
content: "⚠️ ";
}
.light main .warning p,
.rust main .warning p {
border: 2px solid red;
background: #ffcece;
}
.rust main .warning p {
/* overrides previous declaration */
border-color: #961717;
}
.coal main .warning p,
.navy main .warning p,
.ayu main .warning p {
background: #542626
}
/* Make the links higher contrast on dark themes */
.coal main .warning p a,
.navy main .warning p a,
.ayu main .warning p a {
color: #80d0d0
}
span.caption {
font-size: .8em;
font-weight: 600;
}
span.caption code {
font-size: 0.875em;
font-weight: 400;
}

View File

@@ -0,0 +1,269 @@
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>The Element-Call book - The Element-Call Book</title>
<!-- Custom HTML head -->
<meta name="description" content="Element Call - the worlds first decentralised voice and video conferencing solution powered entirely by Matrix!">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferries.css">
<link rel="stylesheet" href="theme/2020-edition.css">
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
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>
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('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item affix "><a href="title-page.html" class="active">The Element-Call book</a></li><li class="chapter-item affix "><a href="foreword.html">Foreword</a></li><li class="chapter-item affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="chapter-item affix "><li class="part-title">Getting started</li><li class="chapter-item "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch01-01-building-blocks.html"><strong aria-hidden="true">1.1.</strong> The building blocks</a></li><li class="chapter-item "><a href="ch01-02-element-call-hello.html"><strong aria-hidden="true">1.2.</strong> Hello Element-Call!</a></li></ol></li><li class="chapter-item "><a href="ch02-00-installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li class="chapter-item "><a href="ch09-00-element-call-examples.html"><strong aria-hidden="true">3.</strong> Element-Call Examples</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="ch09-01-element-call-hello.html"><strong aria-hidden="true">3.1.</strong> ELement-Call-Hello!</a></li></ol></li><li class="chapter-item "><a href="appendix-00.html"><strong aria-hidden="true">4.</strong> Appendix</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="appendix-01-keywords.html"><strong aria-hidden="true">4.1.</strong> A - Keywords</a></li><li class="chapter-item "><a href="appendix-02-operators.html"><strong aria-hidden="true">4.2.</strong> B - Operators and Symbols</a></li><li class="chapter-item "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">4.3.</strong> C - Derivable Traits</a></li><li class="chapter-item "><a href="appendix-04-translation.html"><strong aria-hidden="true">4.4.</strong> D - Translations of the Book</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<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">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<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>
</div>
<h1 class="menu-title">The Element-Call Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/{path}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://gitea.networkx.de/rzerres/element-call/tree/main/book/src/title-page.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<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>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
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>
<h1 id="element-call"><a class="header" href="#element-call">Element Call</a></h1>
<p><em>annotated and documented by Ralf Zerres and all contributers</em></p>
<p>This version of the text assumes youre using Element-Call v0.6.7 or later in
conjuction with Rust v1.83.0 or later. <em>Cargo.toml</em> should define
<code>edition="2021"</code>. That enables and uses Rust 2021 Edition idioms in
all derived projects.</p>
<p>See the <a href="https://https://gitea.networkx.de/rzerres/element-call/book/ch02-00-installation.html">“Installation” section of Chapter 2</a>
to install or update Element-Call.</p>
<p>The 2021 Edition of this book is the initial release. It will be
released with the Element-Call version 1.0.0.</p>
<ul>
<li>Appendix A “Keywords”, explains the new raw identifiers.</li>
<li>Appendix D “Translations”, is work in progress. We will release
instances of this book in the target language once they are translated.</li>
</ul>
<p>For online reading, a HTML rendered version is available at
<a href="https://gitea.networkx.de/rzerres/element-call/book/blob/main/src/img/element-call.png">Element-Call book</a>. Alternatively you might want to have it handy
for offline usage. Either you downlaod a rendered <code>pdf</code> or
<code>ebook</code>version or go ahead and download the source. Then kick on
mdbook (the definition of the target location is optional).</p>
<pre><code class="language-console">mdbook build --dest-dir book_en --open
</code></pre>
<!---
This text is available in [paperback and ebook format from No Starch Press][nsprust].
-->
<!--
[element-call_book_en]: https://gitea.networkx.de/rzerres/element-call/book/
[element-call_book_en_stable]: https://element.io/element-call/stable/book/
-->
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="next prefetch" href="foreword.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="next prefetch" href="foreword.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="ferries.js"></script>
</div>
</body>
</html>

View File

@@ -0,0 +1,102 @@
/* Tomorrow Night Theme */
/* https://github.com/jmblog/color-themes-for-highlightjs */
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
/* https://github.com/jmblog/color-themes-for-highlightjs */
/* Tomorrow Comment */
.hljs-comment {
color: #969896;
}
/* Tomorrow Red */
.hljs-variable,
.hljs-attribute,
.hljs-tag,
.hljs-regexp,
.ruby .hljs-constant,
.xml .hljs-tag .hljs-title,
.xml .hljs-pi,
.xml .hljs-doctype,
.html .hljs-doctype,
.css .hljs-id,
.css .hljs-class,
.css .hljs-pseudo {
color: #cc6666;
}
/* Tomorrow Orange */
.hljs-number,
.hljs-preprocessor,
.hljs-pragma,
.hljs-built_in,
.hljs-literal,
.hljs-params,
.hljs-constant {
color: #de935f;
}
/* Tomorrow Yellow */
.ruby .hljs-class .hljs-title,
.css .hljs-rule .hljs-attribute {
color: #f0c674;
}
/* Tomorrow Green */
.hljs-string,
.hljs-value,
.hljs-inheritance,
.hljs-header,
.hljs-name,
.ruby .hljs-symbol,
.xml .hljs-cdata {
color: #b5bd68;
}
/* Tomorrow Aqua */
.hljs-title,
.css .hljs-hexcolor {
color: #8abeb7;
}
/* Tomorrow Blue */
.hljs-function,
.python .hljs-decorator,
.python .hljs-title,
.ruby .hljs-function .hljs-title,
.ruby .hljs-title .hljs-keyword,
.perl .hljs-sub,
.javascript .hljs-title,
.coffeescript .hljs-title {
color: #81a2be;
}
/* Tomorrow Purple */
.hljs-keyword,
.javascript .hljs-function {
color: #b294bb;
}
.hljs {
display: block;
overflow-x: auto;
background: #1d1f21;
color: #c5c8c6;
}
.coffeescript .javascript,
.javascript .xml,
.tex .hljs-formula,
.xml .javascript,
.xml .vbscript,
.xml .css,
.xml .hljs-cdata {
opacity: 0.5;
}
.hljs-addition {
color: #718c00;
}
.hljs-deletion {
color: #c82829;
}

View File

@@ -0,0 +1 @@
{"entries":{}}

View File

@@ -7,8 +7,11 @@
# Getting started # Getting started
- [Getting Started](ch01-00-getting-started.md) - [Getting Started](ch01-00-getting-started.md)
- [The building blocks](ch01-01-building-blocks.md) - [The routing structures](ch01-01-routing-structures.md)
- [Hello Element-Call!](ch01-02-element-call-hello.md) - [The building blocks](ch01-02-building-blocks.md)
<!--
- [Hello Element-Call!](ch01-03-element-call-hello.md)
-->
- [Installation](ch02-00-installation.md) - [Installation](ch02-00-installation.md)

View File

@@ -3,5 +3,5 @@
Lets start your Element-Call journey! Theres a lot to learn, but every journey starts Lets start your Element-Call journey! Theres a lot to learn, but every journey starts
somewhere. In this chapter, well discuss: somewhere. In this chapter, well discuss:
* WebRTC bases routing structures
* The building blocks of Element-Call * The building blocks of Element-Call
* Installing Element-Call

View File

@@ -1,4 +0,0 @@
## Building blocks
[element_call_building_blocks]: https://gitea.networkx.de/rzerres/element-call/book/blob/main/src/img/element-call_building_blocks.png

View File

@@ -0,0 +1,55 @@
## WebRTC bases routing structures
The following image visualize the concepts of actively used routing
structures inside a RTC applications.
![voip routing structures][voip_routing_structure]
Historically `Elememnt-Call` did implement an infrastructure, where
all participants were fully meshed. That means all participants had a
direct peer to each other in a `Mesh`. This structure does work quite well with a
low number of call partners (e.g 1:1 sessions). Clearly this structure
is totally inefficient and collapsing, as soon as the number of
participants rises: The needed number of streams that have to be
synchronized are increasing exponentioally.
Most `commercial solutions` overcome this bottleneck utilizing a
Multipoint Connection Unit (`MCU`): Each participant of the call is
directly connected to the controlling MCU. The MCU will consolidate
all streams and has only one stream to each participant. It is able to linearly scale.
MCU routing has disadvantages and shortcommings too.
* You can't assign different egress parameters from the MCU to
individual participant streams
* A single MCU can't handle distributed structure
Therefore `Element-Call` has choosen to implement the service on top of a
Selective Forward Unit (`SFU`) capable backend:
![Matrix structures][matrix_structure]
Each participant will only send in one stream to the choosen
`SFU`. The number of egress streams can scale linearly, comparable to
the concept used with an MCU. But in contrast to MCU based
communication clients insede the MatrixRTC are able to dynamicaly
advertise to their SFU what ingress streams they are interested in.
Here are some commen szenarios:
* I'm only interested to get participant A, B, C, E, G but not D and F
* Please only send high resolutions for the speaker and reduce the
bitrate for all other participants
* Change my own egress bitrate to a given value
On top of this, the nature of a Matrix based communication makes use of a
distributed infrastructure. Within MatrixRTC that allows communications
* between different involved SFU's
* Require and handle E2EE meetings for all participants
* Authenticate matrix accounts as well as guest accounts inside a call
![Matrix SFU structures][matrix_sfu_structure]
[matrix_structure]: ./img/matrix_structure.webp
[matrix_sfu_structure]: ./img/matrix_sfu_structure.png
[voip_routing_structure]: ./img/voip_routing_structures.png

View File

@@ -0,0 +1,91 @@
## Building blocks
For good reasons `Element-Call` is subdevided into logical components that encapsulate given functionality
* The Backend
* The reverse Proxy
* The Authentication service
* The Frontend
All this components have to be orchestrated to make up this realtime application. Let's have a look how they interact:
![Element-call structure][element_call_structure]
[element_call_structure]: ./img/element-call-structure.svg
### Backend
The MatrixRTC functionality is handled via [LiveKit][livekit_source].
Livekit is very versatile and flexible. It offers a clean API which
makes it an ideal fit to be used from the integration service.
[livekit_source]: https://github.com/livekit
### Reverse Proxy
In computer networks, a reverse proxy or surrogate server is a proxy
server that appears to any client to be an ordinary web server, but in
reality merely acts as an intermediary that forwards the client's
requests to one or more ordinary web servers. Reverse proxies
help increase scalability, performance, resilience, and security.
![Reverse-Proxy Service][reverse_proxy_service]
For example, your server-domain is only accessible via one official ip
address. But you like to offer multiple services that require secure
web traffik (https). You have to assign officliy signed certificates to this web server, but also need a proxy that, that can distinguish
which backend will handle the data exchange (rules, fqdn).
Following list is an non-exauthive list of popular proxy
implementation that may be run as reverse proxys:
* [HAProxy][haproxy_source]
* [NGINX][nginx_source]
* [traefik][traefik_source]
`Element-Call` will need to use such a reverse proxy, since it needs to re-route service traffik to other components that need to be exposed to the internet (explicitely: livekit, lifekit-jwt-service).
[haproxy_source]: https://github.com/haproxy/haproxy
[nginx_source]: https://github.com/nginx
[reverse_proxy_service]: ./img/reverse_proxy_structure.png
[traefik_source]: https://github.com/traefik/traefik
### Frontend
The `Element-Call` frontend handles the login of participants. You
can choose matrix account that is already registered on your
homeserver, or connect as a guest user to an existing call.
You may obtain the URL to the existing call from any room members.
![Element-Call brower login][element_call_browser_login]
The source code for the frontend is maintained at `github` in the
[Element-Call][element_call_source] repository.
[element_call_source]: https://github.com/element-hq/element-call
[element_call_browser_login]: ./img/element-call-browser-login.png
### Authentication service
After a participant has registerd himself via the `element-call`
frontend (as an existing matrix account or a guest user),
[websockets][websockets_service] are used to forward and manage the
required data via Json Web Tokens (`JWT`) to the livekit backend. This
allows to keep any communication secure, which is an elementary
request for E2EE calls.
![websocket_connection`][websocket_connection]
This job is handled from the
[`livekit_jwt_service`][livekit_jwt_service], that will forward the
correct tokens to the SFU endpoint inside the livekit instance the
user is connected to.
[livekit_jwt_service]: https://github.com/element-hq/lk-jwt-service
[websocket_connection]: ./img/websocket_connection.png
[websockets_service]: https://en.wikipedia.org/wiki/WebSocket

View File

@@ -1,11 +1,7 @@
## Installation ## Installation
The first step is to install Rust. This is described in depth following This section will help you to get up with you own self hosted instance
[Rust book Chapter 1](https://github.com/rust-lang/book/blob/master/src/ch01-01-installation.md) of `Element-Call`.
When creating a OrbTk application, we define the needed dependencies to the
OrbTk crates in the Cargo.toml file of our project. The complile process
will resolve the references and download the source as needed.
> ### Command Line Notation > ### Command Line Notation
> >
@@ -20,69 +16,41 @@ will resolve the references and download the source as needed.
> ***WIP***: What are the most common culprits? Can we provide some general, basic solutions > ***WIP***: What are the most common culprits? Can we provide some general, basic solutions
### Local Documentation ### Container based
OrbTk offers the option to install its documentation locally, so you can read it #### Precompiled docker instances
offline.
Any time a type, a function, a method or a crate is reference by the toolkit #### Source installation
and youre not sure what it does or how to use it, have a look at its application
programming interface [API documentation] to find out!
<!-- [API documentation]: https://www.redox-os.org/orbtk/doc/en --> > ***WIP***: Decide what kind of detail is sufficiant
<!-- [API documentation]: https://github.com/redox-os/orbtk -->
[API documentation]: https://docs.rs/orbtk
### Install Rust on Linux or macOS ### Native OS based
If you are using Linux or macOS open up an terminal and copy and paste the text below and hit the enter key on your keyboard: > ***WIP***: Decide what list of distros we should mention and
> maintain the required package names inside the book
```bash #### Arch Linux packages
curl https://sh.rustup.rs -sSf | sh
```
### Install Rust on Windows For `Arch Linux` you may grep precompiled packages for all components from the `AUR`.
Download and run the Rust windows installer from https://www.rust-lang.org/tools/install. #### Source installation
### Install Redoxer (Redox OS) > ***WIP***: Decide what kind of detail is sufficiant
If you want build and run your Rust application on a [KVM](https://en.wikipedia.org/wiki/Kernel-based_Virtual_Machine) capable OS for Redox you can use [redoxer](https://gitlab.redox-os.org/redox-os/redoxer). You need to download, compile and install the following packages
To install Redoxer you have to first install the rust toolchain. After that open up an terminal and copy and paste the text below and hit the enter key on your keyboard: * element-call
* livekit
* livekit-jwt-service
* nginx
```bash ### Adapt to your domain
cargo +nightly install redoxer
```
To compile and run your application on Redox OS you should check the Redox OS Book. > ***WIP***: Decide what kind of detail is sufficiant
### Editor and IDE integration Please take a minute and make sure you have selected the correct
informations for your domain. It is a hassle to redo the configuration and search for typos that may break the correct execution.
A wide range of editors and IDE's are providing support for Rust code like * Element-Call hostname (fqdn)
* LiveKit hostname
* like syntax-highlighting * Exposed Firewall ports (livekit, livekit-jwt, element-call, homeserver)
* auto-completion
* linting
* lsp support
#### VS Code
There is a big community that rely on the visualstudio implementation
to handle their code base. Following are the steps needed to expand
your installation to support `VS Code for Rust` development:
1. Download VS Code [from](https://code.visualstudio.com/download).
2. Install [Rust Language Server plugin](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust) (the
Rust Language Server).
#### Alternative Editors and IDEs
If you perefer other solution, you will find in depth help inside the
context of this inclomplete links:
* [Atom](https://atom.io/packages/language-rust)
* [Intellij IDEA](https://intellij-rust.github.io)
* [Vim](https://github.com/rust-lang/rust.vim)
* [Emacs](https://github.com/rust-lang/rust-mode)
* [Eclipse](https://github.com/eclipse/corrosion)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 KiB

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -1,12 +1,15 @@
#![crate_name = "element_call_book"] #![crate_name = "element_call_book"]
#![crate_type = "lib"] #![crate_type = "lib"]
//! ![Welcome to the element-call book.][element_call_book] //! Welcome to the Element-Call book.
//!
//! [element_call_book]: https://gitea.networkx.de/rzerres/element-call-book/src/branch/main/src/img/element-call-webui.png "Element-Call UI"
//! ![Element-Call book][element_call_book]
//! //!
//! This repository contains the text source for "The Element-Call" book. //! This repository contains the text source for "The Element-Call" book.
//! We will further reference to it as the `Element-Call Book`. //! We will further reference to it as the `Element-Call Book`.
//! //!
//! [element_call_book]: https://gitea.networkx.de/rzerres/element-call-book/src/branch/main/src/img/element-call-webui.png //!
//! <!-- //! <!--
//! WIP: once it is ready to be shipped //! WIP: once it is ready to be shipped
//! [The book is available in dead-tree form from No Starch Press][nostarch]. //! [The book is available in dead-tree form from No Starch Press][nostarch].
@@ -26,7 +29,7 @@
//! [releases]: https://element.io/element-call/book/releases //! [releases]: https://element.io/element-call/book/releases
//! --> //! -->
//! //!
//! ### Requirements //! ### Requirements
//! //!
//! #### mdBook //! #### mdBook
//! Building the book requires [mdBook] and its helper tools. The used //! Building the book requires [mdBook] and its helper tools. The used
@@ -99,7 +102,7 @@
//! [mdBook localization]: https://github.com/Nutomic/mdBook/tree/localization //! [mdBook localization]: https://github.com/Nutomic/mdBook/tree/localization
//! [rust-mdbook]: https://github.com/rust-lang/rust/blob/master/src/tools/rustbook/Cargo.toml //! [rust-mdbook]: https://github.com/rust-lang/rust/blob/master/src/tools/rustbook/Cargo.toml
//! //!
//! ### Building //! ### Building
//! //!
//! #### Building the book //! #### Building the book
//! //!
@@ -174,7 +177,7 @@
//! //!
//! <!-- //! <!--
//! WIP: once it is ready to be shipped //! WIP: once it is ready to be shipped
//! ### Code of Conduct //! ### 🌻 Code of Conduct
//! //!
//! We are committed to providing a friendly, safe and welcoming //! We are committed to providing a friendly, safe and welcoming
//! environment. Read more about our policy in the [code-of-conduct][coc] page. //! environment. Read more about our policy in the [code-of-conduct][coc] page.
@@ -187,21 +190,17 @@
//! [element-call-room-matrix]: https://matrix.to/#/#element-call-dev:matrix.org>`_` //! [element-call-room-matrix]: https://matrix.to/#/#element-call-dev:matrix.org>`_`
//! --> //! -->
//! //!
//! #### Translations //! ### 🌐 Translations
//! //!
//! We'd love help to translate the book! See the [Translations] label //! We'd love help to translate the book! See the [Translations] label
//! to join in efforts that are currently in progress. Open a new //! to join in efforts that are currently in progress. Open a new
//! issue to start working on a new language! We're waiting on [mdbook //! issue to start working on a new language!
//! support] for multiple languages to be finalized, but feel free to
//! start! A [pull request] looks promising. The mainline version (we
//! do depend on v0.4.12) is capable to render the existing versions
//! where sources are installed in the intended final structure.
//! //!
//! [Translations]: https://gitea.networkx.de/rzerres/element-call/book/issues?q=is%3Aopen+is%3Aissue+label%3ATranslations //! [Translations]: https://gitea.networkx.de/rzerres/element-call/book/issues?q=is%3Aopen+is%3Aissue+label%3ATranslations
//! [mdbook support]: https://github.com/rust-lang-nursery/mdBook/issues/5 //! [mdbook support]: https://github.com/rust-lang-nursery/mdBook/issues/5
//! [pull request]: https://github.com/rust-lang/mdBook/pull/1306 //! [pull request]: https://github.com/rust-lang/mdBook/pull/1306
//! //!
//! ### Spellchecking //! ### Spellchecking
//! //!
//! To scan source files for spelling errors, you can use the `spellcheck.sh` //! To scan source files for spelling errors, you can use the `spellcheck.sh`
//! script. It needs a dictionary of valid words, which is provided in //! script. It needs a dictionary of valid words, which is provided in
@@ -209,7 +208,7 @@
//! `BTreeMap` which the script considers invalid), you need to add this word to //! `BTreeMap` which the script considers invalid), you need to add this word to
//! `dictionary.txt` (keep the sorted order for consistency). //! `dictionary.txt` (keep the sorted order for consistency).
//! //!
//! ### License //! ### License
//! //!
//! <!-- License source --> //! <!-- License source -->
//! [Logo-CC_BY]: https://i.creativecommons.org/l/by/4.0/88x31.png "Creative Common Logo" //! [Logo-CC_BY]: https://i.creativecommons.org/l/by/4.0/88x31.png "Creative Common Logo"

View File

@@ -1,6 +1,8 @@
# Element Call # Element-Call
[element_call_book]: https://gitea.networkx.de/rzerres/element-call/book/blob/main/src/img/element-call.png ![Element-Call][element_call]
[element_call]: ./img/element-call.png
*annotated and documented by Ralf Zerres and all contributers* *annotated and documented by Ralf Zerres and all contributers*