Compare commits

...

3 commits

32 changed files with 557 additions and 213 deletions

View file

@ -46,17 +46,20 @@ plausibleDataDomain = 'faercol.me'
plausibleScriptSource = 'https://plausible.faercol.me/js/script.js'
[params.footer]
trademark = true
trademark = 2023
rss = true
copyright = false
author = true
[params.author]
name = "Melora Hugues"
[params.logo]
logoText = "Hello there!"
logoHomeLink = "/"
[[params.social]]
name = "gitea"
name = "git"
url = "https://git.faercol.me"
[[params.social]]
@ -89,11 +92,11 @@ logoText = "Hello there!"
logoHomeLink = "/fr/"
[menu]
# [[menu.main]]
# identifier = "blog"
# name = "Blog"
# url = "/posts"
# weight = 1
[[menu.main]]
identifier = "blog"
name = "Blog"
url = "/posts"
weight = 1
[[menu.main]]
identifier = "about_me"

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View file

@ -0,0 +1,152 @@
---
title: "Gérer son épargne en action sous Firefly"
date: 2023-12-19T20:10:42+02:00
draft: true
---
## Problématique
## Gestion du portefeuille
### Valeur d'une action
Comme énoncé précédemment, la valeur d'un portefeuille d'actions dépend de la composition de ce portefeuille
(donc de quelles actions et en quelle quantité), et de la valeur unitaire de chacune de ces actions.
Cette valeur unitaire est définie par les marchés financiers et varie continuellement. On considère
que la valeur d'une action est le prix du dernier ordre d'achat passé pour cette action sur les marchés
financiers.
{{< callout type="example" >}}
Considérons la valeur "MSCI World" (un ETF trackant les valeurs des plus grosses entreprises dans
le monde entier). Au 10 décembre, les marchés financiers s'ouvrent avec la valeur de 27.13€ par part
pour cette valeur. à 9h05, une personne passe un ordre d'achat de 15 actions au prix de 27.17€. Dès que
cet ordre est exécuté, on considère que l'action "MSCI World" a la valeur de 27.17€ par action.
{{< /callout >}}
Dans mon cas, je n'ai absolument pas besoin d'une mise à jour rapide des valeurs, une mise à jour
quotidienne est largement suffisante pour mes besoins, et une mise à jour hebdomadaire pourrait même
convenir à vrai dire.
J'ai choisi donc de considérer pour chaque action, sa valeur au moment de la cloture des marchés (17h).
Mais comment calculer cette valeur ?
### Obtenir la valeur d'une action
#### À la recherche d'une API
Pour le reste de cet article, je considèrerai l'action "MSCI Monde" en titre d'exemple. Avec un navigateur,
on arrive facilement à obtenir les informations que l'on veut :
- La bourse européenne (Euronext) nous donne accès à son [cours](https://live.euronext.com/fr/product/etfs/fr0011869353-xpar/lyxor-msci-wor-pea/ewld)
- On obtient facilement les mêmes informations sur [Google Finance](https://www.google.com/finance/quote/EWLD:EPA?hl=fr) ou [Yahoo Finance](https://fr.finance.yahoo.com/quote/EWLD.PA/profile/?guccounter=1)
Cependant, il s'agit d'information destinées à un visionnage humain, aucune API n'est publiquement
disponible pour obtenir ces informations de façon automatisée.
En faisant des recherches sur le sujet, je me heurte rapidement à deux problèmes :
- soit je trouve des services gratuits, mais limités, soit en quantité d'appels (5 appels par jour par exemple)
soit en fonctionnalités (pas d'ETF)
- soit je trouve des services... chers. De l'ordre d'au moins plusieurs dizaines d'euros par mois, ce
qui est complètement en dehors du cadre d'un projet de ce type.
De plus, la majorité des API disponibles sont basées sur les marchés américains. Étant dans des marchés
européens, il est encore plus difficile d'obtenir les informations voulues.
#### Scraping d'Euronext
Finalement, la solution la plus simple revient à faire du scraping d'un site pertinent (cela expose
aux protections anti-bot, mais je n'en ai pas vu sur le site d'Euronext que j'ai décidé d'utiliser,
et le volume de requêtes est en pratique très faible).
Mon point de départ est la fiche d'une action: prenons notre habituel [MSCI world](https://live.euronext.com/fr/product/etfs/fr0011869353-xpar/lyxor-msci-wor-pea/ewld).
Toutes les valeurs intéressantes se trouvent sur un bandeau de la fiche de la valeur. Ici il s'agit du
*dernier cours traité* de 27.188€.
![Bandeau des valeurs de l'action MSCI world sur le site Euronext](euronext.png)
En observant le contenu de la page web, on obtient d'ailleurs ceci :
```html
<div class="col text-ui-grey-0 font-weight-bold data-header-cash ">
<div class="lastprice_min_height pb-1 ">
<span class="data-50 " id="header-instrument-currency"></span>
<span class="data-60" id="header-instrument-price">27,188</span>
</div>
</div>
```
Il suffirait donc de faire un petit script de scraping accédant à l'élément possédant l'id `#header-instrument-price`
pour obtenir directement la valeur voulue. Mais on peut faire encore mieux en observant les requêtes
AJAX effectués depuis le navigateur.
Une requête en particulier est intéressante, puisqu'elle interroge la route `https://live.euronext.com/intraday_chart/getChartData/FR0011869353-XPAR/intraday`
et renvoie un tableau JSON ayant la forme suivante (le tableau est tronqué, mais contient plus de 1000 éléments):
```json
[
{"time":"2023-12-12 17:29","price":26.879999999999999,"volume":11},
{"time":"2023-12-13 09:04","price":26.974,"volume":1888},
...
{"time":"2023-12-19 17:35","price":27.187999999999999,"volume":32}
]
```
Chaque ligne du tableau contient un ordre d'achat passé au cours de la journée. La valeur intéressante
correspond à la dernière ligne de ce tableau : il s'agit du dernier ordre passé, et correspond donc
exactement à la valeur affichée sur la fiche de la valeur, et est donc la valeur que l'on souhaite
obtenir.
À partir de là, la fonction Python suivante est suffisante pour obtenir la valeur d'une action donnée
```python
EURONEXT_BASE_URL = "https://live.euronext.com/intraday_chart/getChartData"
class StoredAction(NamedTuple):
name: str
value: float
date: str
class Action(NamedTuple):
name: str
code: str
def get_last_value_for_action(action: Action) -> StoredAction:
url = f"{EURONEXT_BASE_URL}/{action.code}/intraday"
resp = requests.get(url)
resp_json = resp.json()
if len(resp_json) < 1:
raise ValueError("Empty list of values")
last_value = resp_json[-1]
try:
return StoredAction(
name=action.name,
value=last_value["price"],
date=last_value["time"],
)
except KeyError as exc:
raise ValueError("Invalid format for response") from exc
```
Il suffit de trouver le **code** associé à l'action voulue. Je le trouve à partir de l'URL de la fiche
produit de l'action cherchée. Dans notre exemple, il s'agit de `https://live.euronext.com/fr/product/etfs/fr0011869353-xpar/lyxor-msci-wor-pea/ewld`.
Le code est donc `fr0011869353-xpar`.
{{< callout type="warning" >}}
De façon surprenante, la deuxième partie du code est sensible à la casse et doit être en majuscules :
- `fr0011869353-xpar` ne renverra aucun résultat
- `fr0011869353-XPAR` renverra le résultat attendu
- `FR0011869353-XPAR` renverra aussi le résultat attendu
- `FR0011869353-xpar` ne renverra aucun résultat
{{< /callout >}}
À partir de ces éléments, il m'est donc possible de calculer la valeur de mon portefeuille à partir
de son contenu. Il me reste deux questions à résoudre :
- comment stocker le contenu de ce portefeuille, et le mettre à jour à chaque fois que j'achète une
action ? (ou vend)
- comment mettre à jour la valeur totale de mon portefeuille telle qu'elle apparaît sur FireflyIII ?
## Lien avec Firefly

View file

@ -41,6 +41,7 @@ This theme was highly inspired by the [hello-friend](https://github.com/panr/hug
- Support for sharing buttons
- Support for [Commento](https://commento.io)
- Support for [Plausible](https://plausible.io) (thanks to [@Joffcom](https://github.com/Joffcom))
- Support for [utterances](https://utteranc.es/) comment system
## How to start
@ -102,11 +103,13 @@ paginate = 10
[languages]
[languages.en]
title = "Hello Friend NG"
subtitle = "A simple theme for Hugo"
keywords = ""
copyright = '<a href="https://creativecommons.org/licenses/by-nc/4.0/" target="_blank" rel="noopener">CC BY-NC 4.0</a>'
readOtherPosts = "Read other posts"
[languages.en.params]
subtitle = "A simple theme for Hugo"
[languages.en.params.logo]
logoText = "hello friend ng"
logoHomeLink = "/"

View file

@ -1,50 +1,50 @@
@font-face {
font-family: 'Inter';
font-family: "Inter";
font-style: normal;
font-display: auto;
font-weight: 400;
src: url("../fonts/Inter-Regular.woff2") format("woff2"),
url("../fonts/Inter-Regular.woff") format("woff");
src: url("fonts/Inter-Regular.woff2") format("woff2"),
url("fonts/Inter-Regular.woff") format("woff");
}
@font-face {
font-family: 'Inter';
font-family: "Inter";
font-style: italic;
font-display: auto;
font-weight: 400;
src: url("../fonts/Inter-Italic.woff2") format("woff2"),
url("../fonts/Inter-Italic.woff") format("woff");
src: url("fonts/Inter-Italic.woff2") format("woff2"),
url("fonts/Inter-Italic.woff") format("woff");
}
@font-face {
font-family: 'Inter';
font-family: "Inter";
font-style: normal;
font-display: auto;
font-weight: 600;
src: url("../fonts/Inter-Medium.woff2") format("woff2"),
url("../fonts/Inter-Medium.woff") format("woff");
src: url("fonts/Inter-Medium.woff2") format("woff2"),
url("fonts/Inter-Medium.woff") format("woff");
}
@font-face {
font-family: 'Inter';
font-family: "Inter";
font-style: italic;
font-display: auto;
font-weight: 600;
src: url("../fonts/Inter-MediumItalic.woff2") format("woff2"),
url("../fonts/Inter-MediumItalic.woff") format("woff");
src: url("fonts/Inter-MediumItalic.woff2") format("woff2"),
url("fonts/Inter-MediumItalic.woff") format("woff");
}
@font-face {
font-family: 'Inter';
font-family: "Inter";
font-style: normal;
font-display: auto;
font-weight: 800;
src: url("../fonts/Inter-Bold.woff2") format("woff2"),
url("../fonts/Inter-Bold.woff") format("woff");
src: url("fonts/Inter-Bold.woff2") format("woff2"),
url("fonts/Inter-Bold.woff") format("woff");
}
@font-face {
font-family: 'Inter';
font-family: "Inter";
font-style: italic;
font-display: auto;
font-weight: 800;
src: url("../fonts/Inter-BoldItalic.woff2") format("woff2"),
url("../fonts/Inter-BoldItalic.woff") format("woff");
src: url("fonts/Inter-BoldItalic.woff2") format("woff2"),
url("fonts/Inter-BoldItalic.woff") format("woff");
}

View file

@ -1,3 +1,4 @@
da: dk
de: de
en: gb
es: es

View file

@ -10,6 +10,7 @@
- [codechef](https://simpleicons.org/?q=codechef)
- [codepen](https://simpleicons.org/?q=codepen)
- [cs:go](https://simpleicons.org/?q=counterstrike)
- [cyberdefenders](https://simpleicons.org/?q=cyberdefenders)
- dev
- [deviantart](https://simpleicons.org/?q=deviantart)
- [discogs](https://simpleicons.org/?q=discogs)
@ -58,6 +59,7 @@
- [peertube](https://simpleicons.org/?q=peertube)
- [pinterest](https://simpleicons.org/?q=pinterest)
- [pixelfed](https://github.com/pixelfed/pixelfed/blob/dev/public/img/pixelfed-icon-black.svg)
- [pleroma](https://simpleicons.org/?q=pleroma)
- [podcasts-apple](https://simpleicons.org/?q=podcast)
- [podcasts-google](https://simpleicons.org/?q=podcast)
- [polywork](https://simpleicons.org/?q=polywork)
@ -67,6 +69,7 @@
- [signal](https://simpleicons.org/?q=signal)
- [slack](https://simpleicons.org/?q=slack)
- [soundcloud](https://simpleicons.org/?q=soundcloud)
- [sourcehut](https://simpleicons.org/?q=sourcehut)
- [spotify](https://simpleicons.org/?q=spotify)
- [stackoverflow](https://simpleicons.org/?q=stackoverflow)
- [steam](https://simpleicons.org/?q=Steam)

View file

@ -36,9 +36,6 @@ disableHugoGeneratorInject = false
[permalinks]
posts = "/posts/:year/:month/:title/"
[author]
name = "Jane Doe"
[blackfriday]
hrefTargetBlank = true
@ -48,6 +45,9 @@ disableHugoGeneratorInject = false
series = "series"
[params]
[params.author]
name = "Jane Doe"
dateform = "Jan 2, 2006"
dateformShort = "Jan 2"
dateformNum = "2006-01-02"
@ -78,7 +78,7 @@ disableHugoGeneratorInject = false
#
# This options enables the theme toggle for the theme.
# Per default, this option is off.
# The theme is respecting the prefers-color-scheme of the operating systeme.
# The theme is respecting the prefers-color-scheme of the operating system.
# With this option on, the page user is able to set the scheme he wants.
enableThemeToggle = false
@ -114,7 +114,7 @@ disableHugoGeneratorInject = false
# If you want, you can easily override the default footer with your own content.
#
[params.footer]
trademark = true
trademark = 2023
rss = true
copyright = true
author = true
@ -145,6 +145,19 @@ disableHugoGeneratorInject = false
# Append the current url pathname to logoText
# logoCursorPathname = true
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Addon: Startpage portrait
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Uncomment this if you want a portrait on your start page
#
# [params.portrait]
# path = "/img/image.jpg"
# alt = "Portrait"
# maxWidth = "50px"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Addon: Commento
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Commento is more than just a comments widget you can embed —
# its a return to the roots of the internet.
# An internet without the tracking and invasions of privacy.
@ -156,14 +169,50 @@ disableHugoGeneratorInject = false
# [params.commento]
# url = ""
# Uncomment this if you want a portrait on your start page
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Addon: Utteranc.es
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Utteranc.es is a lightweight comments widget built on GitHub issues.
# See https://utteranc.es/ for documentation
# Uncomment this to enable Utteranc.es.
#
# [params.utterances]
# Your GitHub repository
#
# repository = ""
#
# label used for GitHub issues
#
# label = ""
#
# Blog Post <-> Issue mapping. This parameter is optional. Possible values are:
# - pathname
# - url
# - title
# - og:title
# - issue number
# - specific term
#
# issueTerm = ""
#
# Theme used: possible values are:
# - github-light
# - github-dark
# - preferred-color-scheme
# - github-dark-orange
# - icy-dark
# - dark-blue
# - photon-dark
# - boxy-light
# - gruvbox-dark
#
# theme = ""
#
# [params.portrait]
# path = "/img/image.jpg"
# alt = "Portrait"
# maxWidth = "50px"
# Social icons
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Addon: Social icons
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
[[params.social]]
name = "twitter"
url = "https://twitter.com/"
@ -186,14 +235,16 @@ disableHugoGeneratorInject = false
[languages]
[languages.en]
subtitle = "Hello Friend NG Theme"
weight = 1
copyright = '<a href="https://creativecommons.org/licenses/by-nc/4.0/" target="_blank" rel="noopener">CC BY-NC 4.0</a>'
[languages.en.params]
subtitle = "Hello Friend NG Theme"
[languages.fr]
subtitle = "Hello Friend NG Theme"
weight = 2
copyright = '<a href="https://creativecommons.org/licenses/by-nc/4.0/" target="_blank" rel="noopener">CC BY-NC 4.0</a>'
[languages.fr.params]
subtitle = "Hello Friend NG Theme"
[menu]
[[menu.main]]

View file

@ -0,0 +1,39 @@
# Translations for Danish
# https://gohugo.io/content-management/multilingual/#translation-of-strings
# Generic
#
[translations]
other = "Oversættelser"
[postAvailable]
other = "Også tilgængelig på"
# 404.html
#
[archives]
other = "Arkiver"
[home]
other = "Hjem"
[notFound]
other = "Ups, siden blev ikke fundet…"
# posts/single.html
#
[readingTime]
one = "Ét minut"
other = "{{ .Count }} minutter"
[tableOfContents]
other = "Indholdsfortegnelse"
[wordCount]
one = "Ét Ord"
other = "{{ .Count }} Ord"
[lastModified]
other = "Sidst opdateret"

View file

@ -37,3 +37,8 @@ other = "{{ .Count }} Wörter"
[lastModified]
other = "Letzte Aktualisierung"
# partials/pagination-list.html
[pagination]
newerPosts = "Neuere Beiträge"
olderPosts = "Ältere Beiträge"

View file

@ -37,3 +37,8 @@ other = "{{ .Count }} Words"
[lastModified]
other = "Last updated"
# partials/pagination-list.html
[pagination]
newerPosts = "Newer posts"
olderPosts = "Older posts"

View file

@ -37,3 +37,8 @@ other = "{{ .Count }} Palabras"
[lastModified]
other = "Ultima actualización"
# partials/pagination-list.html
[pagination]
newerPosts = "Entradas más recientes"
olderPosts = "Entradas antiguas"

View file

@ -37,3 +37,8 @@ other = "{{ .Count }} Mots"
[lastModified]
other = "Mise à jour"
# partials/pagination-list.html
[pagination]
newerPosts = "Articles plus récents"
olderPosts = "Articles plus anciens"

View file

@ -34,3 +34,8 @@ other = "Táboa de contidos"
[wordCount]
one = "Unha Palabra"
other = "{{ .Count }} Palabras"
# partials/pagination-list.html
[pagination]
newerPosts = "Entradas más recientes"
olderPosts = "Entradas antiguas"

View file

@ -37,3 +37,8 @@ other = "{{ .Count }} Kata"
[lastModified]
other = "Terakhir diupdate"
# partials/pagination-list.html
[pagination]
newerPosts = "Postingan yang lebih baru"
olderPosts = "Postingan yang lebih lama"

View file

@ -1,4 +1,4 @@
# Translations for English
# Translations for Italian
# https://gohugo.io/content-management/multilingual/#translation-of-strings
# Generic
@ -37,3 +37,8 @@ other = "{{ .Count }} parole"
[lastModified]
other = "Ultimo aggiornamento"
# partials/pagination-list.html
[pagination]
newerPosts = "Voci più recenti"
olderPosts = "Voci più vecchie"

View file

@ -37,3 +37,8 @@ other = "{{ .Count }}文字"
[lastModified]
other = "最終更新"
# partials/pagination-list.html
[pagination]
newerPosts = "新しいエントリー"
olderPosts = "古いエントリー"

View file

@ -1,4 +1,4 @@
# Translations for English
# Translations for Lombardian
# https://gohugo.io/content-management/multilingual/#translation-of-strings
# Generic

View file

@ -1,4 +1,4 @@
# Translations for Portuguese
# Translations for Portuguese (Brasilian)
# https://gohugo.io/content-management/multilingual/#translation-of-strings
# Generic
@ -37,3 +37,8 @@ other = "{{ .Count }} Palavras"
[lastModified]
other = "Última actualização"
# partials/pagination-list.html
[pagination]
newerPosts = "Entradas mais recentes"
olderPosts = "Entradas mais antigas"

View file

@ -37,3 +37,8 @@ other = "{{ .Count }} de cuvinte"
[lastModified]
other = "Ultima modificare"
# partials/pagination-list.html
[pagination]
newerPosts = "Intrări mai noi"
olderPosts = "Intrări mai vechi"

View file

@ -41,3 +41,8 @@ other = "{{ .Count }} слов"
[lastModified]
other = "Последнее обновление"
# partials/pagination-list.html
[pagination]
newerPosts = "Более новые записи"
olderPosts = "Старые записи"

View file

@ -1,4 +1,4 @@
# Translations for English
# Translations for Turkish
# https://gohugo.io/content-management/multilingual/#translation-of-strings
# Generic
@ -37,3 +37,8 @@ other = "{{ .Count }} Kelime"
[lastModified]
other = "Son güncelleme"
# partials/pagination-list.html
[pagination]
newerPosts = "Daha yeni girişler"
olderPosts = "Eski girişler"

View file

@ -41,3 +41,8 @@ other = "{{ .Count }} слів"
[lastModified]
other = "Останнє оновлення"
# partials/pagination-list.html
[pagination]
newerPosts = "Нові записи"
olderPosts = "Старіші записи"

View file

@ -37,3 +37,8 @@ other = "{{ .Count }}字"
[lastModified]
other = "最后修改"
# partials/pagination-list.html
[pagination]
newerPosts = "较新条目"
olderPosts = "旧条目"

View file

@ -1,4 +1,4 @@
<pre class="mermaid">
{{- .Inner | safeHTML }}
</pre>
{{- .Inner | safeHTML }}
</pre>
{{ .Page.Store.Set "hasMermaid" true }}

View file

@ -1,29 +1,25 @@
<!DOCTYPE html>
<html lang="{{ .Site.Language }}">
<head>
{{ partial "head.html" . }}
</head>
<head>
{{ partial "head.html" . }}
<link rel="stylesheet" href="/mermaid.css">
</head>
{{ block "body" . }}
<body>
{{ block "body" . }}
<body>
{{ end }}
<div class="container">
{{ partial "header.html" . }}
<div class="container">
{{ partial "header.html" . }}
<div class="content">
{{ block "main" . }}{{ end }}
<div class="content">
{{ block "main" . }}{{ end }}
</div>
{{ block "footer" . }}
{{ partial "footer.html" . }}
{{ end }}
</div>
{{ block "footer" . }}
{{ partial "footer.html" . }}
{{ end }}
</div>
{{ partial "javascript.html" . }}
</body>
{{ partial "javascript.html" . }}
</body>
</html>

View file

@ -2,7 +2,7 @@
{{if or (.Site.Params.footer.trademark) (.Site.Params.footer.author) (.Site.Params.footer.copyright) (.Site.Params.footer.rss) (.Site.Params.footer.topText) }}
<div class="footer__inner">
<div class="footer__content">
{{ if .Site.Params.footer.trademark }}<span>&copy; {{ now.Format "2006" }}</span>{{ end }}
{{ if .Site.Params.footer.trademark }}<span>&copy; {{ .Site.Params.footer.trademark }}</span>{{ end }}
{{ if .Site.Params.footer.author }}<span><a href="{{ .Site.BaseURL }}">{{ .Site.Author.name }}</a></span>{{ end }}
{{ if .Site.Params.footer.copyright }}<span>{{ .Site.Copyright| safeHTML }}</span>{{ end }}
{{ if .Site.Params.footer.rss }}<span><a href="{{ "posts/index.xml" | absLangURL }}" target="_blank" title="rss"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-rss"><path d="M4 11a9 9 0 0 1 9 9"></path><path d="M4 4a16 16 0 0 1 16 16"></path><circle cx="5" cy="19" r="1"></circle></svg></a></span>{{ end }}

View file

@ -9,3 +9,29 @@
<script src="{{ $val }}"></script>
{{ end }}
{{ end }}
{{ if .Page.Store.Get "hasMermaid" }}
<script type="module">
import mermaid from "https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs";
const settings = localStorage.getItem("theme") === "dark" ?
{
startOnLoad: true,
theme: "dark",
darkMode: true,
themeVariables: {
tertiaryColor: "#dee3ed"
}
}
:
{
startOnLoad: true,
theme: "base",
darkMode: false,
themeVariables: {
tertiaryColor: "#dee3ed"
}
}
;
mermaid.initialize(settings);
</script>
{{ end }}

View file

@ -2,7 +2,7 @@
<ul class="menu__inner">
{{- $currentPage := . -}}
{{ range .Site.Menus.main -}}
<li><a href="{{ .URL | relLangURL }}">{{ or (T .Identifier) .Name }}</a></li>
<li><a href="{{ .URL | relLangURL }}">{{ .Name }}</a></li>
{{- end }}
{{- if .Site.Params.EnableGlobalLanguageMenu }}

View file

@ -4,14 +4,14 @@
<span class="button previous">
<a href="{{ .Paginator.Prev.URL }}">
<span class="button__icon"></span>
<span class="button__text">Newer posts</span>
<span class="button__text">{{ i18n "pagination.newerPosts" }}</span>
</a>
</span>
{{ end }}
{{ if .Paginator.HasNext }}
<span class="button next">
<a href="{{ .Paginator.Next.URL }}">
<span class="button__text">Older posts</span>
<span class="button__text">{{ i18n "pagination.olderPosts" }}</span>
<span class="button__icon"></span>
</a>
</span>

View file

@ -22,8 +22,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2"></polygon><line x1="12" y1="22" x2="12" y2="15.5"></line><polyline points="22 8.5 12 15.5 2 8.5"></polyline><polyline points="2 15.5 12 8.5 22 15.5"></polyline><line x1="12" y1="2" x2="12" y2="8.5"></line></svg>
{{- else if (eq .name "csgo") -}}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M9.103.435c.4347-.3913 1.087-.5362 1.6522-.3623.2174.0725.4058.203.6087.3333.1595.1015.3479.145.4928.261.0725.058.0145.1594.0145.2318.1884.4493.2899.9421.1305 1.4204-.1305.1594-.3624.203-.5508.2754-.029.2029.0435.3913.0725.5942-.0435.029-.0725.058-.116.087.2754-.0145.5508-.0725.8262-.1304.1014-.1015.2608-.0435.3913-.058.0145-.203.087-.3914.087-.5943.029 0 .087-.0145.1159-.029.0145.145 0 .29.0435.4349.0724.058.1884.029.2754.0434 0 .058 0 .116.0144.174 1.6813-.0145 3.377 0 5.0583 0v.2464h.1595v-.9421h.1884c0 .2609-.0145.5072 0 .7681a.1107.1107 0 0 0 .0725.029c0 .029.0144.087.0144.116.058-.058.1305-.1015.2174-.0725.0145.0435.029.087.0435.145-.058.058-.087.1304-.058.2173.4639.0145.9277 0 1.406 0 .0434-.058.1159-.087.1884-.116.029.0146.0724.0436.087.058h.6811c.029.116.029.232.0145.3334h-.6957c-.0145.0145-.058.058-.087.0725-.0724-.0435-.1304-.0725-.2029-.116h-1.2609c-.2464.0725-.5073.058-.7537.0145v.2754h-2.0726c-.087.0725-.1739.116-.2898.1305.0434.2174-.203.2753-.29.4348-.0579.087-.1448.1449-.2318.1739-.0725.4493.087.8696.203 1.29-.1305.029-.2755.0724-.406.1014-.0724.2899-.1449.5942-.2028.884-.058.261-.261.4784-.5073.5798-.174.203-.4058.4059-.6812.4204-.1015.029-.174-.0435-.2464-.1015-.3623.029-.6957-.145-1.0146-.2899-.3478-.1594-.6667-.3623-1-.5507.029.2029-.0725.3768-.145.5507.1595.0725.3769.1305.4638.3044.058.1304.116.2754.116.4348-.0145.5218-.0725 1.0435-.1015 1.5653.0145.3769-.1739.7537-.4348 1.029-.1739-.0144-.3188-.0869-.4783-.1594-.058.1305-.1884.261-.116.4204.058.1884.058.3913.145.5652.4928.5218.9131 1.1015 1.2175 1.7537.3043.6233.5362 1.2755.7826 1.9277.0435 0 .1305-.0145.174-.0145.058.1884 0 .4058.116.5798.1014.1594.0724.3478.0724.5362-.029.4348-.058.8696-.1015 1.3044-.029.3044-.1014.6088-.1449.9132.0145.2318.116.4637.1014.6956-.0144.2175-.0144.4493-.1884.6088.0145.4928-.116.9855.058 1.4638.232.3189.4928.6233.7682.8986.3043.145.6667.174.9276.4349.1014.1594.0434.3478.0145.5217a6.7323 6.7323 0 0 1-1.8697 0c-.2464-.058-.4783-.1594-.7247-.1884-.3334.0145-.7247.145-1.029-.087-.029-.3913.1159-.7681.1884-1.145.029-.1304.1594-.2174.1449-.3478-.029-.4493-.058-.9131-.087-1.3624-.058-.029-.1594-.058-.1449-.145 0-.2173-.0725-.4347-.1304-.6377-.1015-.5507-.145-1.116-.1595-1.6812-.0145-.1595.087-.2754.203-.3769.029-.2464.058-.5072.0724-.7536-.0435-.1305-.145-.232-.203-.3479-.2608.029-.6376.087-.797-.1884-.3769-.5653-.7682-1.145-1.145-1.7102-.1595-.0145-.3479 0-.4928-.1015-.1595-.174-.261-.4058-.3624-.6232-.0435.1739-.0725.3623-.174.5072-.0869.145-.2318.2464-.3333.3769-.1014.2319-.1884.4638-.2753.6957-.1015.2898-.2464.5797-.2754.8986-.0145.1594-.0435.3044-.1015.4493-.0724.116-.2029.1594-.3188.2174-.087.1884-.145.3768-.2754.5363-.087.1014-.232.1304-.2899.2608-.058.174-.145.3334-.2174.4928-.029.174.087.3624.029.5363-.1015.4348-.3189.8406-.5218 1.232-.1014.2898-.1739.5942-.3188.8696-.058.116-.203.145-.3189.1594-.1304.3189-.2754.6232-.3623.9566-.0435.3188-.0435.6522-.029.971 0 .145.087.261.145.3914.0579.174.0144.3478-.0146.5218-.5652.0724-1.145.1304-1.6957-.0435-.058-.0435-.0435-.116-.058-.174-.0435-.2608-.0725-.5362.0145-.7826.1884-.6812.3478-1.3624.5362-2.0436-.0724-.0725-.1739-.1304-.1739-.2464-.0145-.1884 0-.3913.0435-.5797.087-.319.3189-.5653.4348-.8697.0435-.1304.029-.2609.0435-.3913 0-.3044.174-.5508.3044-.8116.1304-.2174.2318-.4493.4058-.6378.116-.1014.116-.2608.2029-.3913.087-.1594.2319-.2899.2319-.4783.029-.2319-.058-.4638-.029-.6957.058-.6812.1884-1.3479.3044-2.029-.058-.0726-.145-.145-.174-.2465.0145-.0724.029-.1304.0435-.2029l-.1304-.2174c.058-.087.116-.1884.174-.2754-.058-.0435-.1305-.1014-.1885-.145.0725-.2173.0435-.5362.3043-.6376.029.0145.1015.029.1305.0434-.0435-.3768-.0435-.7681-.087-1.145-.1014-.4058-.116-.826-.0724-1.232.1449-.2173.4203-.3043.6667-.3188-.3189-.0724-.6378-.1014-.9421-.2029-.0145-.2609.029-.5218.0725-.7826.1304-.5073.0724-1.029.1449-1.5509.0725-.1449.2609-.1739.4203-.1449.1884.029.3768-.029.5653-.087 0-.0724.0145-.1594 0-.2319-.116-.5072-.087-1.029 0-1.5218.116-.6377.3768-1.261.855-1.7102.319-.3044.7827-.4494 1.2176-.4349.1449 0 .2318.145.3478.232.058-.058.116-.116.1594-.174-.0724-.2464-.1884-.5073-.1739-.7681.029-.5798.2174-1.174.6522-1.5654m4.522 4.1017c.029.029.029.029 0 0m.203.029c.0144.1015.0434.203-.0145.2899-.0725.029-.1595.029-.232.0725.203 0 .4059.0145.6088 0 .1594-.0435.1015-.2464.1015-.3624-.1015-.116-.3189-.0435-.4638 0m-.5073.6088c.145.1594.2174.4058.3478.5652.1884-.2464.3334-.5073.5508-.7247-.2609-.0145-.5218.0145-.7827-.0145-.0435.058-.0724.116-.116.174Z"/></svg>
{{- else if (eq .name "cyberdefenders") -}}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M18.918 17.48c-.126 2.727-2.384 4.696-5.364 4.696H7.34v-6.123l-2.185-.957V24h8.381c4.334 0 7.549-2.962 7.549-6.881v-.163c-.65.235-1.372.415-2.167.524Zm1.355-9.501C18.611 4.313 17.726.989 15.432.213c-1.336-.452-2.005-.091-2.637.217-.199.09-.235.361-.072.505.361.307.813.687 1.336 1.174-1.95-1.138-7.333-2.835-7.874-.776-.488 1.86-1.319 4.587-1.319 4.587S.603 5.487.116 7.293c-.488 1.806 3.323 5.274 9.627 7.134 6.303 1.861 11.198 1.373 13.311-.921 2.113-2.294.072-5.473-2.781-5.527Zm-1.247.036c-.487.47-2.077 1.68-5.563 1.427-3.738-.271-6.809-2.474-7.604-3.088-.126-.091-.18-.235-.126-.398.054-.18.126-.469.253-.849.072-.234.343-.343.542-.216 1.571.903 4.1 2.221 6.791 2.402 2.402.163 3.847-.542 4.786-1.066.199-.108.452-.018.542.199l.47 1.156c.036.162.018.325-.091.433Z"/></svg>
{{- else if (eq .name "dev") -}}
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 448 512"><path fill="currentColor" d="M120.12 208.29c-3.88-2.9-7.77-4.35-11.65-4.35H91.03v104.47h17.45c3.88 0 7.77-1.45 11.65-4.35 3.88-2.9 5.82-7.25 5.82-13.06v-69.65c-.01-5.8-1.96-10.16-5.83-13.06zM404.1 32H43.9C19.7 32 .06 51.59 0 75.8v360.4C.06 460.41 19.7 480 43.9 480h360.2c24.21 0 43.84-19.59 43.9-43.8V75.8c-.06-24.21-19.7-43.8-43.9-43.8zM154.2 291.19c0 18.81-11.61 47.31-48.36 47.25h-46.4V172.98h47.38c35.44 0 47.36 28.46 47.37 47.28l.01 70.93zm100.68-88.66H201.6v38.42h32.57v29.57H201.6v38.41h53.29v29.57h-62.18c-11.16.29-20.44-8.53-20.72-19.69V193.7c-.27-11.15 8.56-20.41 19.71-20.69h63.19l-.01 29.52zm103.64 115.29c-13.2 30.75-36.85 24.63-47.44 0l-38.53-144.8h32.57l29.71 113.72 29.57-113.72h32.58l-38.46 144.8z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 448 512" fill="currentColor" stroke ="none"><path d="M120.12 208.29c-3.88-2.9-7.77-4.35-11.65-4.35H91.03v104.47h17.45c3.88 0 7.77-1.45 11.65-4.35 3.88-2.9 5.82-7.25 5.82-13.06v-69.65c-.01-5.8-1.96-10.16-5.83-13.06zM404.1 32H43.9C19.7 32 .06 51.59 0 75.8v360.4C.06 460.41 19.7 480 43.9 480h360.2c24.21 0 43.84-19.59 43.9-43.8V75.8c-.06-24.21-19.7-43.8-43.9-43.8zM154.2 291.19c0 18.81-11.61 47.31-48.36 47.25h-46.4V172.98h47.38c35.44 0 47.36 28.46 47.37 47.28l.01 70.93zm100.68-88.66H201.6v38.42h32.57v29.57H201.6v38.41h53.29v29.57h-62.18c-11.16.29-20.44-8.53-20.72-19.69V193.7c-.27-11.15 8.56-20.41 19.71-20.69h63.19l-.01 29.52zm103.64 115.29c-13.2 30.75-36.85 24.63-47.44 0l-38.53-144.8h32.57l29.71 113.72 29.57-113.72h32.58l-38.46 144.8z"/></svg>
{{- else if (eq .name "deviantart") -}}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M19.207 4.794l.23-.43V0H15.07l-.436.44-2.058 3.925-.646.436H4.58v5.993h4.04l.36.436-4.175 7.98-.24.43V24H8.93l.436-.44 2.07-3.925.644-.436h7.35v-5.993h-4.05l-.36-.438 4.186-7.977z"/></svg>
{{- else if (eq .name "discogs") -}}
@ -122,6 +124,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.401.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.354-.629-2.758-1.379l-.749 2.848c-.269 1.045-1.004 2.352-1.498 3.146 1.123.345 2.306.535 3.55.535 6.607 0 11.985-5.365 11.985-11.987C23.97 5.39 18.592.026 11.985.026L12.017 0z"/></svg>
{{- else if (eq .name "pixelfed") }}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M 12 24 C 5.37258 24 0 18.6274 0 12 C 0 5.37258 5.37258 0 12 0 C 18.6274 0 24 5.37258 24 12 C 24 18.6274 18.6274 24 12 24 Z M 11.0474 14.6198 L 13.2487 14.6198 C 15.3225 14.6198 17.0036 12.9833 17.0036 10.9645 C 17.0036 8.94566 15.3225 7.30909 13.2487 7.30909 L 10.0715 7.30909 C 8.8751 7.30909 7.90523 8.25326 7.90523 9.41796 L 7.90523 17.626 Z"/></svg>
{{- else if (eq .name "pleroma") }}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M6.36 0A1.868 1.868 0 004.49 1.868V24h5.964V0zm7.113 0v12h4.168a1.868 1.868 0 001.868-1.868V0zm0 18.036V24h4.168a1.868 1.868 0 001.868-1.868v-4.096Z"/></svg>
{{- else if (eq .name "podcasts-apple") -}}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M5.34 0A5.328 5.328 0 000 5.34v13.32A5.328 5.328 0 005.34 24h13.32A5.328 5.328 0 0024 18.66V5.34A5.328 5.328 0 0018.66 0zm6.525 2.568c2.336 0 4.448.902 6.056 2.587 1.224 1.272 1.912 2.619 2.264 4.392.12.59.12 2.2.007 2.864a8.506 8.506 0 01-3.24 5.296c-.608.46-2.096 1.261-2.336 1.261-.088 0-.096-.091-.056-.46.072-.592.144-.715.48-.856.536-.224 1.448-.874 2.008-1.435a7.644 7.644 0 002.008-3.536c.208-.824.184-2.656-.048-3.504-.728-2.696-2.928-4.792-5.624-5.352-.784-.16-2.208-.16-3 0-2.728.56-4.984 2.76-5.672 5.528-.184.752-.184 2.584 0 3.336.456 1.832 1.64 3.512 3.192 4.512.304.2.672.408.824.472.336.144.408.264.472.856.04.36.03.464-.056.464-.056 0-.464-.176-.896-.384l-.04-.03c-2.472-1.216-4.056-3.274-4.632-6.012-.144-.706-.168-2.392-.03-3.04.36-1.74 1.048-3.1 2.192-4.304 1.648-1.737 3.768-2.656 6.128-2.656zm.134 2.81c.409.004.803.04 1.106.106 2.784.62 4.76 3.408 4.376 6.174-.152 1.114-.536 2.03-1.216 2.88-.336.43-1.152 1.15-1.296 1.15-.023 0-.048-.272-.048-.603v-.605l.416-.496c1.568-1.878 1.456-4.502-.256-6.224-.664-.67-1.432-1.064-2.424-1.246-.64-.118-.776-.118-1.448-.008-1.02.167-1.81.562-2.512 1.256-1.72 1.704-1.832 4.342-.264 6.222l.413.496v.608c0 .336-.027.608-.06.608-.03 0-.264-.16-.512-.36l-.034-.011c-.832-.664-1.568-1.842-1.872-2.997-.184-.698-.184-2.024.008-2.72.504-1.878 1.888-3.335 3.808-4.019.41-.145 1.133-.22 1.814-.211zm-.13 2.99c.31 0 .62.06.844.178.488.253.888.745 1.04 1.259.464 1.578-1.208 2.96-2.72 2.254h-.015c-.712-.331-1.096-.956-1.104-1.77 0-.733.408-1.371 1.112-1.745.224-.117.534-.176.844-.176zm-.011 4.728c.988-.004 1.706.349 1.97.97.198.464.124 1.932-.218 4.302-.232 1.656-.36 2.074-.68 2.356-.44.39-1.064.498-1.656.288h-.003c-.716-.257-.87-.605-1.164-2.644-.341-2.37-.416-3.838-.218-4.302.262-.616.974-.966 1.97-.97z"/></svg>
{{- else if (eq .name "podcasts-google") -}}
@ -140,6 +144,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zM6.313 15.165a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zM8.834 6.313a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zM18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zM17.688 8.834a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zM15.165 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zM15.165 17.688a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z"/></svg>
{{- else if (eq .name "soundcloud") -}}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M1.175 12.225c-.051 0-.094.046-.101.1l-.233 2.154.233 2.105c.007.058.05.098.101.098.05 0 .09-.04.099-.098l.255-2.105-.27-2.154c0-.057-.045-.1-.09-.1m-.899.828c-.06 0-.091.037-.104.094L0 14.479l.165 1.308c0 .055.045.094.09.094s.089-.045.104-.104l.21-1.319-.21-1.334c0-.061-.044-.09-.09-.09m1.83-1.229c-.061 0-.12.045-.12.104l-.21 2.563.225 2.458c0 .06.045.12.119.12.061 0 .105-.061.121-.12l.254-2.474-.254-2.548c-.016-.06-.061-.12-.121-.12m.945-.089c-.075 0-.135.06-.15.135l-.193 2.64.21 2.544c.016.077.075.138.149.138.075 0 .135-.061.15-.15l.24-2.532-.24-2.623c0-.075-.06-.135-.135-.135l-.031-.017zm1.155.36c-.005-.09-.075-.149-.159-.149-.09 0-.158.06-.164.149l-.217 2.43.2 2.563c0 .09.075.157.159.157.074 0 .148-.068.148-.158l.227-2.563-.227-2.444.033.015zm.809-1.709c-.101 0-.18.09-.18.181l-.21 3.957.187 2.563c0 .09.08.164.18.164.094 0 .174-.09.18-.18l.209-2.563-.209-3.972c-.008-.104-.088-.18-.18-.18m.959-.914c-.105 0-.195.09-.203.194l-.18 4.872.165 2.548c0 .12.09.209.195.209.104 0 .194-.089.21-.209l.193-2.548-.192-4.856c-.016-.12-.105-.21-.21-.21m.989-.449c-.121 0-.211.089-.225.209l-.165 5.275.165 2.52c.014.119.104.225.225.225.119 0 .225-.105.225-.225l.195-2.52-.196-5.275c0-.12-.105-.225-.225-.225m1.245.045c0-.135-.105-.24-.24-.24-.119 0-.24.105-.24.24l-.149 5.441.149 2.503c.016.135.121.24.256.24s.24-.105.24-.24l.164-2.503-.164-5.456-.016.015zm.749-.134c-.135 0-.255.119-.255.254l-.15 5.322.15 2.473c0 .15.12.255.255.255s.255-.12.255-.27l.15-2.474-.165-5.307c0-.148-.12-.27-.271-.27m1.005.166c-.164 0-.284.135-.284.285l-.103 5.143.135 2.474c0 .149.119.277.284.277.149 0 .271-.12.284-.285l.121-2.443-.135-5.112c-.012-.164-.135-.285-.285-.285m1.184-.945c-.045-.029-.105-.044-.165-.044s-.119.015-.165.044c-.09.054-.149.15-.149.255v.061l-.104 6.048.115 2.449v.008c.008.06.03.135.074.18.058.061.142.104.234.104.08 0 .158-.044.209-.09.058-.06.091-.135.091-.225l.015-.24.117-2.203-.135-6.086c0-.104-.061-.193-.135-.239l-.002-.022zm1.006-.547c-.045-.045-.09-.061-.15-.061-.074 0-.149.016-.209.061-.075.061-.119.15-.119.24v.029l-.137 6.609.076 1.215.061 1.185c0 .164.148.314.328.314.181 0 .33-.15.33-.329l.15-2.414-.15-6.637c0-.12-.074-.221-.165-.277m8.934 3.777c-.405 0-.795.086-1.139.232-.24-2.654-2.46-4.736-5.188-4.736-.659 0-1.305.135-1.889.359-.225.09-.27.18-.285.359v9.368c.016.18.15.33.33.345h8.185C22.681 17.218 24 15.914 24 14.28s-1.319-2.952-2.938-2.952"/></svg>
{{- else if (eq .name "sourcehut") -}}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M12 0C5.371 0 0 5.371 0 12s5.371 12 12 12 12-5.371 12-12S18.629 0 12 0Zm0 21.677A9.675 9.675 0 0 1 2.323 12 9.675 9.675 0 0 1 12 2.323 9.675 9.675 0 0 1 21.677 12 9.675 9.675 0 0 1 12 21.677Z"/></svg>
{{- else if (eq .name "spotify") -}}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M12 0C5.4 0 0 5.4 0 12s5.4 12 12 12 12-5.4 12-12S18.66 0 12 0zm5.521 17.34c-.24.359-.66.48-1.021.24-2.82-1.74-6.36-2.101-10.561-1.141-.418.122-.779-.179-.899-.539-.12-.421.18-.78.54-.9 4.56-1.021 8.52-.6 11.64 1.32.42.18.479.659.301 1.02zm1.44-3.3c-.301.42-.841.6-1.262.3-3.239-1.98-8.159-2.58-11.939-1.38-.479.12-1.02-.12-1.14-.6-.12-.48.12-1.021.6-1.141C9.6 9.9 15 10.561 18.72 12.84c.361.181.54.78.241 1.2zm.12-3.36C15.24 8.4 8.82 8.16 5.16 9.301c-.6.179-1.2-.181-1.38-.721-.18-.601.18-1.2.72-1.381 4.26-1.26 11.28-1.02 15.721 1.621.539.3.719 1.02.419 1.56-.299.421-1.02.599-1.559.3z"/></svg>
{{- else if (eq .name "stackoverflow") -}}

View file

@ -1,156 +1,150 @@
{{ define "main" }}
<main class="post">
<main class="post">
<div class="post-info">
<p>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-clock">
<circle cx="12" cy="12" r="10"></circle>
<polyline points="12 6 12 12 16 14"></polyline>
</svg>
{{ i18n "readingTime" .Page.ReadingTime }}
<div class="post-info">
<p>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clock">
<circle cx="12" cy="12" r="10"></circle>
<polyline points="12 6 12 12 16 14"></polyline>
</svg>
{{ i18n "readingTime" .Page.ReadingTime }}
{{ if .IsTranslated }} | {{ i18n "postAvailable" }}
{{ range .Translations }}
<a href="{{ .Permalink }}"><span class="flag fi fi-{{ index $.Site.Data.langFlags (.Lang) }}"></span></a>
{{ end}}
{{ if .IsTranslated }} | {{ i18n "postAvailable" }}
{{ range .Translations }}
<a href="{{ .Permalink }}"><span class="flag fi fi-{{ index $.Site.Data.langFlags (.Lang) }}"></span></a>
{{ end}}
{{ end }}
</p>
</div>
<article>
<h1 class="post-title">
<a href="{{ .Permalink }}">{{ .Title | markdownify }}</a>
</h1>
{{ with .Params.Description }}
<div class="post-excerpt">{{ . }}</div>
{{ end }}
</p>
</div>
<article>
<h1 class="post-title">
<a href="{{ .Permalink }}">{{ .Title | markdownify }}</a>
</h1>
{{ if .Params.Cover }}
<figure class="post-cover">
<img src="{{ .Params.Cover | absURL }}" alt="{{ .Title }}" />
{{ with .Params.Description }}
<div class="post-excerpt">{{ . }}</div>
{{ end }}
{{ if .Params.Cover }}
<figure class="post-cover">
<img src="{{ .Params.Cover | absURL }}" alt="{{ .Title }}" />
{{ if .Params.CoverCaption }}
<figcaption class="center">{{ .Params.CoverCaption | markdownify }}</figcaption>
{{ if .Params.CoverCaption }}
<figcaption class="center">{{ .Params.CoverCaption | markdownify }}</figcaption>
{{ end }}
</figure>
{{ end }}
</figure>
{{ end }}
{{- if .Params.toc }}
<hr />
<aside id="toc">
<div class="toc-title">{{ i18n "tableOfContents" }}</div>
{{ .TableOfContents }}
</aside>
{{- if .Params.toc }}
<hr />
<aside id="toc">
<div class="toc-title">{{ i18n "tableOfContents" }}</div>
{{ .TableOfContents }}
</aside>
<hr />
{{- end }}
{{ if .Params.Audio }}
<div class="post-audio">
<audio controls>
<source src="{{ .Params.Audio }}">
</audio>
</div>
{{ end }}
<div class="post-content">
{{ .Content }}
</div>
</article>
<hr />
<div class="post-info">
{{ partial "tags.html" .Params.tags }}
{{ partial "categories.html" . }}
<p>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
<polyline points="14 2 14 8 20 8"></polyline>
<line x1="16" y1="13" x2="8" y2="13"></line>
<line x1="16" y1="17" x2="8" y2="17"></line>
<polyline points="10 9 9 9 8 9"></polyline>
</svg>
{{ i18n "wordCount" .Page.WordCount }}
</p>
<p>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-calendar">
<rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
<line x1="16" y1="2" x2="16" y2="6"></line>
<line x1="8" y1="2" x2="8" y2="6"></line>
<line x1="3" y1="10" x2="21" y2="10"></line>
</svg>
{{ if .Site.Params.dateformNumTime }}
{{ dateFormat .Site.Params.dateformNumTime .Date.Local }}
{{ else }}
{{ dateFormat "2006-01-02 15:04" .Date.Local }}
{{ end }}
{{ if .Lastmod }}
{{ if not (eq .Lastmod .Date )}}
{{ if .Site.Params.dateformNumTime }}
({{ i18n "lastModified" }}: {{ dateFormat .Site.Params.dateformNumTime .Lastmod.Local }})
{{ else }}
({{ i18n "lastModified" }}: {{ dateFormat "2006-01-02 15:04" .Lastmod.Local }})
{{ end }}
{{ end }}
{{ end }}
</p>
{{- if .GitInfo }}
<p>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-git-commit">
<circle cx="12" cy="12" r="4"></circle>
<line x1="1.05" y1="12" x2="7" y2="12"></line>
<line x1="17.01" y1="12" x2="22.96" y2="12"></line>
</svg>
<a href="{{ .Site.Params.gitUrl -}}{{ .GitInfo.Hash }}" target="_blank" rel="noopener">{{ .GitInfo.AbbreviatedHash }}</a>
@ {{ if .Site.Params.dateformNum }}{{ dateFormat .Site.Params.dateformNum .GitInfo.AuthorDate.Local }}{{ else }}{{ dateFormat "2006-01-02" .GitInfo.AuthorDate.Local }}{{ end }}
</p>
{{- end }}
</div>
{{- if .Site.Params.EnableSharingButtons }}
<hr />
<div class="sharing-buttons">
{{ partial "sharing-buttons.html" . }}
</div>
{{- end }}
{{ if .Params.Audio }}
<div class="post-audio">
<audio controls>
<source src="{{ .Params.Audio }}">
</audio>
</div>
{{ partial "pagination-single.html" . }}
{{ if .Site.DisqusShortname }}
{{ if not (eq .Params.Comments "false") }}
<div id="comments">
{{ template "_internal/disqus.html" . }}
</div>
{{ end }}
{{ end }}
<div class="post-content">
{{ .Content }}
{{ if .Page.Store.Get "hasMermaid" }}
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true });
</script>
{{ end }}
{{ if .Site.Params.Commento.Url }}
<script defer src={{ .Site.Params.Commento.Url }}></script>
<div id="commento"></div>
{{ end }}
</div>
</article>
{{ if .Site.Params.Utterances.Repository }}
<script src="https://utteranc.es/client.js"
repo="{{ .Site.Params.Utterances.Repository }}"
{{ if .Site.Params.Utterances.Label }}label="{{ .Site.Params.Utterances.Label }}"{{ end }}
issue-term="{{ .Site.Params.Utterances.IssueTerm }}"
theme="{{ .Site.Params.Utterances.Theme }}"
crossorigin="anonymous"
async>
</script>
{{ end }}
<hr />
<div class="post-info">
{{ partial "tags.html" .Params.tags }}
{{ partial "categories.html" . }}
<p>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-file-text">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
<polyline points="14 2 14 8 20 8"></polyline>
<line x1="16" y1="13" x2="8" y2="13"></line>
<line x1="16" y1="17" x2="8" y2="17"></line>
<polyline points="10 9 9 9 8 9"></polyline>
</svg>
{{ i18n "wordCount" .Page.WordCount }}
</p>
<p>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-calendar">
<rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
<line x1="16" y1="2" x2="16" y2="6"></line>
<line x1="8" y1="2" x2="8" y2="6"></line>
<line x1="3" y1="10" x2="21" y2="10"></line>
</svg>
{{ if .Site.Params.dateformNumTime }}
{{ dateFormat .Site.Params.dateformNumTime .Date.Local }}
{{ else }}
{{ dateFormat "2006-01-02 15:04" .Date.Local }}
{{ end }}
{{ if .Lastmod }}
{{ if not (eq .Lastmod .Date )}}
{{ if .Site.Params.dateformNumTime }}
({{ i18n "lastModified" }}: {{ dateFormat .Site.Params.dateformNumTime .Lastmod.Local }})
{{ else }}
({{ i18n "lastModified" }}: {{ dateFormat "2006-01-02 15:04" .Lastmod.Local }})
{{ end }}
{{ end }}
{{ end }}
</p>
{{- if .GitInfo }}
<p>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-git-commit">
<circle cx="12" cy="12" r="4"></circle>
<line x1="1.05" y1="12" x2="7" y2="12"></line>
<line x1="17.01" y1="12" x2="22.96" y2="12"></line>
</svg>
<a href="{{ .Site.Params.gitUrl -}}{{ .GitInfo.Hash }}" target="_blank" rel="noopener">{{ .GitInfo.AbbreviatedHash
}}</a>
@ {{ if .Site.Params.dateformNum }}{{ dateFormat .Site.Params.dateformNum .GitInfo.AuthorDate.Local }}{{ else }}{{
dateFormat "2006-01-02" .GitInfo.AuthorDate.Local }}{{ end }}
</p>
{{- end }}
</div>
{{- if .Site.Params.EnableSharingButtons }}
<hr />
<div class="sharing-buttons">
{{ partial "sharing-buttons.html" . }}
</div>
{{- end }}
{{ partial "pagination-single.html" . }}
{{ if .Site.DisqusShortname }}
{{ if not (eq .Params.Comments "false") }}
<div id="comments">
{{ template "_internal/disqus.html" . }}
</div>
{{ end }}
{{ end }}
{{ if .Site.Params.Commento.Url }}
<script defer src={{ .Site.Params.Commento.Url }}></script>
<div id="commento"></div>
{{ end }}
</main>
</main>
{{ end }}