Decentral Messaging (#1)
This commit is contained in:
parent
75b550020a
commit
edd1ac0157
|
@ -0,0 +1,2 @@
|
|||
node_modules
|
||||
public
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
image: monachus/hugo
|
||||
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
|
||||
pages:
|
||||
script:
|
||||
- hugo
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
only:
|
||||
- master
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
[submodule "themes/reveal-hugo/static/reveal-js"]
|
||||
path = themes/reveal-hugo/static/reveal-js
|
||||
url = https://github.com/hakimel/reveal.js.git
|
||||
[submodule "themes/reveal-hugo/static/highlight-js"]
|
||||
path = themes/reveal-hugo/static/highlight-js
|
||||
url = https://github.com/highlightjs/highlight.js.git
|
12
PITCHME.yaml
12
PITCHME.yaml
|
@ -1,12 +0,0 @@
|
|||
logo : https://ccchb.de/logo/CCCHB-logo_256x256_bw.png
|
||||
footnote : "Chaos Computer Club Bremen e.V."
|
||||
|
||||
layout : top-left
|
||||
theme : black
|
||||
highlight : ir-black
|
||||
theme-override : custom.css
|
||||
|
||||
transition : none
|
||||
published : true
|
||||
|
||||
code-line-numbers : true
|
21
README.md
21
README.md
|
@ -1 +1,22 @@
|
|||
## Presentations:
|
||||
|
||||
2018:
|
||||
- [Dezentrales Messaging](https://ccchb.github.io/presentations/decentral_messaging)
|
||||
|
||||
## Create a presentation
|
||||
Run: `hugo server -D`
|
||||
|
||||
Create a new presentation `content/<NAME>/_index.md`
|
||||
|
||||
Browser: http://localhost:1313/presentations/<NAME>
|
||||
|
||||
|
||||
## Update
|
||||
```
|
||||
hugo
|
||||
cd public
|
||||
git add --all
|
||||
git commit -m "Publishing to gh-pages"
|
||||
git push origin gh-pages
|
||||
cd ..
|
||||
```
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
title: "{{ replace .Name "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
outputs:
|
||||
- "Reveal"
|
||||
draft: true
|
||||
---
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
baseURL = "https://ccchb.github.io/presentations/"
|
||||
languageCode = "en-us"
|
||||
title = "Presentation from CCCHB"
|
||||
disableKinds = ["sitemap", "RSS"]
|
||||
theme = "reveal-hugo"
|
||||
|
||||
[params.reveal_hugo]
|
||||
history = true
|
||||
highlight_theme = "qtcreator_dark"
|
||||
margin = 0.2
|
||||
custom_theme = "css/main.css"
|
||||
transition = "slide"
|
||||
transition_speed = "fast"
|
||||
|
||||
|
||||
[outputFormats.Reveal]
|
||||
baseName = "index"
|
||||
mediaType = "text/html"
|
||||
isHTML = true
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
title: "Presentations from CCCHB"
|
||||
outputs:
|
||||
- "Reveal"
|
||||
---
|
||||
|
||||
# Presentations
|
||||
|
||||
- [Decentrales Messaging](./decentral_messaging)
|
|
@ -0,0 +1,348 @@
|
|||
---
|
||||
title: "Dezentrale Messenger"
|
||||
outputs:
|
||||
- "Reveal"
|
||||
---
|
||||
|
||||
<h2 style="white-space: nowrap;">Dezentrale Messenger</h2>
|
||||
<br/>
|
||||
<h4 style="white-space: nowrap;">The very last word in instant messaging</h4>
|
||||
(Motto vom XMPP-Client Converations)
|
||||
|
||||
<span class="text-reboot">genofire - Chaos Computer Club Bremen e.V.</span>
|
||||
|
||||
---
|
||||
|
||||
## Agenda
|
||||
- Dezentralität
|
||||
- XMPP - Der Standard
|
||||
- Software (Client und Server)
|
||||
- Ist der Hoster gut
|
||||
- Verschlüsselung
|
||||
- Ausblick
|
||||
- Alternativen
|
||||
|
||||
---
|
||||
|
||||
## Dezentralität
|
||||
- **Peer-to-Peer**
|
||||
|
||||
Geräte tauschen direkt miteinander Nachrichten aus (ohne eine zentrale Componente)
|
||||
|
||||
- **Federation**
|
||||
|
||||
Kommunikation über zentrale Komponenten
|
||||
|
||||
|
||||
{{% note %}}
|
||||
**P2P**
|
||||
- Postkasten, jeder kann zum Empfänger gehen und selbst etwas in den Kasten werfen.
|
||||
(wenn es keine Post gibt)
|
||||
|
||||
**Federation**
|
||||
- E-Mail (ISP: benutzer@hoster.de)
|
||||
- Telefonnummern (Addr: hat oftmals die ersten Ziffern für sich reserviert)
|
||||
{{% /note %}}
|
||||
|
||||
---
|
||||
|
||||
## Dezentralität
|
||||
|
||||
#### Warum notwendig?
|
||||
|
||||
- Eröffnet ein Wettbewerb
|
||||
- kleine und viele Angriffsziele
|
||||
- vor Kriminelle
|
||||
- vor Regierungen
|
||||
- alle Überwachen
|
||||
- blockieren / sperren (Zensur)
|
||||
- Verringert Missbrauch durch Vertrauen
|
||||
|
||||
{{% note %}}
|
||||
- _Eröffnet einen Wettbewerb:_ damit fortschritt
|
||||
(Gewinne gehen zum größten Teile in die USA)
|
||||
- Entscheidungen: z.B. nur noch auf Englisch, Mark Zuckerberg darf Nachrichten löschen
|
||||
- _Angriffsziele:_
|
||||
- Hacker können nicht alle Server kompromentieren
|
||||
- Regierungen können nicht
|
||||
- den Zugang zu allen Servern verlangen (NSA - Snowden)
|
||||
- alle Server blockieren (Telegram - Russland)
|
||||
- _Verringert Missbrauch durch Vertrauen_
|
||||
- **Auswirkung:** nicht alle Daten können **geklaut** oder **analysiert** werden
|
||||
- Analysiert zur Manipulation (Werbung oder politisch, siehe Cambridge Analytica)
|
||||
- **Bei Missbrauch** leichterer Wechsel
|
||||
{{% /note %}}
|
||||
|
||||
---
|
||||
|
||||
## Dezentralität
|
||||
|
||||
|
||||
#### Nachteile
|
||||
- Komplexität steigt
|
||||
- Gewollte Verringerung an Marktanteil
|
||||
- Kann auch von kriminellen Elementen genutzt werden
|
||||
- Nutzer müssen sich ggf. sich Ihre Adresse und Passwort sich merken
|
||||
|
||||
{{% note %}}
|
||||
- _Komplexität steigt:_ Da nicht nur Clients, sondern auch Server untereinander sicher (Ausfall, vertrauensvoll) kommunizieren müssen.
|
||||
- _kriminellen Elementen:_ wie bei jeder Technologie kann diese auch von Bösen genutzt werden.
|
||||
- _... sich merken:_ allerdings müssen Sie dies auch für Ihre E-Mail-Adresse, was noch Standard im Internet ist.
|
||||
{{% /note %}}
|
||||
|
||||
---
|
||||
### Extensible Messaging and Presence Protocol (XMPP)
|
||||
|
||||
- Existiert seit 1999 (unter den Namen Jabber)
|
||||
- IETF Standard seit 2002
|
||||
|
||||
|
||||
- Google Talk 2005 - 2013 (entwickelte Jingle)
|
||||
- Facebook 2010 - 2014
|
||||
- WhatsApp nutzt es intern
|
||||
|
||||
{{% note %}}
|
||||
- Jingle:
|
||||
- Aushandlung von Datenverbindung (angelehnt an SIP)
|
||||
- für: Datenaustausch, Video/Voice-Chat, ...
|
||||
{{% /note %}}
|
||||
|
||||
---
|
||||
|
||||
## XMPP
|
||||
#### Adressierung
|
||||
JID (Jabber ID) genannt:
|
||||
```
|
||||
node@domain/ressource
|
||||
```
|
||||
|
||||
URI-Format: (falls MUC mit `?join` am Ende)
|
||||
|
||||
```
|
||||
xmpp:node@domain?join
|
||||
```
|
||||
|
||||
{{% note %}}
|
||||
- MUC (Multi User Chat): Gruppenchat
|
||||
|
||||
**Als User**
|
||||
|
||||
- benutzer@server/gerät
|
||||
|
||||
**In MUC**
|
||||
|
||||
- chatraum@muc-server/nickame
|
||||
|
||||
**Transport**
|
||||
- ganz unterschiedlich
|
||||
{{% /note %}}
|
||||
|
||||
---
|
||||
## XMPP
|
||||
|
||||
**Message**
|
||||
|
||||
```xml
|
||||
<message from="geno@fireorbit.de"
|
||||
to="#ccchb@irc.hackint.org" type="groupchat">
|
||||
Hello World
|
||||
</message>
|
||||
```
|
||||
|
||||
Types:
|
||||
|
||||
- chat
|
||||
- groupchat
|
||||
- headline
|
||||
- normal
|
||||
- error
|
||||
|
||||
---
|
||||
## XMPP
|
||||
|
||||
**Present**: Aktuelle Live Informationen
|
||||
|
||||
```xml
|
||||
<present to="#ccchb@irc.hackint.org" type="subscribe">
|
||||
</present>
|
||||
```
|
||||
|
||||
Types:
|
||||
|
||||
- error
|
||||
- probe
|
||||
- subscribe(d)
|
||||
- unavailable
|
||||
- unsubscribe(d)
|
||||
|
||||
---
|
||||
## XMPP
|
||||
|
||||
**IQ** (Instant Query): Abfragen mit Rückantworten
|
||||
|
||||
```xml
|
||||
<iq to="irc.hackint.org" type="get">
|
||||
<ping xmlns='urn:xmpp:ping'/>
|
||||
</iq>
|
||||
```
|
||||
|
||||
Types:
|
||||
|
||||
- get
|
||||
- set
|
||||
- result
|
||||
- error
|
||||
|
||||
{{% note %}}
|
||||
- Die Inhalte, die in diesen XML-Elementen drin sind, werden im RFC nicht vorgegeben und kann für viele Funktionen genutzt werden.
|
||||
{{% /note %}}
|
||||
|
||||
---
|
||||
|
||||
## Software <small>Clients</small>
|
||||
#### Empfehlungen:
|
||||
- Conversations (Android)
|
||||
- Pix-Art Messenger
|
||||
- ChatSecure (iPhone)
|
||||
- Gajim (Desktop)
|
||||
- ConverseJS (WebClient)
|
||||
- Viele mehr
|
||||
- mit [OMEMO](https://omemo.top)
|
||||
- [alle](https://xmpp.org/software/clients.html)
|
||||
|
||||
---
|
||||
|
||||
## Software <small>Clients</small>
|
||||
Bombus - Client in J2ME für normale Telefone
|
||||
<center>
|
||||
<img width="50%" src="img/j2me-bombus.jpg" alt="Wikipedia - Article Java"/>
|
||||
</center>
|
||||
|
||||
---
|
||||
|
||||
## Software <small>Server</small>
|
||||
- **prosody** in lua
|
||||
- leicht erweiterbar
|
||||
- riesige Sammlung an erweiterbaren Modulen (die man nutzen muss)
|
||||
|
||||
- **ejabberd** (Fork: mongooseIM) in erlang
|
||||
- besitzt alle nötigen Funktionen von Haus aus
|
||||
- sehr gut gewartet
|
||||
|
||||
- **OpenFire** in Java
|
||||
|
||||
---
|
||||
|
||||
## Ist der Hoster gut
|
||||
Tools zum Testen des Servers (Auswahl an Servern)
|
||||
|
||||
- [Compliance](https://compliance.conversations.im/) ([support Alles](https://compliance.conversations.im/api/compliant_servers/) / API)
|
||||
- [Status](https://status.conversations.im/historical/) für S2S + Uptime
|
||||
|
||||
XEPs:
|
||||
|
||||
- PEP / PubSub
|
||||
- MAM (für MUC)
|
||||
- HTTP-Upload
|
||||
- DNS-SRV for TLS (HTTPS)
|
||||
|
||||
{{% note %}}
|
||||
- Personal Eventing Protocol: Geolocation, Mood, Activity, Tune
|
||||
- Message Archive Management:
|
||||
- Vorteil gegenüber: Threema und WhatsApp (mit OMEMO auch gegenüber Telegram)
|
||||
- OMEMO: Neue Geräte können alte Nachrichten nicht entschlüsseln
|
||||
- HTTP-Upload: Offline und in MUC Datenaustausch
|
||||
- "umgeht" Firewalls
|
||||
{{% /note %}}
|
||||
|
||||
---
|
||||
## XMPP
|
||||
|
||||
### Verschlüsselung
|
||||
- Off-The-Record
|
||||
- OpenPGP
|
||||
- OX
|
||||
- OMEMO
|
||||
|
||||
Detailert: [here](https://conversations.im/omemo)
|
||||
|
||||
{{% note %}}
|
||||
- Neben TLS (SSL)
|
||||
{{% /note %}}
|
||||
|
||||
---
|
||||
|
||||
## XMPP <small>Verschlüsselung</small>
|
||||
|
||||
- Geräte erstellt **asynchrones** Schlüsselpaar
|
||||
- öffentlichen Schlüssel wird per PubSub auf dem Server hinterlegt
|
||||
- Kontakte werden durch PEP / PubSub über neuen Schlüssel informiert
|
||||
- Dieser muss diesen öffentlichen Schlüssel laden
|
||||
|
||||
{{% note %}}
|
||||
- synchrone: Entspricht einem Passwort, was allen Gesprächsteilnehmern bekannt ist.
|
||||
- asynchrone: mathematisches Verfahren mit Schlüsselpaaren (öffentlicher und privater Schlüssel)
|
||||
- Kontakte = Roster
|
||||
- den **neuen oder weiteren** öffentlichen Schlüssel
|
||||
|
||||
- Signiert und verschlüsselt
|
||||
- zurückziehen des Schlüssels
|
||||
{{% /note %}}
|
||||
|
||||
---
|
||||
|
||||
<center>
|
||||
<h1>Demo</h1>
|
||||
[Anleitung](https://media.kuketz.de/blog/artikel/2016/conversations/Anleitung_Conversations_V1.1_CC-BY-SA.pdf)
|
||||
</center>
|
||||
|
||||
---
|
||||
|
||||
## Ausblick
|
||||
|
||||
- Transports
|
||||
- Biboumi: IRC
|
||||
- Spectrum2: e.g AIM, ICQ, MSN, Yahoo, Telegram, Twitter, "WhatsApp"
|
||||
- PubSub
|
||||
- Blogging / Posting (siehe Movim)
|
||||
- Commands
|
||||
- Internet of Things
|
||||
|
||||
[XEP-Liste](https://xmpp.org/extensions/) letzter Eintrag: XEP-0410: MUC Self-Ping (Schrödinger's Chat)
|
||||
|
||||
{{% note %}}
|
||||
- Transport WhatsApp Warnung, vor Protokolländerungen und Sperrungen
|
||||
{{% /note %}}
|
||||
|
||||
---
|
||||
|
||||
## Alternativen zu XMPP
|
||||
|
||||
#### Peer-to-Peer
|
||||
- Nutzen das Tor-Netzwerk
|
||||
- **Tox**
|
||||
- **Briar**
|
||||
- kann auch Local per Wifi und Bluetooth genutzt werden
|
||||
- ... (viele mehr)
|
||||
- libp2p
|
||||
|
||||
- (mir sonst keine Weiteren bekannt ...)
|
||||
|
||||
---
|
||||
|
||||
## Alternativen zu XMPP
|
||||
|
||||
#### Federation
|
||||
- **Matrix** (Riot):
|
||||
- Änderungsvorschläge am Protokoll werden durch das Unternehmen entschieden
|
||||
- (mir sonst keine Weiteren bekannt ...)
|
||||
|
||||
|
||||
---
|
||||
|
||||
<center>
|
||||
<h1>Ende</h1>
|
||||
<a href="https://www.ccc.de/de/hackerethik"><h4>Hackerethik</h4></a>
|
||||
|
||||
**3. Mißtraue Autoritäten – fördere Dezentralisierung.**
|
||||
</center>
|
22
custom.css
22
custom.css
|
@ -1,22 +0,0 @@
|
|||
body {
|
||||
background: #000;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
html:-webkit-full-screen-ancestor {
|
||||
background: #000;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
html:-moz-full-screen-ancestor {
|
||||
background: #000;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.reveal pre {
|
||||
box-shadow : none;
|
||||
}
|
||||
|
||||
.reveal .slides section > ul {
|
||||
margin-left: 1em;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
reusable = '''
|
||||
|
||||
## Reusable slides
|
||||
|
||||
Store markdown in a [data template](https://gohugo.io/templates/data-templates/) and reuse it in multiple sections or presentations.
|
||||
|
||||
<br>
|
||||
<small>
|
||||
navigate down to learn more
|
||||
</small>
|
||||
<br>
|
||||
<a href="#" class="navigate-down">🔽</a>
|
||||
|
||||
---
|
||||
|
||||
Add a `example` key to data/home.toml:
|
||||
|
||||
```toml
|
||||
example = "I'm a slide"
|
||||
```
|
||||
<br>
|
||||
|
||||
Set the `content` attribute to "home.example":
|
||||
|
||||
```markdown
|
||||
---
|
||||
|
||||
{{< slide content="home.example" >}}
|
||||
|
||||
---
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
💡 Each data template entry can contain one or more slides, separated by `---` with newlines.
|
||||
|
||||
---
|
||||
|
||||
💡 All other slide shortcode attributes (background, transition, etc.) can be used and will be applied to each slide in the data template entry.
|
||||
|
||||
'''
|
|
@ -0,0 +1,9 @@
|
|||
[build]
|
||||
command = "hugo"
|
||||
publish = "public"
|
||||
|
||||
[context.production.environment]
|
||||
HUGO_VERSION = "0.42.2"
|
||||
|
||||
[context.deploy-preview.environment]
|
||||
HUGO_VERSION = "0.42.2"
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,11 @@
|
|||
@import "reveal.css";
|
||||
|
||||
.reveal .slides {
|
||||
text-align: left;
|
||||
}
|
||||
body {
|
||||
background-image: url(https://ccchb.de/logo/CCCHB-logo_256x256_bw.png);
|
||||
background-position: left 20px top 10px;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 8% auto;
|
||||
}
|
|
@ -0,0 +1,293 @@
|
|||
@import "35c3.min.css";
|
||||
|
||||
body {
|
||||
color:#fff;
|
||||
background-color:#000;
|
||||
font-size: 32px;
|
||||
font-weight: normal;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.reveal {
|
||||
padding: 5px;
|
||||
border: 8px solid;
|
||||
border-image: linear-gradient(to right, #00a356, #0084b0) 1;
|
||||
}
|
||||
|
||||
.reveal .controls {
|
||||
color: #00a356;
|
||||
right: 50px;
|
||||
bottom: 50px;
|
||||
}
|
||||
|
||||
::selection {
|
||||
color: #fff;
|
||||
background: #ffc0d5;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
::-moz-selection {
|
||||
color: #fff;
|
||||
background: #ffc0d5;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.reveal .slides > section,
|
||||
.reveal .slides > section > section {
|
||||
line-height: 1.3;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* HEADERS
|
||||
*********************************************/
|
||||
.reveal h1,
|
||||
.reveal h2,
|
||||
.reveal h3,
|
||||
.reveal h4,
|
||||
.reveal h5,
|
||||
.reveal h6 {
|
||||
margin: 0 0 20px 0;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
letter-spacing: normal;
|
||||
text-transform: uppercase;
|
||||
text-shadow: none;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.reveal h1 {
|
||||
font-size: 2.6em;
|
||||
}
|
||||
|
||||
.reveal h2 {
|
||||
font-size: 2.2em;
|
||||
}
|
||||
|
||||
.reveal h3 {
|
||||
font-size: 1.7em;
|
||||
}
|
||||
|
||||
.reveal h4 {
|
||||
font-size: 1.4em;
|
||||
}
|
||||
|
||||
.reveal h1 {
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* OTHER
|
||||
*********************************************/
|
||||
.reveal p {
|
||||
margin: 20px 0;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
/* Ensure certain elements are never larger than the slide itself */
|
||||
.reveal img,
|
||||
.reveal video,
|
||||
.reveal iframe {
|
||||
max-width: 95%;
|
||||
max-height: 95%;
|
||||
}
|
||||
|
||||
.reveal strong,
|
||||
.reveal b {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.reveal ol,
|
||||
.reveal dl,
|
||||
.reveal ul {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
margin: 0 0 0 1em;
|
||||
}
|
||||
|
||||
.reveal ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.reveal ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.reveal ul ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
.reveal ul ul ul {
|
||||
list-style-type: circle;
|
||||
}
|
||||
|
||||
.reveal ul ul,
|
||||
.reveal ul ol,
|
||||
.reveal ol ol,
|
||||
.reveal ol ul {
|
||||
display: block;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.reveal dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal dd {
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.reveal blockquote {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 70%;
|
||||
margin: 20px auto;
|
||||
padding: 5px;
|
||||
font-style: italic;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.reveal blockquote p:first-child,
|
||||
.reveal blockquote p:last-child {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.reveal q {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.reveal pre {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 90%;
|
||||
margin: 20px auto;
|
||||
text-align: left;
|
||||
font-size: 0.55em;
|
||||
font-family: monospace;
|
||||
line-height: 1.2em;
|
||||
word-wrap: break-word;
|
||||
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3);
|
||||
border: 2px solid transparent;
|
||||
border-image: linear-gradient(to right, #00a356, #0084b0) 1 round;
|
||||
}
|
||||
|
||||
.reveal code {
|
||||
font-family: monospace;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.reveal pre code {
|
||||
display: block;
|
||||
padding: 5px;
|
||||
overflow: auto;
|
||||
max-height: 400px;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.reveal table {
|
||||
margin: auto;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.reveal table th {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal table th,
|
||||
.reveal table td {
|
||||
text-align: left;
|
||||
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
.reveal table th[align="center"],
|
||||
.reveal table td[align="center"] {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.reveal table th[align="right"],
|
||||
.reveal table td[align="right"] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.reveal table tbody tr:last-child th,
|
||||
.reveal table tbody tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.reveal sup {
|
||||
vertical-align: super;
|
||||
}
|
||||
|
||||
.reveal sub {
|
||||
vertical-align: sub;
|
||||
}
|
||||
|
||||
.reveal small {
|
||||
display: inline-block;
|
||||
font-size: 0.6em;
|
||||
line-height: 1.2em;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.reveal small * {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* LINKS
|
||||
*********************************************/
|
||||
.reveal .roll span:after {
|
||||
color: #fff;
|
||||
background: #f30053;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* IMAGES
|
||||
*********************************************/
|
||||
.reveal section img {
|
||||
margin: 15px 0px;
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
border: 4px solid #363636;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.reveal section img.plain {
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.reveal a img {
|
||||
-webkit-transition: all .15s linear;
|
||||
-moz-transition: all .15s linear;
|
||||
transition: all .15s linear;
|
||||
}
|
||||
|
||||
.reveal a:hover img {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-color: #00a356;
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* PROGRESS BAR
|
||||
*********************************************/
|
||||
|
||||
.reveal .progress span {
|
||||
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
|
||||
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
|
||||
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
|
||||
}
|
||||
|
||||
.reveal .progress {
|
||||
margin: 2px;
|
||||
z-index: 1000;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
color: #00a356;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 122 KiB |
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 Josh Dzielak
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,102 @@
|
|||
<!doctype html>
|
||||
{{- $reveal_cdn := $.Param "reveal_hugo.reveal_cdn" | default "reveal-js" -}}
|
||||
{{- $highlight_cdn := $.Param "reveal_hugo.highlight_cdn" | default "highlight-js/src/styles" -}}
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{{ or .Page.Title .Site.Title }}</title>
|
||||
{{ with $.Param "description" }}<meta name="description" content="{{ . }}">{{ end }}
|
||||
{{ with .Site.Author.name }}<meta name="author" content="{{ . }}">{{ end }}
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<link rel="stylesheet" href="{{ $reveal_cdn | absURL }}/css/reveal.css">
|
||||
<!-- Theme used for presentation -->
|
||||
{{- $theme := $.Param "reveal_hugo.theme" | default "black" -}}
|
||||
{{- $custom_theme := $.Param "reveal_hugo.custom_theme" -}}
|
||||
{{- if $custom_theme -}}
|
||||
<link rel="stylesheet" href="{{ $custom_theme | relURL }}" id="theme">
|
||||
{{ else -}}
|
||||
<link rel="stylesheet" href="{{ $reveal_cdn | absURL }}/css/theme/{{ $theme }}.css" id="theme">
|
||||
{{- end -}}
|
||||
<!-- Theme used for syntax highlighting of code -->
|
||||
{{- $highlight_theme := $.Param "reveal_hugo.highlight_theme" | default "default" -}}
|
||||
<link rel="stylesheet" href="{{ $highlight_cdn | absURL }}/{{ $highlight_theme }}.css">
|
||||
<!-- Printing and PDF exports -->
|
||||
<script>
|
||||
var link = document.createElement( 'link' );
|
||||
link.rel = 'stylesheet';
|
||||
link.type = 'text/css';
|
||||
link.href = window.location.search.match( /print-pdf/gi ) ? '{{ $reveal_cdn | absURL }}/css/print/pdf.css' : '{{ $reveal_cdn | absURL }}/css/print/paper.css';
|
||||
document.getElementsByTagName( 'head' )[0].appendChild( link );
|
||||
</script>
|
||||
<!-- To insert markup before the closing head tag for all presentations,
|
||||
create layouts/partials/reveal-hugo/head.html -->
|
||||
{{- partial "reveal-hugo/head" . -}}
|
||||
<!-- To insert markup at the end of the head tag for a specific presentation,
|
||||
create layouts/partials/{section}/reveal-hugo/head.html -->
|
||||
{{- $sectionHeadPartial := printf "%s/reveal-hugo/head" (.Page.Section | default "home") -}}
|
||||
{{- if fileExists (printf "layouts/partials/%s.html" $sectionHeadPartial) -}}{{ partial $sectionHeadPartial . }}{{- end }}
|
||||
</head>
|
||||
<body>
|
||||
<div class="reveal">
|
||||
<div class="slides">
|
||||
{{- block "main" . -}}{{- end -}}
|
||||
</div>
|
||||
<!-- To insert markup at the end of the .reveal tag for all presentations,
|
||||
create layouts/partials/reveal-hugo/end.html -->
|
||||
{{- partial "reveal-hugo/end" . -}}
|
||||
<!-- To insert markup at the end of the .reveal tag for a specific presentation,
|
||||
create layouts/partials/{section}/reveal-hugo/end.html -->
|
||||
{{- $sectionHeadPartial := printf "%s/reveal-hugo/end" (.Page.Section | default "home") -}}
|
||||
{{- if fileExists (printf "layouts/partials/%s.html" $sectionHeadPartial) -}}{{ partial $sectionHeadPartial . }}{{- end }}
|
||||
</div>
|
||||
<script type="application/json" id="reveal-hugo-site-params">{{ jsonify .Site.Params.reveal_hugo | safeJS }}</script>
|
||||
<script type="application/json" id="reveal-hugo-page-params">{{ jsonify .Page.Params.reveal_hugo | safeJS }}</script>
|
||||
<script type="text/javascript"> window.revealHugoDependencies = { dependencies: [ { src: '{{ $reveal_cdn | absURL }}/lib/js/classList.js', condition: function() { return !document.body.classList; } },
|
||||
{ src: '{{ $reveal_cdn | absURL }}/plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
|
||||
{ src: '{{ $reveal_cdn | absURL }}/plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
|
||||
{ src: '{{ $reveal_cdn | absURL }}/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
|
||||
{ src: '{{ $reveal_cdn | absURL }}/plugin/zoom-js/zoom.js', async: true },
|
||||
// the notes plugin can't run off the CDN b/c the HTML file isn't there
|
||||
{ src: '{{ "reveal-js/plugin/notes/notes.js" | relURL }}', async: true }
|
||||
]};
|
||||
</script>
|
||||
<script src="{{ $reveal_cdn | absURL }}/lib/js/head.min.js"></script>
|
||||
<script src="{{ $reveal_cdn | absURL }}/js/reveal.js"></script>
|
||||
<script type="text/javascript">
|
||||
// Hugo lowercases all params and Reveal.js needs camelcase
|
||||
// So params in Hugo must be stored in snakecase and we camelize them here
|
||||
function camelize(map) {
|
||||
if (map) {
|
||||
Object.keys(map).forEach(function(k) {
|
||||
newK = k.replace(/(\_\w)/g, function(m) { return m[1].toUpperCase() });
|
||||
if (newK != k) {
|
||||
map[newK] = map[k];
|
||||
delete map[k];
|
||||
}
|
||||
});
|
||||
}
|
||||
return map;
|
||||
}
|
||||
// pattern inspired by https://github.com/RealOrangeOne/hugo-theme-revealjs
|
||||
var revealHugoDefaults = { center: true, controls: true, history: true, progress: true, transition: "slide" };
|
||||
var revealHugoSiteParams = JSON.parse(document.getElementById('reveal-hugo-site-params').innerHTML);
|
||||
var revealHugoPageParams = JSON.parse(document.getElementById('reveal-hugo-page-params').innerHTML);
|
||||
// See all options - https://github.com/hakimel/reveal.js#configuration
|
||||
var options = Object.assign({},
|
||||
camelize(revealHugoDefaults),
|
||||
camelize(revealHugoSiteParams),
|
||||
camelize(revealHugoPageParams),
|
||||
revealHugoDependencies);
|
||||
Reveal.initialize(options);
|
||||
</script>
|
||||
<!-- To insert markup before the closing body tag for all presentations,
|
||||
create layouts/partials/reveal-hugo/body.html -->
|
||||
{{- partial "reveal-hugo/body" . }}
|
||||
<!-- To insert markup at the end of the head tag for a specific presentation,
|
||||
create layouts/partials/{section}/reveal-hugo/body.html -->
|
||||
{{- $sectionBodyPartial := printf "%s/reveal-hugo/body" (.Page.Section | default "home") -}}
|
||||
{{- if fileExists (printf "layouts/partials/%s.html" $sectionBodyPartial) -}}{{ partial $sectionBodyPartial . }}{{- end }}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,3 @@
|
|||
{{ define "main" }}
|
||||
{{ partial "reveal-hugo/slides" (union (slice .Page) (where .Data.Pages "Type" "home")) }}
|
||||
{{ end }}
|
|
@ -0,0 +1,3 @@
|
|||
{{ define "main" }}
|
||||
{{ partial "reveal-hugo/slides" (union (slice .Page) .Pages) }}
|
||||
{{ end }}
|
|
@ -0,0 +1 @@
|
|||
<!-- override this partial to add content before the body tag closes -->
|
|
@ -0,0 +1 @@
|
|||
<!-- override this partial to add content before the .reveal tag closes -->
|
|
@ -0,0 +1 @@
|
|||
<!-- override this partial to add content before the head tag closes -->
|
|
@ -0,0 +1,17 @@
|
|||
<!-- Use the array of pages passed as a param -->
|
||||
{{ range . -}}
|
||||
<!-- Don't process empty content files -->
|
||||
{{- if ne (len .Content) 0 -}}
|
||||
<!-- Remove the <hr /> tag generated by blackfriday for footnotes -->
|
||||
{{- $content := replace .Content "<div class=\"footnotes\">\n\n<hr />" "<div class=\"footnotes\">" -}}
|
||||
<!-- Split the processed content by <hr /> tag -->
|
||||
{{- range (split $content "<hr />") -}}
|
||||
<!-- Only wrap in <section> tag if not already wrapped by shortcode -->
|
||||
{{- if not (in . "data-noprocess") -}}
|
||||
<section>
|
||||
{{- end -}}
|
||||
{{- . | safeHTML -}}
|
||||
</section>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
|
@ -0,0 +1,4 @@
|
|||
<span class='fragment {{ .Get "class" }}'
|
||||
{{ with .Get "index" }}data-fragment-index='{{ . }}'{{ end }}>
|
||||
{{ .Get "c" }}
|
||||
</span>
|
|
@ -0,0 +1,4 @@
|
|||
<span class='fragment {{ .Get "class" }}'
|
||||
{{ with .Get "index" }}data-fragment-index='{{ . }}'{{ end }}>
|
||||
{{ .Inner }}
|
||||
</span>
|
|
@ -0,0 +1,8 @@
|
|||
<section data-noprocess data-markdown
|
||||
data-separator="^\r?\n---\r?\n$"
|
||||
data-separator-vertical="^\r?\n------\r?\n$"
|
||||
data-separator-notes="notes?:">
|
||||
<script type="text/template">
|
||||
{{ .Inner }}
|
||||
</script>
|
||||
</section>
|
|
@ -0,0 +1 @@
|
|||
<aside class="notes">{{ .Inner }}</aside>
|
|
@ -0,0 +1,3 @@
|
|||
<section data-shortcode-section>
|
||||
{{ .Inner }}
|
||||
</section>
|
|
@ -0,0 +1,58 @@
|
|||
{{- $scratch := .Scratch -}}
|
||||
{{- $scratch.Set "slides" slice -}}
|
||||
{{- $content := .Get "content" -}}
|
||||
{{- if $content -}}
|
||||
{{- $lookup := split $content "." }}
|
||||
{{- $html := index .Page.Site.Data (index $lookup 0) (index $lookup 1) | markdownify -}}
|
||||
{{- $slides := split $html "<hr />" -}}
|
||||
{{- range $slides -}}
|
||||
{{- $scratch.Add "slides" . -}}
|
||||
{{- end -}}
|
||||
{{- else -}}
|
||||
{{- $scratch.Add "slides" "" -}}
|
||||
{{- end -}}
|
||||
{{- $params := . -}}
|
||||
{{- $noPrefix := slice "id" "class" -}}
|
||||
{{- $noOutput := slice "content" "template" -}}
|
||||
{{- $template := $params.Get "template" -}}
|
||||
{{- if $template -}}
|
||||
{{- $scratch.Add "templateParams" slice -}}
|
||||
{{- with $.Site.Params.reveal_hugo.templates -}}
|
||||
{{- $scratch.Add "templateParams" . -}}
|
||||
{{- end -}}
|
||||
{{- if ne $.Page.File.LogicalName "_index.md" -}}
|
||||
{{- $scratch.Add "templateParams" ($.Site.GetPage $.Page.Section).Params.reveal_hugo.templates -}}
|
||||
{{- end -}}
|
||||
{{- with $.Page.Params.reveal_hugo.templates -}}
|
||||
{{- $scratch.Add "templateParams" . -}}
|
||||
{{- end -}}
|
||||
{{- $scratch.Add "templateParams" (slice $.Page.Params.reveal_hugo.templates) -}}
|
||||
{{- $templateParams := $scratch.Get "templateParams" }}
|
||||
{{- range $templateParams -}}
|
||||
{{- if (ne . nil) -}}
|
||||
{{- range $key, $value := (index . $template) -}}
|
||||
{{- $scratch.SetInMap "template" $key $value | safeHTMLAttr -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- range $sindex, $svalue := $scratch.Get "slides" }}
|
||||
<section data-noprocess data-shortcode-slide
|
||||
{{- if $template -}}
|
||||
{{- range $key, $value := ($scratch.Get "template") }}
|
||||
{{- $attrName := cond (in $noPrefix $key) $key (delimit (slice "data" $key) "-") }}
|
||||
{{ $attrName | safeHTMLAttr }}="{{ $value }}"
|
||||
{{- end }}
|
||||
data-template="{{ $template }}"
|
||||
{{- end -}}
|
||||
{{- range $key, $value := $.Params -}}
|
||||
{{- if not (in $noOutput $key) -}}
|
||||
{{- $attrName := cond (in $noPrefix $key) $key (delimit (slice "data" $key) "-") }}
|
||||
{{ $attrName | safeHTMLAttr }}="{{ $value }}"
|
||||
{{- end -}}
|
||||
{{- end -}}>
|
||||
{{ $svalue | safeHTML }}
|
||||
{{- if ne $sindex (sub (len ($scratch.Get "slides")) 1) -}}
|
||||
</section>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 3d5a9e5850760a376094418972e07b49783835fa
|
|
@ -0,0 +1 @@
|
|||
Subproject commit c35cce54a5d4800b90e71a43da140c0347308989
|
|
@ -0,0 +1,15 @@
|
|||
name = "reveal-hugo"
|
||||
license = "MIT"
|
||||
licenselink = "https://github.com/dzello/reveal-hugo/blob/master/LICENSE"
|
||||
homepage = "https://reveal-hugo.dzello.com/"
|
||||
tags = ["presentation", "revealjs"]
|
||||
features = ["presentation"]
|
||||
|
||||
[author]
|
||||
name = "Josh Dzielak"
|
||||
homepage = "https://dzello.com/"
|
||||
|
||||
[original]
|
||||
name = "reveal.js"
|
||||
homepage = "https://revealjs.com"
|
||||
repo = "https://github.com/hakimel/reveal.js/"
|
Loading…
Reference in New Issue