a new start

This commit is contained in:
2025-10-25 12:39:30 +02:00
commit c97cadef78
726 changed files with 454051 additions and 0 deletions

9
_includes/base-classes Normal file
View File

@@ -0,0 +1,9 @@
{%- capture classes -%}
{% if site.pivoine.dark_mode.always %}dark-mode{% endif %}
{% if site.pivoine.no_toc %} no-toc{% endif %}
{% if site.pivoine.no_break_layout %} no-break-layout{% endif %}
{% if site.pivoine.no_large_headings %} no-large-headings{% endif %}
{% if site.pivoine.no_third_column %} no-third-column{% endif %}
{% if site.pivoine.no_drawer %} no-drawer{% endif %}
{%- endcapture -%}
{{- classes | strip_newlines | strip -}}

View File

@@ -0,0 +1,43 @@
{% if site.google_analytics %}
<script>!function(w, d) {
w.ga=w.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
/*{% if site.pivoine.cookies_banner %}*/
if (navigator.CookiesOK) {
ga('create', '{{ site.google_analytics }}', 'auto');
} else if (d.cookie.indexOf("hy--cookies-ok=true") > -1) {
ga('create', '{{ site.google_analytics }}', {
'storage': 'none',
'clientId': localStorage ? localStorage.getItem('ga--client-id') : undefined
});
} else {
ga('create', '{{ site.google_analytics }}', {
'storage': 'none'
});
ga('set', 'forceSSL', true);
ga('set', 'anonymizeIp', true);
}
/*{% else %}*/
ga('create', '{{ site.google_analytics }}', 'auto');
/*{% endif %}*/
var pushStateEl = d.getElementById('_pushState');
var timeoutId;
pushStateEl.addEventListener('hy-push-state-load', function() {
w.clearTimeout(timeoutId);
timeoutId = w.setTimeout(function() {
ga('set', 'page', w.location.pathname);
ga('send', 'pageview');
}, 500);
});
d.addEventListener('hy--cookies-ok', function () {
w.ga(function(tracker) {
w.ga("set", "anonymizeIp", undefined);
localStorage && localStorage.setItem("ga--client-id", tracker.get("clientId"));
});
});
w.loadJSDeferred('https://www.google-analytics.com/analytics.js');
}(window, document);</script>
{% endif %}

View File

@@ -0,0 +1,22 @@
<nav id="breadcrumbs" class="screen-only"><ul>
{% assign crumbs = include.url | remove:'index.html' | split: '/' %}
{% if crumbs.size > 1 %}
<li><a href="{{ '/' | relative_url }}">{{ site.data.strings.breadcrumbs_home | default:'home' }}</a></li>
{% for crumb in crumbs offset: 1 %}
{%- if crumb != "page" -%}
<li>
{% unless forloop.last %}
<span>{{ site.data.strings.breadcrumbs_separator | default:'/' }}</span>
{% assign crumb_limit = forloop.index | plus: 1 %}
{% capture href %}{% for crumb1 in crumbs limit: crumb_limit %}{{ crumb1 | append: '/' }}{% endfor %}{% endcapture %}
<a href="{{ href | relative_url }}">{{ crumb | url_decode }}</a>
{% else %}
<span>{{ site.data.strings.breadcrumbs_separator | default:'/' }}</span>
<span>{{ crumbs | reverse | first | url_decode }}</span>
{% endunless %}
</li>
{%- endif -%}
{% endfor %}
{% endif %}
</ul></nav>

View File

@@ -0,0 +1,6 @@
{% if page.comments %}
<aside class="comments related" role="complementary">
<h2 class="hr-bottom">{{ site.data.strings.comments | default:"Comments" }}</h2>
{% include my-comments.html %}
</aside>
{% endif %}

View File

@@ -0,0 +1,18 @@
{% if site.copyright.size > 0 or site.legal.size > 0 or site.pivoine.advertise %}
<footer class="content" role="contentinfo">
<hr/>
{% if site.copyright.size > 0 %}
<p><small class="copyright">{{ site.copyright | markdownify | replace:'<p>','' | replace:'</p>','' }}</small></p>
{% endif %}
{% if site.legal.size > 0 %}
<nav class="legal"><small>
{% for node in site.legal %}
{% assign url = node.url | default: node.href %}
<a class="heading flip-title" href="{% include_cached smart-url url=url %}">{{ node.name | default:node.title }}</a>
{% unless forloop.last %}{{ site.data.strings.separator | default:'|' }}{% endunless %}
{% endfor %}
</small></nav>
{% endif %}
<hr class="sr-only"/>
</footer>
{% endif %}

23
_includes/body/index.html Normal file
View File

@@ -0,0 +1,23 @@
{% include_cached components/dark-mode.html %}
<hy-push-state
id="_pushState"
replace-selector="#_main"
link-selector="a[href]:not([href^='{{ assets_url }}']):not(.external):not(.no-push-state)"
script-selector="script"
duration="500"
hashchange
>
{% capture sidebar %}{% include_cached body/sidebar.html cover=page.cover invert=page.invert_sidebar theme_color=page.theme_color image=image color=color video=video %}{% endcapture %}
{% if page.cover %}{{ sidebar }}{% endif %}
{% include_cached body/menu.html %}
{% include body/main.html %}
{% unless page.cover %}{{ sidebar }}{% endunless %}
</hy-push-state>
{% unless page.redirect %}
{% include_cached body/scripts.html %}
{% include my-body.html %}
{% endunless %}
{% include_cached templates/index.html %}

9
_includes/body/main.html Normal file
View File

@@ -0,0 +1,9 @@
<main
id="_main"
class="content layout-{{ page.layout }}"
role="main"
>
{% unless site.pivoine.no_breadcrumbs %}{% include body/breadcrumbs.html url=page.url %}{% endunless %}
{{ content }}
{% include_cached body/footer.html %}
</main>

18
_includes/body/menu.html Normal file
View File

@@ -0,0 +1,18 @@
<div id="_navbar" class="navbar fixed-top">
<div class="content">
<span class="sr-only">{{ site.data.strings.jump_to | default:"Jump to" }}{{ site.data.strings.colon | default:":" }}</span>
<div class="nav-btn-bar">
<a id="_menu" class="nav-btn no-hover" href="#_drawer--opened">
<span class="sr-only">{{ site.data.strings.navigation | default:"Navigation" }}</span>
<span class="icon-menu"></span>
</a>
<div class="nav-insert-marker"></div>
{% if site.pivoine.search.icon %}
<hm-search class="nav-span" hidden placeholder="{{ site.data.strings.search | default:"Search" }}"></hm-search>
{% elsif site.pivoine.search.always %}
<hm-search class="nav-span" placeholder="{{ site.data.strings.search | default:"Search" }}"></hm-search>
{% endif %}
</div>
</div>
</div>
<hr class="sr-only" hidden />

41
_includes/body/nav.html Normal file
View File

@@ -0,0 +1,41 @@
<span class="sr-only">{{ site.data.strings.navigation | default:"Navigation" }}{{ site.data.strings.colon | default:":" }}</span>
<ul>
{% if site.menu %}
{% for node in site.menu %}
{% assign url = node.url | default: node.href %}
<li>
<a
{% if forloop.first %}id="_drawer--opened"{% endif %}
href="{% include_cached smart-url url=url %}"
class="sidebar-nav-item {% if node.external %}external{% endif %}"
{% if node.rel %}rel="{{ node.rel }}"{% endif %}
>
{{ node.name | default:node.title }}
</a>
</li>
{% endfor %}
{% else %}
{% assign pages = site.html_pages | where: "menu", true %}
{% assign documents = site.documents | where: "menu", true %}
{% assign nodes = pages | concat: documents | sort: "order" %}
{% for node in nodes %}
{% unless node.redirect_to %}
<li>
<a
{% if forloop.first %}id="_navigation"{% endif %}
href="{{ node.url | relative_url }}"
class="sidebar-nav-item"
{% if node.rel %}rel="{{ node.rel }}"{% endif %}
>
{{ node.title }}
</a>
</li>
{% else %}
<li>
<a href="{{ node.redirect_to }}" class="sidebar-nav-item external">{{ node.title }}</a>
</li>
{% endunless %}
{% endfor %}
{% endif %}
</ul>

View File

@@ -0,0 +1,7 @@
<!--[if gt IE 10]><!---->
<script nomodule>{% include scripts/nomodule.min.js %}</script>
<script src="{{ '/assets/js/pivoine-1.0.0.js' | relative_url }}" type="module"></script>
<script src="{{ '/assets/js/LEGACY-pivoine-1.0.0.js' | relative_url }}" nomodule defer></script>
{% include my-scripts.html %}
{% include body/analytics.html %}
<!--<![endif]-->

View File

@@ -0,0 +1,21 @@
{% assign image = include.image %}
{% assign video = include.video %}
{% assign color = include.color %}
{% assign theme_color = include.theme_color %}
{% if image.background %}
{% capture bg_style %}background:{{ image.style }}{% endcapture %}
{% capture bg_class %}sidebar-bg {% if image.overlay %}sidebar-overlay{% endif %}{% endcapture %}
{% else %}
{% assign bg_color = theme_color | default:site.theme_color | default:color %}
{% capture bg_style %}background-color:{{ bg_color }};{% if image != 'none' %}background-image:url({% include_cached smart-url url=image %}){% endif %};overflow: hidden;{% endcapture %}
{% capture bg_class %}sidebar-bg {% if image != 'none' %}sidebar-overlay{% endif %}{% endcapture %}
{% endif %}
<div class="{{ bg_class }}" style="{{ bg_style }}">
{% if video %}
<video id="_video" style="min-width: 100%; height: 100%; object-fit: cover" autoplay muted loop>
<source src="{% include_cached smart-url url=video %}" type="video/mp4">
</video>
{% endif %}
</div>

View File

@@ -0,0 +1,33 @@
<div class="sidebar-sticky">
<div class="sidebar-about">
{% if site.logo %}
<a class="no-hover" href="{{ '/' | relative_url }}" tabindex="-1">
<img src="{% include_cached smart-url url=site.logo %}" class="logo" alt="{{ site.short_title | default:site.title }}" width="120" height="120" loading="lazy" />
</a>
{% endif %}
<a class="sidebar-title" href="{{ '/' | relative_url }}"><h2 class="h1">{{ site.short_title | default:site.title }}</h2></a>
{% assign text = site.tagline | default:site.description %}
{% if text %}
<p class="{% if text.size > 100 %}fine{% endif %}">
{{ text | markdownify | replace:'<p>','' | replace:'</p>','' }}
</p>
{% endif %}
</div>
<nav class="sidebar-nav heading" role="navigation">
{% include body/nav.html %}
</nav>
{% assign author = site.data.authors.first[1] | default:site.author %}
<div class="sidebar-social">
{% include components/social.html author=author %}
</div>
{% if site.pivoine.sound %}
{% assign sounds = site.data.sounds | where: 'default', true %}
<div class="sound-player" data-featured="{{ sounds.first | jsonify | escape }}">
<canvas class="hidden"></canvas>
<a>[ SOUND ON ]</a>
<audio hidden controls="false"></audio>
</div>
{% endif %}
</div>

View File

@@ -0,0 +1,14 @@
<hy-drawer
id="_drawer"
class="{% if include.cover %}cover{% endif %}"
side="left"
threshold="10"
noscroll
{% if include.cover %}opened{% endif %}
>
<header id="_sidebar" class="sidebar{% if include.invert %} invert{% endif %}" role="banner">
{% include_cached body/sidebar-bg.html image=include.image color=include.color theme_color=include.theme_color video=include.video %}
{% include_cached body/sidebar-sticky.html %}
</header>
</hy-drawer>
<hr class="sr-only" hidden />

View File

@@ -0,0 +1,8 @@
{% assign author = site.data.authors[include.author] | default:site.data.authors.first[1] | default:site.author %}
{% if author.about %}
<aside class="about related mt4 mb4" role="complementary">
{% assign about_heading = site.data.strings.about | default:"About" %}
{% include components/author.html author=author heading=about_heading heading_tag='h2' %}
</aside>
{% endif %}

View File

@@ -0,0 +1,24 @@
{% assign plugins = site.plugins | default:site.gems %}
<div class="author mt4">
{% assign author = include.author %}
{% if author.picture %}
{% include_cached components/hy-img.html class="avatar" img=author.picture alt=author.name width="120" height="120" %}
{% elsif plugins contains 'jekyll-avatar' %}
{% assign avatar = author.social.github | default:author.github.username | default:author.github %}
{% include components/avatar-tag.html user=avatar %}
{% endif %}
{% assign heading_tag = include.heading_tag | default:'h2' %}
{% assign heading_id = include.heading_id %}
<{{ heading_tag }} {% if heading_id %}id="{{ heading_id }}"{% endif %} class="page-title hr-bottom">
{{ include.heading | default:author.name }}
</{{ heading_tag }}>
{{ author.about | markdownify }}
<div class="sidebar-social">
{% include components/social.html author=author %}
</div>
</div>

View File

@@ -0,0 +1,4 @@
{% comment %}<!--
Including `avatar` in a partial prevents a parse error when `jekyll-avatar` is not included.
-->{% endcomment %}
{% avatar user=include.user size=128 %}

View File

@@ -0,0 +1,7 @@
{% if site.pivoine.dark_mode.dynamic %}
<script>
window._sunrise = {{ site.pivoine.dark_mode.sunrise | default:"6" }};
window._sunset = {{ site.pivoine.dark_mode.sunset | default:"18" }};
{% include scripts/dark-mode.min.js %}
</script>
{% endif %}

View File

@@ -0,0 +1,6 @@
{% if site.clap_button %}
<clap-button class="mb6" {% if include.hidden == true %}hidden{% endif %}></clap-button>
{% if include.hidden == true %}<hr class="dingbat related mb6" />{% endif %}
{% else %}
<hr class="dingbat related mb6" />
{% endif %}

View File

@@ -0,0 +1,29 @@
{% assign sources = '' %}
{% if include.img.src or include.img.path %}
{% assign srcset = null %}
{% if include.img.srcset %}
{% capture srcset %}{% for hash in include.img.srcset %}{% assign tmp = hash[1] %}{% include_cached smart-url url=tmp %} {{ hash[0] }}{% unless forloop.last %},{% endunless %}{% endfor %}{% endcapture %}
{% endif %}
{% assign src = include.img.src | default:include.img.path %}
{% capture sources %}
src="{% include_cached smart-url url=src %}"
{% if srcset %}srcset="{{ srcset | strip }}"{% endif %}
{% if include.sizes %}sizes="{{ include.sizes | replace:' ', '' }}"{% endif %}
{% endcapture %}
{% else %}
{% capture sources %}
src="{% include_cached smart-url url=include.img %}"
{% endcapture %}
{% endif %}
<img
{{ sources }}
{% if include.alt %}alt="{{ include.alt }}"{% endif %}
{% if include.class %}class="{{ include.class }}"{% endif %}
{% if include.property %}property="{{ include.property }}"{% endif %}
{% if include.width %}width="{{ include.width }}"{% endif %}
{% if include.height %}height="{{ include.height }}"{% endif %}
{% if include.width and include.height %}loading="lazy"{% endif %}
/>

View File

@@ -0,0 +1,3 @@
{% assign src = include.iframe.src | default:include.iframe.path %}
<iframe src="{% include_cached smart-url url=src %}" width="100%" frameborder="no" scrolling="no" allowfullscreen="true" style="width: 100%; aspect-ratio: calc(16/9);"></iframe>

View File

@@ -0,0 +1,12 @@
{% if include.href.size > 0 %}
<a
class="{{ include.class }} {{ include.a_class }}"
href="{{ include.href }}"
{% if include.rel %}rel="{{ include.rel }}"{% endif %}
{% if include.property %}property="{{ include.property }}"{% endif %}
>
{{- include.title -}}
</a>
{% else %}
<span class="{{ include.class }} {{ include.span_class }}">{{ include.title }}</span>
{% endif %}

View File

@@ -0,0 +1,14 @@
{% assign alt = include.alt %}
{% unless alt %}{% capture alt %}<div class="hr pb0"></div>{% endcapture %}{% endunless %}
{% if include.text.size > 0 %}
{% unless include.hide %}
<p class="{{ include.class | default:'note-sm' }}" {% if include.property %}property="{{ include.property }}"{% endif %}>
{{ include.text | markdownify | replace:"<p>","" | replace:"</p>","" }}
</p>
{% else %}
{{ alt }}
{% endunless %}
{% else %}
{{ alt }}
{% endif %}

View File

@@ -0,0 +1,15 @@
<h2 class="sr-only">{{ site.data.strings.pagination | default:"Pagination" }}</h2>
<nav class="pagination heading clearfix" role="navigation">
<ul>
<li class="pagination-item older" >
{% assign next_title = site.data.strings.older | default:"Older" %}
{% assign next_href = paginator.next_page_path | relative_url %}
{% include components/link.html rel="next" title=next_title href=next_href %}
</li>
<li class="pagination-item newer" >
{% assign prev_title = site.data.strings.newer | default:"Newer" %}
{% assign prev_href = paginator.previous_page_path | relative_url %}
{% include components/link.html rel="prev" title=prev_title href=prev_href %}
</li>
</ul>
</nav>

View File

@@ -0,0 +1,7 @@
{% assign post = include.post %}
{% assign format = include.format | default:site.data.strings.date_formats.related_post | default:"%d %b %Y" %}
<li class="h4">
<a href="{{ post.url | relative_url }}" class="flip-title"><span>{{ post.title }}</span></a>
<time class="faded fine" datetime="{{ post.date | date_to_xmlschema }}">{{ post.date | date:format }}</time>
</li>

View File

@@ -0,0 +1,102 @@
{% assign post = include.post %} {% assign no_link_title = include.no_link_title %} {% assign no_excerpt =
include.no_excerpt %} {% assign hide_image = include.hide_image %} {% assign hide_description = include.hide_description
%} {% assign show_gallery = include.show_gallery %} {% assign show_video = include.show_video %} {% assign show_iframe =
include.show_iframe %} {% assign hide_dates = include.hide_dates | default:site.pivoine.hide_dates %} {% assign
hide_posted_in = include.hide_posted_in %}
<article id="post{{ post.id | replace:'/','-' }}" class="page post mb6" role="article">
<header>
<h1 class="post-title flip-project-title">
{% unless no_link_title %}<a href="{{ post.url | relative_url }}" class="flip-title"
>{% endunless %} {{ post.title }} {% unless no_link_title %}</a
>{% endunless %}
</h1>
{%- unless hide_posted_in -%}
<div class="post-date">
{% capture foobar %} {%- unless hide_dates -%} {%- assign post_format = site.data.strings.date_formats.post |
default:"%d %b %Y" -%}
<time datetime="{{ post.date | date_to_xmlschema }}">{{ post.date | date:post_format }}</time>
{%- else -%} {{- site.data.strings.posted | default:"Posted" -}} {%- endunless -%} {{ ' ' }} {%- assign
category_start = site.data.strings.category_start | default:"in " -%} {%- assign category_separator =
site.data.strings.category_separator | default:" / " -%} {%- include components/tag-list.html tags=post.categories
meta=site.featured_categories start_with=category_start separator=category_separator -%} {{ ' ' }} {%- assign
tag_start = site.data.strings.tag_start | default:"on " -%} {%- assign tag_separator =
site.data.strings.tag_separator | default:", " -%} {%- include components/tag-list.html tags=post.tags
meta=site.featured_tags start_with=tag_start separator=tag_separator -%} {% endcapture %}
<span class="ellipsis mr1"> {{ foobar }} </span>
{% unless hide_dates or site.pivoine.hide_last_modified or post.hide_last_modified %} {% if post.last_modified_at
%} {% assign d1 = post.date | date:"%Y-%m-%d" %} {% assign d2 = post.last_modified_at | date:"%Y-%m-%d" %} {% if
d1 != d2 %} {% assign label = site.data.strings.last_modified_at | default:"Last modified at" %} {% assign
last_modified_at_format = site.data.strings.date_formats.last_modified_at | default:"%Y-%m-%d" %}
<span
class="ellipsis"
data-tippy-content="{{ label }}{{ site.data.strings.colon }} {{ post.last_modified_at | date:post_format }}"
>
<span class="sr-only">{{ label }}{{ site.data.strings.colon }}</span>
<span class="{{ site.data.strings.last_modified_icon | default:'icon-history' }}"></span>
<time datetime="{{ post.last_modified_at | date_to_xmlschema }}"
>{{ post.last_modified_at | date:last_modified_at_format }}</time
>
</span>
{% endif %} {% endif %} {% endunless %}
</div>
{%- endunless -%} {% assign alt = false %} {% unless hide_image %}{% if post.image %} {% unless no_link_title %}<a
href="{{ post.url | relative_url }}"
class="no-hover no-print-link {% unless post.hide_image %}flip-project{% endunless %}"
tabindex="-1"
>{% endunless %}
<div class="img-wrapper lead aspect-ratio flip-project-img {% unless no_link_title %}sixteen-nine{% endunless %}">
<div>
{% if show_video %} {% include_cached components/video.html video=post.video poster=post.image %} {% elsif
show_iframe %} {% include_cached components/iframe.html iframe=post.iframe %} {% else %} {% include_cached
components/hy-img.html img=post.image alt=post.title %} {% endif %}
</div>
</div>
{% unless no_link_title %}</a
>{% endunless %} {% assign alt = '' %} {% endif %}{% endunless %} {% include components/message.html
text=post.description hide=hide_description alt=alt %}
</header>
{% if no_excerpt %} {% if post.gallery %}
<div class="gallery-wrapper lead">
{% for image in post.gallery %}
<a class="gallery-item" href="{{ image | relative_url }}" data-fslightbox target="_blank">
{% if post.video_gallery %} {% assign i = image | replace: "mp4", "webp" %} {% include_cached
components/hy-img.html img=i alt=post.title %} {% else %} {% include_cached components/hy-img.html img=image
alt=post.title %} {% endif %}
</a>
{% endfor %}
</div>
{% endif %} {% if post.sound %} {% assign sounds = site.data.sounds | where: 'slug', page.sound %}
<div class="sound-wrapper" data-featured="{{ sounds.first | jsonify | escape }}">
<table class="stretch-table dl-table">
<tbody>
{% for track in sounds.first.tracks %}
<tr>
<td style="text-align: left">
<a class="sound-item" href="/assets/sounds/{{ page.sound }}/{{ track }}" target="_blank">
{{ sounds.first.artist }} - {{ track | replace: ".mp3", "" }}
</a>
</td>
<td style="text-align: right">
<a download href="/assets/sounds/{{ page.sound }}/{{ track }}" target="_blank">
{{ site.data.strings.download }}
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %} {{ post.content }} {% else %} {% capture post_title %}<a
class="heading flip-title"
href="{{ post.url | relative_url }}"
>{{ post.title }}</a
>{% endcapture %} {% assign text = site.data.strings.continue_reading | default:"Continue reading
<!--post_title-->" %}
<footer>
<p class="read-more">{{ text | replace:"<!--post_title-->", post_title }}</p>
</footer>
{% endif %}
</article>

View File

@@ -0,0 +1,35 @@
{% assign post = page %}
{% if page.related_posts %}
{% if major >= 4 and minor >= 1 %}
{% assign related_posts = site.posts | where_exp:"post", "page.related_posts contains post.path or page.related_posts contains post.url" %}
{% else %}
{% assign related_posts_1 = site.posts | where_exp:"post", "page.related_posts contains post.path" %}
{% assign related_posts_2 = site.posts | where_exp:"post", "page.related_posts contains post.url" %}
{% assign related_posts = related_posts_1 | concat:related_posts_2 %}
{% endif %}
{% elsif site.pivoine.use_lsi or site.use_lsi %}
{% assign related_posts = site.related_posts %}
{% elsif post.categories.first %}
{% assign related_posts = site.categories[post.categories.first] | where_exp:"post", "post.url != page.url" %}
{% elsif post.tags.first %}
{% assign related_posts = site.tags[post.tags.first] | where_exp:"post", "post.url != page.url" %}
{% else %}
{% assign related_posts = site.related_posts %}
{% endif %}
{% if related_posts.size > 0 %}
<aside class="related mb4" role="complementary">
<h2 class="hr-bottom">{{ site.data.strings.related_posts | default:"Related Posts" }}</h2>
<ul class="related-posts">
{% for post in related_posts limit:3 %}
{% if post %}
{% include_cached components/post-list-item.html post=post %}
{% else %}
<li>Post with path <code>{{ post_path }}</code> not found.</li>
{% endif %}
{% endfor %}
</ul>
</aside>
{% endif %}

View File

@@ -0,0 +1,40 @@
{% assign platform = include.platform | downcase %}
{% assign username = include.username %}
{% if username.size > 0 %}
{% assign = data_social = site.data.social[platform] | default:site.data_social[platform] %}
{% assign name = data_social.name | default:include.platform %}
{% assign icon = data_social.icon | default:'icon-link' %}
{% assign app = data_social.append %}
{% assign prep = data_social.prepend %}
{% unless data_social %}
{% if platform == "email" %}
{% assign name = "Email" %}
{% assign icon = "icon-mail" %}
{% assign prep = "mailto:" %}
{% elsif platform == "twitter" %}
{% assign name = "Twitter" %}
{% assign icon = "icon-twitter" %}
{% assign prep = "https://twitter.com/" %}
{% elsif platform == "github" %}
{% assign name = "GitHub" %}
{% assign icon = "icon-github" %}
{% assign prep = "https://github.com/" %}
{% endif %}
{% endunless %}
{% if username contains "//" or username contains "mailto:" %}
{% assign url = username %}
{% else %}
{% assign url = username | prepend:prep | append:app %}
{% endif %}
<li>
<a href="{{ url }}" title="{{ name }}" class="no-mark-external">
<span class="{{ icon }}"></span>
<span class="sr-only">{{ name }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,23 @@
<span class="sr-only">{{ site.data.strings.social | default:"Social" }}{{ site.data.strings.colon }}</span>
<ul>
{% if include.author.social %}
{% for link in include.author.social %}
{% include components/social-list-item.html platform=link.first username=link.last %}
{% endfor %}
{% else %}
{% assign twitter_username = author.twitter.username | default: author.twitter | default:site.twitter.username | default:site.twitter | default:site.twitter_username %}
{% if twitter_username %}
{% include components/social-list-item.html platform="twitter" username=twitter_username %}
{% endif %}
{% assign github_username = author.github.username | default: author.github | default:site.github.username | default:site.github | default:site.github_username %}
{% if github_username %}
{% include components/social-list-item.html platform="github" username=github_username %}
{% endif %}
{% assign email = author.email | default: site.email %}
{% if email %}
{% include components/social-list-item.html platform="email" username=email %}
{% endif %}
{% endif %}
</ul>

View File

@@ -0,0 +1,30 @@
{%- assign tags = include.tags -%}
{%- assign meta = include.meta -%}
{%- assign start_with = include.start_with -%}
{%- assign separator = include.separator -%}
{%- assign end_with = include.end_with -%}
{%- assign content = '' -%}
{%- if tags.size > 0 -%}
{%- assign content = start_with -%}
{%- for tag_slug in tags -%}
{%- capture iter_separator -%}{% if forloop.last %}{{ end_with }}{% else %}{{ separator }}{% endif %}{%- endcapture -%}
{%- if major >= 4 and minor >= 1 %}
{%- assign tag = meta | find: "slug", tag_slug -%}
{%- else -%}
{%- assign tag = meta | where: "slug", tag_slug | first -%}
{%- endif -%}
{%- if tag -%}
{%- capture content_temp -%}{{ content }}<a href="{{ tag.url | relative_url }}" class="flip-title">{{ tag.title }}</a>{{ iter_separator }}{%- endcapture -%}
{%- else -%}
{%- capture content_temp -%}{{ content }}<span>{{ tag_slug | capitalize }}</span>{{ iter_separator }}{%- endcapture -%}
{%- endif -%}
{%- assign content = content_temp -%}
{%- endfor -%}
{%- endif -%}
{{- content -}}

View File

@@ -0,0 +1,31 @@
{% assign src = include.video.src | include.video.path | default:include.video %}
{% assign poster = include.video.poster | default:include.poster %}
<media-controller>
<video
slot="media"
src="{% include_cached smart-url url=src %}"
{% if poster %}poster="{% include_cached smart-url url=poster %}"{% endif %}
{% if include.video.class %}class="{{ include.video.class }}"{% endif %}
{% if include.video.property %}property="{{ include.video.property }}"{% endif %}
{% if include.video.width %}width="{{ include.video.width }}"{% endif %}
{% if include.video.height %}height="{{ include.video.height }}"{% endif %}
{% if include.video.width and include.video.height %}loading="lazy"{% endif %}
{% if include.video.autoplay %}autoplay{% endif %}
{% if include.video.loop %}loop{% endif %}
{% if include.video.muted %}muted{% endif %}
{% if include.video.preload %}preload="{{ include.video.preload }}"{% endif %}
{% if include.video.crossorigin %}crossorigin="{{ include.video.crossorigin }}"{% endif %}
></video>
<media-loading-indicator slot="centered-chrome" noautohide></media-loading-indicator>
<media-control-bar>
<media-play-button></media-play-button>
<media-mute-button></media-mute-button>
<media-volume-range></media-volume-range>
<media-time-display></media-time-display>
<media-time-range></media-time-range>
<media-duration-display></media-duration-display>
<media-playback-rate-button></media-playback-rate-button>
<media-fullscreen-button></media-fullscreen-button>
</media-control-bar>
</media-controller>

View File

@@ -0,0 +1 @@
{% capture to_scssify %}{% include styles/inline.scss %}{% endcapture %}{{ to_scssify | scssify }}

View File

@@ -0,0 +1 @@
{% feed_meta %}

15
_includes/head/index.html Normal file
View File

@@ -0,0 +1,15 @@
{% assign google_fonts = site.google_fonts %}
{% assign font_heading = site.font_heading %}
{% assign font = site.font %}
{% include head/meta.html %}
{% include_cached head/meta-static.html %}
{% include head/links.html lang=page.lang %}
{% include_cached head/links-static.html %}
{% include_cached head/scripts.html %}
{% include_cached head/styles.html layout=page.layout color=color theme_color=theme_color %}
{% include my-head.html %}

View File

@@ -0,0 +1,30 @@
{% if plugins contains 'jekyll-feed' %}{% include head/feed-tag.html %}{% endif %}
<link rel="icon" type="image/png" href="/assets/icons/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="/assets/icons/favicon.svg" />
<link rel="shortcut icon" href="/assets/icons/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png" />
<link rel="manifest" href="/assets/icons/site.webmanifest" />
{% if site.google_fonts %}
{%- capture google_fonts_url %}{{ site.google_fonts_url | default:'https://fonts.googleapis.com' }}{%- endcapture -%}
<link rel="dns-prefetch" href="{{ google_fonts_url }}" />
{%- if google_fonts_url == 'https://fonts.googleapis.com' -%}
<link rel="dns-prefetch" href="https://fonts.gstatic.com" />
{%- endif -%}
{% endif %}
{% if site.google_analytics %}
<link rel="dns-prefetch" href="https://www.google-analytics.com" />
{% endif %}
{% if site.kramdown.math_engine == 'katex' %}
{% capture katex_url %}{{ 'assets/bower_components/katex/dist/katex.min.css' | relative_url }}{% endcapture %}
<link rel="dns-prefetch" href="{{ katex_url }}" id="_katexPreload" />
<noscript><link rel="stylesheet" href="{{ katex_url }}"></noscript>
{% endif %}
{% assign disqus = site.disqus | default:site.disqus_shortname %}
{% if disqus %}
<link rel="dns-prefetch" href="https://{{ disqus }}.disqus.com" id="_hrefDisqus" />
{% endif %}

View File

@@ -0,0 +1,2 @@
{% assign lang = include.lang | default:site.lang | default:'en' %}
<link rel="alternate" href="{{ page.url | absolute_url }}" hreflang="{{ lang | downcase | replace:'_','-' }}" />

View File

@@ -0,0 +1,13 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-title" content="{{ site.title }}" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="application-name" content="{{ site.title }}" />
<meta name="generator" content="pivoine v1.0.0" />

30
_includes/head/meta.html Normal file
View File

@@ -0,0 +1,30 @@
{% if page.noindex or page.no_index or page.sitemap == false %}
<meta name="robots" content="noindex" />
{% endif %}
{% unless page.redirect %}
{% if plugins contains 'jekyll-seo-tag' %}
{% include head/seo-tag.html %}
{% else %}
{% include head/seo-fallback.html %}
{% endif %}
{% if site.keywords.size > 0 or page.keywords.size > 0 %}
<meta name="keywords" content="{{ page.keywords | default:site.keywords | join:',' }}" />
{% endif %}
{% else %}
<meta http-equiv="refresh" content="0; url={{ page.redirect.to }}" />
<title>{{ site.data.strings.redirecting | default:"Redirecting..." }}</title>
{% endunless %}
{% if site.pivoine.dark_mode.dynamic %}
<meta name="color-scheme" content="dark light" />
{% elsif site.pivoine.dark_mode.always %}
<meta name="color-scheme" content="dark" />
{% else %}
<meta name="color-scheme" content="light" />
{% endif %}
{% unless site.pivoine.no_theme_color %}
<meta name="theme-color" content="{{ theme_color | default:'rgb(8,46,57)' }}" />
{% endunless %}

View File

@@ -0,0 +1,4 @@
<style id="_pageStyle">
{% capture page_style %}{% include_cached styles/page-style.scss color=include.color theme_color=include.theme_color %}{% endcapture %}
{{ page_style | scssify }}
</style>

View File

@@ -0,0 +1,24 @@
<script>{% include scripts/load-js.min.js %}{% include scripts/loadCSS.min.js %}{% include scripts/cssrelpreload.min.js %}!function(w) {
w._baseURL = '{{ "/" | relative_url }}';
w._publicPath = '{{ "/assets/js/" | relative_url }}';
w._noPushState = {{ site.pivoine.no_push_state | default:site.disable_push_state | default:false }};
w._noDrawer = {{ site.pivoine.no_drawer | default:site.disable_drawer | default:false }};
w._noNavbar = {{ site.pivoine.no_navbar | default:false }};
w._noToc = {{ site.pivoine.no_toc | default:false }};
w._noSearch = {{ site.pivoine.no_search | default:false }};
w._search = {
DATA_URL: '{{ "/assets/sitedata.json?no-cache" | relative_url }}',
STORAGE_KEY: 'mini-search{{ "/" | relative_url }}',
INDEX_KEY: 'index--{{ site.time | date_to_xmlschema }}',
};
w._clapButton = {% if site.clap_button or jekyll.environment != 'production' %}true{% else %}false{% endif %};
}(window);</script>
{% if site.kramdown.math_engine == 'mathjax' %}
<script async src="{{ 'assets/bower_components/MathJax/es5/tex-mml-chtml.js' | relative_url }}" id="_MathJax"></script>
{% endif %}
{% if jekyll.environment != 'production' and site.pivoine.umami %}
<script defer src="{{ site.pivoine.umami.script }}" data-website-id="{{ site.pivoine.umami.id }}"></script>
{% endif %}

View File

@@ -0,0 +1,13 @@
{% assign strings = site.data.strings %}
{% capture title %}
{% if page.url == "/" %}
{{ site.title }}{% if site.tagline %} {{ strings.separator | default:"|" }} {{ site.tagline }}{% endif %}
{% elsif page.title.size > 0 %}
{{ page.title }} {{ strings.separator | default:"|" }} {{ site.title }}
{% else %}
{{ site.title }}
{% endif %}
{% endcapture %}
<title>{{ title | strip }}</title>
<meta name="description" content="{{ page.description | default:page.excerpt | default:site.description | markdownify | strip_html }}" />
<link rel="canonical" href="{{ page.url | absolute_url }}" />

View File

@@ -0,0 +1,18 @@
{% comment %}<!--
Including `seo` in a partial prevents a parse error when `jekyll-seo-tag` is not included
-->{% endcomment %}
{% seo %}
{% if page.accent_video %}
<meta property="og:video" content="{{ page.accent_video | absolute_url }}" />
{% endif %}
{% if site.pivoine.sound and page.sound %}
<meta property="og:type" content="music.album" />
{% assign sounds = site.data.sounds | where: 'slug', page.sound %}
{% for track in sounds.first.tracks %}
{% assign track_url = "/assets/sounds/" | append:page.sound | append:"/" | append: track" %}
<meta property="music:song" content="{{ track_url | absolute_url }}" />
<meta property="music:song:track" content="{{ forloop.index + 1 }}" />
{% endfor %}
{% endif %}

View File

@@ -0,0 +1,25 @@
{% assign google_fonts = site.google_fonts %}
{% capture style_url %}{{ 'assets/css/pivoine-1.0.0.css' | relative_url }}{% endcapture %}
{% capture icons_url %}{{ 'assets/icomoon/style.css' | relative_url }}{% endcapture %}
{% capture game_icons_url %}{{ 'assets/game-icons/css/game-icons.css' | relative_url }}{% endcapture %}
{% if google_fonts %}
{% capture fonts_url %}{{ site.google_fonts_url | default:'https://fonts.googleapis.com' }}/css?family={{ google_fonts | uri_escape }}&display=swap{% endcapture %}
{% endif %}
<link rel="preload" as="style" href="{{ style_url }}" id="_stylePreload" />
<link rel="preload" as="style" href="{{ icons_url }}" id="_iconsPreload" />
<link rel="preload" as="style" href="{{ game_icons_url }}" id="_gameIconsPreload" />
{% if google_fonts %}<link rel="preload" as="style" href="{{ fonts_url }}" id="_fontsPreload" />{% endif %}
<script>
setRel('_stylePreload');
setRel('_iconsPreload');
setRel('_gameIconsPreload');
/*{% if google_fonts %}*/setRel('_fontsPreload');/*{% endif %}*/
</script>
<noscript>
<link rel="stylesheet" href="{{ style_url }}" />
<link rel="stylesheet" href="{{ icons_url }}" />
<link rel="stylesheet" href="{{ game_icons_url }}" />
{% if google_fonts %}<link rel="stylesheet" href="{{ fonts_url }}" />{% endif %}
</noscript>

View File

@@ -0,0 +1,4 @@
{% assign layout = include.layout %}
<style id="_styleInline">
{% include_cached head/css/inline %}
</style>

View File

@@ -0,0 +1,12 @@
{% assign google_fonts = site.google_fonts %}
{% capture style_url %}{{ 'assets/css/pivoine-1.0.0.css' | relative_url }}{% endcapture %}
{% capture icons_url %}{{ 'assets/icomoon/style.css' | relative_url }}{% endcapture %}
{% capture game_icons_url %}{{ 'assets/game-icons/css/game-icons.css' | relative_url }}{% endcapture %}
{% if google_fonts %}
{% capture fonts_url %}{{ site.google_fonts_url | default:'https://fonts.googleapis.com' }}/css?family={{ google_fonts | uri_escape }}&display=swap{% endcapture %}
{% endif %}
<link rel="stylesheet" href="{{ style_url }}" id="_stylePreload" />
<link rel="stylesheet" href="{{ icons_url }}" id="_iconsPreload" />
<link rel="stylesheet" as="style" href="{{ game_icons_url }}" id="_gameIconsPreload" />
{% if google_fonts %}<link rel="stylesheet" href="{{ fonts_url }}" id="_fontsPreload" />{% endif %}

View File

@@ -0,0 +1,12 @@
<!--[if gt IE 8]><!---->
{% if site.pivoine.no_inline_css or jekyll.environment == 'development' %}
{% include_cached head/styles-no-inline.html %}
{% else %}
{% include_cached head/styles-layout.html layout=include.layout %}
{% include_cached head/styles-inline.html %}
{% endif %}
{% unless site.pivoine.no_page_style %}
{% include_cached head/page-style.html color=include.color theme_color=include.theme_color %}
{% endunless %}
<!--<![endif]-->

12
_includes/header.txt Normal file
View File

@@ -0,0 +1,12 @@
/*************************************************************
*
*
* ____ ____ .__ __ /\
* \ \ / /____ | | | | __ ____ _____ ______)/ ______
* \ Y /\__ \ | | | |/ // \\__ \\_ __ \/ ___/
* \ / / __ \| |_| <| | \/ __ \| | \/\___ \
* \___/ (____ /____/__|_ \___| (____ /__| /____ >
* \/ \/ \/ \/ \/
*
*
*************************************************************/

View File

@@ -0,0 +1,2 @@
<!-- This file is only here to prevent an error when using pivoine with Jekyll's default content. -->
GitHub

7
_includes/if-non-null Normal file
View File

@@ -0,0 +1,7 @@
{% capture maybe %}{% include {{ include.try }} %}{% endcapture %}
{% assign maybe = maybe | strip_newlines %}
{% if maybe.size > 0 %}
{{ maybe }}
{% elsif include.fallback %}
{% include {{ include.fallback }} %}
{% endif %}

42
_includes/my-body.html Normal file
View File

@@ -0,0 +1,42 @@
{% comment %}
<!--
Example code for using Matamo as alternative analytics solution.
-->
{% if site.matomo_analytics %}
<script>
var _paq = _paq || [];
{% if site.matomo_analytics.no_cookies %}
_paq.push(['disableCookies']);
{% endif %}
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
_paq.push(['setTrackerUrl', u+'piwik.php']);
_paq.push(['setSiteId', '{{site.matomo_analytics.site_id}}']);
var pushStateEl = document.getElementById('_pushState');
var timeStartLoadPage, referer, timeItTookToLoadPage;
pushStateEl.addEventListener('hy-push-state-start', function() {
timeStartLoadPage = new Date().getTime();
referer = window.location.toString();
});
pushStateEl.addEventListener('hy-push-state-ready', function() {
timeItTookToLoadPage = new Date().getTime() - timeStartLoadPage;
});
pushStateEl.addEventListener('hy-push-state-after', function() {
_paq.push(['setReferrerUrl', referer]);
_paq.push(['setCustomUrl', window.location.toString()]);
_paq.push(['setDocumentTitle', document.title]);
_paq.push(['deleteCustomVariables', 'page']);
_paq.push(['setGenerationTimeMs', timeItTookToLoadPage]);
_paq.push(['trackPageView']);
});
window.loadJSDeferred('{{site.matomo_analytics.root}}piwik.js');
</script>
{% endif %}
{% endcomment %}

View File

@@ -0,0 +1,24 @@
{% assign disqus = site.disqus | default:site.disqus_shortname %}
{% if disqus %}
<div id="disqus_thread"></div>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments powered by Disqus.</a></noscript>
<script>!function(w, d) {
if (d.getElementById("disqus_thread")) {
if (w.DISQUS) {
w.DISQUS.reset({
reload: true,
config() {
this.page.url = w.location.href;
this.page.title = d.title;
},
});
} else {
w.disqus_config = function disqusConfig() {
this.page.url = w.location.href;
this.page.title = d.title;
};
w.loadJSDeferred(d.getElementById("_hrefDisqus").href + '/embed.js');
}
}
}(window, document);</script>
{% endif %}

13
_includes/my-head.html Normal file
View File

@@ -0,0 +1,13 @@
{% comment %}
<!--
Using `preload` so that page rendering doesn't get blocked.
Fill in `href`. You may have to adjust `as` and `onload`/`rel`, depending on content.
-->
<link href="<path/to/content.css>" rel="preload" as="style" onload="this.rel='stylesheet'">
<!--
Fallback in case JavaScript isn't enabled.
Fill in `href`. You may have to adjust `rel`.
-->
<noscript><link href="<path/to/content.css>" rel="stylesheet"></noscript>
{% endcomment %}

55
_includes/my-scripts.html Normal file
View File

@@ -0,0 +1,55 @@
{% comment %}
<!--
Example code for the CloudFlare mail protection script.
CloudFlare will inject this on every page, but due to pivoine's push state approach to page loading,
it will only run on the initial page.
The snippet below will run the code on every `hy-push-state-load` event instead.
-->
<script>
document.getElementById('_pushState').addEventListener('hy-push-state-load', function (e) {
function e(e){
(console.error?console.error:console.log).call(console,e)
}
function t(e){
return l.innerHTML='<a href="'+e.replace(/"/g,"&quot;")+'"></a>',l.childNodes[0].getAttribute("href")
}
function r(e,t){
var r=e.substr(t,2);return parseInt(r,16)
}
function n(e,n){
for(var o="",c=r(e,n),a=n+2;a<e.length;a+=2){
var l=r(e,a)^c;
o+=String.fromCharCode(l)
}
return t(o)
}
var o="/cdn-cgi/l/email-protection#",
c=".__cf_email__",
a="data-cfemail",
l=document.createElement("div");
!function(){
for(var t=document.getElementsByTagName("a"),r=0;r<t.length;r++)
try{
var c=t[r],a=c.href.indexOf(o);
a>-1&&(c.href="mailto:"+n(c.href,a+o.length))
}catch(t){
e(t)
}
}(),
function(){
for(var t=document.querySelectorAll(c),r=0;r<t.length;r++)
try{
var o=t[r],l=n(o.getAttribute(a),0),i=document.createTextNode(l);
o.parentNode.replaceChild(i,o)
}catch(t){
e(t)
}
}()
});
</script>
{% endcomment %}

38
_includes/scripts/cssrelpreload.min.js vendored Normal file
View File

@@ -0,0 +1,38 @@
!(function (a) {
if (a.loadCSS) {
var b = (loadCSS.relpreload = {});
if (
((b.support = function () {
try {
return a.document.createElement("link").relList.supports("preload");
} catch (b) {
return !1;
}
}),
(b.poly = function () {
for (
var b = a.document.getElementsByTagName("link"), c = 0;
c < b.length;
c++
) {
var d = b[c];
"preload" === d.rel &&
"style" === d.getAttribute("as") &&
(a.loadCSS(d.href, d, d.getAttribute("media")), (d.rel = null));
}
}),
!b.support())
) {
b.poly();
var c = a.setInterval(b.poly, 300);
a.addEventListener &&
a.addEventListener("load", function () {
b.poly(), a.clearInterval(c);
}),
a.attachEvent &&
a.attachEvent("onload", function () {
a.clearInterval(c);
});
}
}
})(this);

View File

@@ -0,0 +1,11 @@
!(function (window, document) {
var LM = "light-mode";
var DM = "dark-mode";
var h = new Date().getHours();
if ("matchMedia" in window && window.matchMedia("(prefers-color-scheme)"))
return;
var m = h <= window._sunrise || h >= window._sunset ? DM : LM;
var n = m === DM ? LM : DM;
document.body.classList.add(m);
document.body.classList.remove(n);
})(window, document);

9
_includes/scripts/dark-mode.min.js vendored Normal file
View File

@@ -0,0 +1,9 @@
((e, s) => {
var d = "light-mode",
a = "dark-mode",
o = new Date().getHours();
("matchMedia" in e && e.matchMedia("(prefers-color-scheme)")) ||
((e = (o = o <= e._sunrise || o >= e._sunset ? a : d) == a ? d : a),
s.body.classList.add(o),
s.body.classList.remove(e));
})(window, document);

View File

@@ -0,0 +1,62 @@
// Copyright (c) 2017 Florian Klampfer <https://qwtel.com/>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Compress via uglify:
// uglifyjs load-js.js -c -m > load-js.min.js
!(function (window, document) {
"use strict";
function addEvent(el, type, cb, opts) {
if (el.addEventListener) el.addEventListener(type, cb, opts);
else if (el.attachEvent) el.attachEvent("on" + type, cb);
else el["on" + type] = cb;
}
window.loadJS = function (src, cb) {
var script = document.createElement("script");
script.src = src;
if (cb) addEvent(script, "load", cb, { once: true });
var ref = document.scripts[0];
ref.parentNode.insertBefore(script, ref);
return script;
};
window._loaded = false;
window.loadJSDeferred = function (src, cb) {
var script = document.createElement("script");
script.src = src;
function insert() {
window._loaded = true;
if (cb) addEvent(script, "load", cb, { once: true });
var ref = document.scripts[0];
ref.parentNode.insertBefore(script, ref);
}
if (window._loaded) insert();
else addEvent(window, "load", insert, { once: true });
return script;
};
window.setRel = window.setRelStylesheet = function (id) {
var link = document.getElementById(id);
function set() {
this.rel = "stylesheet";
}
addEvent(link, "load", set, { once: true });
};
})(window, document);

35
_includes/scripts/load-js.min.js vendored Normal file
View File

@@ -0,0 +1,35 @@
((r, a) => {
function d(e, t, n, o) {
e.addEventListener
? e.addEventListener(t, n, o)
: e.attachEvent
? e.attachEvent("on" + t, n)
: (e["on" + t] = n);
}
(r.loadJS = function (e, t) {
var n = a.createElement("script"),
e = ((n.src = e), t && d(n, "load", t, { once: !0 }), a.scripts[0]);
return e.parentNode.insertBefore(n, e), n;
}),
(r._loaded = !1),
(r.loadJSDeferred = function (e, t) {
var n = a.createElement("script");
function o() {
(r._loaded = !0), t && d(n, "load", t, { once: !0 });
var e = a.scripts[0];
e.parentNode.insertBefore(n, e);
}
return (n.src = e), r._loaded ? o() : d(r, "load", o, { once: !0 }), n;
}),
(r.setRel = r.setRelStylesheet =
function (e) {
d(
a.getElementById(e),
"load",
function () {
this.rel = "stylesheet";
},
{ once: !0 },
);
});
})(window, document);

44
_includes/scripts/loadCSS.min.js vendored Normal file
View File

@@ -0,0 +1,44 @@
!(function (a) {
"use strict";
var b = function (b, c, d) {
function e(a) {
return h.body
? a()
: void setTimeout(function () {
e(a);
});
}
function f() {
i.addEventListener && i.removeEventListener("load", f),
(i.media = d || "all");
}
var g,
h = a.document,
i = h.createElement("link");
if (c) g = c;
else {
var j = (h.body || h.getElementsByTagName("head")[0]).childNodes;
g = j[j.length - 1];
}
var k = h.styleSheets;
(i.rel = "stylesheet"),
(i.href = b),
(i.media = "only x"),
e(function () {
g.parentNode.insertBefore(i, c ? g : g.nextSibling);
});
var l = function (a) {
for (var b = i.href, c = k.length; c--; ) if (k[c].href === b) return a();
setTimeout(function () {
l(a);
});
};
return (
i.addEventListener && i.addEventListener("load", f),
(i.onloadcssdefined = l),
l(f),
i
);
};
"undefined" != typeof exports ? (exports.loadCSS = b) : (a.loadCSS = b);
})("undefined" != typeof global ? global : this);

View File

@@ -0,0 +1,25 @@
// `script[nomodule]` polyfill for Safari 10.1.
// Source: https://gist.github.com/samthor/64b114e4a4f539915a95b91ffd340acc
(function () {
var check = document.createElement("script");
if (!("noModule" in check) && "onbeforeload" in check) {
var support = false;
document.addEventListener(
"beforeload",
function (e) {
if (e.target === check) {
support = true;
} else if (!e.target.hasAttribute("nomodule") || !support) {
return;
}
e.preventDefault();
},
true,
);
check.type = "module";
check.src = ".";
document.head.appendChild(check);
check.remove();
}
})();

20
_includes/scripts/nomodule.min.js vendored Normal file
View File

@@ -0,0 +1,20 @@
(() => {
var t,
n = document.createElement("script");
!("noModule" in n) &&
"onbeforeload" in n &&
((t = !1),
document.addEventListener(
"beforeload",
function (e) {
if (e.target === n) t = !0;
else if (!e.target.hasAttribute("nomodule") || !t) return;
e.preventDefault();
},
!0,
),
(n.type = "module"),
(n.src = "."),
document.head.appendChild(n),
n.remove());
})();

10
_includes/smart-url Normal file
View File

@@ -0,0 +1,10 @@
{%- assign url = include.url -%}
{%- assign ch1 = url | slice:0 -%}
{%- if url contains '://' -%}
{{ url }}
{%- elsif ch1 == '/' -%}
{%- assign url = url | remove_first:site.baseurl -%}
{{ url | relative_url }}
{%- else -%}
{{ url }}
{%- endif -%}

1
_includes/smart-url.txt Normal file
View File

@@ -0,0 +1 @@
{% comment %} Retained for backwards compatibility. Use smart-url (without .txt) instead. {% endcomment %}{% include smart-url url=include.url %}

View File

@@ -0,0 +1,18 @@
.note:before {
content: "{{ site.data.strings.note | default:'Note' }}";
}
.page > header > .note-sm:before {
content: "{{ site.data.strings.description | default:'Description' }}";
}
#markdown-toc:before {
content: "{{ site.data.strings.toc | default:'Table of Contents' }}";
}
.layout-resume .note-sm:before {
content: "{{ site.data.strings.resume.summary | default:'Summary' }}";
}
{% if site.pivoine.no_page_style %}
{% assign color = site.accent_color | default:'rgb(79,177,186)' %}
{% assign theme_color = site.theme_color | default:'rgb(8,46,57)' %}
{% include_cached styles/page-style.scss color=color theme_color=theme_color %}
{% endif %}

View File

@@ -0,0 +1,57 @@
// Copyright (c) 2019 Florian Klampfer <https://qwtel.com/>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
{% include styles/variables.scss %}
@import "variables";
@import "my-variables";
@import "mixins";
{% if site.pivoine.dark_mode.dynamic %}
@import "pro/dark-mode-dynamic";
{% else %}
@import "pro/dark-mode";
{% endif %}
@import "html";
@import "pooleparty/__inline__/base";
@import "pooleparty/__inline__/type";
@import "pooleparty/__inline__/table";
@import "pooleparty/__inline__/footer";
@import "pooleparty/__inline__/footnotes";
@import "pooleparty/__inline__/code";
@import "pooleparty/__inline__/posts";
@import "pooleparty/__inline__/related";
@import "pooleparty/__inline__/read-more";
@import "pooleparty/__inline__/message";
@import "pooleparty/__inline__/pagination";
@import "pivoine/__inline__/base";
@import "pivoine/__inline__/utilities";
@import "pivoine/__inline__/links";
@import "pivoine/__inline__/images";
@import "pivoine/__inline__/sidebar";
@import "pivoine/__inline__/social";
@import "pivoine/__inline__/menu";
@import "pivoine/__inline__/toc";
@import "pivoine/__inline__/content";
@import "pivoine/__inline__/avatar";
@import "pivoine/__inline__/katex";
@import "pivoine/__inline__/footer";
@import "pivoine/__inline__/sound";
@import "my-inline";
{% include styles/common.scss %}

View File

@@ -0,0 +1,19 @@
@use "sass:color";
@use "sass:math";
{% assign color = include.color %}
{% assign theme_color = include.theme_color %}
html {
--accent-color: {{ color }};
--accent-color-faded: color.adjust({{ color }}, $alpha: -0.5);
--accent-color-highlight: color.adjust({{ color }}, $alpha: -0.9);
--accent-color-darkened: color.adjust({{ color }}, $lightness: -7.5%);
{% if site.github and site.pivoine.dart_sass_2_compat != true %}
--dark-mode-body-bg: #{hsl(color.channel({{ theme_color }}, "hue", $space: hsl), math.div(color.channel({{ theme_color }}, "saturation", $space: hsl), 8), 17.5%)};
--dark-mode-border-color: #{hsl(color.channel({{ theme_color }}, "hue", $space: hsl), math.div(color.channel({{ theme_color }}, "saturation", $space: hsl), 8), 22.5%)};
{% else %}
--dark-mode-body-bg: #{hsl(hue({{ theme_color }}), calc(saturation({{ theme_color }}) / 8), 17.5%)};
--dark-mode-border-color: #{hsl(hue({{ theme_color }}), calc(saturation({{ theme_color }}) / 8), 22.5%)};
{% endif %}
}

116
_includes/styles/style.scss Normal file
View File

@@ -0,0 +1,116 @@
// Copyright (c) 2019 Florian Klampfer <https://qwtel.com/>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
{% include styles/variables.scss %}
@import "variables";
@import "my-variables";
@import "mixins";
{% if site.pivoine.dark_mode.dynamic %}
@import "pro/dark-mode-dynamic";
{% else %}
@import "pro/dark-mode";
{% endif %}
@import "reboot-mod";
{% unless site.pivoine.no_inline_css or jekyll.environment == 'development' %}
@import "pooleparty/__link__/base";
@import "pooleparty/__link__/type";
@import "pooleparty/__link__/table";
@import "pooleparty/__link__/footer";
@import "pooleparty/__link__/footnotes";
@import "pooleparty/__link__/code";
@import "pooleparty/__link__/posts";
@import "pooleparty/__link__/related";
@import "pooleparty/__link__/read-more";
@import "pooleparty/__link__/message";
@import "pooleparty/__link__/pagination";
@import "pivoine/__link__/base";
@import "pivoine/__link__/utilities";
@import "pivoine/__link__/links";
@import "pivoine/__link__/images";
@import "pivoine/__link__/sidebar";
@import "pivoine/__link__/search";
@import "pivoine/__link__/social";
@import "pivoine/__link__/menu";
@import "pivoine/__link__/toc";
@import "pivoine/__link__/content";
@import "pivoine/__link__/avatar";
@import "pivoine/__link__/katex";
@import "pivoine/__link__/footer";
{% unless site.pivoine.no_mark_external or site.no_mark_external %}
@import "pivoine/__link__/mark-external";
{% endunless %}
{% unless site.pivoine.no_break_layout %}
@import "pivoine/__link__/break-layout";
{% endunless %}
@import "my-style";
{% else %}
@import "html";
@import "pooleparty/_base.pre.scss";
@import "pooleparty/_type.pre.scss";
@import "pooleparty/_table.pre.scss";
@import "pooleparty/_footer.pre.scss";
@import "pooleparty/_footnotes.pre.scss";
@import "pooleparty/_code.pre.scss";
@import "pooleparty/_posts.pre.scss";
@import "pooleparty/_related.pre.scss";
@import "pooleparty/_read-more.pre.scss";
@import "pooleparty/_message.pre.scss";
@import "pooleparty/_pagination.pre.scss";
@import "pivoine/_base.pre.scss";
@import "pivoine/_utilities.pre.scss";
@import "pivoine/_links.pre.scss";
@import "pivoine/_images.pre.scss";
@import "pivoine/_sidebar.pre.scss";
@import "pivoine/_search.pre.scss";
@import "pivoine/_social.pre.scss";
@import "pivoine/_menu.pre.scss";
@import "pivoine/_toc.pre.scss";
@import "pivoine/_content.pre.scss";
@import "pivoine/_avatar.pre.scss";
@import "pivoine/_katex.pre.scss";
@import "pivoine/_footer.pre.scss";
@import "pivoine/_sound.pre.scss";
{% unless site.pivoine.no_mark_external or site.no_mark_external %}
@import "pivoine/_mark-external.pre.scss";
{% endunless %}
{% unless site.pivoine.no_break_layout %}
@import "pivoine/_break-layout.pre.scss";
{% endunless %}
@import "my-inline";
@import "my-style";
{% include styles/common.scss %}
{% endunless %}
@import "spinner";
@import "tippy";
@import "syntax";
@import "pro/syntax-dark";
{% if site.pivoine.dark_mode.dynamic %}
@import "pro/dark-mode-dynamic-syntax";
{% endif %}

View File

@@ -0,0 +1,69 @@
// Copyright (c) 2020 Florian Klampfer <https://qwtel.com/>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// {% assign vars = site.data.variables %}
// {% assign ui_font = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", Arial, sans-serif' %}
// {% assign ui_font_code = 'ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", "Roboto Mono", "Oxygen Mono", "Ubuntu Mono", "Source Code Pro", "Fira Mono", "Droid Sans Mono", "Consolas", "Courier New", monospace' %}
@use "sass:math";
$font-family: {{ vars.font | default:site.font | default:ui_font }};
$font-family-heading: {{ vars.font_heading | default:site.font_heading | default:ui_font }};
$code-font-family: {{ vars.font_code | default:site.font_code | default:ui_font_code }};
$theme-color: {{ vars.theme_color | default:site.theme_color | default:'rgb(8,46,57)' }};
$root-font-size: {{ vars.root_font_size | default:15 }}px;
$root-font-size-medium: {{ vars.root_font_size_medium | default:16 }}px;
$root-font-size-large: {{ vars.root_font_size_large | default:17 }}px;
$root-font-size-print: {{ vars.root_font_size_print | default:8 }}pt;
$root-line-height: {{ vars.root_line_height | default:1.75 }};
$font-weight: {{ vars.font_weight | default:400 }};
$font-weight-bold: {{ vars.font_weight_bold | default:700 }};
$font-weight-heading: {{ vars.font_weight_heading | default:900 }};
$content-width: {{ vars.content_width | default:42 }}rem;
$content-width-2: {{ vars.content_width_2 | default:48 }}rem;
$content-width-5: {{ vars.content_width_5 | default:54 }}rem;
$content-padding: {{ vars.content_padding | default:1 }}rem;
$sidebar-width: {{ vars.sidebar_width | default:21 }}rem;
$break-point-1: {{ vars.break_point_1 | default:42 }}em;
$break-point-2: {{ vars.break_point_2 | default:54 }}em;
$break-point-3: {{ vars.break_point_3 | default:64 }}em;
$break-point-4: {{ vars.break_point_4 | default:72 }}em;
$break-point-5: {{ vars.break_point_5 | default:86 }}em;
$border-radius: {{ vars.border_radius | default:0.5 }}rem;
$break-point-font-large: {{ vars.break_point_font_large | default:124 }}em;
$content-margin-3: 3rem;
$content-margin-5: 4rem;
$gh-pages-compat: {% if site.github and site.pivoine.dart_sass_2_compat != true %}true{% else %}false{% endif %};
// TODO: doc
{% if site.github and site.pivoine.dart_sass_2_compat != true %}
$half-content: (math.div($content-width-5, 2) + $content-margin-5);
{% else %}
$half-content: calc(math.div($content-width-5, 2) + $content-margin-5);
{% endif %}
// The sidebar width starts adjusting dynamically when the content is at the center of the window.
// This is the case when the window size has a `min-width` of content area + twice the sidebar (left, right):
$break-point-dynamic: $content-width-5 + (2 * $content-margin-5) + (2 * $sidebar-width);

View File

@@ -0,0 +1,8 @@
<template id="_animation-template">
<div class="animation-main fixed-top">
{% unless site.pivoine.no_breadcrumbs %}{% include body/breadcrumbs.html url="/" %}{% endunless %}
<div class="content">
<div class="page"></div>
</div>
</div>
</template>

View File

@@ -0,0 +1,6 @@
<template id="_dark-mode-template">
<button id="_dark-mode" class="nav-btn no-hover" >
<span class="sr-only">{{ site.data.strings.dark_mode | default:"Dark Mode" }}</span>
<span class="icon-brightness-contrast"></span>
</button>
</template>

View File

@@ -0,0 +1,10 @@
<template id="_error-template">
<div class="page">
<h1 class="page-title">{{ strings.error.title | default:"Error" }}</h1>
{% capture link %}<a class="this-link" href=""></a>{% endcapture %}
{% assign text = strings.error.message | default:"Sorry, an error occurred while loading: <!--link-->." %}
<p class="lead">
{{ text | replace:"<!--link-->",link }}
</p>
</div>
</template>

View File

@@ -0,0 +1,15 @@
<div hidden>
{% assign strings = site.data.strings %}
<h2 class="sr-only">{{ strings.templates | default: "Templates"}}{{ strings.colon | default:":" }}</h2>
{% include templates/animation.html %}
{% include templates/loading.html %}
{% include templates/error.html %}
{% include templates/permalink.html %}
{% if site.pivoine.dark_mode.icon %}
{% include templates/dark-mode.html %}
{% endif %}
{% if site.pivoine.search.icon %}
{% include templates/search.html %}
{% endif %}
</div>

View File

@@ -0,0 +1,6 @@
<template id="_loading-template">
<div class="loading nav-btn fr">
<span class="sr-only">{{ strings.loading | default:"Loading…" }}</span>
<span class="icon-cog"></span>
</div>
</template>

View File

@@ -0,0 +1,6 @@
<template id="_permalink-template">
<a href="#" class="permalink">
<span class="sr-only">{{ strings.permalink | default:"Permalink" }}</span>
<span class="{{ strings.permalink_icon | default:"content-hash" }}"></span>
</a>
</template>

View File

@@ -0,0 +1,6 @@
<template id="_search-template">
<button id="_search" class="nav-btn no-hover" >
<span class="sr-only">{{ site.data.strings.search | default:"Search" }}</span>
<span class="icon-search"></span>
</button>
</template>