All the code

This commit is contained in:
c0dev0id 2022-12-27 22:04:45 +01:00
parent a4251bf6ae
commit 3ed25b5b3f
47 changed files with 4200 additions and 0 deletions

11
.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
site/photos/*.html
site/photos/*/*.html
site/photos/*/mid
site/photos/*/thm
photos/*.html
photos/*/*.html
photos/*/mid
photos/*/thm
www/*
code/*
site/uugcal/*

120
Makefile Normal file
View File

@ -0,0 +1,120 @@
WWW = ${PWD}/www
SITE = ${PWD}/site
SCRIPTS = ${PWD}/scripts
LOCAL = /var/www/htdocs
REMOTE = sdk@codevoid.de:/home/www/htdocs/shagen
# do everything by default
all: build-and-upload-all
@echo "done."
# Create the photo galleries and create the index and preview html
# pages in site/, so they get parsed in the compile step
PHOTODIRS != find photos/* -maxdepth 0 -mindepth 0 -type d
photos: ${PHOTODIRS}
mkdir -p ${SITE}/photos
cd photos && sh ${SCRIPTS}/mkphotoindex.sh > index.html
find photos -type f -not -name "*.html" -exec install -D {} www/{} \;
find photos -type f -name "*.html" -exec install -D {} site/{} \;
optimize:
find photos -name "*.jpg" -type f -exec jpegoptim -w 12 --all-progressive --strip-all "{}" +
calendar:
mkdir -p ${SITE}/uugcal
cd ${SITE}/uugcal && sh ${SCRIPTS}/mkuugcalendar.sh > index.html
${PHOTODIRS}:
cd "$@" && sh ${SCRIPTS}/mkphotos.sh > index.html
# invoke zod and compile the website into the www/ dir
compile:
mkdir -p ${WWW}
zod ${SITE} ${WWW}
# after mixing different generators in the compile step, let's tidy and
# indent the output properly (XXX is there a tool that does _only_
# indent?)
tidy:
find ${WWW} -type f -name "*.html" \
-exec tidy -q -i -m -c -w 120 -f /dev/null {} \;
find ${WWW} -type f -name "*.html" \
-exec sed -i '/.*meta name="generator".*/d' {} \;
# create gzip variants of text files, so they can be served by httpds
# gzip-static extension
gzip:
find ${WWW} -type f \
\( -name "*.html" -o -name "*.css" \) \
-exec gzip -kf9 {} \;
# set permissions so the web server can read the file
fixperms:
doas chown -R sdk:www ${WWW}
doas chmod -R ugo+wrX,go-w ${WWW}
# we can upload to the local and the remote webserver at the same time
upload-local: stagit
doas rsync -a --delete ${WWW}/ ${LOCAL}/
upload-remote: stagit
doas rsync -a --delete -e ssh ${WWW}/ ${REMOTE}/
upload-all: upload-local upload-remote
build:
make clean; \
make photos; \
make stagit; \
make calendar; \
make compile; \
make tidy; \
make fixperms;
build-and-upload-all:
make build; \
make upload-all;
# deploy to the local webserver for preview
local:
make build; \
make upload-local;
remote:
make build; \
make upload-remote
# clean up temporary files and everything that can be regenerated very fast
clean:
rm -rf ${WWW}/photos
rm -rf ${SITE}/photos
rm -f photos/index.html
rm -f photos/*/*.html
rm -rf ${SITE}/uugcal
rm -rf ${WWW}
# clean and also delete all generated images
realclean: clean
rm -rf photos/*/{thm,mid}
### TARGETS BELOW ARE ONLY FOR CONVENIENCE
stagit:
scripts/reposync.sh
git-add:
find site/photos -type f \
-not -name "*.html" \
-not -path "*/thm/*" \
-not -path "*/mid/*" \
-exec git add "{}" +
# watch files and rebuild automatically
notify:
ulimit -n 1024; \
find ${SITE} ${SCRIPTS} -not -path "*/photos/*" -type f \
| inotifywait -m -e modify --fromfile - \
| while read line; \
do \
make; \
done
.PHONY: ${PHOTODIRS} ${REPOS}

11
config Normal file
View File

@ -0,0 +1,11 @@
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = git@github.com:c0dev0id/website.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main

36
scripts/mkphotoindex.sh Normal file
View File

@ -0,0 +1,36 @@
#!/bin/sh -e
echo "<h1>My Photos</h1>"
[ -f index.txt ] && cat index.txt
makelink() {
_text="$(echo "$1" | sed 's/-/ /g;s/_/ - /g;s/\(....\) \(..\) \(..\)/\1-\2-\3/')"
echo "<li><a href=\"${_dir}\">${_text}</a></li>"
}
echo "<h3>Events:</h3>"
echo "<ul>"
find * -maxdepth 0 -mindepth 0 -type d \
| grep "^20" \
| grep -v "unlisted" \
| sort -r \
| while read _dir
do
makelink "$_dir"
done
echo "</ul>"
echo "<h3>Collections:</h3>"
echo "<ul>"
find * -maxdepth 0 -mindepth 0 -type d \
| grep -v "^20" \
| grep -v "unlisted" \
| sort -r \
| while read _dir
do
makelink "$_dir"
done
echo "</ul>"

90
scripts/mkphotos.sh Normal file
View File

@ -0,0 +1,90 @@
#!/bin/sh -e
## settings
DIR="$(basename "$PWD")"
TITLE="$(basename "$PWD" |sed 's/unlisted-//g' | cut -d"_" -f2- | tr '-' ' ')"
mkdir -p thm mid
echo "<h1>$TITLE</h1>"
[ -f index.txt ] && cat index.txt
echo "<p>"
echo "<table class=\"photo-table\">"
echo "<tr>"
_count=0
find * -maxdepth 0 -mindepth 0 -type f \( -iname "*.jpg" \
-o -iname "*.jpeg" \
-o -iname "*.png" \
-o -iname "*.gif" \
\) \
| sort -r | while read _file
do
_file_thm="thm/${_file%%.*}.jpg"
_file_mid="mid/${_file%%.*}.jpg"
_file_html="${_file%%.*}.html"
_file_descr="${_file%%.*}.txt"
# increase file counter
_count=$(( _count + 1))
if [ ! -f "${_file_thm}" ]
then
convert -quality 73 \
-sharpen 2x2 \
-auto-orient \
-define jpeg:size=440x440 \
"$_file" \
-thumbnail 220x220^ \
-gravity center \
-extent 220x220 \
"${_file_thm}" \
>/dev/null 2>&1 &
fi
if [ ! -f "${_file_mid}" ]
then
convert -quality 83 \
-sharpen 2x2 \
-auto-orient \
-define jpeg:size=1440x2400 \
"$_file" \
-thumbnail 720x1600 \
"${_file_mid}" \
>/dev/null 2>&1 &
fi
if [ ! -f "${_file_html}" ]
then
echo "<h1>$TITLE</h1>" > "${_file_html}"
echo "<p>File: ${_file} (<a href=\"/photos/$DIR/${_file}\" target=_blank>Open Original</a>)</p>" >> "${_file_html}"
echo "<p><img class=\"photo-mid\" src=\"/photos/$DIR/${_file_mid}\"></p>" >> "${_file_html}"
[ -f "${_file_descr}" ] && cat "${_file_descr}" >> "${_file_html}"
echo "<p><a href=index.html>Back to Index</a></p>" >> "${_file_html}"
fi
echo "<td class=\"photo-td\" ><a href=\"/photos/$DIR/${_file_html}\"><img class=\"photo-img\" src=\"${_file_thm}\"></a></td>"
if [ $(( _count % 3 )) -eq 0 ]
then
echo "</tr><tr>"
fi
while [ $(pgrep convert | wc -l) -ge 15 ]
do sleep 0.3; done
done
echo "</tr>"
echo "</table>"
echo "</p>"
echo "<p><a href=../index.html>Back to the gallery index</a></p>"
echo "section: photos" > dir.meta
wait
# it looks like wait doesn't catch processes spawned
# in a subshell. So we check explicitely for running
# convert processes. XXX
while [ $(pgrep convert | wc -l) -ge 1 ]
do sleep 1; done

16
scripts/mkuugcalendar.sh Normal file
View File

@ -0,0 +1,16 @@
#!/bin/sh
REM=$(curl -s "https://raw.githubusercontent.com/c0dev0id/dotfiles/main/.reminders/uugrn.rem")
rm -f uugrn-calendar.*
echo "$REM" | remind -b1 -p24 - 2>/dev/null | rem2pdf > uugrn-calendar.pdf
echo "$REM" | remind -b1 -p24 - 2>/dev/null | rem2html --nostyle --tableonly > uugrn-calendar.html
echo "$REM" | remind -b1 -p24 - 2>/dev/null | rem2ics > uugrn-calendar.ics
echo "<h1>UUGRN Calendar</h1>"
echo "<ul>"
echo "<li><a href=uugrn-calendar.html>HTML Format</a></li>"
echo "<li><a href=uugrn-calendar.pdf>PDF Format</a></li>"
echo "<li><a href=uugrn-calendar.ics>iCAL Format</a></li>"
echo "</ul>"

30
scripts/reposync.sh Executable file
View File

@ -0,0 +1,30 @@
#!/bin/sh -e
add_repo() {(
_dir="$(basename "$1")"
if [ -d "code/${_dir}" ]
then
( cd code/${_dir} && git pull )
else
( cd code && git clone "https://$1" )
fi
_fulldir=$(readlink -f "code/${_dir}")
mkdir -p www/code/${_dir}
cp site/code/*.{css,png} www/code/${_dir}/
cd www/code/${_dir}
stagit -u https://stefanhagen.de/code ${_fulldir}
)}
mkdir -p code
add_repo "github.com/c0dev0id/dotfiles"
add_repo "github.com/c0dev0id/mkpicindex"
add_repo "github.com/c0dev0id/mystuff"
add_repo "github.com/c0dev0id/website"
add_repo "github.com/c0dev0id/xpick"
add_repo "github.com/luakit/luakit"
_repos="$(find code/* -mindepth 0 -maxdepth 0 -type d)"
stagit-index ${_repos} > www/code/index.html

65
scripts/tikz.lua Normal file
View File

@ -0,0 +1,65 @@
local system = require 'pandoc.system'
local tikz_doc_template = [[
\documentclass{standalone}
\usepackage[pdftex]{graphics}
\usepackage[pdftex]{graphicx}
\usepackage{xcolor}
\usepackage{tikz}
\begin{document}
\nopagecolor
%s
\end{document}
]]
local function tikz2image(src, filetype, outfile)
system.with_temporary_directory('tikz2image', function (tmpdir)
system.with_working_directory(tmpdir, function()
local f = io.open('tikz.tex', 'w')
f:write(tikz_doc_template:format(src))
f:close()
os.execute('pdflatex tikz.tex >/dev/null 2>&1')
if filetype == 'pdf' then
os.rename('tikz.pdf', outfile)
else
os.execute('pdf2svg tikz.pdf ' .. outfile .. '>/dev/null 2>&1')
end
end)
end)
end
extension_for = {
html = 'svg',
html4 = 'svg',
html5 = 'svg',
latex = 'pdf',
beamer = 'pdf' }
local function file_exists(name)
local f = io.open(name, 'r')
if f ~= nil then
io.close(f)
return true
else
return false
end
end
local function starts_with(start, str)
return str:sub(1, #start) == start
end
function RawBlock(el)
if starts_with('\\begin{tikzpicture}', el.text) then
local filetype = extension_for[FORMAT] or 'svg'
local fbasename = pandoc.sha1(el.text) .. '.' .. filetype
local fname = system.get_working_directory() .. '/' .. fbasename
if not file_exists(fname) then
tikz2image(el.text, filetype, fname)
end
return pandoc.Para({pandoc.Image({}, fbasename)})
else
return el
end
end

47
site/.zod/config Normal file
View File

@ -0,0 +1,47 @@
; This is an example zodiac configuration file
; A line starting with a `;` is a comment and is ignored.
; The `parse` section is for page templates that will not be converted to
; HTML via an external utility.
;
; [parse]
; extension,extension
; extension
; ...
;
; [parse]
; htm
; html
; The `parse_convert` section is for page templates that will be converted
; to HTML via an external utility.
;
; By default, page templates with the `md` extension are piped through the
; built-in awk implementation of Markdown.
;
; [parse_convert]
; extension,extension command
; extension command
; ...
[parse_convert]
sh sh
md discount
adoc asciidoctor -r asciidoctor-diagram -a data-uri -a allow-uri-read -a svg-embed -a diagram-svg-type=inline -a showtitle -a icons=image -a icontype=svg -a iconsdir=site/images/icons -s -
tex pandoc --embed-resources --lua-filter scripts/tikz.lua
; md,markdown discount
; txt asciidoc -s -
; The `ignore` section is for patterns that zodiac will ignore when
; searching the project directory. Ignored files will not be parsed or
; copied to the target directory.
;
; [ignore]
; pattern
; pattern
; ...

2068
site/asciidoctor.css Normal file

File diff suppressed because it is too large Load Diff

17
site/blog.md Normal file
View File

@ -0,0 +1,17 @@
# Blog
These are my blog posts
* 2021-09-26 [Memory management, virtual and residential memory](/blog/2021-09-26-memory-management.html)
* 2021-01-09 [Mutt inline patch handling](/blog/2021-01-09-mutt-inline-patch-macro.html)
* 2020-11-14 [OpenBSD Full Disk Encryption (FDE) Setup](/blog/2020-11-14-openbsd-fde.html)
* 2020-05-17 [Dark-Mode in Browsers](/blog/2020-05-17-browser-dark-mode.html)
* 2019-10-24 [Building an OpenBSD Kernel](/blog/2019-10-24-building-an-openbsd-kernel.html)
* 2019-10-17 [LineageOS on the Motorola Z2 Force](/blog/2019-10-17-LineageOS-on-Motorola-Z2-Force.html)
* 2019-04-27 [Manage dotfiles with git](/blog/2019-04-27-manage-dotfiles-with-git.html)
*Note that the $ and # in my blog posts have meaning.*
<pre>
$ run this command as user
# run this command as root (or prepend doas/sudo)
</pre>

2
site/blog.meta Normal file
View File

@ -0,0 +1,2 @@
title: Blog
section: blog

View File

@ -0,0 +1,58 @@
# Manage dotfiles with git
I'm managing my dotfiles with git. My method serves me well for a few
years already and so I think it's time to write it down.
If you think git, you might think of a dotfile repository and dozens of
symlinks into the home directory. This is precisely what kept me from
using git until I discovered bare repositories.
Create your dotfile repository with the `--bare` parameter
<pre>
git init --bare ${HOME}/.cfg
</pre>
This creates only a folder for git control files, which normally reside
inside the `.git` folder within the repository.
You can now tell git to use `${HOME}` as your work-tree directory. This
makes git handle your home directory like all the files would be within
the git repository. Now you can:
<pre>
git --git-dir=${HOME}/.cfg/ --work-tree=${HOME} add .vimrc
git --git-dir=${HOME}/.cfg/ --work-tree=${HOME} commit -m "my .vimrc"
</pre>
If course it is silly to type out such a long command every time you
want to interract with your dotfiles. So why not create an alias?
<pre>
alias config='git --git-dir=${HOME}/.cfg/ --work-tree=${HOME}'
</pre>
Put this in your `~/.bashrc` or `~/.kshrc` and you can now use the command
`config` in the same way you usually use git.
<pre>
config add .vimrc
config commit -m "my vimrc"
</pre>
Maybe you have been brave and typed `config status` already. This will
list the content of your whole home directory as "untracked files". This
is not what we want. We can run `git config` and tell it to stop doing
this. But of course we must run our git, which is called `config`.
<pre>
config config --local status.showUntrackedFiles no
</pre>
Now git status will only check what's being tracked. So if you add
your vimrc file and later change it, `config status` will show it,
`config diff` will diff it...
You can now use the power of git with your new `config` command.
The solution is not perfect, but it comes pretty close...

View File

@ -0,0 +1,42 @@
# LineageOS on Motorola Z2 Force
Whenever there is a major LineageOS Update, chances are that I forgot
the flashing process. So here are the notes.
Disclaimer: Due to the missing tools to flash from OpenBSD, I use my
work computer, which runs windows.
*Required Downloads:*
* [Android Platform Tools](https://dl.google.com/android/repository/platform-tools-latest-windows.zip)
(contains adb and fastboot)
* [Motorola Smart Assistant](https://support.lenovo.com/us/en/downloads/ds101291) (contains USB drivers for fastboot)
*Prepare:*
- Install motorola smart assistant
- Extract platform-tools make sure you're in the platform tools
directory or that they are in your $PATH.
*Update steps:*
- &gt; Boot into bootloader (power+down)
- $ fastboot flash boot_a &lt;lineageos_recovery&gt;.img
- $ fastboot flash boot_b &lt;lineageos_recovery&gt;.img
- &gt; Boot into bootloader (power+down) -&gt; Boot Recovery
- &gt; Factory Reset -&gt; Wipe data / factory reset + Wipe System
- &gt; Apply update -&gt; adb sideload
- $ adb sideload &lt;lineageos&gt;.zip
- $ adb sideload &lt;addons&gt;.zip
- &gt; Reboot
$ == commandline activity<br>
&gt; == phone activity
*Notes:*
* "adb devices" works without USB drivers
* "fastboot devices" shows nothing if USB drivers are not installed
* This phone has two boot areas and therefore "fastboot flash boot" will
fail. The areas "boot_a" and "boot_b" must be used instead. If "boot_a"
and "boot_b" are flashed differently, booting will fail.

View File

@ -0,0 +1,47 @@
# Building an OpenBSD Kernel
I'm running OpenBSD-current for a while in order to support my port.
It's only one port at the moment, but that's a start, right?
Anyway... every once in a while I stumble over a patch on the OpenBSD
mailing list I want to try and this requires me to apply the patch and
build the Kernel with it. But how?
Well, the documentation is where
[where you would expect it](https://www.openbsd.org/faq/faq5.html#Custom).
*Download the kernel source*
<pre>
# cd /usr
# cvs -qd anoncvs@anoncvs.ca.openbsd.org:/cvs checkout -P src
</pre>
*Update the kernel source (if you downloaded it a while ago)*
<pre>
# cd /usr/src
# cvs -q up -Pd
</pre>
*Configure Kernel*
<pre>
# cd /usr/src/sys/arch/amd64/conf
# cp GENERIC.MP MYKERNEL
# config MYKERNEL
</pre>
*Build and install kernel (amd64)*
<pre>
# cd /sys/arch/amd64/compile/MYKERNEL
# make clean
# make
# make install # the old kernel is /obsd now
</pre>
That's it. Reboot.
This is ONLY the Kernel. If you need to build the whole system, please
consult the OpenBSD documentation. The manpage release(8) is a good start.

View File

@ -0,0 +1,55 @@
# Browser Dark Mode
Dark Mode luckily has become a thing also in the non-unix world. Finally
browsers can be used with dark interfaces and websites can have
alternative color schemes.
However, in other operating systems, there is a global toggle for dark
mode, which also switches the browser into it. This is not the case on
linux and unix systems.
## Chrome / Chromium / Iridium
Chrome and Chromium starting with version 73 can be tought to start in
dark mode:
<pre>
$ chrome --enable-features=WebUIDarkMode --force-dark-mode
</pre>
Then go to chrome://settings/?search=themes and switch the theme to
"Classic".
## Firefox
Firefox learned the dark mode in release 70.
0. Go to "about:config"
1. Enter "ui.systemUsesDarkTheme" into the search bar
2. Click "Number" and then "+"
3. Enter "1" and click the check mark
Right click on a free spot in the icon bar and select "customize". At
the bottom left of the screen, you can switch to a dark theme.
Note: If you've set privacy.resistFingerprinting to "true" the CSS dark
mode switching won't work. Kudus to
[@andinus@tilde.zone](https://tilde.zone/@andinus) for figuring this out.
There you go, both browsers are in dark mode now. The UI should be dark
and also websites that support the `@media (prefers-color-scheme: dark)`
directive should make use of it.
You can test it on my webpage ([https://codevoid.de](https://codevoid.de)). The
light version has a light gray background and a blue font. The dark version has
a dark gray background and an orange font.
## vim-browser (vimb)
<pre>
$ echo "set dark-mode=true" &gt;&gt; ${HOME}/.config/vimb/config
</pre>
## luakit
Open `:settings` and check `application.prefer_dark_mode`

View File

@ -0,0 +1,32 @@
# OpenBSD FDE Setup
This is a condensed version of [OpenBSD FDE
FAQ](https://www.openbsd.org/faq/faq14.html#softraid).
Boot installer, drop to shell with "s"
<pre>
# cd /dev && sh MAKEDEV sd0
# dd if=/dev/urandom of=/dev/rsd0c bs=1m
# fdisk -iy -g -b 960 sd0 # GPT / without -g and -b for MBR
# disklabel -E sd0
</pre>
Note, switch to kbd en before setting the password as this is
what you have on the boot prompt.
<pre>
# bioctl -c C -l sd0a softraid0
# dd if=/dev/zero of=/dev/rsd1c bs=1m count=1
</pre>
Ctrl+D to restart the installer. Choose sd1 as install target.
If sd1 is not present:
<pre>
# cd /dev && sh MAKEDEV sd1
</pre>
When the installer later asks about installing with MBR or GPT layout,
choose MBR. Even if you boot via UEFI/GPT.

View File

@ -0,0 +1,74 @@
# Mutt inline patch handling
Developers like to send diffs inline in emails. They do this, because it's fast
and easy to read through them, comment on them and also to apply them. Some
version control systems also take over the email text into the patch description
as well.
Up to now, my workflow was manual. I had to save the email somewhere, then open
a terminal, cd to the direcory the patch shall be applied in and call the patch
utility with the path to the saved email as argument.
No more.
This mutt macro takes the current visible email and copies it to a temporary
file (/tmp/mutt-patch.diff). Then it executes the portpatch.sh shell script. All
with one push on ctrl+s while looking at the email.
The macro must be written in one line and ^S can be entered with the keyboard
sequence ctrl+v ctrl+s:
<pre>
macro pager ^S "&lt;shell-escape&gt;rm -f /tmp/mutt-patch.diff&lt;enter&gt;&lt;copy-message&gt;/tmp/mutt-patch.diff&lt;enter&gt;&lt;enter-command&gt;echo 'Saved as /tmp/mutt-patch.diff'&lt;enter&gt;&lt;shell-escape&gt; ~/.mutt/scripts/portpatch.sh /tmp/mutt-patch.diff&lt;enter&gt;"
</pre>
The portpatch.sh script:
<pre>
#!/bin/sh
# needs converters/qprint
clear
echo '---------------------------------------------------------------------'
grep -E 'Subject: |^Index|^RCS|^diff --git|^file +|^[-+]{3} ' "${1}"
echo '---------------------------------------------------------------------'
printf "Apply patch on path [defaults to /usr/ports]? "
read -r _path
printf "Fix quoted-printable mangeled patch? [y/N]: "
read -r _qprint
case ${_qprint} in
[y|Y]) _catcmd="qprint -d"; ;;
*) _catcmd="cat"; ;;
esac
printf "Strip? [0]: "
read -r _strip
${_catcmd} "${1}" | doas patch -Ep${_strip:=0} -d ${_path:=/usr/ports}
cd ${_path} && ksh
</pre>
The script shows some relvant bits from the email patch that are handy
to determine on which path the patch shall be applied.
Next it allows the user to enter a different path. I mostly use /usr/ports, so
this is the default. Then the patch is applied and a ksh shell is opened for
further work.
Quitting the shell brings me back to mutt to work on the next email.
Sometimes someone sends a mangled patch encoded in quoted-printable. My script
allows to fix this with qprint.
Git diffs mostly need strip 1 to cut off the a/ b/ in front of the file path, so
the script is asking for that too. For most patches on ports@, the defaults are
fine and hitting enter 2 times works as intended.
*...and if everyone would generate patches from the /usr/ports root, it wouldn't
even be necessary to enter the path.*
This is quite friggin handy.

View File

@ -0,0 +1,213 @@
# GnuPG Quickstart
I love GPG and the way it works. I know there are many that complain
about it because it has flaws. My stance on this is that I prefer
battle-tested software with known flaws to something with unknown flaws.
Anyway, this should get you started with GnuPG
## Prerequisites
Install gpg and pinentry.
<pre>
# pkg_add gnupg pinentry
</pre>
## You need a Key
If you want to lock and unlock stuff, you need a key. This is how you
get to one:
<pre>
$ gpg --generate-key
</pre>
Hop through the wizard until you see these lines:
<pre>
pub rsa3072 2021-05-19 [SC] [expires: 2023-05-19]
BA696588D9A04AD9F70DA33EC54733F6DBECC2C1
uid John Doe &lt;j.doe@example.com&gt;
sub rsa3072 2021-05-19 [E] [expires: 2023-05-19]
</pre>
If you see an error like:
gpg: agent_genkey failed: Permission denied
Add the following entry and try again.
<pre>
$ echo "allow-loopback-pinentry" &gt;&gt; ~/.gnupg/gpg-agent.conf
</pre>
Congratulations, you got yourself a GPG Key. This long gibberish is your
full GPG Key ID. Most of the time, you can simply use the last 8
characters. So the short version of this GPG Key is DBECC2C1.
You can set it as default key, so it's used to encrypt stuff when no
explicit key is given.
<pre>
$ echo "default-key DBECC2C1" &gt;&gt; ~/.gnupg/gpg.conf
</pre>
## Share the key with your people
If you want someone to be able to encrypt something for you, send him or
her the output of:
<pre>
$ gpg --export -a DBECC2C1
</pre>
You can also use your email address instead of the Key ID, if you have
only one key with it. This key is public. So put it on some webspace and
add a link to your email header or signature.
## Upload the key so people can find it (optional)
You can also upload your key to a key server. For this, configure a
keyserver:
<pre>
$ echo "keyserver hkps://keys.openpgp.org" &gt;&gt; ~/.gnupg/gpg.conf
</pre>
Then send your key to it:
<pre>
$ gpg --send-keys DBECC2C1
</pre>
## You got a key from someone
Add a key from someone else to gnupg, so you can use it to encrypt data
for this person. If the key is on your harddrive, use:
<pre>
$ gpg --import &lt;pubkeyfile.asc&gt;
</pre>
The file ending here is kind of undefined. Some call it .asc, .gpg, .pub
or .key. If the key is on a key server, you can import it like so:
<pre>
$ gpg --recv-key 52BE43BA
</pre>
This would import my key. You can look at it now with:
<pre>
$ gpg --list-keys 52BE43BA
</pre>
## Encrypt a file
This encrypts the file plain.txt with the public key DBECC2C1.
<pre>
$ gpg --encrypt -r DBECC2C1 file.txt
</pre>
Now you have file.txt.gpg, which is the encrypted version
## Decrypt a file
GnuPG automaticall figures out what key it can use to decrypt a file. So
this will output the content of file.txt on the terminal. If you want
to save the output in a file, add -o file.txt.
<pre>
$ gpg -d file.txt.gpg
$ gpg -d file.txt.gpg -o file.txt
</pre>
## Choose a better password prompt (optional)
You can change the way gpg asks for the password:
<pre>
$ cat ~/.gnupg/gpg-agent.conf
[...]
pinentry-program /usr/local/bin/pinentry-curses
[...]
</pre>
Options are:
- pinentry (sometimes also called pinentry-tty)
- pinentry-curses
- pinentry-gtk2: pkg_add pinentry-gtk2
- pinentry-gnome3: pkg_add pinentry-gnome3
- pinentry-dmenu: https://github.com/ritze/pinentry-dmenu
*Note: If you use a console pinentry program and want to use gpg with a
GUI tool (like thunderbird), the password prompt will be invisible and
gpg/thunderbird will freeze.*
Makes sense, doesn't it?
## Start GPG Agent for password caching (optional)
Put this in your .kshrc or .bashrc:
<pre>
export GPG_TTY=$(tty)
gpg-connect-agent /bye
</pre>
## Make a Backup (not so optional)
There is no handholding cloud or support team you can call when you
messed up or deleted your key. So back it up safely.
Either you backup your ~/.gnugp directory, or you export the secret
keys and backup them safely.
<pre>
$ gpg --export-secret-keys -a DBECC2C1 &gt; gpg_key_backup.sec
</pre>
Seriously, don't skip this step.
## Configure Mutt (optional)
Install mutt with the gpgme flavor. Gpgme is the "new way" of handling
gpg in mutt.
<pre>
# pkg_add mutt--gpgme
</pre>
If you're not on OpenBSD, check with `mutt -v` if it was compiled with
the `--enable-gpgme` option. Then enable it in mutt.
<pre>
$ cat ~/.muttrc
[...]
crypt_use_gpgme = yes
[...]
</pre>
In the mutt compose view, you can now select Security Options.
<pre>
From: c0dev0id &lt;c0@example.com&gt;
To: j.doe@example.com
Cc:
Bcc:
Subject: Hello my friend
Reply-To:
Fcc: =Sent
Security: Sign, Encrypt (PGP/MIME)
Sign as: &lt;default&gt;
</pre>
You can change the setting with the key "p", which should bring up a
selection menu.
PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, s/(m)ime or (c)lear?
*That's it! GPG is not difficult. You need to know a few bits, but these are not
more difficult than many other things we do on a daily basis.*

View File

@ -0,0 +1,69 @@
<i>Disclaimer: I'm trying to learn this stuff. Now a year later, I think
I got some terminology wrong. The process address space is not one, but
many pages. How many depends on the page size.</i>
# Memory management, virtual and residential memory
Memory management is a complex topic and most can be left for the kernel
to handle. But having a fundamental idea about where memory is
allocated greatly helps in understanding top(1) and the memory footprint
of applications.
## Process memory address space (page)
When a process starts up, the kernel assigns it a so called memory page.
The page size depends on the architecture. On amd64 it's 2^64 - 1 bytes.
Every memory allocation this process performs, returns a pointer to some
place within this page. Forcing a pointer outside this page, will cause
a SEGFAULT.
<pre>
char *w = 1; // segfault
char *w = malloc(12); // returns pointer within page
</pre>
# Memory allocation (virtual memory)
Let's say we allocatate 2G of memory:
<pre>
char *m = malloc(2*1073741824); // 2*1G in bytes
</pre>
This will grab 2G of consecutive address space within the process memory.
At this point, the memory is likely available but not guaranteed. The
allocation shows up in top(1) as "SIZE" or on linux as "VIRT"ual memory.
This memory is not actually used. So nothing has been written to the
physical RAM chip in your computer.
# Using memory (residential memory)
Once memory gets used, it will actually use up space on your RAM chip.
<pre>
memset(m, 'u', 1073741824);
</pre>
Now we've written the character "u" to the first 1G of our allocated
memory. If we look at top(), we'll see something like this:
<pre>
PID TID PRI NICE SIZE RES STATE WAIT TIME CPU COMMAND
96621 569318 3 0 2048M 1027M sleep/12 ttyin 0:01 1.66% ./a.out
^ ^
allocated memory -' `- used (written) memory
</pre>
Note 1: When memory is swapped to disk, it leaves the residential bucket and
can be seen as swap-&gt;used.
Note 2: Stack memory will also show up as residential when used. Unused stack
memory will *not* show up as virtual memory.
Note 3: Residential memory includes shared memory as well. If you see 10
chrome processes which are consuming 300MB of residential memory each, this
does *not* mean that chrome as a whole is using 3000MB.
TODO: Find out how the shared memory part of RES can be seen on OpenBSD.
(Linux has SHR in top)

2
site/code.meta Normal file
View File

@ -0,0 +1,2 @@
title: Code
section: code

37
site/code.sh Normal file
View File

@ -0,0 +1,37 @@
#!/bin/sh
_distpath="$PWD/www/distfiles"
mkdir -p "$_distpath"
_repopath="/home/sdk/www/repo"
out() { printf ' %s%s\n' "$1"; }
out "<h1>Source Code Repositories</h1>"
out " <p>Stuff I wrote or regularly contribute to</p>"
repo() {
NAME="$1"
LINK="$2"
DESC="$3"
out " <tr>"
out " <td><a href=\"$LINK\">$NAME</a></td>"
out " <td>$DESC</td>"
out " </tr>"
}
out "<table class=\"repotable\">"
out " <tr>"
out " <th>Repository</th>"
out " <th>Description</th>"
out " </tr>"
repo "xpick" "https://github.com/c0dev0id/xpick" "Command line color picker with hex, xterm and rgb support"
repo "mkpicindex" "https://github.com/c0dev0id/mkpicindex" "Image gallery generator with shell tools (static + js version)"
repo "luakit" "https://github.com/luakit/luakit" "Fast, small, webkit based browser framework extensible by Lua"
repo "mystuff" "https://github.com/c0dev0id/mystuff" "My OpenBSD ports"
repo "dotfiles" "https://github.com/c0dev0id/dotfiles" "My Dotfiles"
out "</table>"

BIN
site/code/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
site/code/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

153
site/code/style.css Normal file
View File

@ -0,0 +1,153 @@
:root {
--width : 36;
--rounding : 8px;
--accent : #1d3456;
--dark-grey : #ddd;
--grey : #eee;
--light-grey : #f8f8f8;
--code : #bdd5f6;
--content : min(calc(1rem * var(--width) - 2rem),calc(100vw - 2rem));
}
@font-face {
font-family : 'Proza';
font-weight : 400;
src : url('/proza-r.woff2') format('woff2');
}
@font-face {
font-family : 'Proza';
font-weight : 300;
src : url('/proza-l.woff2') format('woff2');
}
@font-face {
font-family : 'Proza';
font-weight : 300;
font-style : italic;
src : url('/proza-li.woff2') format('woff2');
}
html {
height : 100%;
font-family : Proza,sans-serif;
font-weight : 300;
font-size : clamp(16px, 100vw / var(--width), 20px);
font-feature-settings : 'onum','pnum';
line-height : 1.5;
-webkit-text-size-adjust : none;
text-size-adjust : none;
}
body {
height : 100%;
background : var(--accent);
color : #fff;
}
header,
footer {
font-weight : 400;
}
body {
color: #000;
background-color: #fff;
}
h1, h2, h3, h4, h5, h6 {
font-size: 1em;
margin: 0;
}
img, h1, h2 {
vertical-align: middle;
}
img {
border: 0;
}
a:target {
background-color: #ccc;
}
a.d,
a.h,
a.i,
a.line {
text-decoration: none;
}
#blob a {
color: #555;
}
#blob a:hover {
color: blue;
text-decoration: none;
}
table thead td {
font-weight: bold;
}
table td {
padding: 0 0.4em;
}
#content table td {
vertical-align: top;
white-space: nowrap;
}
#branches tr:hover td,
#tags tr:hover td,
#index tr:hover td,
#log tr:hover td,
#files tr:hover td {
background-color: #eee;
}
#index tr td:nth-child(2),
#tags tr td:nth-child(3),
#branches tr td:nth-child(3),
#log tr td:nth-child(2) {
white-space: normal;
}
.desc {
color: #555;
}
hr {
border: 0;
border-top: 1px solid #555;
height: 1px;
}
pre {
font: 0.8rem 'Consolas',Menlo,monospace
}
pre a.h {
color: #00a;
}
.A,
span.i,
pre a.i {
color: #070;
}
.D,
span.d,
pre a.d {
color: #e00;
}
pre a.h:hover,
pre a.i:hover,
pre a.d:hover {
text-decoration: none;
}

BIN
site/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
site/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

1
site/global.meta Normal file
View File

@ -0,0 +1 @@
site_title: Stefan Hagen

122
site/gpg.txt Normal file
View File

@ -0,0 +1,122 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=ZR0P
-----END PGP PUBLIC KEY BLOCK-----

38
site/helpers.awk Normal file
View File

@ -0,0 +1,38 @@
{ helpers = "yes" }
function load_helpers() {
data["page_title"] = page_title()
data["section_blog"] = section_blog()
data["section_code"] = section_code()
data["section_photos"] = section_photos()
data["page_css"] = page_css()
}
function page_title( title) {
if (data["title"]) {
title = data["title"] " - " data["site_title"]
} else {
title = data["site_title"]
}
return title
}
function section_blog(section) {
if (data["section"] == "blog") {
return " class=\"section\""
}
}
function section_code(section) {
if (data["section"] == "code") {
return " class=\"section\""
}
}
function section_photos(section) {
if (data["section"] == "photos") {
return " class=\"section\""
}
}
function page_css(css) {
if (data["page_css"]) {
return "<link rel=\"stylesheet\" href=\"" data["page_css"] "\" type=\"text/css\">\n "
}
}

BIN
site/images/404.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
site/images/bun.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -0,0 +1,3 @@
<svg width="20" height="16" viewBox="0 0 20 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 14.7929C12 15.4596 12.5404 16 13.2071 16C13.5273 16 13.8343 15.8728 14.0607 15.6464L19.48 10.2271C19.813 9.89415 20 9.44259 20 8.97176C20 8.54798 19.8484 8.13818 19.5726 7.81642L14.0847 1.4138C13.8595 1.15116 13.5309 1 13.185 1C12.5305 1 12 1.53053 12 2.18496V5.01434C9.66201 5.06374 7.90557 4.8176 6.28027 4.13698C4.53922 3.40788 2.90304 2.16138 0.850537 0.143456C0.70688 0.0022192 0.492492 -0.0390072 0.306698 0.0388775C0.120904 0.116762 0 0.298542 0 0.5C0 7.15985 5.96289 11.7483 12 11.99V14.7929ZM13.2071 15C13.0927 15 13 14.9073 13 14.7929V11.5C13 11.2239 12.7761 11 12.5 11C7.10216 11 1.7852 7.23342 1.07916 1.74406C2.77038 3.3059 4.27094 4.37968 5.894 5.05936C7.81401 5.8634 9.85983 6.09714 12.5183 5.99966C12.7872 5.98981 13 5.76901 13 5.5V2.18496C13 2.08281 13.0828 2 13.185 2C13.239 2 13.2903 2.02359 13.3254 2.06459L18.8134 8.46721C18.9338 8.60772 19 8.78669 19 8.97176C19 9.17738 18.9183 9.37458 18.7729 9.51997L13.3536 14.9393C13.3147 14.9782 13.262 15 13.2071 15Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,3 @@
<svg width="19" height="20" viewBox="0 0 19 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.7581 1.62676C15.513 0.693165 13.7528 0.806267 12.6435 1.89114L2.44525 10.8715C0.546832 12.7282 0.542258 15.7358 2.43502 17.5979C4.33701 19.4691 7.43251 19.4741 9.34079 17.609L17.7422 10.393C17.9411 10.1986 18.2635 10.1986 18.4623 10.393C18.6612 10.5874 18.6612 10.9025 18.4623 11.0968L10.0609 18.3129C7.75401 20.5676 4.01184 20.5616 1.71251 18.2994C-0.575654 16.0483 -0.570125 12.4124 1.72488 10.1679L11.9232 1.1875C13.3938 -0.250761 15.7274 -0.400704 17.378 0.837005C19.3649 2.32684 19.5566 5.18521 17.7859 6.91589L7.92572 15.5573C7.02391 16.4387 5.56126 16.4369 4.66167 15.5534C3.7652 14.6729 3.76699 13.2493 4.66567 12.3709L12.65 5.56256C12.8489 5.36819 13.1713 5.36819 13.3702 5.56256C13.569 5.75692 13.569 6.07205 13.3702 6.26641L5.38581 13.0748C4.88416 13.5651 4.88317 14.3597 5.38358 14.8512C5.88573 15.3444 6.70219 15.3454 7.20559 14.8534L17.0657 6.21202C18.4014 4.90658 18.2567 2.75053 16.7581 1.62676Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

98
site/images/icons/cc0.svg Normal file
View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="88px" height="31px" viewBox="-0.5 -0.101 88 31" enable-background="new -0.5 -0.101 88 31" xml:space="preserve">
<g>
<path fill="#FFFFFF" d="M1.803,0.482L84.93,0.631c1.161,0,2.198-0.173,2.198,2.333L87.025,30.52h-87.32V2.862
C-0.295,1.626-0.177,0.482,1.803,0.482z"/>
<g>
<ellipse fill="#FFFFFF" cx="13.887" cy="15.502" rx="11.101" ry="11.174"/>
</g>
<path d="M23.271,4.061c3.484,2.592,5.754,6.744,5.755,11.44c-0.001,4.272-1.88,8.095-4.842,10.705h62.853V4.061H23.271z"/>
<g>
<path fill="#FFFFFF" d="M35.739,7.559c0.392,0,0.728,0.059,1.002,0.173c0.276,0.116,0.5,0.268,0.674,0.456
c0.173,0.189,0.299,0.405,0.379,0.647c0.079,0.242,0.118,0.494,0.118,0.753c0,0.253-0.039,0.503-0.118,0.749
c-0.08,0.244-0.206,0.462-0.379,0.65c-0.174,0.189-0.397,0.341-0.674,0.456c-0.274,0.114-0.61,0.173-1.002,0.173h-1.452v2.267
h-1.382V7.559H35.739z M35.36,10.535c0.158,0,0.312-0.012,0.457-0.035c0.147-0.023,0.276-0.069,0.388-0.137
c0.112-0.068,0.201-0.164,0.269-0.288s0.101-0.287,0.101-0.487c0-0.2-0.033-0.362-0.101-0.487
c-0.067-0.124-0.157-0.221-0.269-0.287c-0.111-0.068-0.24-0.114-0.388-0.138C35.671,8.652,35.518,8.64,35.36,8.64h-1.073v1.896
L35.36,10.535L35.36,10.535z"/>
<path fill="#FFFFFF" d="M43.751,13.4c-0.476,0.417-1.133,0.625-1.972,0.625c-0.851,0-1.509-0.207-1.976-0.62
c-0.466-0.412-0.699-1.052-0.699-1.913V7.559h1.381v3.934c0,0.171,0.016,0.338,0.045,0.505c0.029,0.165,0.091,0.311,0.185,0.439
c0.094,0.126,0.225,0.229,0.392,0.309c0.167,0.081,0.392,0.12,0.673,0.12c0.493,0,0.833-0.11,1.021-0.332
c0.188-0.222,0.282-0.568,0.282-1.04V7.559h1.382v3.934C44.464,12.348,44.227,12.983,43.751,13.4z"/>
<path fill="#FFFFFF" d="M49.07,7.559c0.3,0,0.572,0.027,0.818,0.081c0.244,0.054,0.457,0.14,0.633,0.261
c0.177,0.121,0.312,0.282,0.41,0.482c0.096,0.201,0.146,0.45,0.146,0.745c0,0.318-0.072,0.584-0.216,0.796
c-0.146,0.212-0.357,0.388-0.639,0.523c0.387,0.112,0.676,0.31,0.865,0.589c0.189,0.281,0.286,0.62,0.286,1.015
c0,0.319-0.062,0.595-0.187,0.828c-0.123,0.232-0.289,0.423-0.496,0.571c-0.209,0.148-0.445,0.257-0.713,0.327
c-0.269,0.07-0.541,0.105-0.822,0.105h-3.047V7.559H49.07z M48.895,10.119c0.246,0,0.448-0.059,0.607-0.178
c0.158-0.118,0.236-0.309,0.236-0.576c0-0.147-0.025-0.269-0.078-0.363c-0.053-0.093-0.123-0.168-0.211-0.221
c-0.09-0.053-0.189-0.091-0.305-0.109C49.029,8.65,48.912,8.64,48.789,8.64h-1.294v1.48L48.895,10.119L48.895,10.119
L48.895,10.119z M48.975,12.804c0.135,0,0.264-0.014,0.387-0.04c0.123-0.026,0.23-0.072,0.326-0.133
c0.092-0.062,0.168-0.147,0.226-0.254c0.056-0.104,0.083-0.241,0.083-0.406c0-0.324-0.092-0.557-0.271-0.695
c-0.182-0.138-0.424-0.208-0.723-0.208h-1.505v1.738h1.479v-0.002H48.975z"/>
<path fill="#FFFFFF" d="M54.143,7.559v5.156h3.062v1.168H52.76V7.559H54.143z"/>
<path fill="#FFFFFF" d="M59.748,7.559v6.324h-1.382V7.559H59.748z"/>
<path fill="#FFFFFF" d="M65.451,9.247c-0.082-0.132-0.186-0.249-0.309-0.349c-0.123-0.102-0.263-0.18-0.418-0.236
c-0.156-0.057-0.316-0.084-0.488-0.084c-0.312,0-0.574,0.062-0.793,0.183c-0.217,0.12-0.394,0.283-0.525,0.486
c-0.136,0.204-0.232,0.436-0.296,0.695c-0.062,0.259-0.093,0.528-0.093,0.806c0,0.267,0.031,0.524,0.093,0.776
c0.062,0.251,0.16,0.477,0.296,0.678c0.134,0.201,0.312,0.361,0.525,0.483c0.219,0.12,0.481,0.181,0.793,0.181
c0.424,0,0.752-0.13,0.99-0.389c0.236-0.26,0.383-0.602,0.437-1.028H67c-0.034,0.396-0.126,0.753-0.271,1.072
c-0.146,0.318-0.342,0.591-0.582,0.815c-0.238,0.225-0.521,0.396-0.845,0.513c-0.323,0.119-0.678,0.178-1.065,0.178
c-0.479,0-0.914-0.084-1.297-0.252c-0.385-0.169-0.709-0.398-0.973-0.695c-0.265-0.295-0.468-0.642-0.607-1.04
c-0.142-0.399-0.211-0.829-0.211-1.289c0-0.473,0.069-0.911,0.211-1.316c0.141-0.404,0.344-0.758,0.607-1.059
c0.264-0.302,0.588-0.536,0.973-0.708c0.384-0.172,0.815-0.258,1.297-0.258c0.348,0,0.676,0.051,0.981,0.15
c0.308,0.102,0.583,0.248,0.827,0.44c0.243,0.191,0.443,0.43,0.604,0.712c0.158,0.283,0.259,0.608,0.301,0.975h-1.34
C65.586,9.524,65.533,9.377,65.451,9.247z"/>
<path fill="#FFFFFF" d="M35.615,16.418c0.405,0,0.782,0.062,1.131,0.192c0.35,0.13,0.651,0.324,0.906,0.585
c0.255,0.26,0.455,0.586,0.599,0.975c0.144,0.391,0.216,0.849,0.216,1.371c0,0.463-0.059,0.888-0.176,1.277
c-0.118,0.391-0.295,0.727-0.532,1.012c-0.238,0.281-0.534,0.504-0.89,0.668c-0.354,0.16-0.772,0.242-1.254,0.242h-2.71v-6.322
H35.615z M35.519,21.572c0.199,0,0.393-0.031,0.581-0.098c0.188-0.062,0.354-0.173,0.502-0.323
c0.146-0.151,0.264-0.347,0.352-0.59c0.088-0.241,0.132-0.536,0.132-0.886c0-0.317-0.031-0.606-0.093-0.863
c-0.062-0.256-0.162-0.479-0.304-0.659c-0.141-0.183-0.326-0.323-0.559-0.421c-0.231-0.098-0.517-0.146-0.858-0.146h-0.984v3.986
H35.519z"/>
<path fill="#FFFFFF" d="M39.8,18.289c0.141-0.403,0.344-0.756,0.606-1.059c0.265-0.303,0.589-0.538,0.973-0.709
c0.385-0.171,0.816-0.257,1.298-0.257c0.487,0,0.921,0.086,1.303,0.257c0.381,0.171,0.704,0.406,0.969,0.709
c0.264,0.303,0.466,0.652,0.605,1.059c0.143,0.404,0.213,0.845,0.213,1.316c0,0.46-0.07,0.891-0.213,1.288
c-0.142,0.397-0.344,0.744-0.605,1.04c-0.266,0.295-0.588,0.525-0.969,0.695c-0.382,0.166-0.815,0.252-1.303,0.252
c-0.481,0-0.913-0.086-1.298-0.252c-0.384-0.17-0.708-0.4-0.973-0.695c-0.263-0.296-0.466-0.645-0.606-1.04
c-0.14-0.397-0.211-0.828-0.211-1.288C39.589,19.134,39.659,18.694,39.8,18.289z M41.062,20.379
c0.062,0.252,0.16,0.479,0.295,0.68c0.135,0.2,0.312,0.359,0.527,0.482c0.218,0.121,0.481,0.183,0.792,0.183
c0.312,0,0.576-0.062,0.792-0.183c0.218-0.121,0.394-0.281,0.529-0.482c0.134-0.2,0.231-0.428,0.295-0.68
c0.062-0.25,0.092-0.508,0.092-0.774c0-0.276-0.03-0.547-0.092-0.806c-0.062-0.262-0.161-0.492-0.295-0.696
c-0.136-0.201-0.312-0.365-0.529-0.485c-0.216-0.121-0.48-0.184-0.792-0.184c-0.311,0-0.574,0.062-0.792,0.184
c-0.216,0.12-0.393,0.284-0.527,0.485c-0.135,0.204-0.233,0.437-0.295,0.696c-0.062,0.259-0.093,0.527-0.093,0.806
C40.97,19.871,41.001,20.129,41.062,20.379z"/>
<path fill="#FFFFFF" d="M49.092,16.418l1.471,4.348h0.02l1.393-4.348h1.942v6.322h-1.294v-4.48h-0.02l-1.539,4.48H50l-1.54-4.437
h-0.019v4.437h-1.293v-6.322H49.092z"/>
<path fill="#FFFFFF" d="M58.764,16.418l2.35,6.322H59.68l-0.476-1.408h-2.351l-0.492,1.408h-1.391l2.377-6.322H58.764z
M58.844,20.297l-0.793-2.322h-0.018l-0.817,2.322H58.844z"/>
<path fill="#FFFFFF" d="M63.547,16.418v6.322h-1.382v-6.322H63.547z"/>
<path fill="#FFFFFF" d="M66.604,16.418l2.623,4.242h0.018v-4.242h1.294v6.322h-1.384l-2.611-4.234h-0.02v4.234H65.23v-6.322
H66.604z"/>
</g>
<path d="M85.852,0H1.147C0.239,0-0.5,0.744-0.5,1.658v28.969C-0.5,30.834-0.333,31-0.128,31h87.256
c0.205,0,0.372-0.166,0.372-0.373V1.658C87.5,0.744,86.762,0,85.852,0z M1.147,0.75h84.705c0.498,0,0.902,0.406,0.902,0.908
c0,0,0,20.121,0,28.557H0.245v-8.426c0-8.435,0-20.131,0-20.131C0.245,1.157,0.65,0.75,1.147,0.75z"/>
<g>
<ellipse fill="#FFFFFF" cx="14.156" cy="15.661" rx="11.004" ry="11.076"/>
<path id="text2809_4_" d="M14.22,8.746c-3.862,0-4.834,3.669-4.834,6.779c0,3.111,0.971,6.779,4.834,6.779
c3.863,0,4.834-3.67,4.834-6.779C19.054,12.414,18.083,8.746,14.22,8.746z M14.22,11.301c0.157,0,0.3,0.024,0.435,0.06
c0.278,0.24,0.414,0.573,0.147,1.038l-2.572,4.76c-0.079-0.603-0.091-1.195-0.091-1.634C12.139,14.155,12.233,11.301,14.22,11.301
z M16.146,13.494c0.137,0.731,0.155,1.493,0.155,2.03c0,1.37-0.094,4.223-2.08,4.223c-0.156,0-0.301-0.017-0.435-0.049
c-0.025-0.01-0.049-0.019-0.074-0.025c-0.04-0.012-0.084-0.024-0.122-0.041c-0.442-0.188-0.721-0.531-0.319-1.139L16.146,13.494z"
/>
<path id="path2815_4_" d="M14.195,3.748c-3.245,0-5.98,1.137-8.21,3.422c-1.128,1.135-1.99,2.431-2.589,3.876
c-0.585,1.43-0.876,2.921-0.876,4.478c0,1.57,0.291,3.062,0.876,4.479s1.434,2.69,2.548,3.826
c1.128,1.121,2.395,1.985,3.802,2.588c1.421,0.59,2.903,0.884,4.449,0.884c1.547,0,3.05-0.304,4.499-0.907
c1.448-0.604,2.74-1.471,3.883-2.605c1.101-1.078,1.934-2.317,2.49-3.719c0.571-1.415,0.853-2.932,0.853-4.544
c0-1.598-0.281-3.112-0.852-4.528c-0.571-1.429-1.407-2.693-2.507-3.801C20.263,4.895,17.469,3.748,14.195,3.748z M14.244,5.867
c2.646,0,4.904,0.944,6.784,2.836c0.906,0.912,1.6,1.954,2.073,3.119c0.473,1.164,0.713,2.398,0.713,3.703
c0,2.707-0.92,4.952-2.744,6.746c-0.948,0.927-2.012,1.638-3.196,2.128c-1.17,0.489-2.375,0.732-3.63,0.732
c-1.268,0-2.481-0.239-3.638-0.717c-1.156-0.489-2.193-1.191-3.113-2.104c-0.92-0.925-1.629-1.97-2.13-3.135
c-0.487-1.178-0.738-2.391-0.738-3.653c0-1.276,0.251-2.497,0.738-3.662c0.501-1.178,1.211-2.235,2.13-3.175
C9.317,6.809,11.57,5.867,14.244,5.867z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M20 10C20 15.5228 15.5228 20 10 20C4.47715 20 0 15.5228 0 10C0 4.47715 4.47715 0 10 0C15.5228 0 20 4.47715 20 10ZM11.4232 18.8881C10.9596 18.9618 10.4843 19 10 19C9.51576 19 9.04045 18.9618 8.57692 18.8881V14.1818C8.57692 13.8064 8.63397 13.5516 8.72183 13.3649C8.80718 13.1836 8.93666 13.0343 9.13629 12.8921C9.53269 12.6096 9.33288 11.9848 8.84615 11.9848C7.56957 11.9848 6.73952 11.6882 6.23588 11.2633C5.74434 10.8486 5.5 10.258 5.5 9.51515C5.5 8.90631 5.55001 8.45658 5.65769 8.05142C5.76523 7.6468 5.93638 7.26353 6.20399 6.7924L6.30116 6.62133L6.2557 6.42991C6.14611 5.96848 6.09434 5.63144 6.09272 5.29751C6.09176 5.1003 6.10826 4.89584 6.14593 4.65961C6.68747 4.86613 7.13188 5.11583 7.74963 5.65072L8.03006 5.89353L8.34375 5.69557C8.80856 5.40226 9.25103 5.34848 10 5.34848C10.749 5.34848 11.1915 5.40226 11.6563 5.69557L11.97 5.89353L12.2505 5.65072C12.8682 5.11583 13.3126 4.86613 13.8542 4.65961C13.8918 4.89584 13.9083 5.1003 13.9074 5.29751C13.9057 5.63144 13.854 5.96848 13.7444 6.42991L13.6989 6.62133L13.7961 6.7924C14.0637 7.26353 14.2349 7.6468 14.3424 8.05142C14.4501 8.45658 14.5001 8.90631 14.5001 9.51515C14.5001 10.258 14.2557 10.8486 13.7642 11.2633C13.2606 11.6882 12.4305 11.9848 11.1539 11.9848C10.6672 11.9848 10.4674 1