diff --git a/README.ko.md b/README.ko.md index 294a7ae..31a3c92 100644 --- a/README.ko.md +++ b/README.ko.md @@ -20,6 +20,7 @@ Zzo theme을 이용할 시 가장 매력적인 포인트 한가지는, 한글로 * [갤러리](#gallery) * [컨택 페이지](#contact-page) * [다국어](#multi-language) +* [저자](#author) * [커스터마이징](#customizing) * [외부 라이브러리 사용](#external-library) * [Shortcodes](#shortcodes) @@ -232,7 +233,6 @@ enableThemeChange = true # site color theme # body enableBreadcrumb = true # breadcrumb for list, single page -enablePhotoSwipe = true # image viewer for gallery, single page enableSearch = true # site search with fuse enableSearchHighlight = true # when true, search keyword will be highlighted enableGoToTop = true # scroll to top @@ -918,6 +918,25 @@ copyright = This is my {} copyright text root/static 폴더에 파비콘을 넣어서 테마의 favicon을 overriding 하시면 됩니다. +## Author + +포스트의 저자에 대한 정보를 front matter를 통해서 명시할 수 있습니다. + +```yaml +--- +title: +... +author: # author name +authorEmoji: 🤖 # emoji for subtitle, summary meta data +authorImage: "/images/whoami/avatar.jpg" # image path in the static folder +authorDesc: # author description +socialOptions: # override params.toml file socialOptions + email: "" + facebook: "" + ... +--- +``` + ## External Library 현재 지원하는 외부 라이브러리는 Katex, MathJax, Mermaid, Flowchart.js, chart.js, viz-graph, wavedrom, js-sequence-diagram 입니다. front-matter에 값을 넣어주시면 해당 라이브러리가 로드됩니다. diff --git a/README.md b/README.md index 0663c61..7fd902f 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Thank you for click me!. Zzo theme is a blog theme powered by Hugo with free(alw * [Contact Page](#contact-page) * [Talks Page](#talks-page) * [Multi Language](#multi-language) +* [Author](#author) * [Customizing](#customizing) * [External libraries](#external-library) * [Shortcodes](#shortcodes) @@ -36,8 +37,8 @@ Thank you for click me!. Zzo theme is a blog theme powered by Hugo with free(alw * Multilingual (i18n) * Responsive design * RSS and JSON feeds with full content -* Search with Fuse -* Gallery with Masonry, Photoswipe +* Search +* Gallery * Fast code highlighting * Talks page for external links @@ -226,7 +227,6 @@ enableThemeChange = true # site color theme # body enableBreadcrumb = true # breadcrumb for list, single page -enablePhotoSwipe = true # image viewer for gallery, single page enableSearch = true # site search with Fuse enableSearchHighlight = true # when true, search keyword will be highlighted enableGoToTop = true # scroll to top @@ -918,6 +918,25 @@ The {} part will be your copyright link. Override the default favicon by adding your favicon at root/static folder +## Author + +We have some front matters for specifying the author. + +```yaml +--- +title: +... +author: # author name +authorEmoji: 🤖 # emoji for subtitle, summary meta data +authorImage: "/images/whoami/avatar.jpg" # image path in the static folder +authorDesc: # author description +socialOptions: # override params.toml file socialOptions + email: "" + facebook: "" + ... +--- +``` + ## External Library If you want use external libraries, this theme currently supporting Katex, MathJax, Mermaid, Flowchart.js, chart.js, viz-graph, wavedrom, js-sequence-diagram. Just add some variable to a front-matter. diff --git a/archetypes/author.md b/archetypes/author.md new file mode 100644 index 0000000..52ed374 --- /dev/null +++ b/archetypes/author.md @@ -0,0 +1,38 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +date: {{ .Date }} +description: +tags: +- +series: +- +categories: +- +author: +authorEmoji: 🤖 +authorImage: "/images/whoami/avatar.jpg" +authorDesc: +socialOptions: + email: "" + facebook: "" + twitter: "" + github: "" + stack-overflow: "" + instagram: "" + google-plus: "" + youtube: "" + medium: "" + tumblr: "" + linkedin: "" + pinterest: "" + stack-exchange: "" + telegram: "" + steam: "" + weibo: "" + douban: "" + csdn: "" + zhihu: "" + gitlab: "" + mastodon: "" + jianshu: "" +--- diff --git a/assets/js/helper/closest.js b/assets/js/helper/closest.js new file mode 100644 index 0000000..1971bfe --- /dev/null +++ b/assets/js/helper/closest.js @@ -0,0 +1,12 @@ +var closest = function(node, selector) { + return (node.closest || function (_selector) { + do { + if ((node.matches || node.msMatchesSelector).call(node, _selector)) { + return node; + } + node = node.parentElement || node.parentNode; + } while (node !== null && node.nodeType === 1); + + return null; + }).call(node, selector); +} \ No newline at end of file diff --git a/assets/js/helper/fadeinout.js b/assets/js/helper/fadeinout.js new file mode 100644 index 0000000..f511c7e --- /dev/null +++ b/assets/js/helper/fadeinout.js @@ -0,0 +1,41 @@ +var fadeOut = function(node, duration) { + node.style.opacity = 1; + + var start = performance.now(); + + requestAnimationFrame(function tick(timestamp) { + var easing = (timestamp - start) / duration; + node.style.opacity = Math.max(1 - easing, 0); + + if (easing < 1) { + requestAnimationFrame(tick); + } else { + node.style.opacity = ''; + node.style.display = 'none'; + } + }); +} + +var fadeIn = function (node, duration) { + if (getComputedStyle(node).display !== 'none') return; + + if (node.style.display === 'none') { + node.style.display = ''; + } else { + node.style.display = 'block'; + } + node.style.opacity = 0; + + var start = performance.now(); + + requestAnimationFrame(function tick(timestamp) { + var easing = (timestamp - start) / duration; + node.style.opacity = Math.min(easing, 1); + + if (easing < 1) { + requestAnimationFrame(tick); + } else { + node.style.opacity = ''; + } + }); +} \ No newline at end of file diff --git a/assets/js/helper/getParents.js b/assets/js/helper/getParents.js new file mode 100644 index 0000000..0a85b6a --- /dev/null +++ b/assets/js/helper/getParents.js @@ -0,0 +1,58 @@ +/** + * Get all DOM element up the tree that contain a class, ID, or data attribute + * @param {Node} elem The base element + * @param {String} selector The class, id, data attribute, or tag to look for + * @return {Array} Null if no match + */ +var getParents = function (elem, selector) { + + var parents = []; + var firstChar; + if (selector) { + firstChar = selector.charAt(0); + } + + // Get matches + for (; elem && elem !== document; elem = elem.parentNode) { + if (selector) { + + // If selector is a class + if (firstChar === '.') { + if (elem.classList.contains(selector.substr(1))) { + parents.push(elem); + } + } + + // If selector is an ID + if (firstChar === '#') { + if (elem.id === selector.substr(1)) { + parents.push(elem); + } + } + + // If selector is a data attribute + if (firstChar === '[') { + if (elem.hasAttribute(selector.substr(1, selector.length - 1))) { + parents.push(elem); + } + } + + // If selector is a tag + if (elem.tagName.toLowerCase() === selector) { + parents.push(elem); + } + + } else { + parents.push(elem); + } + + } + + // Return parents if any exist + if (parents.length === 0) { + return null; + } else { + return parents; + } + +}; \ No newline at end of file diff --git a/assets/js/helper/next.js b/assets/js/helper/next.js new file mode 100644 index 0000000..3f65c71 --- /dev/null +++ b/assets/js/helper/next.js @@ -0,0 +1,7 @@ +function next(node, selector) { + if (selector && document.querySelector(selector) !== node.nextElementSibling) { + return null; + } + + return node.nextElementSibling; +} diff --git a/assets/js/helper/prev.js b/assets/js/helper/prev.js new file mode 100644 index 0000000..2891f05 --- /dev/null +++ b/assets/js/helper/prev.js @@ -0,0 +1,7 @@ +var prev = function(node, selector) { + if (selector && document.querySelector(selector) !== node.previousElementSibling) { + return null; + } + + return node.previousElementSibling; +} \ No newline at end of file diff --git a/assets/js/helper/prop.js b/assets/js/helper/prop.js new file mode 100644 index 0000000..67d0bba --- /dev/null +++ b/assets/js/helper/prop.js @@ -0,0 +1,6 @@ +var prop = function (node, name, value) { + if (typeof value === 'undefined') { + return node[name]; + } + node[name] = value; +}; \ No newline at end of file diff --git a/assets/js/jquery.min.js b/assets/js/jquery.min.js deleted file mode 100644 index a1c07fd..0000000 --- a/assets/js/jquery.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0 { const e = ["a[href]", "area[href]", 'input:not([disabled]):not([type="hidden"]):not([aria-hidden])', "select:not([disabled]):not([aria-hidden])", "textarea:not([disabled]):not([aria-hidden])", "button:not([disabled]):not([aria-hidden])", "iframe", "object", "embed", "[contenteditable]", '[tabindex]:not([tabindex^="-"])']; class t { constructor({ targetModal: e, triggers: t = [], onShow: o = (() => { }), onClose: i = (() => { }), openTrigger: n = "data-micromodal-trigger", closeTrigger: s = "data-micromodal-close", disableScroll: a = !1, disableFocus: l = !1, awaitCloseAnimation: d = !1, awaitOpenAnimation: r = !1, debugMode: c = !1 }) { this.modal = document.getElementById(e), this.config = { debugMode: c, disableScroll: a, openTrigger: n, closeTrigger: s, onShow: o, onClose: i, awaitCloseAnimation: d, awaitOpenAnimation: r, disableFocus: l }, t.length > 0 && this.registerTriggers(...t), this.onClick = this.onClick.bind(this), this.onKeydown = this.onKeydown.bind(this) } registerTriggers(...e) { e.filter(Boolean).forEach(e => { e.addEventListener("click", e => this.showModal(e)) }) } showModal() { if (this.activeElement = document.activeElement, this.modal.setAttribute("aria-hidden", "false"), this.modal.classList.add("is-open"), this.scrollBehaviour("disable"), this.addEventListeners(), this.config.awaitOpenAnimation) { const e = () => { this.modal.removeEventListener("animationend", e, !1), this.setFocusToFirstNode() }; this.modal.addEventListener("animationend", e, !1) } else this.setFocusToFirstNode(); this.config.onShow(this.modal, this.activeElement) } closeModal() { const e = this.modal; this.modal.setAttribute("aria-hidden", "true"), this.removeEventListeners(), this.scrollBehaviour("enable"), this.activeElement && this.activeElement.focus(), this.config.onClose(this.modal), this.config.awaitCloseAnimation ? this.modal.addEventListener("animationend", function t() { e.classList.remove("is-open"), e.removeEventListener("animationend", t, !1) }, !1) : e.classList.remove("is-open") } closeModalById(e) { this.modal = document.getElementById(e), this.modal && this.closeModal() } scrollBehaviour(e) { if (!this.config.disableScroll) return; const t = document.querySelector("body"); switch (e) { case "enable": Object.assign(t.style, { overflow: "", height: "" }); break; case "disable": Object.assign(t.style, { overflow: "hidden", height: "100vh" }) } } addEventListeners() { this.modal.addEventListener("touchstart", this.onClick), this.modal.addEventListener("click", this.onClick), document.addEventListener("keydown", this.onKeydown) } removeEventListeners() { this.modal.removeEventListener("touchstart", this.onClick), this.modal.removeEventListener("click", this.onClick), document.removeEventListener("keydown", this.onKeydown) } onClick(e) { e.target.hasAttribute(this.config.closeTrigger) && (this.closeModal(), e.preventDefault()) } onKeydown(e) { 27 === e.keyCode && this.closeModal(e), 9 === e.keyCode && this.maintainFocus(e) } getFocusableNodes() { const t = this.modal.querySelectorAll(e); return Array(...t) } setFocusToFirstNode() { if (this.config.disableFocus) return; const e = this.getFocusableNodes(); e.length && e[0].focus() } maintainFocus(e) { const t = this.getFocusableNodes(); if (this.modal.contains(document.activeElement)) { const o = t.indexOf(document.activeElement); e.shiftKey && 0 === o && (t[t.length - 1].focus(), e.preventDefault()), e.shiftKey || o !== t.length - 1 || (t[0].focus(), e.preventDefault()) } else t[0].focus() } } let o = null; const i = e => { if (!document.getElementById(e)) return console.warn(`MicroModal: ❗Seems like you have missed %c'${e}'`, "background-color: #f8f9fa;color: #50596c;font-weight: bold;", "ID somewhere in your code. Refer example below to resolve it."), console.warn("%cExample:", "background-color: #f8f9fa;color: #50596c;font-weight: bold;", ``), !1 }, n = (e, t) => { if ((e => { if (e.length <= 0) console.warn("MicroModal: ❗Please specify at least one %c'micromodal-trigger'", "background-color: #f8f9fa;color: #50596c;font-weight: bold;", "data attribute."), console.warn("%cExample:", "background-color: #f8f9fa;color: #50596c;font-weight: bold;", '') })(e), !t) return !0; for (var o in t) i(o); return !0 }; return { init: e => { const i = Object.assign({}, { openTrigger: "data-micromodal-trigger" }, e), s = [...document.querySelectorAll(`[${i.openTrigger}]`)], a = ((e, t) => { const o = []; return e.forEach(e => { const i = e.attributes[t].value; void 0 === o[i] && (o[i] = []), o[i].push(e) }), o })(s, i.openTrigger); if (!0 !== i.debugMode || !1 !== n(s, a)) for (var l in a) { let e = a[l]; i.targetModal = l, i.triggers = [...e], o = new t(i) } }, show: (e, n) => { const s = n || {}; s.targetModal = e, !0 === s.debugMode && !1 === i(e) || (o = new t(s)).showModal() }, close: e => { e ? o.closeModalById(e) : o.closeModal() } } })() }); \ No newline at end of file diff --git a/assets/js/swipe.js b/assets/js/swipe.js new file mode 100644 index 0000000..686951b --- /dev/null +++ b/assets/js/swipe.js @@ -0,0 +1,828 @@ +/*! + * Swipe 2.2.14 + * + * Brad Birdsall + * Copyright 2013, MIT License + * +*/ + +// if the module has no dependencies, the above pattern can be simplified to +// eslint-disable-next-line no-extra-semi +; (function (root, factory) { + // eslint-disable-next-line no-undef + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + // eslint-disable-next-line no-undef + define([], function () { + root.Swipe = factory(); + return root.Swipe; + }); + } else if (typeof module === 'object' && module.exports) { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals + root.Swipe = factory(); + } +}(this, function () { + // Establish the root object, `window` (`self`) in the browser, `global` + // on the server, or `this` in some virtual machines. We use `self` + // instead of `window` for `WebWorker` support. + var root = typeof self == 'object' && self.self === self && self || + typeof global == 'object' && global.global === global && global || + this; + + var _document = root.document; + + function Swipe(container, options) { + + 'use strict'; + + options = options || {}; + + // setup initial vars + var start = {}; + var delta = {}; + var isScrolling; + + // setup auto slideshow + var delay = options.auto || 0; + var interval; + + var disabled = false; + + // utilities + // simple no operation function + var noop = function () { }; + // offload a functions execution + var offloadFn = function (fn) { setTimeout(fn || noop, 0); }; + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. + var throttle = function (fn, threshhold) { + threshhold = threshhold || 100; + var timeout = null; + + function cancel() { + if (timeout) clearTimeout(timeout); + } + + function throttledFn() { + var context = this; + var args = arguments; + cancel(); + timeout = setTimeout(function () { + timeout = null; + fn.apply(context, args); + }, threshhold); + } + + // allow remove throttled timeout + throttledFn.cancel = cancel; + + return throttledFn; + }; + + function getScrollbarWidth() { + return root.innerWidth - _document.documentElement.clientWidth; + } + + // check whether event is cancelable + var isCancelable = function (event) { + if (!event) return false; + return typeof event.cancelable !== 'boolean' || event.cancelable; + }; + + // check browser capabilities + var browser = { + addEventListener: !!root.addEventListener, + passiveEvents: (function () { + // Test via a getter in the options object to see if the passive property is accessed + var supportsPassive = false; + try { + var opts = Object.defineProperty({}, 'passive', { + // eslint-disable-next-line getter-return + get: function () { + supportsPassive = true; + } + }); + root.addEventListener('testEvent', null, opts); + root.removeEventListener('testEvent', null, opts); + } + catch (e) { + supportsPassive = false; + } + return supportsPassive; + })(), + // eslint-disable-next-line no-undef + touch: ('ontouchstart' in root) || root.DocumentTouch && _document instanceof DocumentTouch, + transitions: (function (temp) { + var props = ['transitionProperty', 'WebkitTransition', 'MozTransition', 'OTransition', 'msTransition']; + for (var i in props) { + if (temp.style[props[i]] !== undefined) { + return true; + } + } + return false; + })(_document.createElement('swipe')) + }; + + // quit if no root element + if (!container) return; + + var element = container.children[0]; + var slides, slidePos, width, length; + var index = parseInt(options.startSlide, 10) || 0; + var speed = options.speed || 300; + options.continuous = options.continuous !== undefined ? options.continuous : true; + + // check text direction + var slideDir = (function (el, prop, dir) { + if (el.currentStyle) { + dir = el.currentStyle[prop]; + } else if (root.getComputedStyle) { + dir = root.getComputedStyle(el, null).getPropertyValue(prop); + } + return 'rtl' === dir ? 'right' : 'left'; + })(container, 'direction'); + + // AutoRestart option: auto restart slideshow after user's touch event + options.autoRestart = options.autoRestart !== undefined ? options.autoRestart : false; + + // throttled setup + var throttledSetup = throttle(setup); + + // setup event capturing + var events = { + + handleEvent: function (event) { + if (disabled) return; + + switch (event.type) { + case 'mousedown': + case 'touchstart': this.start(event); break; + case 'mousemove': + case 'touchmove': this.move(event); break; + case 'mouseup': + case 'mouseleave': + case 'touchend': this.end(event); break; + case 'webkitTransitionEnd': + case 'msTransitionEnd': + case 'oTransitionEnd': + case 'otransitionend': + case 'transitionend': this.transitionEnd(event); break; + case 'resize': throttledSetup(); break; + } + + if (options.stopPropagation) { + event.stopPropagation(); + } + }, + + start: function (event) { + var touches; + + if (isMouseEvent(event)) { + touches = event; + event.preventDefault(); // For desktop Safari drag + } else { + touches = event.touches[0]; + } + + // measure start values + start = { + + // get initial touch coords + x: touches.pageX, + y: touches.pageY, + + // store time to determine touch duration + time: +new Date() + + }; + + // used for testing first move event + isScrolling = undefined; + + // reset delta and end measurements + delta = {}; + + // attach touchmove and touchend listeners + if (isMouseEvent(event)) { + element.addEventListener('mousemove', this, false); + element.addEventListener('mouseup', this, false); + element.addEventListener('mouseleave', this, false); + } else { + element.addEventListener('touchmove', this, browser.passiveEvents ? { passive: false } : false); + element.addEventListener('touchend', this, false); + } + + }, + + move: function (event) { + var touches; + + if (isMouseEvent(event)) { + touches = event; + } else { + // ensure swiping with one touch and not pinching + if (event.touches.length > 1 || event.scale && event.scale !== 1) { + return; + } + + // we can disable scrolling unless it is already in progress + if (options.disableScroll && isCancelable(event)) { + event.preventDefault(); + } + + touches = event.touches[0]; + } + + // measure change in x and y + delta = { + x: touches.pageX - start.x, + y: touches.pageY - start.y + }; + + // determine if scrolling test has run - one time test + if (typeof isScrolling === 'undefined') { + isScrolling = !!(isScrolling || Math.abs(delta.x) < Math.abs(delta.y)); + } + + // if user is not trying to scroll vertically + if (!isScrolling) { + + // if it is not already scrolling + if (isCancelable(event)) { + // prevent native scrolling + event.preventDefault(); + } + + // stop slideshow + stop(); + + // increase resistance if first or last slide + if (options.continuous) { // we don't add resistance at the end + + translate(circle(index - 1), delta.x + slidePos[circle(index - 1)], 0); + translate(index, delta.x + slidePos[index], 0); + translate(circle(index + 1), delta.x + slidePos[circle(index + 1)], 0); + + } else { + + delta.x = + delta.x / + ((!index && delta.x > 0 || // if first slide and sliding left + index === slides.length - 1 && // or if last slide and sliding right + delta.x < 0 // and if sliding at all + ) ? + (Math.abs(delta.x) / width + 1) // determine resistance level + : 1); // no resistance if false + + // translate 1:1 + translate(index - 1, delta.x + slidePos[index - 1], 0); + translate(index, delta.x + slidePos[index], 0); + translate(index + 1, delta.x + slidePos[index + 1], 0); + } + } + }, + + end: function (event) { + + // measure duration + var duration = +new Date() - start.time; + + // determine if slide attempt triggers next/prev slide + var isValidSlide = + Number(duration) < 250 && // if slide duration is less than 250ms + Math.abs(delta.x) > 20 || // and if slide amt is greater than 20px + Math.abs(delta.x) > width / 2; // or if slide amt is greater than half the width + + // determine if slide attempt is past start and end + var isPastBounds = + !index && delta.x > 0 || // if first slide and slide amt is greater than 0 + index === slides.length - 1 && delta.x < 0; // or if last slide and slide amt is less than 0 + + if (options.continuous) { + isPastBounds = false; + } + + // OLD determine direction of swipe (true:right, false:left) + // determine direction of swipe (1: backward, -1: forward) + var direction = Math.abs(delta.x) / delta.x; + + // if not scrolling vertically + if (!isScrolling) { + + if (isValidSlide && !isPastBounds) { + + // if we're moving right + if (direction < 0) { + + if (options.continuous) { // we need to get the next in this direction in place + + move(circle(index - 1), -width, 0); + move(circle(index + 2), width, 0); + + } else { + move(index - 1, -width, 0); + } + + move(index, slidePos[index] - width, speed); + move(circle(index + 1), slidePos[circle(index + 1)] - width, speed); + index = circle(index + 1); + + } else { + if (options.continuous) { // we need to get the next in this direction in place + + move(circle(index + 1), width, 0); + move(circle(index - 2), -width, 0); + + } else { + move(index + 1, width, 0); + } + + move(index, slidePos[index] + width, speed); + move(circle(index - 1), slidePos[circle(index - 1)] + width, speed); + index = circle(index - 1); + } + + runCallback(getPos(), slides[index], direction); + + } else { + + if (options.continuous) { + + move(circle(index - 1), -width, speed); + move(index, 0, speed); + move(circle(index + 1), width, speed); + + } else { + + move(index - 1, -width, speed); + move(index, 0, speed); + move(index + 1, width, speed); + } + } + } + + // kill touchmove and touchend event listeners until touchstart called again + if (isMouseEvent(event)) { + element.removeEventListener('mousemove', events, false); + element.removeEventListener('mouseup', events, false); + element.removeEventListener('mouseleave', events, false); + } else { + element.removeEventListener('touchmove', events, browser.passiveEvents ? { passive: false } : false); + element.removeEventListener('touchend', events, false); + } + + }, + + transitionEnd: function (event) { + var currentIndex = parseInt(event.target.getAttribute('data-index'), 10); + if (currentIndex === index) { + if (delay || options.autoRestart) restart(); + + runTransitionEnd(getPos(), slides[index]); + } + } + }; + + // trigger setup + setup(); + + // start auto slideshow if applicable + begin(); + + // Expose the Swipe API + return { + // initialize + setup: setup, + + // go to slide + slide: function (to, speed) { + stop(); + slide(to, speed); + }, + + // move to previous + prev: function () { + stop(); + prev(); + }, + + // move to next + next: function () { + stop(); + next(); + }, + + // Restart slideshow + restart: restart, + + // cancel slideshow + stop: stop, + + // return current index position + getPos: getPos, + + // disable slideshow + disable: disable, + + // enable slideshow + enable: enable, + + // return total number of slides + getNumSlides: function () { return length; }, + + // completely remove swipe + kill: kill + }; + + // remove all event listeners + function detachEvents() { + if (browser.addEventListener) { + // remove current event listeners + element.removeEventListener('touchstart', events, browser.passiveEvents ? { passive: true } : false); + element.removeEventListener('mousedown', events, false); + element.removeEventListener('webkitTransitionEnd', events, false); + element.removeEventListener('msTransitionEnd', events, false); + element.removeEventListener('oTransitionEnd', events, false); + element.removeEventListener('otransitionend', events, false); + element.removeEventListener('transitionend', events, false); + root.removeEventListener('resize', events, false); + } else { + root.onresize = null; + } + } + + // add event listeners + function attachEvents() { + if (browser.addEventListener) { + + // set touchstart event on element + if (browser.touch) { + element.addEventListener('touchstart', events, browser.passiveEvents ? { passive: true } : false); + } + + if (options.draggable) { + element.addEventListener('mousedown', events, false); + } + + if (browser.transitions) { + element.addEventListener('webkitTransitionEnd', events, false); + element.addEventListener('msTransitionEnd', events, false); + element.addEventListener('oTransitionEnd', events, false); + element.addEventListener('otransitionend', events, false); + element.addEventListener('transitionend', events, false); + } + + // set resize event on window + root.addEventListener('resize', events, false); + + } else { + root.onresize = throttledSetup; // to play nice with old IE + } + } + + // clone nodes when there is only two slides + function cloneNode(el) { + var clone = el.cloneNode(true); + element.appendChild(clone); + + // tag these slides as clones (to remove them on kill) + clone.setAttribute('data-cloned', true); + + // Remove id from element + clone.removeAttribute('id'); + } + + function setup(opts) { + // Overwrite options if necessary + if (opts != null) { + for (var prop in opts) { + options[prop] = opts[prop]; + } + } + + // cache slides + slides = element.children; + length = slides.length; + + // slides length correction, minus cloned slides + for (var i = 0; i < slides.length; i++) { + if (slides[i].getAttribute('data-cloned')) length--; + } + + // set continuous to false if only one slide + if (slides.length < 2) { + options.continuous = false; + } + + // special case if two slides + if (browser.transitions && options.continuous && slides.length < 3) { + cloneNode(slides[0]); + cloneNode(slides[1]); + + slides = element.children; + } + + // adjust style on rtl + if ('right' === slideDir) { + for (var j = 0; j < slides.length; j++) { + slides[j].style.float = 'right'; + } + } + + // create an array to store current positions of each slide + slidePos = new Array(slides.length); + + // determine width of each slide + //width = container.getBoundingClientRect().width || container.offsetWidth; + width = root.innerWidth - getScrollbarWidth(); + element.style.width = (slides.length * width * 2) + 'px'; + // stack elements + var pos = slides.length; + while (pos--) { + var slide = slides[pos]; + + slide.style.width = width + 'px'; + slide.setAttribute('data-index', pos); + + if (browser.transitions) { + slide.style[slideDir] = (pos * -width) + 'px'; + move(pos, index > pos ? -width : (index < pos ? width : 0), 0); + } + } + + // reposition elements before and after index + if (options.continuous && browser.transitions) { + move(circle(index - 1), -width, 0); + move(circle(index + 1), width, 0); + } + + if (!browser.transitions) { + element.style[slideDir] = (index * -width) + 'px'; + } + + container.style.visibility = 'visible'; + + // reinitialize events + detachEvents(); + attachEvents(); + } + + function prev() { + if (disabled) return; + + if (options.continuous) { + slide(index - 1); + } else if (index) { + slide(index - 1); + } + } + + function next() { + if (disabled) return; + if (options.continuous) { + slide(index + 1); + } else if (index < slides.length - 1) { + slide(index + 1); + } + } + + function runCallback(pos, index, dir) { + if (options.callback) { + options.callback(pos, index, dir); + } + } + + function runTransitionEnd(pos, index) { + if (options.transitionEnd) { + options.transitionEnd(pos, index); + } + } + + function circle(index) { + + // a simple positive modulo using slides.length + return (slides.length + (index % slides.length)) % slides.length; + } + + function getPos() { + // Fix for the clone issue in the event of 2 slides + var currentIndex = index; + + if (currentIndex >= length) { + currentIndex = currentIndex - length; + } + + return currentIndex; + } + + function slide(to, slideSpeed) { + + // ensure to is of type 'number' + to = typeof to !== 'number' ? parseInt(to, 10) : to; + + // do nothing if already on requested slide + if (index === to) return; + + if (browser.transitions) { + + var direction = Math.abs(index - to) / (index - to); // 1: backward, -1: forward + + // get the actual position of the slide + if (options.continuous) { + var natural_direction = direction; + direction = -slidePos[circle(to)] / width; + + // if going forward but to < index, use to = slides.length + to + // if going backward but to > index, use to = -slides.length + to + if (direction !== natural_direction) { + to = -direction * slides.length + to; + } + + } + + var diff = Math.abs(index - to) - 1; + + // move all the slides between index and to in the right direction + while (diff--) { + move(circle((to > index ? to : index) - diff - 1), width * direction, 0); + } + + to = circle(to); + + move(index, width * direction, slideSpeed || speed); + move(to, 0, slideSpeed || speed); + + if (options.continuous) { // we need to get the next in place + move(circle(to - direction), -(width * direction), 0); + } + + } else { + + to = circle(to); + animate(index * -width, to * -width, slideSpeed || speed); + // no fallback for a circular continuous if the browser does not accept transitions + } + + index = to; + offloadFn(function () { + runCallback(getPos(), slides[index], direction); + }); + } + + function move(index, dist, speed) { + translate(index, dist, speed); + slidePos[index] = dist; + } + + function translate(index, dist, speed) { + + var slide = slides[index]; + var style = slide && slide.style; + + if (!style) return; + + style.webkitTransitionDuration = + style.MozTransitionDuration = + style.msTransitionDuration = + style.OTransitionDuration = + style.transitionDuration = speed + 'ms'; + + style.webkitTransform = + style.msTransform = + style.MozTransform = + style.OTransform = + style.transform = 'translateX(' + dist + 'px)'; + } + + function animate(from, to, speed) { + + // if not an animation, just reposition + if (!speed) { + element.style[slideDir] = to + 'px'; + return; + } + + var start = +new Date(); + + var timer = setInterval(function () { + var timeElap = +new Date() - start; + + if (timeElap > speed) { + + element.style[slideDir] = to + 'px'; + + if (delay || options.autoRestart) restart(); + + runTransitionEnd(getPos(), slides[index]); + + clearInterval(timer); + + return; + } + + element.style[slideDir] = (((to - from) * (Math.floor((timeElap / speed) * 100) / 100)) + from) + 'px'; + }, 4); + + } + + function begin() { + delay = options.auto || 0; + if (delay) interval = setTimeout(next, delay); + } + + function stop() { + delay = 0; + clearTimeout(interval); + } + + function restart() { + stop(); + begin(); + } + + function disable() { + stop(); + disabled = true; + } + + function enable() { + disabled = false; + restart(); + } + + function isMouseEvent(e) { + return /^mouse/.test(e.type); + } + + function kill() { + // cancel slideshow + stop(); + + // remove inline styles + container.style.visibility = ''; + + // reset element + element.style.width = ''; + element.style[slideDir] = ''; + + // reset slides + var pos = slides.length; + while (pos--) { + + if (browser.transitions) { + translate(pos, 0, 0); + } + + var slide = slides[pos]; + + // if the slide is tagged as clone, remove it + if (slide.getAttribute('data-cloned')) { + var _parent = slide.parentElement; + _parent.removeChild(slide); + } + + // remove styles + slide.style.width = ''; + slide.style[slideDir] = ''; + + slide.style.webkitTransitionDuration = + slide.style.MozTransitionDuration = + slide.style.msTransitionDuration = + slide.style.OTransitionDuration = + slide.style.transitionDuration = ''; + + slide.style.webkitTransform = + slide.style.msTransform = + slide.style.MozTransform = + slide.style.OTransform = ''; + + // remove custom attributes (?) + // slide.removeAttribute('data-index'); + } + + // remove all events + detachEvents(); + + // remove throttled function timeout + throttledSetup.cancel(); + } + } + + if (root.jQuery || root.Zepto) { + (function ($) { + $.fn.Swipe = function (params) { + return this.each(function () { + $(this).data('Swipe', new Swipe($(this)[0], params)); + }); + }; + })(root.jQuery || root.Zepto); + } + + return Swipe; +})); \ No newline at end of file diff --git a/assets/js/zzo.js b/assets/js/zzo.js deleted file mode 100644 index 831f725..0000000 --- a/assets/js/zzo.js +++ /dev/null @@ -1,188 +0,0 @@ -$(document).ready(function() { - // theme change - var localTheme = localStorage.getItem('theme'); - if (localTheme) { - $('.select-theme__item').each(function () { - $(this).removeClass('is-active'); - }); - $(`.select-theme a:contains("${localTheme}")`).addClass('is-active'); - } - - $('.select-theme__item').click(function (e) { - var selectedThemeVariant = $(e.target).text().trim(); - localStorage.setItem('theme', selectedThemeVariant); - - if ($(this).attr('class').trim() === selectedThemeVariant) { - return null; - } - - $('#root').removeAttr('class').addClass(`theme__${selectedThemeVariant}`); - var nodes = $('.select-theme').children('.dropdown-item'); - - nodes.each(function () { - if ($(this).text().trim() === selectedThemeVariant) { - if (!$(this).hasClass('is-active')) { - $(this).addClass('is-active'); - } - } else { - if ($(this).hasClass('is-active')) { - $(this).removeClass('is-active'); - } - } - }); - - if (window.mermaid) { - if (selectedThemeVariant === "dark" || selectedThemeVariant === "hacker") { - mermaid.initialize({ theme: 'dark' }); - location.reload(); - } else { - mermaid.initialize({ theme: 'default' }); - location.reload(); - } - } - - var utterances = document.querySelector('iframe'); - if (utterances) { - utterances.contentWindow.postMessage({ - type: 'set-theme', - theme: selectedThemeVariant === "dark" || selectedThemeVariant === "hacker" ? 'photon-dark' : 'github-light', - }, 'https://utteranc.es'); - } - }); - - // go to top - $('.gtt').click(function () { - $("html, body").animate({ scrollTop: 0 }, 250); - }); - - if ($(window).scrollTop() === 0) { - $('.gtt').hide(200); - } else if ($(this).scrollTop() > $(document).height() - $(window).height() - 250) { // near the bottom - $('.gtt').show(200); - } else { - $('.gtt').hide(200); - } - - // scroll - var position = $(window).scrollTop(); - $(window).scroll(function () { - var navbar = $('.navbar'); - - var scroll = $(window).scrollTop(); - if (scroll > position) { // scroll down - if (scroll < 250) { - $('.gtt').hide(200); - } else { - $('.gtt').show(200); - } - - if (scroll < 45) { - return null; - } - - if (!navbar.hasClass('navbar--hide')) { - navbar.addClass('navbar--hide'); - } else if (navbar.hasClass('navbar--show')) { - navbar.removeClass('navbar--show'); - } - - $(".single__contents :header").each(function () { - if (!$("#toggle-toc").is(":checked")) { - return null; - } - - if ($(window).scrollTop() >= $(this).position().top) { - var id = $(this).attr('id'); - $('.toc a').removeClass('active'); - $('.toc a[href="#' + id + '"]').addClass('active'); - - $('#TableOfContents > ul > li').each(function () { - $(this).find('ul').css('display', 'none'); - }); - $(`#TableOfContents [href="#${id}"]`).next().css('display', 'block'); - $(`#TableOfContents [href="#${id}"]`).parents('ul').css('display', 'block'); - } - }); - } else { // scroll up - if (scroll < 250) { - $('.gtt').hide(200); - } - - if (navbar.hasClass('navbar--hide')) { - navbar.removeClass('navbar--hide'); - } else if (!navbar.hasClass('navbar--show')) { - navbar.addClass('navbar--show'); - } - - $(".single__contents :header").each(function () { - if (!$("#toggle-toc").is(":checked")) { - return null; - } - - if ($(window).scrollTop() >= $(this).position().top) { - var id = $(this).attr('id'); - $('.toc a').removeClass('active'); - $('.toc a[href="#' + id + '"]').addClass('active'); - - $('#TableOfContents > ul > li').each(function () { - $(this).find('ul').css('display', 'none'); - }); - $(`#TableOfContents [href="#${id}"]`).next().css('display', 'block'); - $(`#TableOfContents [href="#${id}"]`).parents('ul').css('display', 'block'); - } - }); - } - position = scroll; - }); - - // navbar - $('.navbar__burger').click(function() { - if ($(this).hasClass('is-active')) { - $(this).removeClass('is-active'); - $('.navbar__menu').removeClass('is-active'); - } else { - $(this).addClass('is-active'); - $('.navbar__menu').addClass('is-active'); - } - }); - - // mobile search - $('.mobile-search').hide(200); - $('#mobileSearchBtn').click(function() { - $('#search-mobile-container').fadeIn(250); - $('#search-mobile').focus(); - $('html').css('overflow-y', 'hidden'); - }); - $('#search-mobile-close').click(function() { - $('#search-mobile-container').fadeOut(250); - $('#search-mobile').val(''); - $('#search-mobile-results').empty(); - $('html').css('overflow-y', 'visible'); - }); - $('#search-mobile').keydown(function(e) { - // e.key === "Enter" - if (e.key === "Escape") { - $('#search-mobile-container').fadeOut(250); - $('#search-mobile').val(''); - $('#search-mobile-results').empty(); - $('html').css('overflow-y', 'visible'); - } - }); - - // markdown table - const tables = document.querySelectorAll('.single__contents > table'); - for (let i = 0; i < tables.length; i++) { - const table = tables[i]; - const wrapper = document.createElement('div'); - wrapper.className = 'table-wrapper'; - table.parentElement.replaceChild(wrapper, table); - wrapper.appendChild(table); - } - - // utils - $.fn.digits = function() { - return this.each(function() { - $(this).text($(this).text().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")); - }) - } -}); diff --git a/assets/lib/photoswipe/custom-skin.css b/assets/lib/photoswipe/custom-skin.css deleted file mode 100644 index 84bd678..0000000 --- a/assets/lib/photoswipe/custom-skin.css +++ /dev/null @@ -1,586 +0,0 @@ -/*! PhotoSwipe Default UI CSS by Dmitry Semenov | photoswipe.com | MIT license */ -/* - Contents: - 1. Buttons - 2. Share modal and links - 3. Index indicator ("1 of X" counter) - 4. Caption - 5. Loading indicator - 6. Additional styles (root element, top bar, idle state, hidden state, etc.) -*/ -/* - - 1. Buttons - */ -/*