481 lines
21 KiB
HTML
481 lines
21 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html lang="en">
|
||
|
<head>
|
||
|
<meta charset="utf-8" />
|
||
|
<title>tastyteablog</title>
|
||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||
|
<meta name="description" content="" />
|
||
|
<meta name="author" content="tastytea" />
|
||
|
<meta property="og:title" content="tastyteablog" />
|
||
|
<meta property="og:description" content="" />
|
||
|
<meta property="og:type" content="website" />
|
||
|
<meta property="og:url" content="https://blog.tastytea.de/" />
|
||
|
|
||
|
<meta property="og:updated_time" content="2019-02-14T21:38:28+01:00"/>
|
||
|
<meta name="generator" content="Hugo 0.54.0" />
|
||
|
<link href="https://blog.tastytea.de/index.xml" rel="alternate" type="application/rss+xml" title="tastyteablog Feed" />
|
||
|
<link rel="shortcut icon" href="https://blog.tastytea.de/img/favicon.png" type="image/png" />
|
||
|
<!--[if lte IE 8]>
|
||
|
<link rel="stylesheet" href="https://blog.tastytea.de/assets/style-compat.css" />
|
||
|
<![endif]-->
|
||
|
<!--[if gt IE 8]><!-->
|
||
|
<link rel="stylesheet" href="https://blog.tastytea.de/assets/style.css" />
|
||
|
<!--<![endif]-->
|
||
|
</head>
|
||
|
<body>
|
||
|
<div class="pure-g">
|
||
|
<div class="pure-u-1-24 pure-u-md-5-24"></div>
|
||
|
<div class="pure-u-22-24 pure-u-md-14-24">
|
||
|
<div class="navigation-header">
|
||
|
<div class="pure-menu pure-menu-horizontal">
|
||
|
<a class="pure-menu-heading pure-menu-link" href="/">
|
||
|
tastyteablog
|
||
|
</a>
|
||
|
<ul class="pure-menu-list pull-end navigation-header-subtitle">
|
||
|
<li class="pure-menu-item pure-menu-disabled">I write things here.</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="navigation-content">
|
||
|
<div class="pure-menu pure-menu-horizontal">
|
||
|
<ul class="pure-menu-list">
|
||
|
<li class="pure-menu-item">
|
||
|
<a class="pure-menu-link" href="/posts/">Posts</a>
|
||
|
</li>
|
||
|
<li class="pure-menu-item">
|
||
|
<a class="pure-menu-link" href="/tags/">Tags</a>
|
||
|
</li>
|
||
|
<li class="pure-menu-item">
|
||
|
<a class="pure-menu-link" href="/index.xml">RSS</a>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
<p >
|
||
|
<div>
|
||
|
<h2 class="post-title">
|
||
|
|
||
|
<a href="https://blog.tastytea.de/posts/wireguard-vpn-with-2-or-more-subnets/">WireGuard VPN with 2 or more subnets</a>
|
||
|
</h2>
|
||
|
<div class="post-meta">
|
||
|
Date [
|
||
|
<time datetime="2019-02-14T21:38:28+01:00">2019-02-14</time>
|
||
|
]
|
||
|
Tags [
|
||
|
<a href="https://blog.tastytea.de/tags/wireguard/">wireguard</a>
|
||
|
<a href="https://blog.tastytea.de/tags/vpn/">vpn</a>
|
||
|
]
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
<div>
|
||
|
<div class="paragraph">
|
||
|
<p>I wanted to create a <a href="https://en.wikipedia.org/wiki/WireGuard">WireGuard</a> VPN with
|
||
|
2 subnets in different physical places, each with their own server. I couldn’t
|
||
|
find an example how to do that, so I wrote this one.</p>
|
||
|
</div>
|
||
|
<div class="sect1">
|
||
|
<h2 id="_introduction">Introduction</h2>
|
||
|
<div class="sectionbody">
|
||
|
<div class="paragraph">
|
||
|
<p>I’m going to use the IP range <code>fd69::/48</code> for the VPN, <code>fd69:0:0:1::/64</code> for
|
||
|
subnet 1 and <code>fd69:0:0:2::/64</code> for subnet 2. I’m going to call the server of
|
||
|
subnet 1 <code>server1</code>, its first client <code>client1a</code>, the second one <code>client1b</code> and
|
||
|
so on.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>All clients in subnet 1 will connect to <code>server1</code> and all clients in subnet 2
|
||
|
will connect to <code>server2</code>. <code>server1</code> and <code>server2</code> will be connected. If
|
||
|
<code>client1a</code> wants to connect to <code>client2a</code>, the route will be:
|
||
|
<code>client1a → server1 → server2 → client2a</code>.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect1">
|
||
|
<h2 id="_preparations">Preparations</h2>
|
||
|
<div class="sectionbody">
|
||
|
<div class="paragraph">
|
||
|
<p><a href="https://www.wireguard.com/install/">Install WireGuard</a>, create <code>/etc/wireguard</code>
|
||
|
and generate a key-pair on each participating peer.</p>
|
||
|
</div>
|
||
|
<div class="listingblock">
|
||
|
<div class="content">
|
||
|
<pre><div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">mkdir /etc/wireguard
|
||
|
<span class="nb">cd</span> /etc/wireguard
|
||
|
<span class="nb">umask</span> <span class="m">077</span>
|
||
|
wg genkey <span class="p">|</span> tee privatekey <span class="p">|</span> wg pubkey > publickey</code></pre></div></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect1">
|
||
|
<h2 id="_configure_servers">Configure servers</h2>
|
||
|
<div class="sectionbody">
|
||
|
<div class="listingblock">
|
||
|
<div class="title"><code>server1:/etc/wireguard/wg0.conf</code>:</div>
|
||
|
<div class="content">
|
||
|
<pre><div class="highlight"><pre class="chroma"><code class="language-cfg" data-lang="cfg"><span class="c1"># This peer</span>
|
||
|
<span class="k">[Interface]</span>
|
||
|
<span class="na">Address</span> <span class="o">=</span> <span class="s">fd69:0:0:1::1/48</span>
|
||
|
<span class="na">PrivateKey</span> <span class="o">=</span> <span class="s"><PRIVATE KEY OF server1></span>
|
||
|
<span class="na">ListenPort</span> <span class="o">=</span> <span class="s">51820</span>
|
||
|
|
||
|
<span class="c1"># Server of subnet 2</span>
|
||
|
<span class="k">[Peer]</span>
|
||
|
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s"><PUBLIC KEY OF server2></span>
|
||
|
<span class="na">Endpoint</span> <span class="o">=</span> <span class="s">server2:51820</span>
|
||
|
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69:0:0:2::/64</span>
|
||
|
|
||
|
<span class="c1"># Clients of subnet 1</span>
|
||
|
<span class="k">[Peer]</span>
|
||
|
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s"><PUBLIC KEY OF client1a></span>
|
||
|
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69:0:0:1::a/128</span>
|
||
|
|
||
|
<span class="k">[Peer]</span>
|
||
|
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s"><PUBLIC KEY OF client1b></span>
|
||
|
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69:0:0:1::b/128</span></code></pre></div></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="listingblock">
|
||
|
<div class="title"><code>server2:/etc/wireguard/wg0.conf</code>:</div>
|
||
|
<div class="content">
|
||
|
<pre><div class="highlight"><pre class="chroma"><code class="language-cfg" data-lang="cfg"><span class="c1"># This peer</span>
|
||
|
<span class="k">[Interface]</span>
|
||
|
<span class="na">Address</span> <span class="o">=</span> <span class="s">fd69:0:0:2::1/48</span>
|
||
|
<span class="na">PrivateKey</span> <span class="o">=</span> <span class="s"><PRIVATE KEY OF server2></span>
|
||
|
<span class="na">ListenPort</span> <span class="o">=</span> <span class="s">51820</span>
|
||
|
|
||
|
<span class="c1"># Server of subnet 1</span>
|
||
|
<span class="k">[Peer]</span>
|
||
|
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s"><PUBLIC KEY OF server1></span>
|
||
|
<span class="na">Endpoint</span> <span class="o">=</span> <span class="s">server1:51820</span>
|
||
|
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69:0:0:1::/64</span>
|
||
|
|
||
|
<span class="c1"># Clients of subnet 2</span>
|
||
|
<span class="k">[Peer]</span>
|
||
|
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s"><PUBLIC KEY OF client2a></span>
|
||
|
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69:0:0:2::a/128</span></code></pre></div></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect1">
|
||
|
<h2 id="_configure_clients">Configure clients</h2>
|
||
|
<div class="sectionbody">
|
||
|
<div class="listingblock">
|
||
|
<div class="title"><code>client1a:/etc/wireguard/wg0.conf</code>:</div>
|
||
|
<div class="content">
|
||
|
<pre><div class="highlight"><pre class="chroma"><code class="language-cfg" data-lang="cfg"><span class="k">[Interface]</span>
|
||
|
<span class="na">Address</span> <span class="o">=</span> <span class="s">fd69:0:0:1::a/48</span>
|
||
|
<span class="na">PrivateKey</span> <span class="o">=</span> <span class="s"><PRIVATE KEY OF client1a></span>
|
||
|
|
||
|
<span class="k">[Peer]</span>
|
||
|
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s"><PUBLIC KEY OF server1></span>
|
||
|
<span class="na">Endpoint</span> <span class="o">=</span> <span class="s">server1:51820</span>
|
||
|
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69::/48</span>
|
||
|
<span class="na">PersistentKeepalive</span> <span class="o">=</span> <span class="s">25</span></code></pre></div></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="listingblock">
|
||
|
<div class="title"><code>client1b:/etc/wireguard/wg0.conf</code>:</div>
|
||
|
<div class="content">
|
||
|
<pre><div class="highlight"><pre class="chroma"><code class="language-cfg" data-lang="cfg"><span class="k">[Interface]</span>
|
||
|
<span class="na">Address</span> <span class="o">=</span> <span class="s">fd69:0:0:1::b/48</span>
|
||
|
<span class="na">PrivateKey</span> <span class="o">=</span> <span class="s"><PRIVATE KEY OF client1b></span>
|
||
|
|
||
|
<span class="k">[Peer]</span>
|
||
|
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s"><PUBLIC KEY OF server1></span>
|
||
|
<span class="na">Endpoint</span> <span class="o">=</span> <span class="s">server1:51820</span>
|
||
|
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69::/48</span>
|
||
|
<span class="na">PersistentKeepalive</span> <span class="o">=</span> <span class="s">25</span></code></pre></div></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="listingblock">
|
||
|
<div class="title"><code>client2a:/etc/wireguard/wg0.conf</code>:</div>
|
||
|
<div class="content">
|
||
|
<pre><div class="highlight"><pre class="chroma"><code class="language-cfg" data-lang="cfg"><span class="k">[Interface]</span>
|
||
|
<span class="na">Address</span> <span class="o">=</span> <span class="s">fd69:0:0:2::a/48</span>
|
||
|
<span class="na">PrivateKey</span> <span class="o">=</span> <span class="s"><PRIVATE KEY OF client2a></span>
|
||
|
|
||
|
<span class="k">[Peer]</span>
|
||
|
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s"><PUBLIC KEY OF server2></span>
|
||
|
<span class="na">Endpoint</span> <span class="o">=</span> <span class="s">server1:51820</span>
|
||
|
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69::/48</span>
|
||
|
<span class="na">PersistentKeepalive</span> <span class="o">=</span> <span class="s">25</span></code></pre></div></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The <code>AllowedIPs</code> setting acts as a routing table. When a peer tries to send a
|
||
|
packet to an IP, it will check <code>AllowedIPs</code>, and if the IP appears in the list,
|
||
|
it will send it through the WireGuard interface.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The <code>PersistentKeepalive</code> setting ensures that the connection is maintained and
|
||
|
that the peer continues to be reachable, even behind a NAT.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect1">
|
||
|
<h2 id="_start_vpn">Start VPN</h2>
|
||
|
<div class="sectionbody">
|
||
|
<div class="paragraph">
|
||
|
<p>Run <code>wg-quick up wg0</code> on each peer.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect1">
|
||
|
<h2 id="_further_reading">Further reading</h2>
|
||
|
<div class="sectionbody">
|
||
|
<div class="paragraph">
|
||
|
<p>The article <a href="https://www.stavros.io/posts/how-to-configure-wireguard/">How to easily configure WireGuard</a>
|
||
|
by Stavros Korokithakis helped me a great deal in understanding WireGuard.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
</p>
|
||
|
<p class="post-divider">
|
||
|
<div>
|
||
|
<h2 class="post-title">
|
||
|
|
||
|
<a href="https://blog.tastytea.de/posts/using-asciidoc-with-gitea/">Using AsciiDoc(tor) with Gitea</a>
|
||
|
</h2>
|
||
|
<div class="post-meta">
|
||
|
Date [
|
||
|
<time datetime="2019-01-26T13:03:36+01:00">2019-01-26</time>
|
||
|
]
|
||
|
Tags [
|
||
|
<a href="https://blog.tastytea.de/tags/asciidoc/">asciidoc</a>
|
||
|
<a href="https://blog.tastytea.de/tags/gitea/">gitea</a>
|
||
|
]
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
<div>
|
||
|
<div class="paragraph">
|
||
|
<p>In this blogpost I describe what I did to get AsciiDoc support into
|
||
|
<a href="https://gitea.io/">Gitea</a>. If you want more than syntax highlighting and basic
|
||
|
formatting, Gitea has to be patched unfortunately(this
|
||
|
<a href="https://github.com/go-gitea/gitea/issues/4935">issue</a> has already been reported).
|
||
|
But I think most people will only need to edit 1 configuration file and are
|
||
|
done.</p>
|
||
|
</div>
|
||
|
<div class="sect1">
|
||
|
<h2 id="_asciidoctor_or_asciidoc">Asciidoctor or AsciiDoc?</h2>
|
||
|
<div class="sectionbody">
|
||
|
<div class="paragraph">
|
||
|
<p><a href="https://asciidoctor.org/">Asciidoctor</a> has inbuilt support for
|
||
|
<a href="https://highlightjs.org/">highlight.js</a>, the solution Gitea
|
||
|
uses and is therefore the best choice in most scenarios. If you can’t or don’t
|
||
|
want to use it you can use <a href="http://asciidoc.org/">AsciiDoc</a>.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Add the following section to <code>conf/app.ini</code> in your Gitea path. The change
|
||
|
causes <code>.adoc</code> files to be rendered with asciidoctor.</p>
|
||
|
</div>
|
||
|
<div class="listingblock">
|
||
|
<div class="content">
|
||
|
<pre><div class="highlight"><pre class="chroma"><code class="language-ini" data-lang="ini"><span class="k">[markup.asciidoc]</span>
|
||
|
<span class="na">ENABLED</span> <span class="o">=</span> <span class="s">true</span>
|
||
|
<span class="c1">; List of file extensions that should be rendered by an external command</span>
|
||
|
<span class="na">FILE_EXTENSIONS</span> <span class="o">=</span> <span class="s">.adoc,.asciidoc</span>
|
||
|
<span class="c1">; External command to render all matching extensions</span>
|
||
|
<span class="na">RENDER_COMMAND</span> <span class="o">=</span> <span class="s">"asciidoctor --backend=html5 --no-header-footer --attribute source-highlighter=highlightjs --out-file=- -"</span>
|
||
|
<span class="c1">; Don't pass the file on STDIN, pass the filename as argument instead.</span>
|
||
|
<span class="na">IS_INPUT_FILE</span> <span class="o">=</span> <span class="s">false</span></code></pre></div></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>If you want to use asciidoc instead the command would be:
|
||
|
<code>asciidoc --backend=xhtml11 --no-header-footer --attribute
|
||
|
source-highlighter=highlight --out-file=- -</code>. I would choose the <code>xhtml11</code>
|
||
|
backend because it is the only one that encloses code snippets with <code><code></code>
|
||
|
tags. Instead of
|
||
|
<a href="http://www.andre-simon.de/doku/highlight/en/highlight.html">highlight</a> you can
|
||
|
use <a href="http://www.gnu.org/software/src-highlite/">source-highlight</a> or
|
||
|
<a href="http://pygments.org/">Pygments</a>.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>If you use asciidoctor and don’t need tables or other fancy stuff you’re now
|
||
|
done! If you use asciidoc, you’ll have to patch Gitea to get syntax
|
||
|
highlighting.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect1">
|
||
|
<h2 id="_patching_gitea">Patching Gitea</h2>
|
||
|
<div class="sectionbody">
|
||
|
<div class="paragraph">
|
||
|
<p>The sanitizer strips almost all attributes from HTML-tags, as a security
|
||
|
precaution. I’ve added exceptions for:</p>
|
||
|
</div>
|
||
|
<div class="ulist">
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p><code>class</code> attributes on all the tags Asciidoctor introduces,</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p>Numerous attributes on <code>table</code> tags,</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>align</code> and <code>valign</code> on <code>td</code> tags,</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>style</code> attributes on <code>span</code> tags, but only if they contain nothing more than
|
||
|
color and font definitions.</p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>If you use Asciidoctor with highlight.js output, you don’t need to allow <code>style</code>
|
||
|
attributes, if you don’t use tables you can omit the lines that deal with them
|
||
|
and the <code>class</code> exception is only useful if you add custom CSS to use them.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Apply the patch with <code>patch -p1 < gitea_relax-sanitizer.patch</code>.</p>
|
||
|
</div>
|
||
|
<div class="listingblock">
|
||
|
<div class="content">
|
||
|
<pre><div class="highlight"><pre class="chroma"><code class="language-diff" data-lang="diff"><span class="gh">diff -ur a/modules/markup/sanitizer.go b/modules/markup/sanitizer.go
|
||
|
</span><span class="gh"></span><span class="gd">--- a/modules/markup/sanitizer.go 2019-01-26 16:04:56.014108339 +0100
|
||
|
</span><span class="gd"></span><span class="gi">+++ b/modules/markup/sanitizer.go 2019-01-26 16:03:21.776401012 +0100
|
||
|
</span><span class="gi"></span><span class="gu">@@ -38,6 +38,16 @@
|
||
|
</span><span class="gu"></span>
|
||
|
// Custom URL-Schemes
|
||
|
sanitizer.policy.AllowURLSchemes(setting.Markdown.CustomURLSchemes...)
|
||
|
<span class="gi">+ // Allow style on span tags
|
||
|
</span><span class="gi">+ sanitizer.policy.AllowAttrs("style").Matching(regexp.MustCompile(`^(background-)?color:[^;]+(; ?font[^;]+)?;?$`)).OnElements("span")
|
||
|
</span><span class="gi">+
|
||
|
</span><span class="gi">+ // Allow class attribute
|
||
|
</span><span class="gi">+ sanitizer.policy.AllowAttrs("class").OnElements("code", "pre", "span", "div", "p", "table", "td")
|
||
|
</span><span class="gi">+
|
||
|
</span><span class="gi">+ // Allow table attributes
|
||
|
</span><span class="gi">+ sanitizer.policy.AllowAttrs("width", "frame", "rules", "cellspacing", "cellpadding").OnElements("table")
|
||
|
</span><span class="gi">+ sanitizer.policy.AllowAttrs("width").OnElements("col")
|
||
|
</span><span class="gi">+ sanitizer.policy.AllowAttrs("align", "valign").OnElements("td")
|
||
|
</span><span class="gi"></span> })
|
||
|
}
|
||
|
</code></pre></div></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect1">
|
||
|
<h2 id="_tables_without_borders">Tables without borders</h2>
|
||
|
<div class="sectionbody">
|
||
|
<div class="paragraph">
|
||
|
<p>I used tables without borders in a manpage I wrote for the list of options.
|
||
|
Gitea insist on drawing borders around them, so I had to create a custom CSS
|
||
|
snippet.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>In your Gitea directory, create <code>custom/templates/custom/header.tmpl</code>.</p>
|
||
|
</div>
|
||
|
<div class="listingblock">
|
||
|
<div class="content">
|
||
|
<pre><div class="highlight"><pre class="chroma"><code class="language-css" data-lang="css"><span class="o"><</span><span class="nt">style</span><span class="o">></span>
|
||
|
<span class="c">/* Additions for asciidoc */</span>
|
||
|
<span class="p">.</span><span class="nc">markdown</span><span class="p">:</span><span class="nd">not</span><span class="o">(</span><span class="nt">code</span><span class="o">)</span> <span class="nt">table</span><span class="p">.</span><span class="nc">frame-none</span>
|
||
|
<span class="p">{</span>
|
||
|
<span class="k">border</span><span class="p">:</span> <span class="mi">0</span> <span class="cp">!important</span><span class="p">;</span>
|
||
|
<span class="p">}</span>
|
||
|
<span class="p">.</span><span class="nc">markdown</span><span class="p">:</span><span class="nd">not</span><span class="o">(</span><span class="nt">code</span><span class="o">)</span> <span class="nt">table</span><span class="p">.</span><span class="nc">grid-none</span> <span class="o">*</span>
|
||
|
<span class="p">{</span>
|
||
|
<span class="k">border</span><span class="p">:</span> <span class="mi">0</span> <span class="cp">!important</span><span class="p">;</span>
|
||
|
<span class="p">}</span>
|
||
|
<span class="o"></</span><span class="nt">style</span><span class="o">></span></code></pre></div></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<div class="pagination-content">
|
||
|
<div class="pure-menu pure-menu-horizontal">
|
||
|
<ul class="pure-menu-list">
|
||
|
<span class="pure-menu-item pure-menu-disabled">
|
||
|
Pages
|
||
|
</span>
|
||
|
<li class="pure-menu-item pure-menu-selected">
|
||
|
<a href="/" class="pure-menu-link">First</a>
|
||
|
</li>
|
||
|
<li class="pure-menu-item pure-menu-selected">
|
||
|
<a href="/" class="pure-menu-link">Last</a>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="footer-content">
|
||
|
<div class="pure-menu pure-menu-horizontal">
|
||
|
<ul class="pure-menu-list">
|
||
|
<li class="pure-menu-item">
|
||
|
<a class="pure-menu-link" href="https://tastytea.de/">Website</a>
|
||
|
</li>
|
||
|
<li class="pure-menu-item">
|
||
|
<a class="pure-menu-link" href="https://schlomp.space/tastytea">Sourcecode</a>
|
||
|
</li>
|
||
|
<li class="pure-menu-item">
|
||
|
<a class="pure-menu-link" href="https://likeable.space/users/tastytea">Fediverse</a>
|
||
|
</li>
|
||
|
<li class="pure-menu-item">
|
||
|
<a href="https://blog.tastytea.de/index.xml" class="pure-menu-link">RSS</a>
|
||
|
</li>
|
||
|
<li class="pure-menu-item">
|
||
|
<a class="pure-menu-link" id="btn-gototop">
|
||
|
<span class="fixup">⇧︎</span>
|
||
|
</a>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="pure-menu pure-menu-horizontal">
|
||
|
<ul class="pure-menu-list">
|
||
|
<li class="pure-menu-item pure-menu-disabled">
|
||
|
© 2019 — CC BY-NC 4.0
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
</div>
|
||
|
<script>
|
||
|
function setElementsClass(selector, value) {
|
||
|
Array.prototype.forEach.call(
|
||
|
document.querySelectorAll(selector),
|
||
|
function(elem) { elem.className = value; }
|
||
|
);
|
||
|
}
|
||
|
|
||
|
setElementsClass('img', 'pure-img');
|
||
|
setElementsClass('table', 'pure-table');
|
||
|
|
||
|
function onResize() {
|
||
|
setElementsClass(
|
||
|
'.pure-menu', document.documentElement.clientWidth >= 568 ?
|
||
|
'pure-menu pure-menu-horizontal' : 'pure-menu'
|
||
|
);
|
||
|
}
|
||
|
onResize();
|
||
|
window.addEventListener('resize', onResize);
|
||
|
|
||
|
document.getElementById('btn-gototop').addEventListener('click', function() {
|
||
|
function scroll() {
|
||
|
if (window.pageYOffset > 0) { setTimeout(scroll, 8); }
|
||
|
window.scroll(0, window.pageYOffset - 128);
|
||
|
}
|
||
|
scroll();
|
||
|
});
|
||
|
</script>
|
||
|
|
||
|
</div>
|
||
|
<div class="pure-u-1-24 pure-u-md-5-24"></div>
|
||
|
</div>
|
||
|
</body>
|
||
|
</html>
|