From 16c9d78ae518aebb65c3bca5871b2550bbabca16 Mon Sep 17 00:00:00 2001
From: Alexander Dunkel <13646666+Sieboldianus@users.noreply.github.com>
Date: Sun, 18 Aug 2019 16:27:31 +0200
Subject: [PATCH] Add code copy button to all code fields in the blog (#81)
---
README.md | 2 +
assets/js/code-copy.js | 56 +++++++++++++++++++
assets/scss/style.scss | 31 ++++++++++
exampleSite/config.toml | 2 +
layouts/_default/baseof.html | 13 ++++-
..._d11fe7b62c27961c87ecd0f2490357b9.content} | 6 +-
...e.js_d11fe7b62c27961c87ecd0f2490357b9.json | 1 +
...n.js_d11fe7b62c27961c87ecd0f2490357b9.json | 1 -
...s_c16d144eee185fbddd582cd5e25a4fae.content | 2 +-
...scss_c16d144eee185fbddd582cd5e25a4fae.json | 2 +-
10 files changed, 110 insertions(+), 6 deletions(-)
create mode 100644 assets/js/code-copy.js
rename resources/_gen/assets/js/js/{main.js_d11fe7b62c27961c87ecd0f2490357b9.content => bundle.js_d11fe7b62c27961c87ecd0f2490357b9.content} (63%)
create mode 100755 resources/_gen/assets/js/js/bundle.js_d11fe7b62c27961c87ecd0f2490357b9.json
delete mode 100644 resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.json
mode change 100644 => 100755 resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.content
mode change 100644 => 100755 resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.json
diff --git a/README.md b/README.md
index e1cf944..ba6c3d2 100755
--- a/README.md
+++ b/README.md
@@ -13,6 +13,7 @@ Hermit is a minimal and fast theme for Hugo. It's built for bloggers who want a
* Featured image is supported. It will be displayed as a dimmed background of the page.
* Displays all of your posts on a single page, with one section per year, simple and compact.
* Extremely lightweight and load fast. No third party framework, no unnecessary code.
+* All code fields feature syntax highlighting and a code-copy function
* Responsive & Retina Ready. Scales gracefully from a big screen all the way down to the smallest mobile phone. Assets in vector format ensures that it looks sharp on high-resolution screens.
**[Theme Demo](https://hugo-theme-hermit.netlify.com/)** (uses contents and config from the `exampleSite` folder)
@@ -111,5 +112,6 @@ You can inject any html code to every page's document head or right above the cl
* [normalize.css](https://necolas.github.io/normalize.css/) - [MIT](https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
* [animate.css](https://daneden.github.io/animate.css/) - [MIT](https://github.com/daneden/animate.css/blob/master/LICENSE)
* [feather](https://feathericons.com/) - [MIT](https://github.com/feathericons/feather/blob/master/LICENSE)
+* [code-copy.js](assets/js/code-copy.js) - [Tom Spencer](https://www.fiznool.com/blog/2018/09/14/adding-click-to-copy-buttons-to-a-hugo-powered-blog/)
Thanks!
diff --git a/assets/js/code-copy.js b/assets/js/code-copy.js
new file mode 100644
index 0000000..68036c8
--- /dev/null
+++ b/assets/js/code-copy.js
@@ -0,0 +1,56 @@
+/**
+ * Utils
+ */
+
+// Add code-copy buttons using progressive enhancement
+// © 2019. Tom Spencer
+// https://www.fiznool.com/blog/2018/09/14/adding-click-to-copy-buttons-to-a-hugo-powered-blog/
+(function() {
+ 'use strict';
+
+ if(!document.queryCommandSupported('copy')) {
+ return;
+ }
+
+ function flashCopyMessage(el, msg) {
+ el.textContent = msg;
+ setTimeout(function() {
+ el.textContent = "Copy";
+ }, 1000);
+ }
+
+ function selectText(node) {
+ var selection = window.getSelection();
+ var range = document.createRange();
+ range.selectNodeContents(node);
+ selection.removeAllRanges();
+ selection.addRange(range);
+ return selection;
+ }
+
+ function addCopyButton(containerEl) {
+ var copyBtn = document.createElement("button");
+ copyBtn.className = "highlight-copy-btn";
+ copyBtn.textContent = "Copy";
+
+ var codeEl = containerEl.firstElementChild;
+ copyBtn.addEventListener('click', function() {
+ try {
+ var selection = selectText(codeEl);
+ document.execCommand('copy');
+ selection.removeAllRanges();
+
+ flashCopyMessage(copyBtn, 'Copied!')
+ } catch(e) {
+ console && console.log(e);
+ flashCopyMessage(copyBtn, 'Failed :\'(')
+ }
+ });
+
+ containerEl.appendChild(copyBtn);
+ }
+
+ // Add copy button to code blocks
+ var highlightBlocks = document.getElementsByClassName('highlight');
+ Array.prototype.forEach.call(highlightBlocks, addCopyButton);
+})();
diff --git a/assets/scss/style.scss b/assets/scss/style.scss
index 4476504..51143d4 100644
--- a/assets/scss/style.scss
+++ b/assets/scss/style.scss
@@ -153,6 +153,37 @@ table {
display: none;
}
+// Code copy buttons
+//
+
+.highlight {
+ position: relative;
+}
+
+.highlight pre {
+ padding-right: 75px;
+}
+
+.highlight-copy-btn {
+ position: absolute;
+ bottom: 7px;
+ right: 7px;
+ border: 0;
+ border-radius: 4px;
+ padding: 1px;
+ font-size: 0.7em;
+ line-height: 1.8;
+ color: #fff;
+ background-color: #777;
+ opacity: 0.6;
+ min-width: 55px;
+ text-align: center;
+}
+
+.highlight-copy-btn:hover {
+ background-color: #666;
+}
+
// Accessibility
//
.screen-reader-text {
diff --git a/exampleSite/config.toml b/exampleSite/config.toml
index 3c94862..4e60475 100644
--- a/exampleSite/config.toml
+++ b/exampleSite/config.toml
@@ -48,6 +48,8 @@ enableEmoji = true # Shorthand emojis in content files - https://gohugo.io/func
relatedPosts = false # Add a related content section to all single posts page
+ code_copy_button = true # Turn on/off the code-copy-button for code-fields
+
# Add custom css
# customCSS = ["css/foo.css", "css/bar.css"]
diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html
index cdb9a1f..6d312b6 100644
--- a/layouts/_default/baseof.html
+++ b/layouts/_default/baseof.html
@@ -30,8 +30,17 @@
{{ block "header" . -}}{{ end -}}
{{ block "main" . -}}{{ end -}}
{{ block "footer" . -}}{{ end }}
- {{ $script := resources.Get "js/main.js" | minify | fingerprint -}}
-
+
+ {{ $main := resources.Get "js/main.js" -}}
+ {{ if .Site.Params.code_copy_button | default true -}}
+ {{ $codeCopy := resources.Get "js/code-copy.js" -}}
+ {{ $script := slice $main $codeCopy | resources.Concat "js/bundle.js" | minify | fingerprint -}}
+
+ {{ else -}}
+ {{ $script := $main | minify | fingerprint -}}
+
+ {{ end }}
+
{{- partial "analytics.html" . }}
{{- if templates.Exists "partials/extra-foot.html" -}}
{{ partial "extra-foot.html" . }}
diff --git a/resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.content b/resources/_gen/assets/js/js/bundle.js_d11fe7b62c27961c87ecd0f2490357b9.content
similarity index 63%
rename from resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.content
rename to resources/_gen/assets/js/js/bundle.js_d11fe7b62c27961c87ecd0f2490357b9.content
index cd989df..7137f68 100644
--- a/resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.content
+++ b/resources/_gen/assets/js/js/bundle.js_d11fe7b62c27961c87ecd0f2490357b9.content
@@ -6,4 +6,8 @@ mobileMenuVisible=false;}}
const showImg=()=>{document.querySelector('.bg-img').classList.add('show-bg-img');}
const hideImg=()=>{document.querySelector('.bg-img').classList.remove('show-bg-img');}
const toggleToc=()=>{document.getElementById('toc').classList.toggle('show-toc');}
-if(header!==null){listen('#menu-btn',"click",toggleMobileMenu);listen('#toc-btn',"click",toggleToc);listen('#img-btn',"click",showImg);listen('.bg-img',"click",hideImg);document.querySelectorAll('.post-year').forEach((ele)=>{ele.addEventListener('click',()=>{window.location.hash='#'+ele.id;});});window.addEventListener('scroll',throttle(()=>{autoHideHeader();if(mobileMenuVisible==true){toggleMobileMenu();}},250));}
\ No newline at end of file
+if(header!==null){listen('#menu-btn',"click",toggleMobileMenu);listen('#toc-btn',"click",toggleToc);listen('#img-btn',"click",showImg);listen('.bg-img',"click",hideImg);document.querySelectorAll('.post-year').forEach((ele)=>{ele.addEventListener('click',()=>{window.location.hash='#'+ele.id;});});window.addEventListener('scroll',throttle(()=>{autoHideHeader();if(mobileMenuVisible==true){toggleMobileMenu();}},250));};(function(){'use strict';if(!document.queryCommandSupported('copy')){return;}
+function flashCopyMessage(el,msg){el.textContent=msg;setTimeout(function(){el.textContent="Copy";},1000);}
+function selectText(node){var selection=window.getSelection();var range=document.createRange();range.selectNodeContents(node);selection.removeAllRanges();selection.addRange(range);return selection;}
+function addCopyButton(containerEl){var copyBtn=document.createElement("button");copyBtn.className="highlight-copy-btn";copyBtn.textContent="Copy";var codeEl=containerEl.firstElementChild;copyBtn.addEventListener('click',function(){try{var selection=selectText(codeEl);document.execCommand('copy');selection.removeAllRanges();flashCopyMessage(copyBtn,'Copied!')}catch(e){console&&console.log(e);flashCopyMessage(copyBtn,'Failed :\'(')}});containerEl.appendChild(copyBtn);}
+var highlightBlocks=document.getElementsByClassName('highlight');Array.prototype.forEach.call(highlightBlocks,addCopyButton);})();
\ No newline at end of file
diff --git a/resources/_gen/assets/js/js/bundle.js_d11fe7b62c27961c87ecd0f2490357b9.json b/resources/_gen/assets/js/js/bundle.js_d11fe7b62c27961c87ecd0f2490357b9.json
new file mode 100755
index 0000000..523e6ac
--- /dev/null
+++ b/resources/_gen/assets/js/js/bundle.js_d11fe7b62c27961c87ecd0f2490357b9.json
@@ -0,0 +1 @@
+{"Target":"js/bundle.min.4a9a0ac3d2217822c7865b4161e6c2a71de1d70492264337755427898dd718f6.js","MediaType":"application/javascript","Data":{"Integrity":"sha256-SpoKw9IheCLHhltBYebCpx3h1wSSJkM3dVQniY3XGPY="}}
\ No newline at end of file
diff --git a/resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.json b/resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.json
deleted file mode 100644
index ece2781..0000000
--- a/resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Target":"js/main.min.35ccbf1cdceb91e4c64c06b5d009d6e2977fafe56beda7762febd4e67528d2ac.js","MediaType":"application/javascript","Data":{"Integrity":"sha256-Ncy/HNzrkeTGTAa10AnW4pd/r+Vr7ad2L+vU5nUo0qw="}}
\ No newline at end of file
diff --git a/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.content b/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.content
old mode 100644
new mode 100755
index 4ad7f30..475f72e
--- a/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.content
+++ b/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.content
@@ -2,4 +2,4 @@
* Version - 3.7.0
* Licensed under the MIT license - http://opensource.org/licenses/MIT
*
-* Copyright (c) 2019 Daniel Eden*/@-webkit-keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(0.215,0.61,0.355,1);animation-timing-function:cubic-bezier(0.215,0.61,0.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(0.215,0.61,0.355,1);animation-timing-function:cubic-bezier(0.215,0.61,0.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.delay-1s{-webkit-animation-delay:1s;animation-delay:1s}.animated.delay-2s{-webkit-animation-delay:2s;animation-delay:2s}.animated.delay-3s{-webkit-animation-delay:3s;animation-delay:3s}.animated.delay-4s{-webkit-animation-delay:4s;animation-delay:4s}.animated.delay-5s{-webkit-animation-delay:5s;animation-delay:5s}.animated.fast{-webkit-animation-duration:.8s;animation-duration:.8s}.animated.faster{-webkit-animation-duration:.5s;animation-duration:.5s}.animated.slow{-webkit-animation-duration:2s;animation-duration:2s}.animated.slower{-webkit-animation-duration:3s;animation-duration:3s}@media(prefers-reduced-motion),(print){.animated{-webkit-animation:unset!important;animation:unset!important;-webkit-transition:none!important;transition:none!important}}::-webkit-scrollbar{width:8px;height:8px;background:#2c3e50}::-webkit-scrollbar-thumb{background:#888}::-webkit-scrollbar-thumb:hover{background:#e8eef2}html{background:#494f5c;line-height:1.6;letter-spacing:.06em;scroll-behavior:smooth}body,button,input,select,textarea{color:#e8eef2;font-family:trebuchet ms,Verdana,verdana ref,segoe ui,Candara,lucida grande,lucida sans unicode,lucida sans,Tahoma,sans-serif}pre,code,pre tt{font-family:Consolas,andale mono wt,andale mono,Menlo,Monaco,lucida console,lucida sans typewriter,dejavu sans mono,bitstream vera sans mono,liberation mono,nimbus mono l,courier new,Courier,yahei consolas hybrid,monospace,segoe ui emoji,pingfang sc,microsoft yahei}pre{padding:.7em 1.1em;overflow:auto;font-size:.9em;line-height:1.5;letter-spacing:normal;white-space:pre;color:#eee;background:#2c3e50;border-radius:4px}pre code{padding:0;margin:0;background:#2c3e50}code{color:#eee;background:#7d828a;border-radius:3px;padding:0 3px;margin:0 4px;word-wrap:break-word;letter-spacing:normal}blockquote{border-left:.25em solid;margin:1em;padding:0 1em;font-style:italic}blockquote cite{font-weight:700;font-style:normal}blockquote cite::before{content:"—— "}a{color:#e8eef2;text-decoration:none;border:none;transition-property:color;transition-duration:.4s;transition-timing-function:ease-out}a:hover{color:#fff;text-shadow:0 0 1px #fff}hr{opacity:.2;border-width:0 0 5px;border-style:dashed;background:transparent;width:50%;margin:1.8em auto}table{border-collapse:collapse;border-spacing:0;empty-cells:show;width:100%;max-width:100%}table th,table td{padding:1.5%;border:1px solid}table th{font-weight:700;vertical-align:bottom}.section-inner{margin:0 auto;max-width:1200px;width:93%}.thin{max-width:720px;margin:auto}.feather{display:inline-block;vertical-align:-.125em;width:1em;height:1em}.sub-menu{font-size:.7em}.desktop-only,.desktop-only-ib{display:none}.screen-reader-text{border:0;clip:rect(1px,1px,1px,1px);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute!important;width:1px;word-wrap:normal!important}.screen-reader-text:focus{background-color:#f1f1f1;border-radius:3px;box-shadow:0 0 2px 2px rgba(0,0,0,.6);clip:auto!important;clip-path:none;color:#21759b;display:block;font-size:14px;font-size:.875rem;font-weight:700;height:auto;left:5px;line-height:normal;padding:15px 23px 14px;text-decoration:none;top:5px;width:auto;z-index:100000}#site-header{position:fixed;z-index:1;bottom:0;width:100%;box-sizing:border-box;box-shadow:-1px -2px 3px rgba(0,0,0,.45);background-color:#3b3e48}.hdr-wrapper{display:flex;justify-content:space-between;align-items:center;padding:.5em 0;font-size:1.2rem}.hdr-wrapper .site-branding{display:inline-block;margin-right:.8em;font-size:1.2em}.hdr-wrapper .site-nav{display:inline-block;font-size:1.1em;opacity:.8}.hdr-wrapper .site-nav .has-children{padding-right:.5em;border-right:2px solid #7d828a}.hdr-wrapper .site-nav .sub-menu>a{margin-left:.3em}.hdr-wrapper .site-nav a{margin-left:.8em}.hdr-icons{font-size:1.2em}.hdr-social{display:inline-block;margin-left:.6em}.hdr-social>a{margin-left:.4em}.hdr-btn{border:none;background:0 0;padding:0;margin-left:.4em;cursor:pointer}#menu-btn{display:none;margin-left:.6em;cursor:pointer}#mobile-menu{position:fixed;bottom:4.8em;right:1.5em;display:none;padding:.6em 1.8em;z-index:1;box-sizing:border-box;box-shadow:-1px -2px 3px 0 rgba(0,0,0,.45);background-color:#3b3e48}#mobile-menu ul{list-style:none;margin:0;padding:0;line-height:2;font-size:1.2em}#site-footer{text-align:center;font-size:.9em;margin-bottom:96px;margin-top:64px}#site-footer p{margin:0}#spotlight{display:flex;height:100vh;flex-direction:column;align-items:center;justify-content:center;max-width:93%;margin:auto;font-size:1.5rem}#spotlight.error-404{flex-direction:row;line-height:normal}p.img-404{margin:0}p.img-404 svg{width:180px;max-width:100%;height:auto}.banner-404{margin-left:2em}.banner-404 h1{font-size:3em;margin:.5rem 0}.banner-404 p{margin-top:0}.banner-404 .btn-404{font-size:.8em}.banner-404 .btn-404 a{display:inline-block;border:2px solid #e8eef2;border-radius:5px;padding:5px;transition-property:color,border-color}.banner-404 .btn-404 a:first-child{margin-right:1em}.banner-404 .btn-404 a:hover{border-color:#fff}.banner-404 .btn-404 a svg{margin-right:.5em}#home-center{display:flex;flex-grow:1;flex-direction:column;justify-content:center}#home-title{margin:0;text-align:center}#home-subtitle{margin-top:0;margin-bottom:1.5em;text-align:center;line-height:normal;font-size:.7em;font-style:italic;opacity:.9}#home-social{font-size:1.4em;text-align:center;opacity:.8}#home-social a{margin:0 .2em}#home-nav{opacity:.8}#home-nav a{display:block;text-align:center;margin-top:.5em}#home-footer{text-align:center;font-size:.6em;line-height:normal;opacity:.6}#home-footer p{margin-top:0}.posts-group{display:flex;margin-bottom:1.9em;line-height:normal}.posts-group .post-year{padding-top:6px;margin-right:1.8em;font-size:1.6em;opacity:.6}.posts-group .post-year:hover{text-decoration:underline;cursor:pointer}.posts-group .posts-list{flex-grow:1;margin:0;padding:0;list-style:none}.posts-group .post-item{border-bottom:1px #7d828a dashed}.posts-group .post-item a{display:flex;justify-content:space-between;align-items:baseline;padding:12px 0}.posts-group .post-day{flex-shrink:0;margin-left:1em;opacity:.6}.bg-img{width:100vw;height:100vh;opacity:.03;z-index:-1;position:fixed;top:0;background-attachment:fixed;background-repeat:no-repeat;background-size:cover;background-position:50%;transition:opacity .5s}.show-bg-img{z-index:100;opacity:1;cursor:pointer}.post-header{margin-top:1.2em;line-height:normal}.post-header .post-meta{font-size:.9em;letter-spacing:normal;opacity:.6}.post-header h1{margin-top:.1em}hr.post-end{width:50%;margin-top:1.6em;margin-bottom:.8em;margin-left:0;border-style:solid;border-bottom-width:4px}.content a{word-wrap:break-word;border:none;box-shadow:inset 0 -4px 0 #018574;transition-property:box-shadow;transition-duration:.1s}.content a:hover{box-shadow:inset 0 -1em 0 #018574}.content figure{max-width:100%;height:auto;margin:0;text-align:center}.content figure p{font-size:.8em;font-style:italic;opacity:.6}.content figure.left{float:left;margin-right:1.5em;max-width:50%}.content figure.right{float:right;margin-left:1.5em;max-width:50%}.content figure.big{max-width:100vw}.content img{display:block;max-width:100%;height:auto;margin:auto;border-radius:4px}.content ul,.content ol{padding:0;margin-left:1.8em}.content a.anchor{float:left;margin-left:-20px;padding-right:6px;box-shadow:none;opacity:.8}.content a.anchor:hover{background:0 0;color:#018574;opacity:1}.content a.anchor svg{display:inline-block;width:14px;height:14px;vertical-align:baseline;visibility:hidden}.content a.anchor:focus svg{visibility:visible}.content h1:hover a.anchor svg,.content h2:hover a.anchor svg,.content h3:hover a.anchor svg,.content h4:hover a.anchor svg,.content h5:hover a.anchor svg,.content h6:hover a.anchor svg{visibility:visible}.footnotes{font-size:.85em}.footnotes a{box-shadow:none;text-decoration:underline;transition-property:color}.footnotes a:hover{background:transparent}.footnotes a.footnote-return{text-decoration:none}.footnotes ol{line-height:1.8}.footnote-ref a{box-shadow:none;text-decoration:none;padding:2px;border-radius:2px;background-color:#2c3e50}.post-info{font-size:.8rem;line-height:normal;opacity:.6}.post-info p{margin:.8em 0}.post-info a:hover{border-bottom:1px solid #018574}.post-info svg{margin-right:.8em}.post-info .tag{margin-right:.5em}.post-info .tag::before{content:"#"}#toc{position:fixed;left:50%;top:0;display:none}.toc-title{margin-left:1em;margin-bottom:.5em;font-size:.8em;font-weight:700}#TableOfContents{font-size:.8em;opacity:.6}#TableOfContents ul{padding-left:1em;margin:0}#TableOfContents>ul{list-style-type:none}#TableOfContents>ul ul ul{font-size:.9em}#TableOfContents a:hover{border-bottom:#018574 1px solid}.post-nav{display:flex;justify-content:space-between;margin-top:1.5em;margin-bottom:2.5em;font-size:1.2em}.post-nav a{flex-basis:50%;flex-grow:1}.post-nav .next-post{text-align:left;padding-right:5px}.post-nav .prev-post{text-align:right;padding-left:5px}.post-nav .post-nav-label{font-size:.8em;opacity:.8;text-transform:uppercase}.related-posts{padding:.8em;margin-top:1.5em;font-size:.8rem;border:3px dashed rgba(255,255,255,.2);border-radius:5px}.related-posts h2{margin:0;line-height:normal}.related-posts ul{margin-top:.5em;margin-bottom:0}@media(min-width:800px){.site-main{margin-top:3em}hr.post-end{width:40%}}@media(min-width:960px){.site-main{margin-top:6em}}@media(min-width:1300px){.site-main{margin-top:8em}.desktop-only,#toc.show-toc{display:block}.desktop-only-ib{display:inline-block}figure.left{margin-left:-240px}figure.left p{text-align:left}figure.right{margin-right:-240px}figure.right p{text-align:right}figure.big{width:1200px;margin-left:-240px}hr.post-end{width:30%}#toc{top:13em;margin-left:370px;max-width:220px}}@media(min-width:1800px){.site-main{margin-top:10em}.section-inner{max-width:1600px}.thin{max-width:960px}figure.left{max-width:75%;margin-left:-320px}figure.right{max-width:75%;margin-right:-320px}figure.big{width:1600px;margin-left:-320px}hr.post-end{width:30%}#toc{top:15em;margin-left:490px;max-width:300px}}@media(max-width:760px){.hide-in-mobile,.site-nav.hide-in-mobile{display:none}#menu-btn{display:inline-block}.posts-group{display:block}.posts-group .post-year{margin:-6px 0 4px}#spotlight.error-404{flex-direction:column;text-align:center}#spotlight.error-404 .banner-404{margin:0}}@media(max-width:520px){.content figure.left,.content figure.right{float:unset;max-width:100%;margin:0}hr.post-end{width:60%}#mobile-menu{right:1.2em}}
\ No newline at end of file
+* Copyright (c) 2019 Daniel Eden*/@-webkit-keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(0.215,0.61,0.355,1);animation-timing-function:cubic-bezier(0.215,0.61,0.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(0.215,0.61,0.355,1);animation-timing-function:cubic-bezier(0.215,0.61,0.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.delay-1s{-webkit-animation-delay:1s;animation-delay:1s}.animated.delay-2s{-webkit-animation-delay:2s;animation-delay:2s}.animated.delay-3s{-webkit-animation-delay:3s;animation-delay:3s}.animated.delay-4s{-webkit-animation-delay:4s;animation-delay:4s}.animated.delay-5s{-webkit-animation-delay:5s;animation-delay:5s}.animated.fast{-webkit-animation-duration:.8s;animation-duration:.8s}.animated.faster{-webkit-animation-duration:.5s;animation-duration:.5s}.animated.slow{-webkit-animation-duration:2s;animation-duration:2s}.animated.slower{-webkit-animation-duration:3s;animation-duration:3s}@media(prefers-reduced-motion),(print){.animated{-webkit-animation:unset!important;animation:unset!important;-webkit-transition:none!important;transition:none!important}}::-webkit-scrollbar{width:8px;height:8px;background:#2c3e50}::-webkit-scrollbar-thumb{background:#888}::-webkit-scrollbar-thumb:hover{background:#e8eef2}html{background:#494f5c;line-height:1.6;letter-spacing:.06em;scroll-behavior:smooth}body,button,input,select,textarea{color:#e8eef2;font-family:trebuchet ms,Verdana,verdana ref,segoe ui,Candara,lucida grande,lucida sans unicode,lucida sans,Tahoma,sans-serif}pre,code,pre tt{font-family:Consolas,andale mono wt,andale mono,Menlo,Monaco,lucida console,lucida sans typewriter,dejavu sans mono,bitstream vera sans mono,liberation mono,nimbus mono l,courier new,Courier,yahei consolas hybrid,monospace,segoe ui emoji,pingfang sc,microsoft yahei}pre{padding:.7em 1.1em;overflow:auto;font-size:.9em;line-height:1.5;letter-spacing:normal;white-space:pre;color:#eee;background:#2c3e50;border-radius:4px}pre code{padding:0;margin:0;background:#2c3e50}code{color:#eee;background:#7d828a;border-radius:3px;padding:0 3px;margin:0 4px;word-wrap:break-word;letter-spacing:normal}blockquote{border-left:.25em solid;margin:1em;padding:0 1em;font-style:italic}blockquote cite{font-weight:700;font-style:normal}blockquote cite::before{content:"—— "}a{color:#e8eef2;text-decoration:none;border:none;transition-property:color;transition-duration:.4s;transition-timing-function:ease-out}a:hover{color:#fff;text-shadow:0 0 1px #fff}hr{opacity:.2;border-width:0 0 5px;border-style:dashed;background:transparent;width:50%;margin:1.8em auto}table{border-collapse:collapse;border-spacing:0;empty-cells:show;width:100%;max-width:100%}table th,table td{padding:1.5%;border:1px solid}table th{font-weight:700;vertical-align:bottom}.section-inner{margin:0 auto;max-width:1200px;width:93%}.thin{max-width:720px;margin:auto}.feather{display:inline-block;vertical-align:-.125em;width:1em;height:1em}.sub-menu{font-size:.7em}.desktop-only,.desktop-only-ib{display:none}.highlight{position:relative}.highlight pre{padding-right:75px}.highlight-copy-btn{position:absolute;bottom:7px;right:7px;border:0;border-radius:4px;padding:1px;font-size:.7em;line-height:1.8;color:#fff;background-color:#777;opacity:.6;min-width:55px;text-align:center}.highlight-copy-btn:hover{background-color:#666}.screen-reader-text{border:0;clip:rect(1px,1px,1px,1px);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute!important;width:1px;word-wrap:normal!important}.screen-reader-text:focus{background-color:#f1f1f1;border-radius:3px;box-shadow:0 0 2px 2px rgba(0,0,0,.6);clip:auto!important;clip-path:none;color:#21759b;display:block;font-size:14px;font-size:.875rem;font-weight:700;height:auto;left:5px;line-height:normal;padding:15px 23px 14px;text-decoration:none;top:5px;width:auto;z-index:100000}#site-header{position:fixed;z-index:1;bottom:0;width:100%;box-sizing:border-box;box-shadow:-1px -2px 3px rgba(0,0,0,.45);background-color:#3b3e48}.hdr-wrapper{display:flex;justify-content:space-between;align-items:center;padding:.5em 0;font-size:1.2rem}.hdr-wrapper .site-branding{display:inline-block;margin-right:.8em;font-size:1.2em}.hdr-wrapper .site-nav{display:inline-block;font-size:1.1em;opacity:.8}.hdr-wrapper .site-nav .has-children{padding-right:.5em;border-right:2px solid #7d828a}.hdr-wrapper .site-nav .sub-menu>a{margin-left:.3em}.hdr-wrapper .site-nav a{margin-left:.8em}.hdr-icons{font-size:1.2em}.hdr-social{display:inline-block;margin-left:.6em}.hdr-social>a{margin-left:.4em}.hdr-btn{border:none;background:0 0;padding:0;margin-left:.4em;cursor:pointer}#menu-btn{display:none;margin-left:.6em;cursor:pointer}#mobile-menu{position:fixed;bottom:4.8em;right:1.5em;display:none;padding:.6em 1.8em;z-index:1;box-sizing:border-box;box-shadow:-1px -2px 3px 0 rgba(0,0,0,.45);background-color:#3b3e48}#mobile-menu ul{list-style:none;margin:0;padding:0;line-height:2;font-size:1.2em}#site-footer{text-align:center;font-size:.9em;margin-bottom:96px;margin-top:64px}#site-footer p{margin:0}#spotlight{display:flex;height:100vh;flex-direction:column;align-items:center;justify-content:center;max-width:93%;margin:auto;font-size:1.5rem}#spotlight.error-404{flex-direction:row;line-height:normal}p.img-404{margin:0}p.img-404 svg{width:180px;max-width:100%;height:auto}.banner-404{margin-left:2em}.banner-404 h1{font-size:3em;margin:.5rem 0}.banner-404 p{margin-top:0}.banner-404 .btn-404{font-size:.8em}.banner-404 .btn-404 a{display:inline-block;border:2px solid #e8eef2;border-radius:5px;padding:5px;transition-property:color,border-color}.banner-404 .btn-404 a:first-child{margin-right:1em}.banner-404 .btn-404 a:hover{border-color:#fff}.banner-404 .btn-404 a svg{margin-right:.5em}#home-center{display:flex;flex-grow:1;flex-direction:column;justify-content:center}#home-title{margin:0;text-align:center}#home-subtitle{margin-top:0;margin-bottom:1.5em;text-align:center;line-height:normal;font-size:.7em;font-style:italic;opacity:.9}#home-social{font-size:1.4em;text-align:center;opacity:.8}#home-social a{margin:0 .2em}#home-nav{opacity:.8}#home-nav a{display:block;text-align:center;margin-top:.5em}#home-footer{text-align:center;font-size:.6em;line-height:normal;opacity:.6}#home-footer p{margin-top:0}.posts-group{display:flex;margin-bottom:1.9em;line-height:normal}.posts-group .post-year{padding-top:6px;margin-right:1.8em;font-size:1.6em;opacity:.6}.posts-group .post-year:hover{text-decoration:underline;cursor:pointer}.posts-group .posts-list{flex-grow:1;margin:0;padding:0;list-style:none}.posts-group .post-item{border-bottom:1px #7d828a dashed}.posts-group .post-item a{display:flex;justify-content:space-between;align-items:baseline;padding:12px 0}.posts-group .post-day{flex-shrink:0;margin-left:1em;opacity:.6}.bg-img{width:100vw;height:100vh;opacity:.03;z-index:-1;position:fixed;top:0;background-attachment:fixed;background-repeat:no-repeat;background-size:cover;background-position:50%;transition:opacity .5s}.show-bg-img{z-index:100;opacity:1;cursor:pointer}.post-header{margin-top:1.2em;line-height:normal}.post-header .post-meta{font-size:.9em;letter-spacing:normal;opacity:.6}.post-header h1{margin-top:.1em}hr.post-end{width:50%;margin-top:1.6em;margin-bottom:.8em;margin-left:0;border-style:solid;border-bottom-width:4px}.content a{word-wrap:break-word;border:none;box-shadow:inset 0 -4px 0 #018574;transition-property:box-shadow;transition-duration:.1s}.content a:hover{box-shadow:inset 0 -1em 0 #018574}.content figure{max-width:100%;height:auto;margin:0;text-align:center}.content figure p{font-size:.8em;font-style:italic;opacity:.6}.content figure.left{float:left;margin-right:1.5em;max-width:50%}.content figure.right{float:right;margin-left:1.5em;max-width:50%}.content figure.big{max-width:100vw}.content img{display:block;max-width:100%;height:auto;margin:auto;border-radius:4px}.content ul,.content ol{padding:0;margin-left:1.8em}.content a.anchor{float:left;margin-left:-20px;padding-right:6px;box-shadow:none;opacity:.8}.content a.anchor:hover{background:0 0;color:#018574;opacity:1}.content a.anchor svg{display:inline-block;width:14px;height:14px;vertical-align:baseline;visibility:hidden}.content a.anchor:focus svg{visibility:visible}.content h1:hover a.anchor svg,.content h2:hover a.anchor svg,.content h3:hover a.anchor svg,.content h4:hover a.anchor svg,.content h5:hover a.anchor svg,.content h6:hover a.anchor svg{visibility:visible}.footnotes{font-size:.85em}.footnotes a{box-shadow:none;text-decoration:underline;transition-property:color}.footnotes a:hover{background:transparent}.footnotes a.footnote-return{text-decoration:none}.footnotes ol{line-height:1.8}.footnote-ref a{box-shadow:none;text-decoration:none;padding:2px;border-radius:2px;background-color:#2c3e50}.post-info{font-size:.8rem;line-height:normal;opacity:.6}.post-info p{margin:.8em 0}.post-info a:hover{border-bottom:1px solid #018574}.post-info svg{margin-right:.8em}.post-info .tag{margin-right:.5em}.post-info .tag::before{content:"#"}#toc{position:fixed;left:50%;top:0;display:none}.toc-title{margin-left:1em;margin-bottom:.5em;font-size:.8em;font-weight:700}#TableOfContents{font-size:.8em;opacity:.6}#TableOfContents ul{padding-left:1em;margin:0}#TableOfContents>ul{list-style-type:none}#TableOfContents>ul ul ul{font-size:.9em}#TableOfContents a:hover{border-bottom:#018574 1px solid}.post-nav{display:flex;justify-content:space-between;margin-top:1.5em;margin-bottom:2.5em;font-size:1.2em}.post-nav a{flex-basis:50%;flex-grow:1}.post-nav .next-post{text-align:left;padding-right:5px}.post-nav .prev-post{text-align:right;padding-left:5px}.post-nav .post-nav-label{font-size:.8em;opacity:.8;text-transform:uppercase}.related-posts{padding:.8em;margin-top:1.5em;font-size:.8rem;border:3px dashed rgba(255,255,255,.2);border-radius:5px}.related-posts h2{margin:0;line-height:normal}.related-posts ul{margin-top:.5em;margin-bottom:0}@media(min-width:800px){.site-main{margin-top:3em}hr.post-end{width:40%}}@media(min-width:960px){.site-main{margin-top:6em}}@media(min-width:1300px){.site-main{margin-top:8em}.desktop-only,#toc.show-toc{display:block}.desktop-only-ib{display:inline-block}figure.left{margin-left:-240px}figure.left p{text-align:left}figure.right{margin-right:-240px}figure.right p{text-align:right}figure.big{width:1200px;margin-left:-240px}hr.post-end{width:30%}#toc{top:13em;margin-left:370px;max-width:220px}}@media(min-width:1800px){.site-main{margin-top:10em}.section-inner{max-width:1600px}.thin{max-width:960px}figure.left{max-width:75%;margin-left:-320px}figure.right{max-width:75%;margin-right:-320px}figure.big{width:1600px;margin-left:-320px}hr.post-end{width:30%}#toc{top:15em;margin-left:490px;max-width:300px}}@media(max-width:760px){.hide-in-mobile,.site-nav.hide-in-mobile{display:none}#menu-btn{display:inline-block}.posts-group{display:block}.posts-group .post-year{margin:-6px 0 4px}#spotlight.error-404{flex-direction:column;text-align:center}#spotlight.error-404 .banner-404{margin:0}}@media(max-width:520px){.content figure.left,.content figure.right{float:unset;max-width:100%;margin:0}hr.post-end{width:60%}#mobile-menu{right:1.2em}}
\ No newline at end of file
diff --git a/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.json b/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.json
old mode 100644
new mode 100755
index 982ade6..1b63b4f
--- a/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.json
+++ b/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.json
@@ -1 +1 @@
-{"Target":"css/style.min.568c54a56780af2a70c45272522247710b69dbfc080b315211fb98381e3796f8.css","MediaType":"text/css","Data":{"Integrity":"sha256-VoxUpWeArypwxFJyUiJHcQtp2/wICzFSEfuYOB43lvg="}}
\ No newline at end of file
+{"Target":"css/style.min.5ee5e7976cd09872c64e40a582206543f6aa38c69a8c43898aadc70040344b92.css","MediaType":"text/css","Data":{"Integrity":"sha256-XuXnl2zQmHLGTkClgiBlQ/aqOMaajEOJiq3HAEA0S5I="}}
\ No newline at end of file