diff --git a/assets/ButtonBadges.toml b/assets/ButtonBadges.toml
index 4e73971..f9865dc 100644
--- a/assets/ButtonBadges.toml
+++ b/assets/ButtonBadges.toml
@@ -1,36 +1,168 @@
-[[site]]
+[[10-site]]
+[10-site.title]
+en = "About this site"
+it = "Riguardo questo sito"
+
+[[20-me]]
+[20-me.title]
+en = "Myself and my essence"
+it = "Io e la mia essenza"
+
+[[30-thanks]]
+[30-thanks.title]
+en = "Made thanks to"
+it = "Fatto grazie a"
+
+#[[40-spam]]
+#[40-spam.title]
+#en = "Interesting"
+#it = "D'interesse"
+
+[[50-fun]]
+[50-fun.title]
+en = "Other things"
+it = "Altre cose"
+
+#######################################
+
+[[10-site]]
alt = "CC BY-SA"
file = "CC-BY-SA.svg"
href = "https://creativecommons.org/licenses/by-sa/4.0/deed.it?ref=chooser-v1&title=%E2%9C%A8sitoctt%E2%9C%A8&href=https://sitoctt.octt.eu.org&creator=OctoSpacc"
-[[site]]
+[[10-site]]
alt = "✨sitoctt"
file = "Sites/sitoctt-1.png"
href = "/it/miscellanea/Raccolta-Siti-Internet/#il-mio"
-[[site]]
+[[10-site]]
alt = "Warning: Page contains JavaScript!"
file = "Warning-Page-contains-JavaScript.png"
-[[site]]
+[[10-site]]
alt = "Best viewed with any browser"
file = "BEST-viewed-with-ANY-BROWSER.gif"
-[[site]]
+[[10-site]]
alt = "Mobile-Friendly"
file = "MOBILE-FRIENDLY.png"
-[[site]]
+[[10-site]]
alt = "This site is Miku-approved"
file = "this-site-is-MIKU-APPROVED.gif"
-[[site]]
+[[10-site]]
alt = "Not secure (HTTP) version"
file = "Not-secure-defcon1.gif"
href = "http://http.sitoctt.octt.eu.org"
-[[site]]
+[[10-site]]
alt = "Download Offline Version"
file = "OFF-LINE-VERSION.png"
href = "https://github.com/octospacc/sitoctt/archive/refs/heads/gh-pages.zip"
+#######################################
+
+[[20-me]]
+alt = "Follow me on Mastodon"
+file = "Follow-me-on-mastodon.png"
+href = "https://mastodon.uno/@octo"
+rel = "me"
+
+[[20-me]]
+alt = "Bandiera Octt"
+file = "Octt-Flag.png"
+
+[[20-me]]
+alt = "Rainbow"
+file = "rainbow_bev.png"
+href = "https://en.wikipedia.org/wiki/Refraction"
+spam = true
+
+# Source: https://astral.town | License: Unknown
+[[20-me]]
+alt = "Occhi blink blink"
+src = "@/Media/Blink-0.gif"
+
+[[20-me]]
+alt = "I wear cute socks!"
+file = "I-wear-cute-socks.gif"
+
+[[20-me]]
+alt = "nya~"
+file = "nya.png"
+
+[[20-me]]
+alt = "Hello Kitty"
+file = "HELLO-Kitty.gif"
+href = "https://www.sanrio.com"
+spam = true
+
+[[20-me]]
+alt = "Girl rot"
+file = "GRL-ROT.gif"
+
+[[20-me]]
+alt = "Cyber rot"
+file = "CYBER-ROT.gif"
+
+[[20-me]]
+alt = "Girls for Notepad"
+file = "girls-4-notepad.gif"
+
+[[20-me]]
+alt = "Perfect Soldier"
+file = "Perfect-Soldier.gif"
+
+[[20-me]]
+alt = "I like computer"
+file = "I-LIKE-COMPUTER.png"
+
+#######################################
+
+[[30-thanks]]
+alt = "Made with Hugo"
+file = "HUGO.webp"
+href = "https://gohugo.io"
+spam = true
+
+[[30-thanks]]
+alt = "Made with CSS"
+file = "MADE-WITH-CASCADING-STYLE-SHEETS-cyan.png"
+href = "https://developer.mozilla.org/en-US/docs/Web/CSS"
+spam = true
+
+[[30-thanks]]
+alt = "Made on GNU/Linux"
+file = "Made-on-GNU-Linux.png"
+href = "https://www.gnu.org/home.it"
+spam = true
+
+[[30-thanks]]
+alt = "Made with Notepad++"
+file = "Made-with-Notepad++.png"
+href = "https://notepad-plus-plus.org"
+spam = true
+
+[[30-thanks]]
+alt = "Made with Microsoft Notepad"
+file = "Powered-by-Microsoft-Notepad.gif"
+
+[[30-thanks]]
+alt = "Graphics by GIMP"
+file = "Graphics-by-Gimp.png"
+href = "https://www.gimp.org"
+spam = true
+
+[[30-thanks]]
+alt = "Fueled by Coffee"
+file = "Fueled-by-COFFEE.gif"
+
+[[30-thanks]]
+alt = "Powered by THE VOID"
+file = "Powered-by-THE-VOID.png"
+
+[[30-thanks]]
+alt = "Powered by Bob"
+file = "POWERED-BY-bob.gif"
+
diff --git a/content/it/miscellanea/Raccolta-Siti-Internet.md b/content/it/miscellanea/Raccolta-Siti-Internet.md
index 7fec8f6..a7262ad 100644
--- a/content/it/miscellanea/Raccolta-Siti-Internet.md
+++ b/content/it/miscellanea/Raccolta-Siti-Internet.md
@@ -64,7 +64,7 @@ _L'immagine è in formato PNG e già compressa il più possibile.[^Comandi di Co
Come si può leggere dal nome del sito e dal dominio, è il sito di Arci (o anche Aurora). Lo ha messo in piedi oggi (2022-06-30), dopo che ha detto di non sapere cosa fare con tutto il tempo libero estivo, e io le ho detto "fai l'Arcisito".
• Clearweb: [arci.me](https://arci.me)
-- **🇬🇧️ Gianmarco Gargiulo**
+- **🇬🇧️ 🇮🇹️ Gianmarco Gargiulo**
![serimemo]({{< assetsRoot >}}/Media/Buttons/88x31/Sites/gianmarco.gg-gmgpin.gif)
Sito con layout moderno, ma design decisamente creativo, con un lato artistico ben espresso nelle illustrazioni. La home page funge da lista dell'archivio dei contenuti, e i tipi diversi vengono illustrati con il formato più appropriato. Molto incentrato su Linux e il software libero, ma i disegni e le foto fanno una bella figura.
• Clearweb: [gianmarco.gg](https://gianmarco.gg)
diff --git a/hugo.toml b/hugo.toml
index c14a1cc..4b86928 100644
--- a/hugo.toml
+++ b/hugo.toml
@@ -47,7 +47,17 @@ defaultContentLanguageInSubdir = true
favicon = "/favicon.ico"
author = "OctoSpacc"
recent_posts_number = 5
- other_posts_number = 6
+ other_posts_number = 5
toc = true
show_reading_time = true
#custom_css = [ "Global.scss", "sitoctt.scss" ]
+
+[outputFormats]
+ [outputFormats.SearchIndex]
+ mediaType = "text/javascript"
+ baseName = "searchindex"
+ isPlainText = true
+
+[outputs]
+ home = [ "HTML", "SearchIndex" ]
+
diff --git a/i18n/en.toml b/i18n/en.toml
index 7589bec..da392f6 100644
--- a/i18n/en.toml
+++ b/i18n/en.toml
@@ -3,3 +3,9 @@ other = "The content of this page has been entirely machine-translated into Engl
[notes-refs]
other = "🏷️ Notes and References"
+
+[search]
+other = "Search"
+
+[searchNoJs]
+other = "No-JS Search"
diff --git a/i18n/it.toml b/i18n/it.toml
index 1219b49..72b3535 100644
--- a/i18n/it.toml
+++ b/i18n/it.toml
@@ -3,3 +3,9 @@ other = "Il contenuto di questa pagina è stato interamente tradotto a macchina
[notes-refs]
other = "🏷️ Note e Riferimenti"
+
+[search]
+other = "Cerca"
+
+[searchNoJs]
+other = "Ricerca No-JS"
diff --git a/layouts/index.searchindex.js b/layouts/index.searchindex.js
new file mode 100644
index 0000000..1f9c885
--- /dev/null
+++ b/layouts/index.searchindex.js
@@ -0,0 +1,28 @@
+{{- $index := slice -}}
+{{- $pages := .Site.Pages -}}
+{{- range $pages -}}
+ {{- $section := .Site.GetPage "section" .Section -}}
+ {{- if .Date -}}
+ {{- $index = $index | append (dict
+ "date" (.Date | time.Format (.Site.Language.Params.dateFormat | default ":date_long"))
+ "title" (.Title | emojify | safeJS)
+ "section" ($section.Title | emojify | safeJS)
+ "summary" (.Summary | safeJS)
+ "content" (.Plain | safeJS)
+ "permalink" .RelPermalink
+ "externalUrl" .Params.externalUrl
+ "type" .Type
+ ) -}}
+ {{- else -}}
+ {{- $index = $index | append (dict
+ "title" (.Title | emojify | safeJS)
+ "section" ($section.Title | emojify | safeJS)
+ "summary" (.Summary | safeJS)
+ "content" (.Plain | safeJS)
+ "permalink" .RelPermalink
+ "externalUrl" .Params.externalUrl
+ "type" .Type
+ ) -}}
+ {{- end -}}
+{{- end -}}
+window.SiteSearchIndex={{- $index | jsonify -}}
diff --git a/layouts/partials/comments.html b/layouts/partials/comments.html
index 3be6830..dd3114a 100644
--- a/layouts/partials/comments.html
+++ b/layouts/partials/comments.html
@@ -1,15 +1,25 @@
+{{ $repo := "octospacc/sitoctt" }}
+{{ $repoId := "R_kgDOHbCR4A" }}
+{{ $category := "Comments" }}
+{{ $categoryId := "DIC_kwDOHbCR4M4CiAIZ" }}
+{{ $theme := "noborder_light" }}
+
+ async="async"
+ onload="document.querySelector('iframe.GiscusFallback').remove();"
+>
diff --git a/layouts/partials/footer-buttons.html b/layouts/partials/footer-buttons.html
index 142fc0a..4b149a6 100644
--- a/layouts/partials/footer-buttons.html
+++ b/layouts/partials/footer-buttons.html
@@ -1,16 +1,26 @@
+{{- $language := (string .Language) -}}
{{- with resources.Get "ButtonBadges.toml" -}}
{{- with . | transform.Unmarshal -}}
{{- range $group, $badges := . -}}
{{- range $badges -}}
- {{- $newprops := (dict
- "srcRelative" .file
- "hrefLinkback" .linkback
- ) -}}
- {{- if .spam -}}
- {{- $newprops = (merge $newprops (dict "rel" "nofollow")) -}}
+ {{- $src := .src -}}
+ {{- if (or .file .src) -}}
+ {{- if $src -}}
+ {{ $src = (partial "functions/ParseFileUrl.html" $src) }}
+ {{- end -}}
+ {{- $newprops := (dict
+ "src" $src
+ "srcRelative" .file
+ "hrefLinkback" .linkback
+ ) -}}
+ {{- if .spam -}}
+ {{- $newprops = (merge $newprops (dict "rel" "nofollow noopener" "target" "_blank")) -}}
+ {{- end -}}
+ {{ partial "ImgButton.html" (merge . $newprops) }}
+ {{- else -}}
+
{{ partial "functions/FromLanguageObject.html" (dict "Object" .title "Language" $language) }}
{{- end -}}
- {{ partial "ImgButton.html" (merge . $newprops) }}
{{- end -}}
{{- end -}}
@@ -19,132 +29,6 @@
-{{ partial "ImgButton.html" (dict
- "alt" "Follow me on Mastodon"
- "srcRelative" "Follow-me-on-mastodon.png"
- "href" "https://mastodon.uno/@octo"
- "rel" "me"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Bandiera Octt"
- "srcRelative" "Octt-Flag.png"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Rainbow"
- "srcRelative" "rainbow_bev.png"
- "href" "https://en.wikipedia.org/wiki/Refraction"
- "rel" "nofollow"
-) }}
-
-
-{{ partial "ImgButton.html" (dict
- "alt" "Occhi blink blink"
- "src" (printf "%s/Media/Blink-0.gif" (partial "assetsRoot.html"))
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "I wear cute socks!"
- "srcRelative" "I-wear-cute-socks.gif"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "nya"
- "srcRelative" "nya.png"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Hello Kitty"
- "srcRelative" "HELLO-Kitty.gif"
- "href" "https://www.sanrio.com"
- "rel" "nofollow"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Girl rot"
- "srcRelative" "GRL-ROT.gif"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Cyber rot"
- "srcRelative" "CYBER-ROT.gif"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Girls for Notepad"
- "srcRelative" "girls-4-notepad.gif"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Perfect Soldier"
- "srcRelative" "Perfect-Soldier.gif"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "I like computer"
- "srcRelative" "I-LIKE-COMPUTER.png"
-) }}
-
-
-
-{{ partial "ImgButton.html" (dict
- "alt" "Made with Hugo"
- "srcRelative" "HUGO.webp"
- "href" "https://gohugo.io"
- "rel" "nofollow"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Made with CSS"
- "srcRelative" "MADE-WITH-CASCADING-STYLE-SHEETS-cyan.png"
- "href" "https://developer.mozilla.org/en-US/docs/Web/CSS"
- "rel" "nofollow"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Made on GNU/Linux"
- "srcRelative" "Made-on-GNU-Linux.png"
- "href" "https://www.gnu.org/home.it"
- "rel" "nofollow"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Made with Notepad++"
- "srcRelative" "Made-with-Notepad++.png"
- "href" "https://notepad-plus-plus.org"
- "rel" "nofollow"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Made with Microsoft Notepad"
- "srcRelative" "Powered-by-Microsoft-Notepad.gif"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Graphics by GIMP"
- "srcRelative" "Graphics-by-Gimp.png"
- "href" "https://www.gimp.org"
- "rel" "nofollow"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Fueled by Coffee"
- "srcRelative" "Fueled-by-COFFEE.gif"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Powered by THE VOID"
- "srcRelative" "Powered-by-THE-VOID.png"
-) }}
-
-{{ partial "ImgButton.html" (dict
- "alt" "Powered by Bob"
- "srcRelative" "POWERED-BY-bob.gif"
-) }}
-
-
-
{{ partial "ImgButton.html" (dict
"alt" "Internet Archive"
"srcRelative" "Sites/Internet-Archive.png"
diff --git a/layouts/partials/functions/FromLanguageObject.html b/layouts/partials/functions/FromLanguageObject.html
new file mode 100644
index 0000000..92f8bff
--- /dev/null
+++ b/layouts/partials/functions/FromLanguageObject.html
@@ -0,0 +1 @@
+{{- return (or (index .Object .Language) (index .Object "en") (index .Object "it")) -}}
diff --git a/layouts/partials/functions/ParseFileUrl.html b/layouts/partials/functions/ParseFileUrl.html
new file mode 100644
index 0000000..8d0cbbf
--- /dev/null
+++ b/layouts/partials/functions/ParseFileUrl.html
@@ -0,0 +1,5 @@
+{{ $url := . }}
+{{ if hasPrefix . "@" }}
+ {{ $url = (printf "%s/%s" (partial "assetsRoot") (trim . "@/")) }}
+{{ end }}
+{{ return $url }}
diff --git a/layouts/partials/search-applet.html b/layouts/partials/search-applet.html
new file mode 100644
index 0000000..1a352d8
--- /dev/null
+++ b/layouts/partials/search-applet.html
@@ -0,0 +1,38 @@
+
+
diff --git a/static/ajax-navigation.js b/static/ajax-navigation.js
new file mode 100644
index 0000000..e737e26
--- /dev/null
+++ b/static/ajax-navigation.js
@@ -0,0 +1,56 @@
+(function(){
+// TODO investigate/fix strange screen flash when navigating back from an hash URL
+// TODO error handling, caching, loading indication, totally handle hash change
+
+var oldUrl = null;
+var firstLoad = true;
+window.SiteInitOnLoad = [];
+
+function initPage () {
+ oldUrl = location.href;
+ document.body.scrollIntoView();
+ Array.from(document.querySelectorAll('a')).forEach(function(anchorEl){
+ var isInternalLink = anchorEl.href.startsWith(location.protocol + '//' + location.host);
+ var isPagewideLink = (anchorEl.href.split('#')[0] === location.href.split('#')[0]);
+ if (isInternalLink && !isPagewideLink) {
+ anchorEl.onclick = (function(clickEvent){
+ clickEvent.preventDefault();
+ loadContent(anchorEl.href, true);
+ });
+ }
+ });
+ if (!firstLoad) {
+ SiteInitOnLoad.forEach(function(routine){ routine(); });
+ }
+ firstLoad = false;
+}
+
+function loadContent (url, push) {
+ var fallbackTimeout = setTimeout((function(){ location.href = url; }), 3e3);
+ fetch(url)
+ .then(function(request){ return request.text(); })
+ .then(function(html){
+ var domNew = (new DOMParser).parseFromString(html, 'text/html');
+ if (push) {
+ history.pushState(null, null, url);
+ }
+ document.head.innerHTML = domNew.head.innerHTML;
+ document.body.innerHTML = domNew.body.innerHTML;
+ initPage();
+ clearTimeout(fallbackTimeout);
+ }).catch(function(err){
+ console.error(err);
+ location.href = url;
+ });
+}
+
+window.addEventListener('load', initPage);
+
+window.addEventListener('popstate', (stateEvent) => {
+ if (location.href.split('#')[0] !== oldUrl.split('#')[0]) {
+ loadContent(location.href, false);
+ }
+ oldUrl = location.href;
+});
+
+})();
diff --git a/static/lib/fuse.min.js b/static/lib/fuse.min.js
new file mode 100644
index 0000000..1f534ad
--- /dev/null
+++ b/static/lib/fuse.min.js
@@ -0,0 +1,9 @@
+/**
+ * Fuse.js v7.0.0 - Lightweight fuzzy-search (http://fusejs.io)
+ *
+ * Copyright (c) 2023 Kiro Risk (http://kiro.me)
+ * All Rights Reserved. Apache Software License 2.0
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+var e,t;e=this,t=function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var n=1;n
e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&void 0!==arguments[0]?arguments[0]:{},n=t.getFn,i=void 0===n?$.getFn:n,o=t.fieldNormWeight,c=void 0===o?$.fieldNormWeight:o;r(this,e),this.norm=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,n=new Map,r=Math.pow(10,t);return{get:function(t){var i=t.match(F).length;if(n.has(i))return n.get(i);var o=1/Math.pow(i,.5*e),c=parseFloat(Math.round(o*r)/r);return n.set(i,c),c},clear:function(){n.clear()}}}(c,3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return o(e,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=t,this._keysMap={},t.forEach((function(t,n){e._keysMap[t.id]=n}))}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,m(this.docs[0])?this.docs.forEach((function(t,n){e._addString(t,n)})):this.docs.forEach((function(t,n){e._addObject(t,n)})),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();m(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,i=void 0===r?$.getFn:r,o=n.fieldNormWeight,c=void 0===o?$.fieldNormWeight:o,a=new R({getFn:i,fieldNormWeight:c});return a.setKeys(e.map(A)),a.setSources(t),a.create(),a}function N(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.errors,r=void 0===n?0:n,i=t.currentLocation,o=void 0===i?0:i,c=t.expectedLocation,a=void 0===c?0:c,s=t.distance,u=void 0===s?$.distance:s,h=t.ignoreLocation,l=void 0===h?$.ignoreLocation:h,f=r/e.length;if(l)return f;var d=Math.abs(a-o);return u?f+d/u:d?1:f}var W=32;function T(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},i=r.location,o=void 0===i?$.location:i,c=r.distance,a=void 0===c?$.distance:c,s=r.threshold,u=void 0===s?$.threshold:s,h=r.findAllMatches,l=void 0===h?$.findAllMatches:h,f=r.minMatchCharLength,d=void 0===f?$.minMatchCharLength:f,v=r.includeMatches,g=void 0===v?$.includeMatches:v,y=r.ignoreLocation,p=void 0===y?$.ignoreLocation:y;if(t.length>W)throw new Error("Pattern length exceeds max of ".concat(W,"."));for(var m,k=t.length,M=e.length,b=Math.max(0,Math.min(o,M)),x=u,w=b,S=d>1||g,L=S?Array(M):[];(m=e.indexOf(t,w))>-1;){var _=N(t,{currentLocation:m,expectedLocation:b,distance:a,ignoreLocation:p});if(x=Math.min(_,x),w=m+k,S)for(var O=0;O=P;D-=1){var K=D-1,q=n[e.charAt(K)];if(S&&(L[K]=+!!q),z[D]=(z[D+1]<<1|1)&q,E&&(z[D]|=(j[D+1]|j[D])<<1|1|j[D+1]),z[D]&C&&(A=N(t,{errors:E,currentLocation:K,expectedLocation:b,distance:a,ignoreLocation:p}))<=x){if(x=A,(w=K)<=b)break;P=Math.max(1,2*b-w)}}if(N(t,{errors:E+1,currentLocation:b,expectedLocation:b,distance:a,ignoreLocation:p})>x)break;j=z}var B={isMatch:w>=0,score:Math.max(.001,A)};if(S){var J=function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:$.minMatchCharLength,n=[],r=-1,i=-1,o=0,c=e.length;o=t&&n.push([r,i]),r=-1)}return e[o-1]&&o-r>=t&&n.push([r,o-1]),n}(L,d);J.length?g&&(B.indices=J):B.isMatch=!1}return B}function z(e){for(var t={},n=0,r=e.length;n1&&void 0!==arguments[1]?arguments[1]:{},o=i.location,c=void 0===o?$.location:o,a=i.threshold,s=void 0===a?$.threshold:a,u=i.distance,h=void 0===u?$.distance:u,l=i.includeMatches,f=void 0===l?$.includeMatches:l,d=i.findAllMatches,v=void 0===d?$.findAllMatches:d,g=i.minMatchCharLength,y=void 0===g?$.minMatchCharLength:g,p=i.isCaseSensitive,m=void 0===p?$.isCaseSensitive:p,k=i.ignoreLocation,M=void 0===k?$.ignoreLocation:k;if(r(this,e),this.options={location:c,threshold:s,distance:h,includeMatches:f,findAllMatches:v,minMatchCharLength:y,isCaseSensitive:m,ignoreLocation:M},this.pattern=m?t:t.toLowerCase(),this.chunks=[],this.pattern.length){var b=function(e,t){n.chunks.push({pattern:e,alphabet:z(e),startIndex:t})},x=this.pattern.length;if(x>W){for(var w=0,S=x%W,L=x-S;w1&&void 0!==arguments[1]?arguments[1]:{},c=o.location,a=void 0===c?$.location:c,s=o.threshold,u=void 0===s?$.threshold:s,h=o.distance,l=void 0===h?$.distance:h,f=o.includeMatches,d=void 0===f?$.includeMatches:f,v=o.findAllMatches,g=void 0===v?$.findAllMatches:v,y=o.minMatchCharLength,p=void 0===y?$.minMatchCharLength:y,m=o.isCaseSensitive,k=void 0===m?$.isCaseSensitive:m,M=o.ignoreLocation,b=void 0===M?$.ignoreLocation:M;return r(this,n),(i=t.call(this,e))._bitapSearch=new D(e,{location:a,threshold:u,distance:l,includeMatches:d,findAllMatches:g,minMatchCharLength:p,isCaseSensitive:k,ignoreLocation:b}),i}return o(n,[{key:"search",value:function(e){return this._bitapSearch.searchIn(e)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),n}(K),X=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){for(var t,n=0,r=[],i=this.pattern.length;(t=e.indexOf(this.pattern,n))>-1;)n=t+i,r.push([t,n-1]);var o=!!r.length;return{isMatch:o,score:o?0:1,indices:r}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),n}(K),Y=[B,X,U,V,H,G,J,Q],Z=Y.length,ee=/ +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,te=new Set([Q.type,X.type]),ne=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=n.isCaseSensitive,o=void 0===i?$.isCaseSensitive:i,c=n.includeMatches,a=void 0===c?$.includeMatches:c,s=n.minMatchCharLength,u=void 0===s?$.minMatchCharLength:s,h=n.ignoreLocation,l=void 0===h?$.ignoreLocation:h,f=n.findAllMatches,d=void 0===f?$.findAllMatches:f,v=n.location,g=void 0===v?$.location:v,y=n.threshold,p=void 0===y?$.threshold:y,m=n.distance,k=void 0===m?$.distance:m;r(this,e),this.query=null,this.options={isCaseSensitive:o,includeMatches:a,minMatchCharLength:u,findAllMatches:d,ignoreLocation:l,location:g,threshold:p,distance:k},this.pattern=o?t:t.toLowerCase(),this.query=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.split("|").map((function(e){for(var n=e.trim().split(ee).filter((function(e){return e&&!!e.trim()})),r=[],i=0,o=n.length;i2&&void 0!==arguments[2]?arguments[2]:{}).auto,r=void 0===n||n;return ue(e)||(e=he(e)),function e(n){var i=Object.keys(n),o=function(e){return!!e[ae]}(n);if(!o&&i.length>1&&!ue(n))return e(he(n));if(function(e){return!g(e)&&b(e)&&!ue(e)}(n)){var c=o?n[ae]:i[0],a=o?n[se]:n[c];if(!m(a))throw new Error(function(e){return"Invalid value for key ".concat(e)}(c));var s={keyId:C(c),pattern:a};return r&&(s.searcher=ie(a,t)),s}var u={children:[],operator:i[0]};return i.forEach((function(t){var r=n[t];g(r)&&r.forEach((function(t){u.children.push(e(t))}))})),u}(e)}function fe(e,t){var n=e.matches;t.matches=[],x(n)&&n.forEach((function(e){if(x(e.indices)&&e.indices.length){var n={indices:e.indices,value:e.value};e.key&&(n.key=e.key.src),e.idx>-1&&(n.refIndex=e.idx),t.matches.push(n)}}))}function de(e,t){t.score=e.score}var ve=function(){function e(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;r(this,e),this.options=t(t({},$),i),this.options.useExtendedSearch,this._keyStore=new j(this.options.keys),this.setCollection(n,o)}return o(e,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof R))throw new Error("Incorrect 'index' type");this._myIndex=t||P(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight})}},{key:"add",value:function(e){x(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},t=[],n=0,r=this._docs.length;n1&&void 0!==arguments[1]?arguments[1]:{}).limit,n=void 0===t?-1:t,r=this.options,i=r.includeMatches,o=r.includeScore,c=r.shouldSort,a=r.sortFn,s=r.ignoreFieldNorm,u=m(e)?m(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e);return function(e,t){var n=t.ignoreFieldNorm,r=void 0===n?$.ignoreFieldNorm:n;e.forEach((function(e){var t=1;e.matches.forEach((function(e){var n=e.key,i=e.norm,o=e.score,c=n?n.weight:null;t*=Math.pow(0===o&&c?Number.EPSILON:o,(c||1)*(r?1:i))})),e.score=t}))}(u,{ignoreFieldNorm:s}),c&&u.sort(a),k(n)&&n>-1&&(u=u.slice(0,n)),function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,i=void 0===r?$.includeMatches:r,o=n.includeScore,c=void 0===o?$.includeScore:o,a=[];return i&&a.push(fe),c&&a.push(de),e.map((function(e){var n=e.idx,r={item:t[n],refIndex:n};return a.length&&a.forEach((function(t){t(e,r)})),r}))}(u,this._docs,{includeMatches:i,includeScore:o})}},{key:"_searchStringList",value:function(e){var t=ie(e,this.options),n=this._myIndex.records,r=[];return n.forEach((function(e){var n=e.v,i=e.i,o=e.n;if(x(n)){var c=t.searchIn(n),a=c.isMatch,s=c.score,u=c.indices;a&&r.push({item:n,idx:i,matches:[{score:s,value:n,norm:o,indices:u}]})}})),r}},{key:"_searchLogical",value:function(e){var t=this,n=le(e,this.options),r=function e(n,r,i){if(!n.children){var o=n.keyId,c=n.searcher,a=t._findMatches({key:t._keyStore.get(o),value:t._myIndex.getValueForItemAtKeyId(r,o),searcher:c});return a&&a.length?[{idx:i,item:r,matches:a}]:[]}for(var s=[],u=0,h=n.children.length;u1&&void 0!==arguments[1]?arguments[1]:{},n=t.getFn,r=void 0===n?$.getFn:n,i=t.fieldNormWeight,o=void 0===i?$.fieldNormWeight:i,c=e.keys,a=e.records,s=new R({getFn:r,fieldNormWeight:o});return s.setKeys(c),s.setIndexRecords(a),s},ve.config=$,function(){re.push.apply(re,arguments)}(ne),ve},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Fuse=t();
\ No newline at end of file
diff --git a/static/site-search.js b/static/site-search.js
new file mode 100644
index 0000000..f244404
--- /dev/null
+++ b/static/site-search.js
@@ -0,0 +1,183 @@
+(function(){
+
+function init () {
+
+var fuse;
+var hideButton = document.getElementById("close-search-button");
+var wrapper = document.getElementById("search-wrapper");
+var modal = document.getElementById("search-modal");
+var input = document.getElementById("search-query");
+var output = document.getElementById("search-results");
+var first = output.firstChild;
+var last = output.lastChild;
+var searchVisible = false;
+var indexed = false;
+var hasResults = false;
+
+hideButton.addEventListener("click", hideSearch);
+wrapper.addEventListener("click", hideSearch);
+modal.addEventListener("click", function (event) {
+ event.stopPropagation();
+ event.stopImmediatePropagation();
+ return false;
+});
+document.addEventListener("keydown", function (event) {
+ if (event.key == "/") {
+ if (!searchVisible) {
+ event.preventDefault();
+ displaySearch();
+ } else {
+ input.focus();
+ }
+ }
+
+ if (event.key == "Escape") {
+ hideSearch();
+ }
+
+ if (event.key == "ArrowDown") {
+ if (searchVisible && hasResults) {
+ event.preventDefault();
+ if (document.activeElement == input) {
+ first.focus();
+ } else if (document.activeElement == last) {
+ last.focus();
+ } else {
+ document.activeElement.parentElement.nextSibling.firstElementChild.focus();
+ }
+ }
+ }
+
+ if (event.key == "ArrowUp") {
+ if (searchVisible && hasResults) {
+ event.preventDefault();
+ if (document.activeElement == input) {
+ input.focus();
+ } else if (document.activeElement == first) {
+ input.focus();
+ } else {
+ document.activeElement.parentElement.previousSibling.firstElementChild.focus();
+ }
+ }
+ }
+
+ // Enter to get to results
+ if (event.key == "Enter") {
+ if (searchVisible && hasResults) {
+ event.preventDefault();
+ if (document.activeElement == input) {
+ first.focus();
+ } else {
+ document.activeElement.click();
+ }
+ }
+ }
+
+});
+
+// Update search on each keypress
+input.onkeyup = function (event) {
+ executeQuery(this.value);
+};
+
+function displaySearch() {
+ if (!indexed) {
+ buildIndex();
+ }
+ if (!searchVisible) {
+ document.body.style.overflow = "hidden";
+ wrapper.style.visibility = "visible";
+ input.focus();
+ searchVisible = true;
+ }
+ input.value = document.querySelector('.SiteSearchForm > input').value;
+}
+
+function hideSearch() {
+ if (searchVisible) {
+ document.body.style.overflow = "visible";
+ wrapper.style.visibility = "hidden";
+ input.value = "";
+ document.querySelector('.SiteSearchForm > input').value = "";
+ output.innerHTML = "";
+ document.activeElement.blur();
+ searchVisible = false;
+ }
+}
+
+function buildIndex() {
+ var options = {
+ shouldSort: true,
+ ignoreLocation: true,
+ threshold: 0.0,
+ includeMatches: true,
+ keys: [
+ { name: "title", weight: 0.8 },
+ { name: "section", weight: 0.2 },
+ { name: "summary", weight: 0.6 },
+ { name: "content", weight: 0.4 },
+ ],
+ };
+ fuse = new Fuse(SiteSearchIndex, options);
+ indexed = true;
+}
+
+function executeQuery(term) {
+ let results = fuse.search(term);
+ let resultsHTML = "";
+
+ if (results.length > 0) {
+ results.forEach(function (value, key) {
+ var title = value.item.externalUrl? value.item.title + ''+value.item.externalUrl+'' : value.item.title;
+ var linkconfig = value.item.externalUrl? 'target="_blank" rel="noopener" href="'+value.item.externalUrl+'"' : 'href="'+value.item.permalink+'"';
+ resultsHTML =
+ resultsHTML +
+ `
+
+
+
+ ${title}
+
+
${value.item.section}·${value.item.date? value.item.date : ""}
+
${value.item.summary}
+
+ →
+
+
+ `;
+ });
+ hasResults = true;
+ } else {
+ resultsHTML = "";
+ hasResults = false;
+ }
+
+ output.innerHTML = resultsHTML;
+ if (results.length > 0) {
+ first = output.firstChild.firstElementChild;
+ last = output.lastChild.firstElementChild;
+ }
+}
+
+var inputText = document.querySelector('.SiteSearchForm > form > div > input[type="submit"]').value.split(' ')[0];
+document.querySelector('.SiteSearchForm > form > div').remove();
+document.querySelector('.SiteSearchForm').innerHTML = document.querySelector('.SiteSearchForm > form > input').outerHTML; //+ 'CTRL+/');
+
+var inputEl = document.querySelector('.SiteSearchForm > input');
+//inputEl.classList.add('bg-transparent', 'white');
+inputEl.placeholder = (inputText + '... 🔎️ [CTRL+/]');
+inputEl.onclick = inputEl.oninput = inputEl.onchange = inputEl.onpaste = displaySearch;
+inputEl.onkeydown = (function(event){
+ if (event.key == "Enter") {
+ event.preventDefault();
+ displaySearch();
+ }
+});
+
+}
+
+init();
+window.SiteInitOnLoad.push(init);
+
+})();
diff --git a/themes/ananke/layouts/_default/baseof.html b/themes/ananke/layouts/_default/baseof.html
index df609a0..e2ac605 100644
--- a/themes/ananke/layouts/_default/baseof.html
+++ b/themes/ananke/layouts/_default/baseof.html
@@ -57,12 +57,13 @@
{{ block "head" . }}{{ partial "head-additions.html" . }}{{ end }}
-
-
+
+
{{ block "header" . }}{{ partial "site-header.html" .}}{{ end }}
{{ block "main" . }}{{ end }}
{{ block "footer" . }}{{ partialCached "site-footer.html" . }}{{ end }}
+ {{ partial "search-applet.html" . }}
diff --git a/themes/ananke/layouts/partials/page-header.html b/themes/ananke/layouts/partials/page-header.html
index d8809f1..62bbea5 100644
--- a/themes/ananke/layouts/partials/page-header.html
+++ b/themes/ananke/layouts/partials/page-header.html
@@ -1,7 +1,7 @@
{{ $featured_image := partial "func/GetFeaturedImage.html" . }}
{{ if $featured_image }}
{{/* Trimming the slash and adding absURL make sure the image works no matter where our site lives */}}
-