feat: completely reworked structure with nostyleplease theme

This commit is contained in:
ae 2025-02-17 00:52:19 +02:00
parent bee4eded67
commit 0262fc4ca8
Signed by: ae
GPG Key ID: 995EFD5C1B532B3E
52 changed files with 512 additions and 482 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "themes/thunderball"]
path = themes/thunderball
url = https://git.umbrella.haus/ae/thunderball.git

5
content/_index.md Normal file
View File

@ -0,0 +1,5 @@
---
title: ""
date: 2025-02-16T16:36:41+02:00
draft: false
---

View File

@ -1,6 +0,0 @@
+++
title = 'Blog'
date = 2023-11-13T13:23:38+02:00
draft = false
menu = 'main'
+++

View File

@ -1,158 +0,0 @@
+++
title = 'Spinning up a Dockerized Onion Mirror'
date = 2024-04-07T20:21:17+03:00
author = ''
draft = false
tags = ['tor', 'docker', 'privacy']
categories = ['self-hosting']
+++
I decided to spin up an [onion mirror of this website](http://golfed6fzytoktol4de4o4nerap3xuykhfm5makfzscib65df3khnpyd.onion) just for the fun of it. Funnily enough hosting an onion service is actually easier than hosting a clearweb site.
When searching for information about Dockerizing onion services, I noticed that the guides found with quick web searches vary significantly in quality, especially from a security standpoint. This prompted me to compile my own notes and thoughts on the topic into this compact post.
## TL;DR
If you only want to use Tor as a rewriting proxy (i.e. client types in the v3 address, and the proxy serves the upstream clearweb site through Tor), [Onionspray](https://gitlab.torproject.org/tpo/onion-services/onionspray/) is a great choice.
For those who aren't concerned about fine-tuning or more in-depth details of the configuration, here's [a great repository to get started with](https://github.com/ha1fdan/hidden-service-docker) that I also used as the base for my setup. The compose configuration found in the repository manually installs the newest available version of Tor, which is much better than relying on the image's contributors to update it in a premade image.
If you want a vanity v3 address, you can use a tool like [mkp2240](https://github.com/cathugger/mkp224o).
## Setup
Here's the slightly modified `docker-compose.yml` I use:
```yaml
services:
tor:
image: alpine:latest
container_name: tor
command: sh -c "apk update && apk add --no-cache tor && chmod 700 /var/lib/tor/onion-service && chown -R root:root /var/lib/tor && (cat /var/lib/tor/onion-service/hostname || echo 'Hostname not available.') && tor -f /etc/tor/torrc"
volumes:
- ./tor:/etc/tor:rw
- ./onion-mirror:/var/lib/tor/onion-service:rw
- nginx-tor-socket:/var/run/onion-sockets:rw
depends_on:
- nginx
restart: unless-stopped
nginx:
image: nginx:latest
container_name: nginx-onion
command:
volumes:
- ./web/config/onion-default.conf:/etc/nginx/conf.d/default.conf:rw
- ./web/public:/usr/share/nginx/html:ro
- nginx-tor-socket:/var/run/onion-sockets:rw
healthcheck:
test:
[
"CMD",
"curl",
"-f",
"--unix-socket",
"/var/run/onion-sockets/site.sock",
"||",
"exit 1",
]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
nginx-tor-socket:
```
Combined with a minimal nginx configuration and `torrc`:
```text
server {
listen unix:/var/run/onion-sockets/site.sock;
server_name golfed6fzytoktol4de4o4nerap3xuykhfm5makfzscib65df3khnpyd.onion;
access_log off;
server_tokens off;
add_header X-Content-Type-Options "nosniff";
add_header X-Frame-Options SAMEORIGIN;
proxy_hide_header X-Powered-By;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
```
```text
HiddenServiceDir /var/lib/tor/onion-service/
HiddenServicePort 80 unix:/var/run/onion-sockets/site.sock
```
## In-depth configuration
Despite my use case being quite casual, I still wanted to follow [the best practices of hosting an onion service](https://riseup.net/en/security/network-security/tor/onionservices-best-practices).
### Service isolation
As recommended in the Riseup guide, it's crucial to carefully isolate clearweb services from the onion ones to prevent any unwanted information leaks. For more critical services, it's definitely worth hosting them in a completely different location with only a minimal number of public-facing ports open. Personally, I solved this by spinning up an individual nginx container that essentially hosts a separate copy of this site.
### Sockets over TCP
Since Tor doesn't require binding to physical ports, there's no need to worry about conflicting ports. Instead, it's worth to consider using Unix sockets for local communication rather than TCP. Unix sockets can reduce the overhead of TCP/IP networking by allowing local inter-process communication to occur through the file system. They can also offer a bit more security by not accidentally exposing services through network ports (although this is already quite easily manageable with containers as long as you don't mix up the ports of different services).
```text
HiddenServicePort 80 unix:/var/run/onion-sockets/site.sock
```
```text
server {
listen unix:/var/run/onion-sockets/site.sock;
server_name golfed6fzytoktol4de4o4nerap3xuykhfm5makfzscib65df3khnpyd.onion;
}
```
### Do you need TLS?
Most of the time, there's no need for a TLS certificate with an onion service. As [this section](https://community.torproject.org/onion-services/advanced/https/) well describes, you might lose more than you gain: many CAs don't support the .onion TLD, and third-party certificates might unintentionally leak .onion names. Fortunately, you can now get DV certificates (instead of EV certificates) for onion sites from the Greek non-profit HARICA. However, support from Let's Encrypt CA is still missing.
The few benefits of having a certificate include using the `https` URI scheme and ensuring the traffic from your web server to Tor is encrypted (which could be especially useful if the instances aren't running on the same machine).
### Onionscan
[Onionscan](https://onionscan.org/) is the Tor Project's contributors' recommendation for detecting possible misconfigurations or information leaks. The original project is practically abandoned, but here's [an up-to-date fork](https://github.com/415ALS/onionscanv3) with v3 address support.
### Onion-Location
To take advantage of Tor Browser's Onion-Location redirection, you should add the following response header to your clearweb site's configuration:
```text
add_header Onion-Location http://golfed6fzytoktol4de4o4nerap3xuykhfm5makfzscib65df3khnpyd.onion$request_uri;
```
Or alternatively include an HTML `<meta>` attribute:
```html
<meta
http-equiv="onion-location"
content="http://golfed6fzytoktol4de4o4nerap3xuykhfm5makfzscib65df3khnpyd.onion"
/>
```
Notably, with proxying enabled through Cloudflare, I encountered difficulties in getting the response headers to pass through to the client, necessitating the use of the `<meta>` attribute instead.
## Resources
I highly recommend checking out the sites I browsed while figuring this stuff out, especially [The Onion Services Ecosystem](https://tpo.pages.torproject.net/onion-services/ecosystem/):
- [Tor Project's Guide on Setting Up Onion Service](https://community.torproject.org/onion-services/setup/)
- [Tor Project's Tips on Operational Security](https://community.torproject.org/onion-services/advanced/opsec/)
- [Tor Project's Tips on HTTPS for Onion Services](https://community.torproject.org/onion-services/advanced/https/)
- [Riseup's Best Practices Guide](https://riseup.net/en/security/network-security/tor/onionservices-best-practices)
- [Introduction to Onionspray](https://tpo.pages.torproject.net/onion-services/ecosystem/apps/web/onionspray/)
- [Tor Project's Onionsite Checklist](https://tpo.pages.torproject.net/onion-services/ecosystem/apps/web/checklist/)
- ["Connect two NGINX's through UNIX sockets" by David Sierra](https://blog.davidsierra.dev/posts/connect-nginxs-through-sockets/)
- ["Create a complete Tor Onion Service with Docker and OpenSUSE in less than 15 minutes" by Jason S. Evans](https://www.youtube.com/watch?v=iUxiTk6w1sc)
- [Onionscan Documentation](https://onionscan.org/)

View File

@ -1,55 +0,0 @@
+++
title = 'Welcome to the Invisible Internet! — Setting up I2P on a VPS'
date = 2024-11-17T18:49:59+02:00
author = ''
draft = false
tags = ['i2p', 'docker', 'privacy']
categories = ['self-hosting']
+++
A major hurdle for the wider adoption of the I2P protocol is the same as with many other purely P2P protocols: you need to reach a certain peer connectivity level before anything becomes usable. For example, [this Mental Outlaw video](https://youtu.be/KhG29riqVUE) about I2P shows that it can take many hours of waiting before most eepsites become accessible. This is drastically different from e.g. Tor, which is basically plug-and-play.
Setting up I2P on a remote VPS and port forwarding that connection with SSH provides a robust solution to this problem, as the client being online 24/7 guarantees excellent connectivity.
## Setting up I2P
It's advisable to create a separate `.env` file and set the `EXT_PORT` environment variable there (this is the exposed host port where I2NP will be reachable, i.e. it must also be unblocked from the firewall).
The advertised memory usage for I2P's JVM is 128 MB, but it's still good to set a cap using the `JVM_XMX` environment variable. Additionally, the `i2ptorrents:i2psnark` volume can be commented out if you don't need BitTorrent support. See the [official documentation](https://github.com/i2p/i2p.i2p/blob/master/Docker.md) for more information on possible configuration options.
```yaml
services:
i2p:
image: geti2p/i2p
container_name: i2p
restart: unless-stopped
ports:
- ${EXT_PORT}:${EXT_PORT}/tcp
- ${EXT_PORT}:${EXT_PORT}/udp
volumes:
- ${PWD}/i2pconfig:/i2p/.i2p:rw # Mandatory configs
- ${PWD}/i2ptorrents:/i2psnark:rw # Torrenting support
environment:
JVM_XMX: 256m
EXT_PORT: ${EXT_PORT:?host port must be manually set}
```
Once the container is fully configured, run `docker compose up -d` and check the `i2p` container's logs. You should see something like this (there should be no warnings about the connection being firewalled):
```
Starting I2P
[startapp] Running in container
[startapp] Running in docker network
[startapp] setting reachable IP to container IP 172.18.0.1
Starting I2P 2.7.0-0
```
## Connecting via an SSH tunnel
The `AllowTcpForwarding` variable in the OpenSSH configuration (`/etc/ssh/sshd_config`) defaults to `yes`, but must be modified if explicitly set to `no`. After this the following command can be used to start the tunnel in the background (implied by `-f` and `-n` flags):
```shell
ssh -fnN -L [LOCAL_PORT]:[CONTAINER_LOCAL_IP]:[REMOTE_PORT] [USERNAME]@[VPS_IP]
```
Once the container is booted up for the first time, the installation setup must be completed by accessing the router console via port `7657`. Then, configure the I2P proxy via port `4444` to your browser and you're ready to go. If you want to configure any additional services, here's the [complete list of the ports used by I2P](https://geti2p.net/en/docs/ports).

View File

@ -1,5 +1,5 @@
+++
title = 'Exploration of a Random MetaMask Phishing Campaign'
title = 'Exploring a Telegram-based MetaMask phishing campaign'
date = 2024-10-27T21:04:50+02:00
author = ''
draft = false
@ -7,13 +7,11 @@ tags = ['phishing']
categories = ['random']
+++
A few days ago, I received a pretty credible-looking MetaMask phishing email stating that my account had been locked due to an attempt to connect a new device to it. Too bad I don't even own a MetaMask account, but despite that, I decided to spend a bit of time and look into how the whole campaign worked, as I rarely receive any kind of spam nowadays.
![Picture of the original email message](/images/metamask-phishing-exploration/email.png)
A few days ago, I received a pretty credible-looking MetaMask phishing email stating that my account had been locked due to an attempt to connect a new device to it. I don't use such wallet, but this sparked my interest and I decided to spend a bit of time and look into how the phishing campaign was structured.
## Email attachment
The attached HTML file `RemovedDevice.html` contained a bare-bones HTML structure with a bit of JS and a long Base64 encoded string which the attached script would decode and use jQuery to attach it back to the website body.
The attached HTML file `RemovedDevice.html` contained a barebones HTML structure with a bit of JS and a long Base64 encoded string which the attached script would decode and use jQuery to attach it back to the website body.
```javascript
$(document).ready(function () {
@ -40,7 +38,7 @@ function saveFile(name, type, data) {
The resulting webpage would display 12/15/18/21/24 input fields for a crypto wallet seed phrases of various lengths.
The campaign operator was using Telegram as the backend, but didn't apparently care enough to even attempt to hide the API token and chat ID from the source with some obfuscation logic. Additionally it's also clear that the data was being exfiltrated into a private chat based on the chat ID format (private chats don't have a dash prefix, whereas supergroups and channels have a `-100` prefix).
The backend of this campaign relied on Telegram, and to my surprise the utilized API token and chat ID weren't obfuscated in any way. Also the fact that the comments were still present in the source code indicate that the campaign was just pasted from a public template. The visible chat ID tells us that the data was being exfiltrated into a private chat as Telegram's supergroup and channel IDs would have a `-100` prefix.
```javascript
// Add your telegram token,chatid
@ -48,7 +46,7 @@ const token = "7686154983:AAFtpdY6iTjT7UiTK6cXh0fM2T4CKfjRHl0";
const chatId = "7839331161";
```
Before sending the collected information to the Telegram chat, the JavaScript code would also make a quick `GET` request to `ipinfo.io` to get the victim's public IP and related location data. This information would probably be used to pick a proxy for the wallet draining stage.
Before sending the collected information to the Telegram chat, the JavaScript code would also make a quick GET request to get the victim's public IP and related location data. I couldn't really figure out the point of this as MetaMask is a self-custodial wallet and doesn't utilize any kind of fraud prevention system that could stop the attacker from draining the targeted account if their geolocation didn't match with the wallet's owner.
```javascript
wordForm1.addEventListener("submit", (e) => {
@ -99,7 +97,7 @@ wordForm1.addEventListener("submit", (e) => {
## Greetings
After discovering the valid token from the source, I had a sudden urge to try it out 🤔. I began with a simple `getMe` request:
Using the visible API token and chat ID I was able to find out a bit more about the bot itself via a `getMe` request and even send out randomly generated data to make it more difficult to detect any working seed phrases from large amount of responses:
```json
{
@ -118,8 +116,6 @@ After discovering the valid token from the source, I had a sudden urge to try it
}
```
And then proceeded to something a bit more interesting:
```python
import random
import requests
@ -159,4 +155,6 @@ while True:
sleep(random.randint(1, 10))
```
In the end I was able to send roughly 10k messages before the person behind the campaign revoked the API token. I hope he'll have a fun time trying to sort out the legitimate responses from the ones I sent.
I left the bot running in a Docker container for some time, and in the end I was able to send roughly 10k messages before the campaign operator revoked the API token.
Next time I get a cryptocurrency related phishing email like this, I'd like to try tracking the stolen funds by giving out the seed phrase of a fresh wallet with e.g. $5-10 USD worth of funds inside and see what kind of anti-forensic methods would the attacker utilize (although given the quality of this campaign, they'd probably just deposit immediately into a full-KYC CEX).

View File

@ -1,15 +1,13 @@
+++
title = 'Walkthrough of Shellcode Reflective DLL Injection (sRDI)'
title = 'Walkthrough of shellcode reflective DLL injection (sRDI)'
date = 2023-12-09T20:42:26+02:00
author = ''
draft = false
tags = ['windows', 'srdi']
categories = ['exploits']
categories = ['malware']
+++
In the ever-evolving landscape of malware, Shellcode Reflective DLL Injection (RDI) stands as a formidable technique despite its age, distinguished by its stealth and efficiency. Unlike traditional DLL injection methods, which often leave apparent traces for AV systems to detect, RDI operates on a more subtle level. Basically it challenges typical defensive solutions such as behavior monitoring, heuristics, or signature-based detection.
Implementing a reflective loader myself provided a great insight into PE files and Windows API, and it is definitely a good initial foothold into more advanced techniques.
In the ever-evolving landscape of malware, Shellcode Reflective DLL Injection (RDI) still stands as a formidable technique despite its age. What differentiates it from traditional DLL injection methods is that it doesn't leave apparent traces to the targeted filesystem, which is why it has a chance to bypass basic defensive solutions relying on behavior monitoring, heuristics, or signature-based detection.
## Steps
@ -23,7 +21,7 @@ Implementing a reflective loader myself provided a great insight into PE files a
## Implementation
The complete implementation can be found from [the Gitea repository](https://git.umbrella.haus/ae/airborne). The following explanations focus on the loader itself as the supporting components (process injector, shellcode generator, and payload) are basically just pasted from existing implementations mentioned in the [references](#references).
The complete implementation can be found from [a Gitea repository](https://git.umbrella.haus/ae/airborne). The following explanations focus on the loader itself as the supporting components (process injector, shellcode generator, and payload) are basically just pasted from existing implementations mentioned in the [references](#references).
The following helper functions are utilized to make the RVA calculations a bit easier to read:
@ -125,8 +123,6 @@ After locating the base address of `kernel32.dll`, our next step is to identify
A PE file is structured into various components, including the DOS Header, DOS Stub, NT Headers, and a Section Table, which houses the actual file contents in segments like `.text` and `.data`. Our focus is on the Export Directory located within the NT Headers, a section that lists exported functions and their addresses. We can access the Export Directory by utilizing the `IMAGE_DIRECTORY_ENTRY_EXPORT` offset within the `IMAGE_DATA_DIRECTORY`.
![Image of the PE file structure](/images/understanding-srdi/pe-file-structure.png)
Similar to how we navigated through modules, we now iterate through the Export Directory entries to locate our required functions. This way we're able to bypass the usual API call mechanisms that could trigger security alerts:
```rust

View File

@ -2,55 +2,18 @@ baseURL: https://golfed.xyz
title: Golfed
language: en-GB
theme: thunderball
theme: nostyleplease
params:
contacts:
- name: email
url: mailto:hello@golfed.xyz
display: hello(at)golfed.xyz
- name: matrix
url: https://matrix.to/#/@ae:golfed.xyz
display: "@ae:golfed.xyz"
- name: signal
url: https://signal.me/#eu/9aAt0tk36ErVZygWxf_dk81_r_2jTaxUxVCuvl_h6LONUyREI7hLm42Oa8RYJgoz
display: "@xmr.02"
- name: telegram
url: https://t.me/shrlis
display: "@shrlis"
- name: xmr
url: /xmr.txt
display: 83B5pK...FHe23Y
- name: pgp
url: https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x1530f5132a1228578d2b4168995efd5c1b532b3e
display: 1530F5...32B3E
services:
- name: blog
url: /blog
display: Blog
- name: umbrella.haus
url: https://umbrella.haus
display: Umbrella
- name: .onion
url: http://golfed6fzytoktol4de4o4nerap3xuykhfm5makfzscib65df3khnpyd.onion/
display: golfed...khnpyd.onion
theme_config:
appearance: dark
back_home_text: <<
date_format: 2006-01-02
isListGroupByDate: false
assets:
favicon: /images/favicon.ico
favicon16: /images/favicon-16x16.png
favicon32: /images/favicon-32x32.png
faviconsvg: /images/favicon.svg
favicon96: /images/favicon-96x96.png
appleTouchIcon: /images/apple-touch-icon.png
safariPinnedTabIcon: /images/safari-pinned-tab.svg
safariPinnedTabColor: /images/"#5bbad5"
manifest: /images/manifest.json
msTileColor: /images/"#2b5797"
msTileIcon: /images/mstile-150x150.png
themeColor: /images/"#040404"
logo: /images/logo.svg
opengraph:
# only include website title + 30 word abstract into embeds
description: "{{ substr .Summary 0 30 }} ..."
twitter:image:src: ""
og:image: ""
manifest: /manifest.json

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 986 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 425 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

View File

@ -1,189 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="700.000000pt" height="700.000000pt" viewBox="0 0 700.000000 700.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.14, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,700.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M3278 6996 c-1 -2 -37 -6 -78 -9 -119 -10 -261 -30 -365 -51 -141
-29 -197 -43 -295 -71 -225 -65 -499 -175 -680 -273 -129 -70 -150 -82 -217
-124 -316 -197 -641 -488 -877 -783 -427 -535 -686 -1173 -753 -1860 -10 -102
-10 -568 0 -660 93 -854 449 -1591 1052 -2175 79 -77 125 -119 225 -204 62
-53 279 -208 352 -251 144 -86 204 -119 320 -177 75 -37 139 -68 142 -68 4 0
25 -9 49 -19 108 -48 321 -119 468 -156 57 -14 120 -30 139 -35 19 -5 51 -12
70 -15 19 -3 60 -10 90 -15 89 -15 162 -24 285 -36 154 -15 582 -8 695 10 14
3 45 7 70 10 49 7 200 32 240 40 14 3 39 8 55 12 64 12 324 88 413 120 372
135 704 321 1010 567 131 105 377 343 474 457 305 361 543 793 677 1226 34
109 95 361 107 439 5 28 9 52 9 55 2 5 15 105 21 155 14 120 19 206 19 385 0
186 -10 391 -20 423 -2 6 -6 35 -9 62 -25 232 -111 556 -218 825 -340 856
-1027 1560 -1873 1917 -345 146 -603 212 -1040 268 -50 7 -550 16 -557 11z
m698 -210 c67 -7 234 -41 338 -67 95 -24 276 -85 288 -97 4 -4 -52 -9 -125
-10 -72 -1 -157 -4 -187 -7 -52 -4 -57 -3 -135 49 -44 29 -119 72 -167 94 -49
23 -88 44 -88 47 0 2 6 3 13 0 6 -2 35 -6 63 -9z m-992 -90 c-27 -23 -92 -82
-144 -132 l-95 -92 -55 2 c-69 2 -217 -15 -305 -34 -58 -13 -57 -14 -52 28 7
64 30 123 51 137 22 15 206 65 321 89 96 19 252 41 304 42 22 0 19 -5 -25 -40z
m566 10 c124 -26 238 -62 328 -103 95 -43 95 -43 -46 -79 -151 -39 -325 -98
-474 -161 l-108 -45 -102 51 c-57 28 -118 54 -135 57 -18 4 -33 12 -33 19 0
27 219 193 335 254 72 37 87 38 235 7z m-1400 -241 c-4 -25 -8 -48 -8 -50 -1
-3 -2 -16 -2 -30 0 -14 -5 -25 -11 -25 -26 0 -232 -110 -330 -176 l-108 -73
-66 29 c-36 16 -65 31 -65 34 0 8 119 90 220 152 107 64 362 194 371 188 3 -2
3 -24 -1 -49z m2530 -40 c129 -8 319 -44 367 -69 23 -12 106 -90 163 -152 105
-116 201 -276 264 -441 20 -51 36 -94 36 -97 0 -6 -20 1 -185 59 -125 44 -466
137 -556 150 -24 4 -51 8 -58 9 -20 4 -25 15 -61 125 -46 141 -120 279 -209
391 l-20 25 22 6 c23 5 93 4 237 -6z m-432 -80 c73 -77 132 -162 178 -255 32
-66 64 -146 64 -164 0 -4 -24 -6 -52 -2 -70 7 -168 16 -248 21 -64 5 -439 5
-594 2 l-79 -2 -27 67 c-15 37 -44 90 -64 118 l-36 51 67 30 c140 63 416 146
588 178 33 6 69 12 80 15 53 10 64 5 123 -59z m-1658 -61 c0 -3 -24 -40 -53
-82 -67 -98 -157 -241 -157 -250 -1 -12 -39 -57 -41 -47 -5 40 -8 87 -14 202
l-7 132 43 12 c96 26 229 45 229 33z m294 -8 c43 -8 156 -47 156 -55 0 -3 -46
-33 -102 -66 -57 -32 -160 -96 -230 -142 -71 -45 -128 -80 -128 -77 0 9 109
174 158 239 63 84 92 114 106 110 6 -3 24 -7 40 -9z m-739 -206 c3 -52 8 -111
10 -130 3 -19 7 -58 9 -87 l5 -51 -127 89 c-70 50 -138 98 -151 107 l-24 18
64 41 c61 40 201 115 205 110 1 -1 5 -45 9 -97z m3514 -48 c85 -73 248 -233
306 -302 51 -60 155 -220 196 -302 41 -82 82 -178 75 -178 -2 0 -53 35 -113
78 -103 74 -236 156 -352 218 l-54 29 -23 92 c-31 124 -92 277 -159 398 -30
54 -55 101 -55 103 0 7 96 -66 179 -136z m-2434 70 c37 -26 114 -156 101 -169
-5 -5 -75 -17 -231 -39 -64 -9 -288 -54 -317 -64 -85 -28 42 61 282 197 155
89 150 86 165 75z m-1743 -88 c26 -9 51 -20 54 -26 3 -5 -9 -26 -29 -46 -54
-57 -147 -182 -172 -232 -31 -61 -37 -65 -130 -89 -68 -18 -193 -59 -259 -86
-19 -8 -19 -8 0 24 40 69 194 251 307 364 132 131 118 126 229 91z m380 -206
c76 -50 136 -93 134 -96 -3 -2 -61 -5 -130 -7 -144 -4 -308 -15 -318 -22 -21
-12 -4 25 29 66 47 57 134 151 141 151 3 0 68 -41 144 -92z m2458 -41 c19 -3
67 -8 105 -12 99 -9 105 -11 106 -48 4 -119 -5 -299 -15 -316 -2 -3 -7 -22
-10 -41 -17 -104 -80 -295 -94 -287 -4 3 -27 14 -52 25 -25 11 -85 39 -135 62
-194 90 -487 205 -664 262 -36 12 -67 22 -68 23 -1 0 6 30 17 66 11 35 20 66
19 69 0 3 3 29 7 58 3 29 8 67 9 85 2 17 3 37 4 44 1 6 16 14 34 16 46 6 695
0 737 -6z m-957 -72 c-2 -27 -8 -72 -15 -100 -7 -27 -13 -52 -13 -55 -5 -28
-19 -51 -29 -47 -29 11 -379 97 -456 112 -98 19 -123 25 -118 31 7 6 291 66
378 80 19 3 46 7 60 10 14 2 48 7 75 10 28 4 52 8 55 11 2 2 18 3 35 1 29 -3
30 -4 28 -53z m1592 -37 c174 -43 345 -98 499 -162 90 -38 100 -45 104 -71 8
-49 7 -314 -2 -390 -20 -187 -120 -551 -154 -563 -6 -2 -45 22 -87 53 -65 49
-364 243 -433 283 -13 7 -76 43 -140 79 -64 36 -127 72 -139 79 l-21 13 19 52
c31 82 76 248 89 329 7 41 14 84 16 95 2 11 5 73 6 138 l1 118 41 -7 c23 -3
113 -24 201 -46z m-3105 -137 c-1 -3 -54 -32 -119 -64 -65 -31 -171 -88 -237
-126 -103 -60 -119 -66 -122 -50 -5 27 35 181 51 196 14 14 133 31 272 40 55
3 101 6 102 7 6 5 53 3 53 -3z m827 -66 c148 -24 489 -103 541 -125 23 -10 23
-10 -20 -71 -48 -68 -132 -168 -157 -186 -18 -12 -2 -25 -251 207 -63 59 -135
126 -160 149 -45 42 -45 42 -15 37 17 -3 45 -8 62 -11z m-1477 -92 c-6 -38
-12 -103 -14 -146 -1 -43 -7 -82 -12 -86 -5 -5 -52 -42 -105 -83 -140 -106
-200 -159 -331 -290 -102 -102 -121 -116 -120 -88 0 16 13 149 16 171 7 50 46
188 77 275 40 111 63 134 211 208 102 51 278 119 287 111 1 -2 -2 -34 -9 -72z
m1384 -137 c49 -44 103 -94 120 -109 75 -69 176 -170 176 -177 0 -19 -274
-179 -307 -180 -9 0 -90 307 -107 410 -2 14 -11 56 -20 93 -9 38 -16 75 -16
84 0 17 19 3 154 -121z m3361 8 c97 -64 216 -159 308 -245 66 -61 69 -67 77
-124 8 -61 6 -424 -3 -460 -3 -11 -8 -40 -11 -65 -10 -71 -15 -98 -41 -205
-22 -95 -87 -301 -106 -337 -7 -14 -40 14 -181 156 -186 185 -218 215 -346
321 -67 54 -83 72 -79 89 3 12 30 92 60 179 31 86 54 157 52 157 -2 0 4 26 12
58 42 160 56 287 62 560 l1 34 58 -32 c31 -18 93 -56 137 -86z m-4075 92 c0
-3 -6 -11 -12 -18 -7 -7 -44 -49 -83 -93 -38 -44 -72 -82 -76 -85 -3 -3 -45
-54 -93 -115 -119 -150 -115 -145 -124 -145 -10 0 -68 96 -83 138 -6 18 -9 38
-6 45 6 15 211 139 367 220 117 62 110 59 110 53z m400 -98 c6 -29 14 -64 16
-78 3 -14 21 -89 39 -167 67 -275 68 -285 54 -293 -11 -7 -53 -17 -163 -36
-11 -2 -50 -6 -88 -9 -78 -6 -76 -11 -48 90 43 158 62 219 111 361 28 82 53
157 56 167 8 26 10 22 23 -35z m1271 3 c176 -61 213 -75 369 -139 161 -66 410
-179 423 -192 30 -29 -220 -383 -399 -565 -115 -117 -108 -114 -145 -74 -17
19 -57 61 -88 95 -31 33 -103 112 -161 174 -58 62 -166 176 -240 253 -74 77
-135 143 -135 147 0 4 23 34 51 66 79 90 97 113 153 197 28 42 53 77 55 77 1
0 54 -18 117 -39z m-1546 -154 c-29 -89 -67 -220 -86 -290 -38 -145 -34 -141
-135 -107 -81 28 -144 58 -144 70 0 12 143 192 234 295 71 81 178 195 181 195
2 0 -21 -73 -50 -163z m-730 -206 c20 -38 52 -87 71 -109 19 -22 34 -45 34
-51 0 -5 -33 -61 -74 -123 -105 -162 -196 -326 -301 -541 l-92 -189 -37 44
c-104 120 -199 310 -221 436 -7 41 -5 45 50 112 81 99 292 305 415 404 58 47
108 86 112 86 4 0 23 -31 43 -69z m-820 -95 c-10 -49 -12 -275 -4 -314 6 -28
1 -41 -28 -85 -20 -29 -67 -104 -105 -167 -68 -112 -70 -114 -64 -70 3 25 8
56 11 70 3 14 7 34 9 45 30 148 97 361 158 508 24 55 31 60 23 13z m2698 -88
c114 -118 309 -324 345 -365 9 -11 53 -60 97 -108 44 -48 83 -93 88 -101 7
-13 0 -19 -155 -132 -172 -125 -606 -349 -629 -325 -4 5 -30 80 -57 168 -28
88 -62 196 -76 240 -25 81 -128 438 -139 485 -6 24 0 29 102 79 59 29 150 82
202 117 52 35 96 63 99 64 2 0 58 -55 123 -122z m1555 18 c176 -101 428 -263
564 -363 l68 -49 -31 -59 c-96 -185 -230 -383 -388 -570 -91 -108 -314 -335
-329 -335 -6 0 -66 68 -134 152 -167 206 -397 481 -465 557 -18 20 -32 41 -30
48 1 7 40 52 87 100 184 189 310 354 426 556 21 37 41 67 45 67 3 0 87 -47
187 -104z m1902 -161 c69 -124 127 -276 144 -380 9 -57 12 -147 11 -263 -3
-174 -6 -213 -25 -322 -23 -129 -28 -152 -61 -265 -54 -185 -61 -198 -86 -152
-114 203 -224 377 -275 433 -18 21 -18 22 26 135 75 192 142 438 160 584 2 22
7 58 11 80 7 45 13 133 14 215 1 68 10 61 81 -65z m-5008 16 c67 -31 125 -52
196 -71 48 -12 46 -4 27 -100 -15 -78 -28 -149 -31 -175 -2 -16 -8 -52 -14
-80 -10 -56 -17 -103 -26 -173 -3 -26 -7 -58 -9 -72 -7 -48 -14 -106 -21 -180
-4 -41 -8 -86 -9 -100 -2 -14 -3 -47 -4 -74 l-1 -48 -47 6 c-152 22 -368 97
-503 176 -99 58 -102 62 -84 108 87 215 420 812 454 812 5 0 37 -13 72 -29z
m907 -252 c56 -195 91 -311 179 -592 22 -70 36 -129 32 -132 -12 -7 -230 -62
-275 -69 -22 -4 -47 -9 -55 -11 -83 -26 -507 -42 -504 -20 1 6 5 53 9 105 3
52 8 109 10 125 2 17 7 57 11 90 3 33 7 67 9 75 1 8 6 42 9 75 13 106 81 493
89 501 1 1 48 5 104 9 56 4 150 17 210 29 59 12 109 21 110 21 2 -1 29 -93 62
-206z m-1983 -166 c61 -150 145 -282 246 -389 l70 -73 -15 -48 c-8 -26 -35
-114 -60 -195 -26 -80 -48 -157 -51 -170 -2 -12 -9 -41 -15 -63 -14 -53 -48
-228 -56 -290 -4 -28 -9 -52 -12 -55 -3 -3 -27 20 -55 50 -139 155 -266 408
-309 618 -12 56 -11 71 5 135 24 94 91 260 148 367 54 101 82 150 86 150 2 0
10 -17 18 -37z m5070 -55 c103 -86 405 -383 461 -454 l32 -41 -41 -79 c-161
-312 -374 -599 -665 -894 l-162 -165 -29 40 c-15 22 -71 101 -122 175 -52 74
-98 140 -102 145 -5 6 -66 89 -138 186 l-129 175 143 145 c251 254 444 502
573 738 50 92 62 111 72 111 4 0 52 -37 107 -82z m-1699 -213 c168 -196 266
-314 403 -485 68 -85 130 -162 137 -171 13 -15 5 -24 -69 -82 -266 -207 -604
-405 -917 -537 -79 -33 -145 -59 -146 -58 -11 14 -184 467 -262 688 -79 224
-85 242 -81 245 5 6 116 55 123 55 10 0 242 118 320 162 91 53 275 176 345
232 30 24 60 41 66 37 7 -3 43 -42 81 -86z m-2765 -394 c92 -50 317 -131 413
-147 17 -3 57 -10 89 -17 l59 -12 3 -300 c1 -165 5 -329 8 -365 3 -36 8 -96
11 -135 3 -38 8 -91 11 -117 6 -46 5 -48 -20 -48 -74 0 -358 74 -496 130 -100
40 -254 121 -330 174 -83 57 -85 63 -68 171 4 28 10 73 13 100 3 28 10 66 15
85 5 19 12 51 15 70 11 66 56 235 96 363 l40 128 52 -30 c29 -16 69 -38 89
-50z m5169 -173 c75 -115 174 -302 204 -386 12 -35 11 -40 -28 -117 -134 -261
-332 -541 -562 -795 -73 -80 -256 -260 -265 -260 -4 0 -38 55 -76 123 -37 67
-110 192 -161 277 l-94 154 123 121 c140 138 212 214 283 300 28 33 52 62 55
65 73 71 282 378 404 593 15 26 29 47 32 47 2 0 41 -55 85 -122z m-3483 20
c16 -46 44 -123 62 -173 37 -107 47 -132 141 -380 39 -104 78 -203 85 -220 32
-71 29 -75 -81 -106 -55 -16 -109 -31 -120 -33 -11 -3 -49 -11 -85 -20 -36 -8
-78 -17 -95 -20 -16 -3 -53 -10 -82 -15 -29 -6 -74 -13 -100 -16 -26 -4 -59
-8 -73 -11 -93 -16 -540 -28 -553 -14 -3 3 -8 41 -12 85 -3 44 -8 94 -10 110
-17 129 -30 761 -16 770 4 2 72 5 152 6 128 2 224 11 369 33 68 11 247 53 315
74 33 10 63 17 66 16 3 -2 20 -41 37 -86z m-2557 -276 c60 -109 157 -238 255
-337 l92 -93 1 -183 c0 -101 2 -202 5 -224 10 -96 18 -171 21 -187 6 -29 -8
-20 -45 30 -144 195 -233 380 -294 612 -35 131 -64 283 -72 366 -3 38 -8 72
-11 77 -2 4 -1 7 4 7 4 0 24 -31 44 -68z m6525 -79 c-9 -54 -23 -123 -30 -153
l-13 -55 -16 54 -17 54 42 104 c22 57 43 101 46 99 2 -3 -3 -49 -12 -103z
m-2184 35 c108 -136 458 -630 465 -660 9 -30 -313 -266 -579 -424 -122 -72
-399 -215 -518 -267 -113 -49 -216 -87 -228 -82 -7 2 -38 58 -69 122 -67 142
-213 463 -213 468 0 3 -11 28 -24 57 -39 85 -56 130 -56 143 0 7 37 27 83 45
113 45 401 185 522 255 136 78 361 228 470 313 50 39 95 71 101 72 7 0 27 -19
46 -42z m1990 -435 c9 -80 -2 -240 -22 -318 -35 -137 -182 -418 -328 -630 -57
-81 -192 -257 -221 -286 -9 -9 -45 -48 -80 -87 -35 -40 -67 -72 -70 -72 -4 0
-17 39 -31 88 -13 48 -43 136 -67 195 l-43 108 163 162 c170 170 191 192 298
322 134 163 283 374 356 506 16 27 31 49 34 49 4 0 9 -17 11 -37z m-5749 -120
c145 -92 430 -207 615 -248 71 -16 169 -35 230 -45 40 -7 72 -17 73 -23 6
-103 63 -369 131 -610 28 -98 48 -180 46 -182 -6 -7 -159 21 -274 50 -235 59
-481 165 -668 290 -102 68 -124 89 -132 123 -3 15 -10 41 -14 57 -9 29 -34
162 -44 235 -13 88 -26 367 -17 375 7 8 8 7 54 -22z m2420 -283 c75 -174 174
-392 243 -537 30 -63 54 -118 54 -122 0 -5 -8 -11 -17 -14 -272 -82 -548 -141
-748 -162 -33 -4 -71 -9 -85 -11 -37 -8 -511 -14 -542 -8 -24 5 -30 17 -67
132 -57 179 -108 383 -135 537 -3 17 -10 54 -16 84 -5 30 -8 56 -6 58 2 3 93
6 202 8 110 2 215 6 234 9 19 2 62 8 95 11 167 17 480 83 640 134 33 11 67 19
75 18 9 -2 38 -56 73 -137z m2014 -142 c102 -171 117 -197 180 -316 25 -45 43
-87 41 -92 -11 -32 -464 -353 -613 -435 -27 -15 -79 -44 -115 -65 -139 -81
-579 -280 -619 -280 -20 0 -338 555 -323 564 4 2 63 27 132 56 153 64 358 161
465 222 44 24 103 57 130 73 148 83 424 272 555 379 30 24 60 45 65 45 6 1 52
-68 102 -151z m-4027 -681 c88 -37 265 -100 320 -112 8 -2 40 -10 70 -18 62
-17 103 -25 225 -46 70 -13 113 -19 136 -20 10 -1 26 -22 39 -53 50 -117 108
-229 177 -347 l73 -124 -37 7 c-299 49 -603 169 -852 335 -92 61 -166 130
-234 219 -69 89 -167 250 -167 273 0 5 33 -8 73 -30 39 -22 119 -59 177 -84z
m4401 -66 c26 -84 46 -208 39 -243 -8 -41 -26 -59 -165 -164 -280 -210 -552
-361 -857 -474 l-76 -29 -49 24 c-26 14 -74 48 -105 77 -54 51 -178 196 -178
209 0 3 21 14 48 24 50 19 65 25 232 100 304 136 636 335 927 556 l118 89 22
-51 c13 -28 32 -81 44 -118z m-1907 -113 c105 -188 129 -230 188 -328 l39 -65
-58 -18 c-54 -16 -240 -65 -273 -72 -8 -2 -33 -8 -55 -13 -22 -6 -57 -13 -79
-16 -21 -4 -41 -8 -45 -10 -3 -2 -33 -7 -66 -11 -32 -3 -62 -8 -65 -10 -3 -2
-33 -6 -67 -10 -35 -4 -75 -8 -90 -10 -113 -15 -409 -23 -563 -15 l-65 3 -48
61 c-68 87 -151 223 -218 356 -32 63 -57 115 -56 116 1 1 103 4 227 8 124 3
241 8 261 10 21 3 72 9 115 15 44 6 97 13 119 16 22 2 51 7 65 10 14 3 39 7
55 10 17 3 53 10 80 15 28 6 60 12 72 14 46 9 330 86 368 100 22 8 45 15 52
15 6 1 55 -77 107 -171z m397 -630 c35 -46 97 -117 137 -160 40 -42 69 -78 65
-81 -9 -5 -192 -46 -233 -52 -35 -5 -170 -26 -200 -31 -112 -18 -529 -25 -682
-11 -42 4 -110 16 -151 26 -110 29 -316 137 -313 165 1 5 46 11 101 12 223 4
423 27 710 80 59 11 371 93 425 112 30 11 60 20 66 21 6 0 40 -36 75 -81z
m-1791 -103 c14 -2 43 -6 65 -10 27 -4 52 -17 77 -42 21 -20 36 -38 34 -41 -4
-4 -212 68 -266 93 l-35 15 50 -5 c28 -3 61 -8 75 -10z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

View File

@ -4,15 +4,16 @@
"start_url": "https://golfed.xyz",
"icons": [
{
"src": "/android-chrome-192x192.png",
"src": "/images/web-app-manifest-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
"purpose": "maskable"
},
{
"src": "/android-chrome-512x512.png",
"src": "/images/web-app-manifest-512x512.png",
"sizes": "512x512",
"type": "image/png"
"type": "image/png",
"purpose": "maskable"
}
],
"theme_color": "#242424",

View File

@ -1 +0,0 @@
83B5pKorh2J58RZvF3oyxhZcxpbYnpRDCcQeETzhSKUZFvyHRWmMzepeg5NksY6f1DcCfUtQ6wphF3x3cT4bhXvWSFHe23Y

View File

@ -0,0 +1,185 @@
// -------------- THEME SWITCHER -------------- //
@mixin theme($--bg-color, $--primary-text-color, $--secondary-text-color, $--link-color, $--visited-link-color, $--highlight) {
background-color: $--bg-color;
color: $--primary-text-color;
a {
color: $--link-color;
&:visited { color: $--visited-link-color; }
}
details {
border: thin solid $--primary-text-color;
}
details summary {
color: $--primary-text-color;
}
details[open] summary {
border-bottom: 1px solid $--primary-text-color;
}
pre {
background: $--bg-color;
}
code:not(pre > code) {
background-color: $--primary-text-color;
color: $--bg-color;
}
*:target {
background: $--highlight;
color: $--primary-text-color;
}
table, th, td {
border: thin solid $--primary-text-color;
}
.toc {
border: thin solid $--primary-text-color;
padding: 1rem;
}
figcaption { color: $--secondary-text-color; }
blockquote {
border: thin solid $--primary-text-color;
}
}
@mixin dark-appearance {
@include theme(#000300, #f1fffa, #000300, #8b9556, #d1603d, #53917e); // modus-vivendi
}
@mixin light-appearance {
@include theme(#ffffff, #000000, #595959, #3548cf, #8f0075, #dae5ec); // modus-operandi
}
body[a="dark"] { @include dark-appearance; }
body[a="light"] { @include light-appearance; }
@media (prefers-color-scheme: dark) {
body[a="auto"] { @include dark-appearance; }
}
@media (prefers-color-scheme: light) {
body[a="auto"] { @include light-appearance; }
}
// -------------------------------------------- //
html { height: 100%; }
body {
font-family: monospace;
font-size: 16px;
line-height: 1.4;
margin: 0;
min-height: 100%;
overflow-wrap: break-word;
}
h2, h3, h4, h5, h6 { margin-top: 1.5rem; }
p { margin: 1rem 0; }
li { margin: 0.4rem 0; }
a {
text-decoration: none;
&:hover { text-decoration: underline; }
}
hr {
text-align: center;
border: 0;
margin: 2rem 0;
&:before { content: '/////' }
&:after { content: attr(data-content) '/////' }
}
pre {
padding: 1em;
overflow-x: auto; /* Fix pre content overflowing parent without scroll bar */
}
table { width: 100%; }
table, th, td {
border-collapse: collapse;
padding: 0.4rem;
}
code {
text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
-moz-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
code:not(pre > code) {
padding: 0.1em 0.2em;
font-size: 90%;
}
code.has-jax {
-webkit-font-smoothing: antialiased;
background: inherit !important;
border: none !important;
font-size: 100%;
}
blockquote {
padding: 1rem;
p { margin: 0; }
}
img {
max-width: 100%;
display: block;
margin: 0 auto;
}
figcaption {
text-align: center;
opacity: 0.5;
}
details {
padding: 1rem;
}
details summary {
text-decoration: none;
}
details[open] summary {
margin-bottom: 0.5em;
padding-bottom: 0.5em;
}
.post-meta {
display: flex;
justify-content: space-between;
align-items: center;
}
.w {
max-width: 640px;
margin: 0 auto;
padding: 4rem 2rem;
}
.toc {
padding: 1rem;
}
.site-footer {
margin-top: 2em;
}

View File

@ -0,0 +1,16 @@
[[entries]]
title = "posts"
[entries.post_list]
limit = 5
show_more = true
show_more_text = "see more ..."
show_more_url = "posts"
[[entries]]
title = "contacts"
entries = [
{ title = "email (hello at golfed.xyz)", url = "mailto:hello@golfed.xyz" },
{ title = "pgp (1530F5...32B3E)", url = "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x1530f5132a1228578d2b4168995efd5c1b532b3e" },
{ title = "matrix (@ae:golfed.xyz)", url = "https://matrix.to/#/@ae:golfed.xyz" },
{ title = "signal (xmr.02)", url = "https://signal.me/#eu/9aAt0tk36ErVZygWxf_dk81_r_2jTaxUxVCuvl_h6LONUyREI7hLm42Oa8RYJgoz" },
]

View File

@ -0,0 +1,8 @@
{{ define "main" }}
{{- partial "back_link.html" . -}}
<header>
<h1>404 Not Found</h1>
</header>
{{ end }}

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="{{ $.Site.LanguageCode }}">
{{- partial "head.html" . -}}
<body a="{{ $.Site.Params.theme_config.appearance | default "auto" }}">
<main class="page-content" aria-label="Content">
<div class="w">
{{- block "main" . }}{{- end }}
{{ partial "footer.html" }}
</div>
</main>
</body>
</html>

View File

@ -0,0 +1,8 @@
{{ define "main" }}
{{ partial "back_link.html" .}}
<h1>{{ .Title }}</h1>
{{ .Content }}
{{ partial "post_list.html" (dict "context" . "section" .Section)}}
{{ end }}

View File

@ -0,0 +1,21 @@
{{ define "main" }}
{{ partial "back_link.html" .}}
<article>
<p class="post-meta">
<time datetime="{{ .Date }}">
{{ .Date | time.Format site.Params.theme_config.date_format }}
</time>
</p>
<h1>{{ .Title }}</h1>
{{ if .Params.toc }}
<aside {{ if .Params.tocBorder }} class="toc" {{ end }}>
{{ .TableOfContents }}
</aside>
{{ end }}
{{ .Content }}
</article>
{{ end }}

View File

@ -0,0 +1,8 @@
{{ define "main" }}
{{ partial "back_link.html" .}}
<h1>{{ .Title }}</h1>
{{ .Content }}
{{ partial "post_list.html" (dict "context" .)}}
{{ end }}

View File

@ -0,0 +1,8 @@
{{ define "main" }}
{{ partial "back_link.html" .}}
<h1>{{ .Title }}</h1>
{{ .Content }}
{{ partial "post_list.html" (dict "context" .)}}
{{ end }}

View File

@ -0,0 +1,12 @@
{{ define "main" }}
<header>
<h1>{{ $.Site.Title }}</h1>
{{- if $.Site.Params.theme_config.show_description -}}
<p>{{ $.Site.Params.description }}</p>
{{- end -}}
</header>
{{ .Content }}
{{ partial "menu_item.html" (dict "context" . "collection" $.Site.Data.menu.entries) }}
{{ end }}

View File

@ -0,0 +1 @@
<a href="{{ "" | relURL }}">{{ $.Site.Params.theme_config.back_home_text }}</a>

View File

@ -0,0 +1,3 @@
<footer class="site-footer">
<p>{{ now.Format "2006" }} / <a href="http://golfed6fzytoktol4de4o4nerap3xuykhfm5makfzscib65df3khnpyd.onion/" target="_blank" rel="noopener noreferrer">.onion</a> / <a href="/contact.txt" target="_blank" rel="noopener noreferrer">contact.txt</a> / <a href="https://umbrella.haus" target="_blank" rel="noopener noreferrer">umbrella.haus</a></p>
</footer>

View File

@ -0,0 +1,28 @@
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
{{ if .IsPage }} <meta name="description" content="{{ .Summary }}"> {{ end }}
<title>
{{ if not .IsHome }}
{{ .Title }}
{{ else }}
{{ $.Site.Title }}
{{ end }}
</title>
<link rel="shortcut icon" type="image/x-icon" href="{{ $.Site.Params.favicon | relURL }}" />
{{ $options := (dict "outputStyle" "compressed" "enableSourceMap" (not hugo.IsProduction)) }}
{{ $sass := resources.Get "css/main.scss" }}
{{ $style := $sass | css.Sass $options | resources.Fingerprint "sha512" }}
<link rel="stylesheet" href="{{ $style.Permalink | relURL }}" integrity="{{ $style.Data.Integrity }}" />
{{ if .Params.mathjax }} {{ partial "mathjax.html" . }} {{ end }}
<!-- Custom icons -->
<link rel="icon" type="image/png" href="{{ site.Params.assets.favicon96 | default "favicon-96x96.png" | absURL }}" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="{{ site.Params.assets.faviconsvg | default "favicon.svg" | absURL }}" />
<link rel="shortcut icon" href="{{ site.Params.assets.favicon | default "favicon.ico" | absURL }}" />
<link rel="apple-touch-icon" sizes="180x180" href="{{ site.Params.assets.appleTouchIcon | default "apple-touch-icon.png" | absURL }}" />
<link rel="manifest" href="{{ site.Params.assets.manifest | default "manifest.json" | absURL }}" />
</head>

View File

@ -0,0 +1,21 @@
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']],
displayMath: [['$$','$$'], ['\\[', '\\]']],
processEscapes: true,
processEnvironments: true
},
options: {
skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre']
}
};
window.addEventListener('load', (event) => {
document.querySelectorAll("mjx-container").forEach(function(x){
x.parentElement.classList += 'has-jax'})
});
</script>
<script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

View File

@ -0,0 +1,19 @@
<ul>
{{- range $item := .collection -}}
<li>
{{- with $item.url -}}
<a href="{{ $item.url | relURL }}">{{ safeHTML $item.title }}</a>
{{- else -}}
{{ safeHTML $item.title }}
{{- end -}}
</li>
{{- if $item.entries }}
{{ partial "menu_item.html" (dict "context" . "collection" $item.entries) }}
{{- end -}}
{{- if $item.post_list -}}
{{ partial "post_list.html" (dict "context" . "section" $item.post_list.section "limit" $item.post_list.limit "show_more" $item.post_list.show_more "show_more_text" $item.post_list.show_more_text "show_more_url" $item.post_list.show_more_url) -}}
{{- end -}}
{{- end -}}
</ul>

View File

@ -0,0 +1,39 @@
{{- $posts := "" -}}
{{- if .section -}}
{{- $posts = (where site.RegularPages "Section" .section) -}}
{{- else -}}
{{- if (eq .context.Kind "taxonomy") -}}
{{- $posts = .context.Pages -}}
{{- else -}}
{{- if (eq .context.Kind "term") -}}
{{- $posts = .context.Data.Pages -}}
{{- else -}}
{{- $posts = site.RegularPages }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $limit_exceeded:= "" -}}
{{- if (and .limit (gt (len $posts) .limit)) -}}
{{- $limit_exceeded = true -}}
{{- else -}}
{{- $limit_exceeded = false -}}
{{ end }}
{{- if (gt (len $posts) 0) }}
{{- if .limit }}
{{ $posts = (first .limit $posts ) }}
{{ end }}
<ul>
{{- range $post := $posts -}}
<li>
<span>{{- ($post.Date | time.Format site.Params.theme_config.date_format) }}</span>
<a href="{{ $post.Permalink | relURL }}">{{ $post.Title }}</a>
</li>
{{ end }}
{{- if and .show_more $limit_exceeded }}
<li><a href="{{ .show_more_url | relURL }}">{{ .show_more_text | default "Show more..." }}</a></li>
{{ end }}
</ul>
{{ end }}

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="{{ $.Site.LanguageCode }}">
{{- partial "head.html" . -}}
<body a="{{ $.Site.Params.theme_config.appearance | default "auto" }}">
<main class="page-content" aria-label="Content">
<div class="w">
<div class="post-meta">
{{ partial "back_link.html" .}}
<p>
<time datetime="{{ .Date }}">
{{ .Date | time.Format site.Params.theme_config.date_format }}
</time>
</p>
</div>
{{- block "main" . }}{{- end }}
{{ partial "footer.html" }}
</div>
</main>
</body>
</html>

View File

@ -0,0 +1,21 @@
{{ define "main" }}
<h1>{{ .Title }}</h1>
{{ .Content }}
<!-- divide post list by year -->
{{ if .Site.Params.theme_config.isListGroupByDate }}
{{ range .Pages.GroupByDate "2006 Year" }}
<p>{{ .Key }}</p>
<ul>
{{ range .Pages }}
<li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
{{ end }}
</ul>
{{ end }}
{{ else }}
{{ partial "post_list.html" (dict "context" . "section" .Section)}}
{{ end }}
{{ end }}

View File

@ -0,0 +1,14 @@
{{ define "main" }}
<article>
<h1>{{ .Title }}</h1>
{{ if .Params.toc }}
<aside {{ if .Params.tocBorder }} class="toc" {{ end }}>
{{ .TableOfContents }}
</aside>
{{ end }}
{{ .Content }}
</article>
{{ end }}

View File

@ -0,0 +1,6 @@
<details {{ if eq (.Get "open" | default "false") "true" }}open{{ end }}>
<summary>
{{ .Get "summary" | default "Details:" }}
</summary>
{{ .Inner | markdownify }}
</details>

View File

@ -0,0 +1,3 @@
<span>
$${{ .Get 0 }}$$
</span>

View File

@ -0,0 +1,3 @@
<span>
\({{ .Get 0 }}\)
</span>

View File

@ -0,0 +1,21 @@
# theme.toml template for a Hugo theme
# See https://github.com/gohugoio/hugoThemes#themetoml for an example
name = "no-style-please"
license = "MIT"
licenselink = "https://github.com/Masellum/hugo-theme-nostyleplease/blob/main/LICENSE"
description = "a (nearly) no-CSS, fast, minimalist Hugo theme ported from riggraz/no-style-please."
homepage = "https://github.com/Masellum/hugo-theme-nostyleplease"
tags = ["blog", "minimalist"]
features = []
min_version = "0.41.0"
[author]
name = "Masellum"
homepage = "Masellum.github.io"
# If porting an existing theme
[original]
name = "riggraz"
homepage = "https://riggraz.dev/"
repo = "https://github.com/riggraz/no-style-please"

@ -1 +0,0 @@
Subproject commit 41c99f7e974b698c1a91669cf653c4dcf0b293d0