From e2784768ae8bb0934adb7e701074235a3519c597 Mon Sep 17 00:00:00 2001
From: weru <fromweru@gmail.com>
Date: Fri, 24 Feb 2023 15:58:15 +0000
Subject: [PATCH] add algolia

---
 assets/js/search/algolia.js                      |    2 
 layouts/partials/functions/getAlgoliaConfig.html |    4 +
 assets/js/search/index.js                        |   26 ++++----
 assets/js/variables.js                           |   18 ------
 assets/js/mode.js                                |    8 +-
 assets/js/search/fuse.js                         |    0 
 assets/js/code.js                                |    2 
 exampleSite/config/_default/params.toml          |   12 +++
 layouts/partials/scripts/bundle.html             |   29 ++-------
 layouts/partials/scripts/getJsBundle.html        |    2 
 layouts/partials/scripts/search.html             |   11 +++
 layouts/partials/scripts/index.html              |    0 
 layouts/partials/functions/getScript.html        |    2 
 assets/js/search/variables.js                    |   46 +++++++++++++++
 14 files changed, 103 insertions(+), 59 deletions(-)

diff --git a/assets/js/code.js b/assets/js/code.js
index 46bf48c..578c311 100644
--- a/assets/js/code.js
+++ b/assets/js/code.js
@@ -285,7 +285,7 @@
         Array.from(lines).forEach(line => {
           line = line.lastElementChild;
           let line_contents = line.textContent.trim(' ');
-          line_contents.indexOf('$') !== 0 ? pushClass(line, 'shell') : false;
+          line_contents.indexOf('$') !== 0 && line_contents.trim(' ').length ? pushClass(line, 'shell') : false;
         });
       }
 
diff --git a/assets/js/mode.js b/assets/js/mode.js
index 08b1abc..036bac4 100644
--- a/assets/js/mode.js
+++ b/assets/js/mode.js
@@ -15,11 +15,9 @@
   acceptable_chars = [...acceptable_chars];
   let mode = getComputedStyle(doc).getPropertyValue(key).replace(/\"/g, '').trim();
 
-  mode = [...mode].filter(function(letter){
-    return acceptable_chars.includes(letter);
-  });
-
-  return mode.join('');
+  return [...mode]
+    .filter(letter => acceptable_chars.includes(letter))
+    .join('');
 }
 
 function changeMode(is_dark_mode) {
diff --git a/assets/js/search/algolia.js b/assets/js/search/algolia.js
new file mode 100644
index 0000000..9df60f1
--- /dev/null
+++ b/assets/js/search/algolia.js
@@ -0,0 +1,2 @@
+/*! algoliasearch-lite.umd.js | 4.14.3 | © Algolia, inc. | https://github.com/algolia/algoliasearch-client-javascript */
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).algoliasearch=t()}(this,(function(){"use strict";function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function r(r){for(var n=1;n<arguments.length;n++){var o=null!=arguments[n]?arguments[n]:{};n%2?t(Object(o),!0).forEach((function(t){e(r,t,o[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(o)):t(Object(o)).forEach((function(e){Object.defineProperty(r,e,Object.getOwnPropertyDescriptor(o,e))}))}return r}function n(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function o(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if(!(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e)))return;var r=[],n=!0,o=!1,a=void 0;try{for(var u,i=e[Symbol.iterator]();!(n=(u=i.next()).done)&&(r.push(u.value),!t||r.length!==t);n=!0);}catch(e){o=!0,a=e}finally{try{n||null==i.return||i.return()}finally{if(o)throw a}}return r}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function a(e){return function(e){if(Array.isArray(e)){for(var t=0,r=new Array(e.length);t<e.length;t++)r[t]=e[t];return r}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function u(e){var t,r="algoliasearch-client-js-".concat(e.key),n=function(){return void 0===t&&(t=e.localStorage||window.localStorage),t},a=function(){return JSON.parse(n().getItem(r)||"{}")};return{get:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return Promise.resolve().then((function(){var r=JSON.stringify(e),n=a()[r];return Promise.all([n||t(),void 0!==n])})).then((function(e){var t=o(e,2),n=t[0],a=t[1];return Promise.all([n,a||r.miss(n)])})).then((function(e){return o(e,1)[0]}))},set:function(e,t){return Promise.resolve().then((function(){var o=a();return o[JSON.stringify(e)]=t,n().setItem(r,JSON.stringify(o)),t}))},delete:function(e){return Promise.resolve().then((function(){var t=a();delete t[JSON.stringify(e)],n().setItem(r,JSON.stringify(t))}))},clear:function(){return Promise.resolve().then((function(){n().removeItem(r)}))}}}function i(e){var t=a(e.caches),r=t.shift();return void 0===r?{get:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}},n=t();return n.then((function(e){return Promise.all([e,r.miss(e)])})).then((function(e){return o(e,1)[0]}))},set:function(e,t){return Promise.resolve(t)},delete:function(e){return Promise.resolve()},clear:function(){return Promise.resolve()}}:{get:function(e,n){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return r.get(e,n,o).catch((function(){return i({caches:t}).get(e,n,o)}))},set:function(e,n){return r.set(e,n).catch((function(){return i({caches:t}).set(e,n)}))},delete:function(e){return r.delete(e).catch((function(){return i({caches:t}).delete(e)}))},clear:function(){return r.clear().catch((function(){return i({caches:t}).clear()}))}}}function s(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{serializable:!0},t={};return{get:function(r,n){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}},a=JSON.stringify(r);if(a in t)return Promise.resolve(e.serializable?JSON.parse(t[a]):t[a]);var u=n(),i=o&&o.miss||function(){return Promise.resolve()};return u.then((function(e){return i(e)})).then((function(){return u}))},set:function(r,n){return t[JSON.stringify(r)]=e.serializable?JSON.stringify(n):n,Promise.resolve(n)},delete:function(e){return delete t[JSON.stringify(e)],Promise.resolve()},clear:function(){return t={},Promise.resolve()}}}function c(e){for(var t=e.length-1;t>0;t--){var r=Math.floor(Math.random()*(t+1)),n=e[t];e[t]=e[r],e[r]=n}return e}function l(e,t){return t?(Object.keys(t).forEach((function(r){e[r]=t[r](e)})),e):e}function f(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),n=1;n<t;n++)r[n-1]=arguments[n];var o=0;return e.replace(/%s/g,(function(){return encodeURIComponent(r[o++])}))}var h={WithinQueryParameters:0,WithinHeaders:1};function d(e,t){var r=e||{},n=r.data||{};return Object.keys(r).forEach((function(e){-1===["timeout","headers","queryParameters","data","cacheable"].indexOf(e)&&(n[e]=r[e])})),{data:Object.entries(n).length>0?n:void 0,timeout:r.timeout||t,headers:r.headers||{},queryParameters:r.queryParameters||{},cacheable:r.cacheable}}var m={Read:1,Write:2,Any:3},p=1,v=2,y=3;function g(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:p;return r(r({},e),{},{status:t,lastUpdate:Date.now()})}function b(e){return"string"==typeof e?{protocol:"https",url:e,accept:m.Any}:{protocol:e.protocol||"https",url:e.url,accept:e.accept||m.Any}}var O="GET",P="POST";function q(e,t){return Promise.all(t.map((function(t){return e.get(t,(function(){return Promise.resolve(g(t))}))}))).then((function(e){var r=e.filter((function(e){return function(e){return e.status===p||Date.now()-e.lastUpdate>12e4}(e)})),n=e.filter((function(e){return function(e){return e.status===y&&Date.now()-e.lastUpdate<=12e4}(e)})),o=[].concat(a(r),a(n));return{getTimeout:function(e,t){return(0===n.length&&0===e?1:n.length+3+e)*t},statelessHosts:o.length>0?o.map((function(e){return b(e)})):t}}))}function w(e,t,n,o){var u=[],i=function(e,t){if(e.method===O||void 0===e.data&&void 0===t.data)return;var n=Array.isArray(e.data)?e.data:r(r({},e.data),t.data);return JSON.stringify(n)}(n,o),s=function(e,t){var n=r(r({},e.headers),t.headers),o={};return Object.keys(n).forEach((function(e){var t=n[e];o[e.toLowerCase()]=t})),o}(e,o),c=n.method,l=n.method!==O?{}:r(r({},n.data),o.data),f=r(r(r({"x-algolia-agent":e.userAgent.value},e.queryParameters),l),o.queryParameters),h=0,d=function t(r,a){var l=r.pop();if(void 0===l)throw{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:A(u)};var d={data:i,headers:s,method:c,url:S(l,n.path,f),connectTimeout:a(h,e.timeouts.connect),responseTimeout:a(h,o.timeout)},m=function(e){var t={request:d,response:e,host:l,triesLeft:r.length};return u.push(t),t},p={onSuccess:function(e){return function(e){try{return JSON.parse(e.content)}catch(t){throw function(e,t){return{name:"DeserializationError",message:e,response:t}}(t.message,e)}}(e)},onRetry:function(n){var o=m(n);return n.isTimedOut&&h++,Promise.all([e.logger.info("Retryable failure",x(o)),e.hostsCache.set(l,g(l,n.isTimedOut?y:v))]).then((function(){return t(r,a)}))},onFail:function(e){throw m(e),function(e,t){var r=e.content,n=e.status,o=r;try{o=JSON.parse(r).message}catch(e){}return function(e,t,r){return{name:"ApiError",message:e,status:t,transporterStackTrace:r}}(o,n,t)}(e,A(u))}};return e.requester.send(d).then((function(e){return function(e,t){return function(e){var t=e.status;return e.isTimedOut||function(e){var t=e.isTimedOut,r=e.status;return!t&&0==~~r}(e)||2!=~~(t/100)&&4!=~~(t/100)}(e)?t.onRetry(e):2==~~(e.status/100)?t.onSuccess(e):t.onFail(e)}(e,p)}))};return q(e.hostsCache,t).then((function(e){return d(a(e.statelessHosts).reverse(),e.getTimeout)}))}function j(e){var t={value:"Algolia for JavaScript (".concat(e,")"),add:function(e){var r="; ".concat(e.segment).concat(void 0!==e.version?" (".concat(e.version,")"):"");return-1===t.value.indexOf(r)&&(t.value="".concat(t.value).concat(r)),t}};return t}function S(e,t,r){var n=T(r),o="".concat(e.protocol,"://").concat(e.url,"/").concat("/"===t.charAt(0)?t.substr(1):t);return n.length&&(o+="?".concat(n)),o}function T(e){return Object.keys(e).map((function(t){return f("%s=%s",t,(r=e[t],"[object Object]"===Object.prototype.toString.call(r)||"[object Array]"===Object.prototype.toString.call(r)?JSON.stringify(e[t]):e[t]));var r})).join("&")}function A(e){return e.map((function(e){return x(e)}))}function x(e){var t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return r(r({},e),{},{request:r(r({},e.request),{},{headers:r(r({},e.request.headers),t)})})}var N=function(e){var t=e.appId,n=function(e,t,r){var n={"x-algolia-api-key":r,"x-algolia-application-id":t};return{headers:function(){return e===h.WithinHeaders?n:{}},queryParameters:function(){return e===h.WithinQueryParameters?n:{}}}}(void 0!==e.authMode?e.authMode:h.WithinHeaders,t,e.apiKey),a=function(e){var t=e.hostsCache,r=e.logger,n=e.requester,a=e.requestsCache,u=e.responsesCache,i=e.timeouts,s=e.userAgent,c=e.hosts,l=e.queryParameters,f={hostsCache:t,logger:r,requester:n,requestsCache:a,responsesCache:u,timeouts:i,userAgent:s,headers:e.headers,queryParameters:l,hosts:c.map((function(e){return b(e)})),read:function(e,t){var r=d(t,f.timeouts.read),n=function(){return w(f,f.hosts.filter((function(e){return 0!=(e.accept&m.Read)})),e,r)};if(!0!==(void 0!==r.cacheable?r.cacheable:e.cacheable))return n();var a={request:e,mappedRequestOptions:r,transporter:{queryParameters:f.queryParameters,headers:f.headers}};return f.responsesCache.get(a,(function(){return f.requestsCache.get(a,(function(){return f.requestsCache.set(a,n()).then((function(e){return Promise.all([f.requestsCache.delete(a),e])}),(function(e){return Promise.all([f.requestsCache.delete(a),Promise.reject(e)])})).then((function(e){var t=o(e,2);t[0];return t[1]}))}))}),{miss:function(e){return f.responsesCache.set(a,e)}})},write:function(e,t){return w(f,f.hosts.filter((function(e){return 0!=(e.accept&m.Write)})),e,d(t,f.timeouts.write))}};return f}(r(r({hosts:[{url:"".concat(t,"-dsn.algolia.net"),accept:m.Read},{url:"".concat(t,".algolia.net"),accept:m.Write}].concat(c([{url:"".concat(t,"-1.algolianet.com")},{url:"".concat(t,"-2.algolianet.com")},{url:"".concat(t,"-3.algolianet.com")}]))},e),{},{headers:r(r(r({},n.headers()),{"content-type":"application/x-www-form-urlencoded"}),e.headers),queryParameters:r(r({},n.queryParameters()),e.queryParameters)}));return l({transporter:a,appId:t,addAlgoliaAgent:function(e,t){a.userAgent.add({segment:e,version:t})},clearCache:function(){return Promise.all([a.requestsCache.clear(),a.responsesCache.clear()]).then((function(){}))}},e.methods)},C=function(e){return function(t,r){return t.method===O?e.transporter.read(t,r):e.transporter.write(t,r)}},k=function(e){return function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n={transporter:e.transporter,appId:e.appId,indexName:t};return l(n,r.methods)}},J=function(e){return function(t,n){var o=t.map((function(e){return r(r({},e),{},{params:T(e.params||{})})}));return e.transporter.read({method:P,path:"1/indexes/*/queries",data:{requests:o},cacheable:!0},n)}},E=function(e){return function(t,o){return Promise.all(t.map((function(t){var a=t.params,u=a.facetName,i=a.facetQuery,s=n(a,["facetName","facetQuery"]);return k(e)(t.indexName,{methods:{searchForFacetValues:R}}).searchForFacetValues(u,i,r(r({},o),s))})))}},I=function(e){return function(t,r,n){return e.transporter.read({method:P,path:f("1/answers/%s/prediction",e.indexName),data:{query:t,queryLanguages:r},cacheable:!0},n)}},F=function(e){return function(t,r){return e.transporter.read({method:P,path:f("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},r)}},R=function(e){return function(t,r,n){return e.transporter.read({method:P,path:f("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:r},cacheable:!0},n)}},D=1,W=2,H=3;function Q(e,t,n){var o,a={appId:e,apiKey:t,timeouts:{connect:1,read:2,write:30},requester:{send:function(e){return new Promise((function(t){var r=new XMLHttpRequest;r.open(e.method,e.url,!0),Object.keys(e.headers).forEach((function(t){return r.setRequestHeader(t,e.headers[t])}));var n,o=function(e,n){return setTimeout((function(){r.abort(),t({status:0,content:n,isTimedOut:!0})}),1e3*e)},a=o(e.connectTimeout,"Connection timeout");r.onreadystatechange=function(){r.readyState>r.OPENED&&void 0===n&&(clearTimeout(a),n=o(e.responseTimeout,"Socket timeout"))},r.onerror=function(){0===r.status&&(clearTimeout(a),clearTimeout(n),t({content:r.responseText||"Network request failed",status:r.status,isTimedOut:!1}))},r.onload=function(){clearTimeout(a),clearTimeout(n),t({content:r.responseText,status:r.status,isTimedOut:!1})},r.send(e.data)}))}},logger:(o=H,{debug:function(e,t){return D>=o&&console.debug(e,t),Promise.resolve()},info:function(e,t){return W>=o&&console.info(e,t),Promise.resolve()},error:function(e,t){return console.error(e,t),Promise.resolve()}}),responsesCache:s(),requestsCache:s({serializable:!1}),hostsCache:i({caches:[u({key:"".concat("4.14.3","-").concat(e)}),s()]}),userAgent:j("4.14.3").add({segment:"Browser",version:"lite"}),authMode:h.WithinQueryParameters};return N(r(r(r({},a),n),{},{methods:{search:J,searchForFacetValues:E,multipleQueries:J,multipleSearchForFacetValues:E,customRequest:C,initIndex:function(e){return function(t){return k(e)(t,{methods:{search:F,searchForFacetValues:R,findAnswers:I}})}}}}))}return Q.version="4.14.3",Q}));
\ No newline at end of file
diff --git a/assets/js/fuse.js b/assets/js/search/fuse.js
similarity index 100%
rename from assets/js/fuse.js
rename to assets/js/search/fuse.js
diff --git a/assets/js/search.js b/assets/js/search/index.js
similarity index 91%
rename from assets/js/search.js
rename to assets/js/search/index.js
index af0dc0c..7138bf0 100644
--- a/assets/js/search.js
+++ b/assets/js/search/index.js
@@ -1,6 +1,3 @@
-const search_result_class = 'search_result';
-const empty_string = '';
-
 function initializeSearch(index) {
   let search_keys = ['title', 'id', 'link', 'body', 'section'];
   search_keys = search_keys.concat(other_searchable_fields);
@@ -198,13 +195,18 @@
 }
 
 window.addEventListener('load', function() {
-  const page_language = document.documentElement.lang;
-  const search_index = `${ page_language === 'en' ? empty_string : page_language}/index.json`;
-  fetch(new URL(search_index, root_url).href)
-  .then(response => response.json())
-  .then(function(search_data) {
-    search_data = search_data.length ? search_data : [];
-    initializeSearch(search_data);
-  })
-  .catch((error) => console.error(error));
+  console.log(algolia_config, 'enabled', algolia_config.id);
+  if(algolia_config.on) {
+    initAlgoliaSearch();
+  } else {
+    const page_language = document.documentElement.lang;
+    const search_index = `${ page_language === 'en' ? empty_string : page_language}/index.json`;
+    fetch(new URL(search_index, root_url).href)
+    .then(response => response.json())
+    .then(function(search_data) {
+      search_data = search_data.length ? search_data : [];
+      initializeSearch(search_data);
+    })
+    .catch((error) => console.error(error));
+  }
 });
diff --git a/assets/js/search/variables.js b/assets/js/search/variables.js
new file mode 100644
index 0000000..80b12cc
--- /dev/null
+++ b/assets/js/search/variables.js
@@ -0,0 +1,46 @@
+const search_result_class = 'search_result';
+const empty_string = '';
+const search_field_class = '.search_field';
+const search_class = '.search';
+
+// defined in i18n / translation files
+const quick_links = '{{ T "quick_links" }}';
+const search_results_label = '{{ T "search_results_label" }}';
+const short_search_query = '{{ T "short_search_query" }}'
+const type_to_search = '{{ T "type_to_search" }}';
+const no_matches_found = '{{ T "no_matches" }}';
+
+// values defined under config/_default/params.toml
+let other_searchable_fields = '{{ delimit (default slice site.Params.otherSearchableFields) ", " }}'
+
+if(other_searchable_fields.length > 2) {
+  other_searchable_fields = other_searchable_fields
+    .split(",")
+    .map(search_value => search_value.toLowerCase().trim());
+} else {
+  other_searchable_fields = [];
+}
+
+// Algolia specific
+const algolia_config = JSON.parse(`{{ partialCached "functions/getAlgoliaConfig" . }}`);
+
+function initAlgoliaSearch() {
+  const algolia_client = algoliasearch(algolia_config.id, algolia_config.key);
+  const algolia_index = algolia_client.initIndex(algolia_config.index);
+
+  // Fuse specific
+
+  // Search for "query string" in the index "contacts"
+  algolia_index.search('custom css').then(({ hits }) => {
+    console.log(hits);
+  });
+
+  // Perform the same search, but only retrieve 50 results
+  // Return only the attributes "firstname" and "lastname"
+  algolia_index.search('query string', {
+    attributesToRetrieve: ['firstname', 'lastname'],
+    hitsPerPage: 50,
+  }).then(({ hits }) => {
+    console.log(hits);
+  });
+}
diff --git a/assets/js/variables.js b/assets/js/variables.js
index 2a728fc..c338e25 100644
--- a/assets/js/variables.js
+++ b/assets/js/variables.js
@@ -10,8 +10,6 @@
 let root_url = '{{ strings.TrimSuffix "/" .Site.BaseURL }}/';
 root_url = root_url.startsWith('http') ? root_url : window.location.origin;
 
-const search_field_class = '.search_field';
-const search_class = '.search';
 const go_back_class = 'button_back';
 const line_class = '.line';
 
@@ -19,23 +17,7 @@
 const code_block_config = JSON.parse('{{ partial "functions/getCodeConfig" . }}');
 const iconsPath = `{{ partialCached "functions/getIconPath" . }}`;
 
-// values defined under config/_default/params.toml
-let other_searchable_fields = '{{ delimit (default slice site.Params.otherSearchableFields) ", " }}'
-
-if(other_searchable_fields.length > 2) {
-  other_searchable_fields = other_searchable_fields
-    .split(",")
-    .map(search_value => search_value.toLowerCase().trim());
-} else {
-  other_searchable_fields = [];
-}
-
 // defined in i18n / translation files
-const quick_links = '{{ T "quick_links" }}';
-const search_results_label = '{{ T "search_results_label" }}';
-const short_search_query = '{{ T "short_search_query" }}'
-const type_to_search = '{{ T "type_to_search" }}';
-const no_matches_found = '{{ T "no_matches" }}';
 const copy_text = '{{ T "copy" }}';
 const copied_text = '{{ T "copied" }}';
 const toggle_line_numbers_text = '{{ T "toggle_line_numbers" }}';
diff --git a/exampleSite/config/_default/params.toml b/exampleSite/config/_default/params.toml
index f29b706..630de72 100644
--- a/exampleSite/config/_default/params.toml
+++ b/exampleSite/config/_default/params.toml
@@ -9,7 +9,8 @@
 
 time_format_blog = "Monday, January 02, 2006"
 time_format_default = "January 2, 2006"
-enableDarkMode = true # set to false to disable darkmode by default # user will still have the option to use dark mode
+enableDarkMode = false # set to false to disable darkmode by default # user will still have the option to use dark mode
+defaultLightingMode = "auto" # other possible values: "dark", "light"
 
 # sets the maximum number of lines per codeblock. The codeblock will however be scrollable and expandable.
 codeMaxLines = 7
@@ -22,7 +23,16 @@
 
 otherSearchableFields = ["Tags", "Categories", "CustomField"] # As they appear in frontmatter
 
+# search
+[search]
+on = true
 # Site logo
+[search.algolia]
+enable = true # if false search will default to fusejs
+id = "Q40WQQX84U" # Application ID
+index = "compose" # Index name
+key = "da87401a458102ec6bbd6cc5e5cf8d95" # Search-Only API Key
+
 [logo]
   lightMode = "images/compose.svg"
   darkMode = "images/compose-light.svg"
diff --git a/layouts/partials/functions/getAlgoliaConfig.html b/layouts/partials/functions/getAlgoliaConfig.html
new file mode 100644
index 0000000..7bfc1be
--- /dev/null
+++ b/layouts/partials/functions/getAlgoliaConfig.html
@@ -0,0 +1,4 @@
+{{- $defaults := (dict "id" "#" "key" "#") }}
+{{- $config := default $defaults site.Params.search.algolia }}
+
+{{- return (jsonify (dict "on" $config.enable "id" $config.id "key" $config.key "index" $config.index)) }}
\ No newline at end of file
diff --git a/layouts/partials/functions/getScript.html b/layouts/partials/functions/getScript.html
new file mode 100644
index 0000000..2e3f0ee
--- /dev/null
+++ b/layouts/partials/functions/getScript.html
@@ -0,0 +1,2 @@
+{{ $scriptPath := printf "js/%s.js" .slug }}
+{{ return (resources.Get $scriptPath | resources.ExecuteAsTemplate $scriptPath .) }}
\ No newline at end of file
diff --git a/layouts/partials/scripts/bundle.html b/layouts/partials/scripts/bundle.html
index 0bd2666..b282e40 100644
--- a/layouts/partials/scripts/bundle.html
+++ b/layouts/partials/scripts/bundle.html
@@ -1,23 +1,8 @@
-{{- $variablesPath := "js/variables.js" }}
-{{- $variables := resources.Get $variablesPath | resources.ExecuteAsTemplate $variablesPath . }}
-
-{{- $funcPath := "js/functions.js" }}
-{{- $functions := resources.Get $funcPath | resources.ExecuteAsTemplate $funcPath . }}
-
-{{- $codePath := "js/code.js" }}
-{{- $code := resources.Get $codePath | resources.ExecuteAsTemplate $codePath . }}
-
-{{- $fusePath := "js/fuse.js" }}
-{{- $fuse := resources.Get $fusePath | resources.ExecuteAsTemplate $fusePath . }}
-
-{{- $searchPath := "js/search.js" }}
-{{- $search := resources.Get $searchPath | resources.ExecuteAsTemplate $searchPath . }}
-
-{{- $modePath := "js/mode.js" }}
-{{- $mode := resources.Get $modePath | resources.ExecuteAsTemplate $modePath . }}
-
-{{- $mainScriptPath := "js/index.js" }}
-{{- $main := resources.Get $mainScriptPath | resources.ExecuteAsTemplate $mainScriptPath . }}
+{{- $variables := partial "functions/getScript" (dict "slug" "variables") }}
+{{- $functions := partial "functions/getScript" (dict "slug" "functions") }}
+{{- $code := partial "functions/getScript" (dict "slug" "code") }}
+{{- $mode := partial "functions/getScript" (dict "slug" "mode") }}
+{{- $main := partial "functions/getScript" (dict "slug" "index") }}
 
 {{- $customScriptPath := "js/custom.js" }}
 {{ if (fileExists "../../assets/js/custom.js") }}
@@ -25,9 +10,9 @@
 {{ end }}
 {{- $custom := resources.Get $customScriptPath | resources.ExecuteAsTemplate $customScriptPath . }}
 
-{{- $bundle := slice $variables $functions $code $mode $main $fuse $search $custom | resources.Concat "js/bundle.js" | resources.Fingerprint "sha512" }}
-<script src="{{ $bundle.Permalink }}" async></script>
+{{- partial "scripts/getJsBundle" (dict "scripts" (slice $variables $functions $code $mode $main $custom) "slug" "bundle") }}
 
+{{- partialCached "scripts/search" . -}}
 {{- partialCached "hooks/scripts" . -}}
 
 {{- $sp := .Site.Params }}
diff --git a/layouts/partials/scripts/getJsBundle.html b/layouts/partials/scripts/getJsBundle.html
new file mode 100644
index 0000000..2704875
--- /dev/null
+++ b/layouts/partials/scripts/getJsBundle.html
@@ -0,0 +1,2 @@
+{{- $bundle := .scripts | resources.Concat (printf "js/%s.js" .slug) | resources.Fingerprint "sha512" }}
+<script src="{{ $bundle.Permalink }}" async></script>
\ No newline at end of file
diff --git a/layouts/partials/scripts/index.html b/layouts/partials/scripts/index.html
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/layouts/partials/scripts/index.html
diff --git a/layouts/partials/scripts/search.html b/layouts/partials/scripts/search.html
new file mode 100644
index 0000000..f2e7330
--- /dev/null
+++ b/layouts/partials/scripts/search.html
@@ -0,0 +1,11 @@
+{{- $fuse := partial "functions/getScript" (dict "slug" "search/fuse") }}
+{{- $variables := partial "functions/getScript" (dict "slug" "search/variables") }}
+{{- $algolia := partial "functions/getScript" (dict "slug" "search/algolia") }}
+{{- $search := partial "functions/getScript" (dict "slug" "search/index") }}
+
+{{- $searchLib := $fuse }}
+{{- if site.Params.search.algolia.enable }}
+  {{- $searchLib = $algolia }}
+{{- end }}
+
+{{- partial "scripts/getJsBundle" (dict "scripts" (slice $searchLib $variables $search) "slug" "search") }}
\ No newline at end of file

--
Gitblit v1.10.0