diff --git a/dist/reveal.min.js b/dist/reveal.min.js index b968efe..ee4b254 100644 --- a/dist/reveal.min.js +++ b/dist/reveal.min.js @@ -5,4 +5,4 @@ * * Copyright (C) 2020 Hakim El Hattab, https://hakim.se */ -!function(e){var t={};function a(r){if(t[r])return t[r].exports;var n=t[r]={i:r,l:!1,exports:{}};return e[r].call(n.exports,n,n.exports,a),n.l=!0,n.exports}a.m=e,a.c=t,a.d=function(e,t,r){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(a.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)a.d(r,n,function(t){return e[t]}.bind(null,n));return r},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="",a(a.s=0)}([function(e,t,a){"use strict";a.r(t);const r=/registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener/,n=(e,t)=>{for(let a in t)e[a]=t[a];return e},i=e=>Array.prototype.slice.call(e),s=e=>{if("string"==typeof e){if("null"===e)return null;if("true"===e)return!0;if("false"===e)return!1;if(e.match(/^-?[\d\.]+$/))return parseFloat(e)}return e},o=(e,t)=>{e.style.transform=t},l=(e,t)=>{let a=e.parentNode;for(;a;){let e=a.matches||a.matchesSelector||a.msMatchesSelector;if(e&&e.call(a,t))return a;a=a.parentNode}return null},d=e=>{let t=document.createElement("style");t.type="text/css",t.styleSheet?t.styleSheet.cssText=e:t.appendChild(document.createTextNode(e)),document.getElementsByTagName("head")[0].appendChild(t)};class c{constructor(e){this.Reveal=e}load(e,t={}){e.style.display=this.Reveal.getConfig().display,i(e.querySelectorAll("img[data-src], video[data-src], audio[data-src], iframe[data-src]")).forEach(e=>{("IFRAME"!==e.tagName||shouldPreload(e))&&(e.setAttribute("src",e.getAttribute("data-src")),e.setAttribute("data-lazy-loaded",""),e.removeAttribute("data-src"))}),i(e.querySelectorAll("video, audio")).forEach(e=>{let t=0;i(e.querySelectorAll("source[data-src]")).forEach(e=>{e.setAttribute("src",e.getAttribute("data-src")),e.removeAttribute("data-src"),e.setAttribute("data-lazy-loaded",""),t+=1}),t>0&&e.load()});let a=e.slideBackgroundElement;if(a){a.style.display="block";let r=e.slideBackgroundContentElement,n=e.getAttribute("data-background-iframe");if(!1===a.hasAttribute("data-loaded")){a.setAttribute("data-loaded","true");let i=e.getAttribute("data-background-image"),s=e.getAttribute("data-background-video"),o=e.hasAttribute("data-background-video-loop"),l=e.hasAttribute("data-background-video-muted");if(i)r.style.backgroundImage="url("+encodeURI(i)+")";else if(s&&!this.Reveal.isSpeakerNotes()){let e=document.createElement("video");o&&e.setAttribute("loop",""),l&&(e.muted=!0),isMobileDevice&&(e.muted=!0,e.autoplay=!0,e.setAttribute("playsinline","")),s.split(",").forEach(t=>{e.innerHTML+=''}),r.appendChild(e)}else if(n&&!0!==t.excludeIframes){let e=document.createElement("iframe");e.setAttribute("allowfullscreen",""),e.setAttribute("mozallowfullscreen",""),e.setAttribute("webkitallowfullscreen",""),e.setAttribute("allow","autoplay"),e.setAttribute("data-src",n),e.style.width="100%",e.style.height="100%",e.style.maxHeight="100%",e.style.maxWidth="100%",r.appendChild(e)}}let i=r.querySelector("iframe[data-src]");i&&shouldPreload(a)&&!/autoplay=(1|true|yes)/gi.test(n)&&i.getAttribute("src")!==n&&i.setAttribute("src",n)}}unload(e){e.style.display="none";let t=this.Reveal.getSlideBackground(e);t&&(t.style.display="none",i(t.querySelectorAll("iframe[src]")).forEach(e=>{e.removeAttribute("src")})),i(e.querySelectorAll("video[data-lazy-loaded][src], audio[data-lazy-loaded][src], iframe[data-lazy-loaded][src]")).forEach(e=>{e.setAttribute("data-src",e.getAttribute("src")),e.removeAttribute("src")}),i(e.querySelectorAll("video[data-lazy-loaded] source[src], audio source[src]")).forEach(e=>{e.setAttribute("data-src",e.getAttribute("src")),e.removeAttribute("src")})}formatEmbeddedContent(){let e=(e,t,a)=>{i(this.Reveal.getSlidesElement().querySelectorAll("iframe["+e+'*="'+t+'"]')).forEach(t=>{let r=t.getAttribute(e);r&&-1===r.indexOf(a)&&t.setAttribute(e,r+(/\?/.test(r)?"&":"?")+a)})};e("src","youtube.com/embed/","enablejsapi=1"),e("data-src","youtube.com/embed/","enablejsapi=1"),e("src","player.vimeo.com/","api=1"),e("data-src","player.vimeo.com/","api=1")}startEmbeddedContent(e){e&&!this.Reveal.isSpeakerNotes()&&(i(e.querySelectorAll('img[src$=".gif"]')).forEach(e=>{e.setAttribute("src",e.getAttribute("src"))}),i(e.querySelectorAll("video, audio")).forEach(e=>{if(l(e,".fragment")&&!l(e,".fragment.visible"))return;let t=config.autoPlayMedia;if("boolean"!=typeof t&&(t=e.hasAttribute("data-autoplay")||!!l(e,".slide-background")),t&&"function"==typeof e.play)if(e.readyState>1)this.startEmbeddedMedia({target:e});else if(isMobileDevice){let t=e.play();t&&"function"==typeof t.catch&&!1===e.controls&&t.catch(()=>{e.controls=!0,e.addEventListener("play",()=>{e.controls=!1})})}else e.removeEventListener("loadeddata",this.startEmbeddedMedia),e.addEventListener("loadeddata",this.startEmbeddedMedia)}),i(e.querySelectorAll("iframe[src]")).forEach(e=>{l(e,".fragment")&&!l(e,".fragment.visible")||this.startEmbeddedIframe({target:e})}),i(e.querySelectorAll("iframe[data-src]")).forEach(e=>{l(e,".fragment")&&!l(e,".fragment.visible")||e.getAttribute("src")!==e.getAttribute("data-src")&&(e.removeEventListener("load",this.startEmbeddedIframe),e.addEventListener("load",this.startEmbeddedIframe),e.setAttribute("src",e.getAttribute("data-src")))}))}startEmbeddedMedia(e){let t=!!l(e.target,"html"),a=!!l(e.target,".present");t&&a&&(e.target.currentTime=0,e.target.play()),e.target.removeEventListener("loadeddata",this.startEmbeddedMedia)}startEmbeddedIframe(e){let t=e.target;if(t&&t.contentWindow){let a=!!l(e.target,"html"),r=!!l(e.target,".present");if(a&&r){let e=config.autoPlayMedia;"boolean"!=typeof e&&(e=t.hasAttribute("data-autoplay")||!!l(t,".slide-background")),/youtube\.com\/embed\//.test(t.getAttribute("src"))&&e?t.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}',"*"):/player\.vimeo\.com\//.test(t.getAttribute("src"))&&e?t.contentWindow.postMessage('{"method":"play"}',"*"):t.contentWindow.postMessage("slide:start","*")}}}stopEmbeddedContent(e,t={}){t=n({unloadIframes:!0},t),e&&e.parentNode&&(i(e.querySelectorAll("video, audio")).forEach(e=>{e.hasAttribute("data-ignore")||"function"!=typeof e.pause||(e.setAttribute("data-paused-by-reveal",""),e.pause())}),i(e.querySelectorAll("iframe")).forEach(e=>{e.contentWindow&&e.contentWindow.postMessage("slide:stop","*"),e.removeEventListener("load",this.startEmbeddedIframe)}),i(e.querySelectorAll('iframe[src*="youtube.com/embed/"]')).forEach(e=>{!e.hasAttribute("data-ignore")&&e.contentWindow&&"function"==typeof e.contentWindow.postMessage&&e.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}',"*")}),i(e.querySelectorAll('iframe[src*="player.vimeo.com/"]')).forEach(e=>{!e.hasAttribute("data-ignore")&&e.contentWindow&&"function"==typeof e.contentWindow.postMessage&&e.contentWindow.postMessage('{"method":"pause"}',"*")}),!0===t.unloadIframes&&i(e.querySelectorAll("iframe[data-src]")).forEach(e=>{e.setAttribute("src","about:blank"),e.removeAttribute("src")}))}}class u{constructor(e){this.Reveal=e,this.autoAnimateCounter=0}run(e,t){if(this.removeEphemeralAutoAnimateAttributes(),this.autoAnimateStyleSheet&&this.autoAnimateStyleSheet.parentNode&&(this.autoAnimateStyleSheet.parentNode.removeChild(this.autoAnimateStyleSheet),this.autoAnimateStyleSheet=null),e.hasAttribute("data-auto-animate")&&t.hasAttribute("data-auto-animate")){this.autoAnimateStyleSheet=this.autoAnimateStyleSheet||document.createElement("style"),this.autoAnimateStyleSheet.type="text/css",document.head.appendChild(this.autoAnimateStyleSheet);let a=this.getAutoAnimateOptions(t);e.dataset.autoAnimate="pending",t.dataset.autoAnimate="pending";let r=this.getAutoAnimatableElements(e,t).map(e=>this.getAutoAnimateCSS(e.from,e.to,e.options||{},a,this.autoAnimateCounter++));"false"!==t.dataset.autoAnimateUnmatched&&!0===this.Reveal.getConfig().autoAnimateUnmatched&&(this.getUnmatchedAutoAnimateElements(t).forEach(e=>{e.dataset.autoAnimateTarget="unmatched"}),r.push(`[data-auto-animate="running"] [data-auto-animate-target="unmatched"] { transition: opacity ${.8*a.duration}s ease ${.2*a.duration}s; }`)),this.autoAnimateStyleSheet.innerHTML=r.join(""),requestAnimationFrame(()=>{this.autoAnimateStyleSheet&&(getComputedStyle(this.autoAnimateStyleSheet).fontWeight,t.dataset.autoAnimate="running")})}}removeEphemeralAutoAnimateAttributes(){i(this.Reveal.getRevealElement().querySelectorAll("[data-auto-animate-target]")).forEach(e=>{delete e.dataset.autoAnimateTarget})}getAutoAnimateCSS(e,t,a,r,n){e.dataset.autoAnimateTarget="",t.dataset.autoAnimateTarget=n;let i=this.getAutoAnimateOptions(t,r);void 0!==a.delay&&(i.delay=a.delay),void 0!==a.duration&&(i.duration=a.duration),void 0!==a.easing&&(i.easing=a.easing);let s=this.getAutoAnimatableProperties("from",e,a),o=this.getAutoAnimatableProperties("to",t,a);if(!1!==a.translate||!1!==a.scale){let e=this.Reveal.getScale(),t={x:(s.x-o.x)/e,y:(s.y-o.y)/e,scaleX:s.width/o.width,scaleY:s.height/o.height};t.x=Math.round(1e3*t.x)/1e3,t.y=Math.round(1e3*t.y)/1e3,t.scaleX=Math.round(1e3*t.scaleX)/1e3,t.scaleX=Math.round(1e3*t.scaleX)/1e3;let r=!1!==a.translate&&(0!==t.x||0!==t.y),n=!1!==a.scale&&(0!==t.scaleX||0!==t.scaleY);if(r||n){let e=[];r&&e.push(`translate(${t.x}px, ${t.y}px)`),n&&e.push(`scale(${t.scaleX}, ${t.scaleY})`),s.styles.transform=e.join(" "),s.styles["transform-origin"]="top left",o.styles.transform="none"}}for(let e in o.styles){const t=o.styles[e],a=s.styles[e];t===a?delete o.styles[e]:(!0===t.explicitValue&&(o.styles[e]=t.value),!0===a.explicitValue&&(s.styles[e]=a.value))}let l="",d=Object.keys(o.styles);if(d.length>0){s.styles.transition="none",o.styles.transition=`all ${i.duration}s ${i.easing} ${i.delay}s`,o.styles["transition-property"]=d.join(", "),o.styles["will-change"]=d.join(", "),l='[data-auto-animate-target="'+n+'"] {'+Object.keys(s.styles).map(e=>e+": "+s.styles[e]+" !important;").join("")+'}[data-auto-animate="running"] [data-auto-animate-target="'+n+'"] {'+Object.keys(o.styles).map(e=>e+": "+o.styles[e]+" !important;").join("")+"}"}return l}getAutoAnimateOptions(e,t){let a={easing:this.Reveal.getConfig().autoAnimateEasing,duration:this.Reveal.getConfig().autoAnimateDuration,delay:0};if(a=n(a,t),e.closest&&e.parentNode){let t=e.parentNode.closest("[data-auto-animate-target]");t&&(a=this.getAutoAnimateOptions(t,a))}return e.dataset.autoAnimateEasing&&(a.easing=e.dataset.autoAnimateEasing),e.dataset.autoAnimateDuration&&(a.duration=parseFloat(e.dataset.autoAnimateDuration)),e.dataset.autoAnimateDelay&&(a.delay=parseFloat(e.dataset.autoAnimateDelay)),a}getAutoAnimatableProperties(e,t,a){let r={styles:[]};if(!1!==a.translate||!1!==a.scale){let e;e="function"==typeof a.measure?a.measure(t):t.getBoundingClientRect(),r.x=e.x,r.y=e.y,r.width=e.width,r.height=e.height}const n=getComputedStyle(t);return(a.styles||this.Reveal.getConfig().autoAnimateStyles).forEach(t=>{let a;"string"==typeof t&&(t={property:t}),a=void 0!==t.from&&"from"===e?{value:t.from,explicitValue:!0}:void 0!==t.to&&"to"===e?{value:t.to,explicitValue:!0}:n[t.property],""!==a&&(r.styles[t.property]=a)}),r}getAutoAnimatableElements(e,t){let a=("function"==typeof this.Reveal.getConfig().autoAnimateMatcher?this.Reveal.getConfig().autoAnimateMatcher:this.getAutoAnimatePairs).call(this,e,t),r=[];return a.filter((e,t)=>{if(-1===r.indexOf(e.to))return r.push(e.to),!0})}getAutoAnimatePairs(e,t){let a=[];const r="h1, h2, h3, h4, h5, h6, p, li";return this.findAutoAnimateMatches(a,e,t,"[data-id]",e=>e.nodeName+":::"+e.getAttribute("data-id")),this.findAutoAnimateMatches(a,e,t,r,e=>e.nodeName+":::"+e.innerText),this.findAutoAnimateMatches(a,e,t,"img, video, iframe",e=>e.nodeName+":::"+(e.getAttribute("src")||e.getAttribute("data-src"))),this.findAutoAnimateMatches(a,e,t,"pre",e=>e.nodeName+":::"+e.innerText),a.forEach(e=>{e.from.matches(r)?e.options={scale:!1}:e.from.matches("pre")&&(e.options={scale:!1,styles:["width","height"]},this.findAutoAnimateMatches(a,e.from,e.to,".hljs .hljs-ln-code",e=>e.textContent,{scale:!1,styles:[],measure:this.getLocalBoundingBox.bind(this)}),this.findAutoAnimateMatches(a,e.from,e.to,".hljs .hljs-ln-line[data-line-number]",e=>e.getAttribute("data-line-number"),{scale:!1,styles:["width"],measure:this.getLocalBoundingBox.bind(this)}))},this),a}getLocalBoundingBox(e){const t=this.Reveal.getScale();return{x:Math.round(e.offsetLeft*t*100)/100,y:Math.round(e.offsetTop*t*100)/100,width:Math.round(e.offsetWidth*t*100)/100,height:Math.round(e.offsetHeight*t*100)/100}}findAutoAnimateMatches(e,t,a,r,n,i){let s={},o={};[].slice.call(t.querySelectorAll(r)).forEach((e,t)=>{const a=n(e);"string"==typeof a&&a.length&&(s[a]=s[a]||[],s[a].push(e))}),[].slice.call(a.querySelectorAll(r)).forEach((t,a)=>{const r=n(t);let l;if(o[r]=o[r]||[],o[r].push(t),s[r]){const e=o[r].length-1,t=s[r].length-1;s[r][e]?(l=s[r][e],s[r][e]=null):s[r][t]&&(l=s[r][t],s[r][t]=null)}l&&e.push({from:l,to:t,options:i})})}getUnmatchedAutoAnimateElements(e){return[].slice.call(e.children).reduce((e,t)=>{const a=t.querySelector("[data-auto-animate-target]");return t.hasAttribute("data-auto-animate-target")||a||e.push(t),t.querySelector("[data-auto-animate-target]")&&(e=e.concat(this.getUnmatchedAutoAnimateElements(t))),e},[])}disable(){i(this.Reveal.getRevealElement().querySelectorAll('[data-auto-animate]:not([data-auto-animate=""])')).forEach(e=>{e.dataset.autoAnimate=""}),this.removeEphemeralAutoAnimateAttributes(),this.autoAnimateStyleSheet&&this.autoAnimateStyleSheet.parentNode&&(this.autoAnimateStyleSheet.parentNode.removeChild(this.autoAnimateStyleSheet),this.autoAnimateStyleSheet=null)}}const p=(e,t)=>{const a=document.createElement("script");a.type="text/javascript",a.async=!1,a.defer=!1,a.src=e,"function"==typeof t&&(a.onload=a.onreadystatechange=e=>{("load"===e.type||/loaded|complete/.test(a.readyState))&&(a.onload=a.onreadystatechange=a.onerror=null,t())},a.onerror=e=>{a.onload=a.onreadystatechange=a.onerror=null,t(new Error("Failed loading script: "+a.src+"\n"+e))});const r=document.querySelector("head");r.insertBefore(a,r.lastChild)};class h{constructor(){this.state="pending",this.registeredPlugins={},this.asyncDependencies=[]}load(e){return this.state="loading",new Promise(t=>{let a=[],r=0;e.forEach(e=>{e.condition&&!e.condition()||(e.async?this.asyncDependencies.push(e):a.push(e))}),a.length?(r=a.length,a.forEach(e=>{p(e.src,()=>{"function"==typeof e.callback&&e.callback(),0==--r&&this.initPlugins().then(t)})})):this.initPlugins().then(t)})}initPlugins(){return new Promise(e=>{let t=Object.keys(this.registeredPlugins).length;if(0===t)this.loadAsync().then(e);else{let a=()=>{0==--t&&this.loadAsync().then(e)};for(let e in this.registeredPlugins){let t=this.registeredPlugins[e];if("function"==typeof t.init){let e=t.init();e&&"function"==typeof e.then?e.then(a):a()}else a()}}})}loadAsync(){return this.state="loaded",this.asyncDependencies.length&&this.asyncDependencies.forEach(e=>{p(e.src,e.callback)}),Promise.resolve()}registerPlugin(e,t){void 0===this.registeredPlugins[e]?(this.registeredPlugins[e]=t,"loaded"===this.state&&"function"==typeof t.init&&t.init()):console.warn('reveal.js: "'+e+'" plugin has already been registered')}hasPlugin(e){return!!this.registeredPlugins[e]}getPlugin(e){return this.registeredPlugins[e]}getRegisteredPlugins(){return this.registeredPlugins}}class g{constructor(e,t){this.diameter=100,this.diameter2=this.diameter/2,this.thickness=6,this.playing=!1,this.progress=0,this.progressOffset=1,this.container=e,this.progressCheck=t,this.canvas=document.createElement("canvas"),this.canvas.className="playback",this.canvas.width=this.diameter,this.canvas.height=this.diameter,this.canvas.style.width=this.diameter2+"px",this.canvas.style.height=this.diameter2+"px",this.context=this.canvas.getContext("2d"),this.container.appendChild(this.canvas),this.render()}setPlaying(e){const t=this.playing;this.playing=e,!t&&this.playing?this.animate():this.render()}animate(){const e=this.progress;this.progress=this.progressCheck(),e>.8&&this.progress<.2&&(this.progressOffset=this.progress),this.render(),this.playing&&requestAnimationFrame(this.animate.bind(this))}render(){let e=this.playing?this.progress:0,t=this.diameter2-this.thickness,a=this.diameter2,r=this.diameter2;this.progressOffset+=.1*(1-this.progressOffset);const n=-Math.PI/2+e*(2*Math.PI),i=-Math.PI/2+this.progressOffset*(2*Math.PI);this.context.save(),this.context.clearRect(0,0,this.diameter,this.diameter),this.context.beginPath(),this.context.arc(a,r,t+4,0,2*Math.PI,!1),this.context.fillStyle="rgba( 0, 0, 0, 0.4 )",this.context.fill(),this.context.beginPath(),this.context.arc(a,r,t,0,2*Math.PI,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="rgba( 255, 255, 255, 0.2 )",this.context.stroke(),this.playing&&(this.context.beginPath(),this.context.arc(a,r,t,i,n,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="#fff",this.context.stroke()),this.context.translate(a-14,r-14),this.playing?(this.context.fillStyle="#fff",this.context.fillRect(0,0,10,28),this.context.fillRect(18,0,10,28)):(this.context.beginPath(),this.context.translate(4,0),this.context.moveTo(0,0),this.context.lineTo(24,14),this.context.lineTo(0,28),this.context.fillStyle="#fff",this.context.fill()),this.context.restore()}on(e,t){this.canvas.addEventListener(e,t,!1)}off(e,t){this.canvas.removeEventListener(e,t,!1)}destroy(){this.playing=!1,this.canvas.parentNode&&this.container.removeChild(this.canvas)}}var f={width:960,height:700,margin:.04,minScale:.2,maxScale:2,controls:!0,controlsTutorial:!0,controlsLayout:"bottom-right",controlsBackArrows:"faded",progress:!0,slideNumber:!1,showSlideNumber:"all",hashOneBasedIndex:!1,hash:!1,history:!1,keyboard:!0,keyboardCondition:null,overview:!0,disableLayout:!1,center:!0,touch:!0,loop:!1,rtl:!1,navigationMode:"default",shuffle:!1,fragments:!0,fragmentInURL:!1,embedded:!1,help:!0,pause:!0,showNotes:!1,autoPlayMedia:null,preloadIframes:null,autoAnimate:!0,autoAnimateMatcher:null,autoAnimateEasing:"ease",autoAnimateDuration:1,autoAnimateUnmatched:!0,autoAnimateStyles:["opacity","color","background-color","padding","font-size","line-height","letter-spacing","border-width","border-color","border-radius","outline","outline-offset"],autoSlide:0,autoSlideStoppable:!0,autoSlideMethod:null,defaultTiming:null,mouseWheel:!1,previewLinks:!1,postMessage:!0,postMessageEvents:!1,focusBodyOnPageVisibilityChange:!0,transition:"slide",transitionSpeed:"default",backgroundTransition:"fade",parallaxBackgroundImage:"",parallaxBackgroundSize:"",parallaxBackgroundRepeat:"",parallaxBackgroundPosition:"",parallaxBackgroundHorizontal:null,parallaxBackgroundVertical:null,pdfMaxPagesPerSlide:Number.POSITIVE_INFINITY,pdfSeparateFragments:!0,pdfPageHeightOffset:-1,viewDistance:3,mobileViewDistance:2,display:"block",hideInactiveCursor:!0,hideCursorTime:5e3,dependencies:[]};const m=e=>{let t=e.match(/^#([0-9a-f]{3})$/i);if(t&&t[1])return t=t[1],{r:17*parseInt(t.charAt(0),16),g:17*parseInt(t.charAt(1),16),b:17*parseInt(t.charAt(2),16)};let a=e.match(/^#([0-9a-f]{6})$/i);if(a&&a[1])return a=a[1],{r:parseInt(a.substr(0,2),16),g:parseInt(a.substr(2,2),16),b:parseInt(a.substr(4,2),16)};let r=e.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);if(r)return{r:parseInt(r[1],10),g:parseInt(r[2],10),b:parseInt(r[3],10)};let n=e.match(/^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\,\s*([\d]+|[\d]*.[\d]+)\s*\)$/i);return n?{r:parseInt(n[1],10),g:parseInt(n[2],10),b:parseInt(n[3],10),a:parseFloat(n[4])}:null};var v=function(e,t){const a={},l=navigator.userAgent;let p,v,b,y,A,w,S,E,k,L=!1,x=!1,M=null,N=null,P=!1,q=!1,C=[],I=1,T={layout:"",overview:""},R={},D=new h,O=new c(a),B=new u(a),z={},H=0,j=0,$=!1,W=0,U=!1,F=0,V=0,X=-1,Y=!1,K={startX:0,startY:0,startCount:0,captured:!1,threshold:40},_={},J={};function Q(){L=!0,function(){R.slides.classList.add("no-transition"),S?R.wrapper.classList.add("no-hover"):R.wrapper.classList.remove("no-hover");/iphone/gi.test(l)?R.wrapper.classList.add("ua-iphone"):R.wrapper.classList.remove("ua-iphone");R.background=ee(R.wrapper,"div","backgrounds",null),R.progress=ee(R.wrapper,"div","progress",""),R.progressbar=R.progress.querySelector("span"),R.controls=ee(R.wrapper,"aside","controls",`\n\t\t\t\n\t\t\t\n\t\t\t`),R.slideNumber=ee(R.wrapper,"div","slide-number",""),R.speakerNotes=ee(R.wrapper,"div","speaker-notes",null),R.speakerNotes.setAttribute("data-prevent-swipe",""),R.speakerNotes.setAttribute("tabindex","0"),R.pauseOverlay=ee(R.wrapper,"div","pause-overlay",p.controls?'':null),R.wrapper.setAttribute("role","application"),R.controlsLeft=i(R.wrapper.querySelectorAll(".navigate-left")),R.controlsRight=i(R.wrapper.querySelectorAll(".navigate-right")),R.controlsUp=i(R.wrapper.querySelectorAll(".navigate-up")),R.controlsDown=i(R.wrapper.querySelectorAll(".navigate-down")),R.controlsPrev=i(R.wrapper.querySelectorAll(".navigate-prev")),R.controlsNext=i(R.wrapper.querySelectorAll(".navigate-next")),R.controlsRightArrow=R.controls.querySelector(".navigate-right"),R.controlsLeftArrow=R.controls.querySelector(".navigate-left"),R.controlsDownArrow=R.controls.querySelector(".navigate-down"),R.statusDiv=function(){let e=R.wrapper.querySelector(".aria-status");e||(e=document.createElement("div"),e.style.position="absolute",e.style.height="1px",e.style.width="1px",e.style.overflow="hidden",e.style.clip="rect( 1px, 1px, 1px, 1px )",e.classList.add("aria-status"),e.setAttribute("aria-live","polite"),e.setAttribute("aria-atomic","true"),R.wrapper.appendChild(e));return e}()}(),p.postMessage&&window.addEventListener("message",e=>{let t=e.data;if("string"==typeof t&&"{"===t.charAt(0)&&"}"===t.charAt(t.length-1)&&(t=JSON.parse(t),t.method&&"function"==typeof a[t.method]))if(!1===r.test(t.method)){const e=a[t.method].apply(a,t.args);de("callback",{method:t.method,result:e})}else console.warn('reveal.js: "'+t.method+'" is is blacklisted from the postMessage API')},!1),setInterval(()=>{0===R.wrapper.scrollTop&&0===R.wrapper.scrollLeft||(R.wrapper.scrollTop=0,R.wrapper.scrollLeft=0)},1e3),nt().forEach(e=>{i(e.querySelectorAll("section")).forEach((e,t)=>{t>0&&(e.classList.remove("present"),e.classList.remove("past"),e.classList.add("future"),e.setAttribute("aria-hidden","true"))})}),re(),et(),Xe(!0),setTimeout(()=>{R.slides.classList.remove("no-transition"),R.wrapper.classList.add("ready"),le("ready",{indexh:v,indexv:b,currentSlide:A})},1),oe()&&(ie(),"complete"===document.readyState?G():window.addEventListener("load",G))}function Z(e){let t="";if(3===e.nodeType)t+=e.textContent;else if(1===e.nodeType){let a=e.getAttribute("aria-hidden"),r="none"===window.getComputedStyle(e).display;"true"===a||r||i(e.childNodes).forEach(e=>{t+=Z(e)})}return t=t.trim(),""===t?"":t+" "}function G(){let e=ve(window.innerWidth,window.innerHeight),t=Math.floor(e.width*(1+p.margin)),a=Math.floor(e.height*(1+p.margin)),r=e.width,n=e.height;d("@page{size:"+t+"px "+a+"px; margin: 0px;}"),d(".reveal section>img, .reveal section>video, .reveal section>iframe{max-width: "+r+"px; max-height:"+n+"px}"),document.body.classList.add("print-pdf"),document.body.style.width=t+"px",document.body.style.height=a+"px",me(r,n);let s=p.slideNumber&&/all|print/i.test(p.showSlideNumber);i(R.wrapper.querySelectorAll(".slides section")).forEach((function(e){e.setAttribute("data-slide-number",Fe(e))})),i(R.wrapper.querySelectorAll(".slides section")).forEach((function(e){if(!1===e.classList.contains("stack")){let o=(t-r)/2,l=(a-n)/2,d=e.scrollHeight,c=Math.max(Math.ceil(d/a),1);c=Math.min(c,p.pdfMaxPagesPerSlide),(1===c&&p.center||e.classList.contains("center"))&&(l=Math.max((a-d)/2,0));let u=document.createElement("div");if(u.className="pdf-page",u.style.height=(a+p.pdfPageHeightOffset)*c+"px",e.parentNode.insertBefore(u,e),u.appendChild(e),e.style.left=o+"px",e.style.top=l+"px",e.style.width=r+"px",e.slideBackgroundElement&&u.insertBefore(e.slideBackgroundElement,e),p.showNotes){let a=ct(e);if(a){let e=8,r="string"==typeof p.showNotes?p.showNotes:"inline",n=document.createElement("div");n.classList.add("speaker-notes"),n.classList.add("speaker-notes-pdf"),n.setAttribute("data-layout",r),n.innerHTML=a,"separate-page"===r?u.parentNode.insertBefore(n,u.nextSibling):(n.style.left=e+"px",n.style.bottom=e+"px",n.style.width=t-2*e+"px",u.appendChild(n))}}if(s){let t=document.createElement("div");t.classList.add("slide-number"),t.classList.add("slide-number-pdf"),t.innerHTML=e.getAttribute("data-slide-number"),u.appendChild(t)}if(p.pdfSeparateFragments){let e,t,a=pt(u.querySelectorAll(".fragment"),!0);a.forEach((function(a){e&&e.forEach((function(e){e.classList.remove("current-fragment")})),a.forEach((function(e){e.classList.add("visible","current-fragment")}));let r=u.cloneNode(!0);u.parentNode.insertBefore(r,(t||u).nextSibling),e=a,t=r})),a.forEach((function(e){e.forEach((function(e){e.classList.remove("visible","current-fragment")}))}))}else i(u.querySelectorAll(".fragment:not(.fade-out)")).forEach((function(e){e.classList.add("visible")}))}})),le("pdf-ready")}function ee(e,t,a,r=""){let n=e.querySelectorAll("."+a);for(let t=0;t1&&p.autoSlide&&p.autoSlideStoppable&&(k=new g(R.wrapper,()=>Math.min(Math.max((Date.now()-X)/F,0),1)),k.on("click",Qt),Y=!1),!1===p.fragments&&i(R.slides.querySelectorAll(".fragment")).forEach(e=>{e.classList.add("visible"),e.classList.remove("current-fragment")});let s="none";p.slideNumber&&!oe()&&("all"===p.showSlideNumber||"speaker"===p.showSlideNumber&&Ge())&&(s="block"),R.slideNumber.style.display=s,"default"!==p.navigationMode?R.wrapper.setAttribute("data-navigation-mode",p.navigationMode):R.wrapper.removeAttribute("data-navigation-mode"),"linear"===p.navigationMode?(_["→ , ↓ , SPACE , N , L , J"]="Next slide",_["← , ↑ , P , H , K"]="Previous slide"):(_["N , SPACE"]="Next slide",_.P="Previous slide",_["← , H"]="Navigate left",_["→ , L"]="Navigate right",_["↑ , K"]="Navigate up",_["↓ , J"]="Navigate down"),_["Home , Shift ←"]="First slide",_["End , Shift →"]="Last slide",_["B , ."]="Pause",_.F="Fullscreen",_["ESC, O"]="Slide overview",Oe()}function ne(){U=!0,window.addEventListener("hashchange",Xt,!1),window.addEventListener("resize",Yt,!1),p.touch&&("onpointerdown"in window?(R.wrapper.addEventListener("pointerdown",Dt,!1),R.wrapper.addEventListener("pointermove",Ot,!1),R.wrapper.addEventListener("pointerup",Bt,!1)):window.navigator.msPointerEnabled?(R.wrapper.addEventListener("MSPointerDown",Dt,!1),R.wrapper.addEventListener("MSPointerMove",Ot,!1),R.wrapper.addEventListener("MSPointerUp",Bt,!1)):(R.wrapper.addEventListener("touchstart",It,!1),R.wrapper.addEventListener("touchmove",Tt,!1),R.wrapper.addEventListener("touchend",Rt,!1))),p.keyboard&&(document.addEventListener("keydown",Ct,!1),document.addEventListener("keypress",qt,!1)),p.progress&&R.progress&&R.progress.addEventListener("click",Ht,!1),R.pauseOverlay.addEventListener("click",Ce,!1),p.focusBodyOnPageVisibilityChange&&document.addEventListener("visibilitychange",Kt,!1);let e=["touchstart","click"];l.match(/android/gi)&&(e=["touchstart"]),e.forEach(e=>{R.controlsLeft.forEach(t=>t.addEventListener(e,jt,!1)),R.controlsRight.forEach(t=>t.addEventListener(e,$t,!1)),R.controlsUp.forEach(t=>t.addEventListener(e,Wt,!1)),R.controlsDown.forEach(t=>t.addEventListener(e,Ut,!1)),R.controlsPrev.forEach(t=>t.addEventListener(e,Ft,!1)),R.controlsNext.forEach(t=>t.addEventListener(e,Vt,!1))})}function ie(){U=!1,document.removeEventListener("keydown",Ct,!1),document.removeEventListener("keypress",qt,!1),window.removeEventListener("hashchange",Xt,!1),window.removeEventListener("resize",Yt,!1),R.wrapper.removeEventListener("pointerdown",Dt,!1),R.wrapper.removeEventListener("pointermove",Ot,!1),R.wrapper.removeEventListener("pointerup",Bt,!1),R.wrapper.removeEventListener("MSPointerDown",Dt,!1),R.wrapper.removeEventListener("MSPointerMove",Ot,!1),R.wrapper.removeEventListener("MSPointerUp",Bt,!1),R.wrapper.removeEventListener("touchstart",It,!1),R.wrapper.removeEventListener("touchmove",Tt,!1),R.wrapper.removeEventListener("touchend",Rt,!1),R.pauseOverlay.removeEventListener("click",Ce,!1),p.progress&&R.progress&&R.progress.removeEventListener("click",Ht,!1),["touchstart","click"].forEach(e=>{R.controlsLeft.forEach(t=>t.removeEventListener(e,jt,!1)),R.controlsRight.forEach(t=>t.removeEventListener(e,$t,!1)),R.controlsUp.forEach(t=>t.removeEventListener(e,Wt,!1)),R.controlsDown.forEach(t=>t.removeEventListener(e,Ut,!1)),R.controlsPrev.forEach(t=>t.removeEventListener(e,Ft,!1)),R.controlsNext.forEach(t=>t.removeEventListener(e,Vt,!1))})}function se(e){"string"==typeof e.layout&&(T.layout=e.layout),"string"==typeof e.overview&&(T.overview=e.overview),T.layout?o(R.slides,T.layout+" "+T.overview):o(R.slides,T.overview)}function oe(){return/print-pdf/gi.test(window.location.search)}function le(e,t){let a=document.createEvent("HTMLEvents",1,2);a.initEvent(e,!0,!0),n(a,t),R.wrapper.dispatchEvent(a),de(e)}function de(e,t){if(p.postMessageEvents&&window.parent!==window.self){let a={namespace:"reveal",eventName:e,state:ut()};n(a,t),window.parent.postMessage(JSON.stringify(a),"*")}}function ce(e="a"){i(R.wrapper.querySelectorAll(e)).forEach(e=>{/^(http|www)/gi.test(e.getAttribute("href"))&&e.addEventListener("click",Jt,!1)})}function ue(e="a"){i(R.wrapper.querySelectorAll(e)).forEach(e=>{/^(http|www)/gi.test(e.getAttribute("href"))&&e.removeEventListener("click",Jt,!1)})}function pe(e){"boolean"==typeof e?e?he():ge():R.overlay?ge():he()}function he(){if(p.help){ge(),R.overlay=document.createElement("div"),R.overlay.classList.add("overlay"),R.overlay.classList.add("overlay-help"),R.wrapper.appendChild(R.overlay);let e='

Keyboard Shortcuts


';e+="";for(let t in _)e+=``;for(let t in J)J[t].key&&J[t].description&&(e+=``);e+="
KEYACTION
${t}${_[t]}
${J[t].key}${J[t].description}
",R.overlay.innerHTML=`\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
${e}
\n\t\t\t\t
\n\t\t\t`,R.overlay.querySelector(".close").addEventListener("click",e=>{ge(),e.preventDefault()},!1)}}function ge(){R.overlay&&(R.overlay.parentNode.removeChild(R.overlay),R.overlay=null)}function fe(){if(R.wrapper&&!oe()){if(!p.disableLayout){S&&document.documentElement.style.setProperty("--vh",.01*window.innerHeight+"px");const e=ve(),t=I;me(p.width,p.height),R.slides.style.width=e.width+"px",R.slides.style.height=e.height+"px",I=Math.min(e.presentationWidth/e.width,e.presentationHeight/e.height),I=Math.max(I,p.minScale),I=Math.min(I,p.maxScale),1===I?(R.slides.style.zoom="",R.slides.style.left="",R.slides.style.top="",R.slides.style.bottom="",R.slides.style.right="",se({layout:""})):I>1&&z.zoom&&window.devicePixelRatio<2?(R.slides.style.zoom=I,R.slides.style.left="",R.slides.style.top="",R.slides.style.bottom="",R.slides.style.right="",se({layout:""})):(R.slides.style.zoom="",R.slides.style.left="50%",R.slides.style.top="50%",R.slides.style.bottom="auto",R.slides.style.right="auto",se({layout:"translate(-50%, -50%) scale("+I+")"}));const a=i(R.wrapper.querySelectorAll(".slides section"));for(let t=0,r=a.length;t .stretch")).forEach(a=>{let r=function(e,t=0){if(e){let a,r=e.style.height;return e.style.height="0px",e.parentNode.style.height="auto",a=t-e.parentNode.offsetHeight,e.style.height=r+"px",e.parentNode.style.removeProperty("height"),a}return t}(a,t);if(/(img|video)/gi.test(a.nodeName)){const t=a.naturalWidth||a.videoWidth,n=a.naturalHeight||a.videoHeight,i=Math.min(e/t,r/n);a.style.width=t*i+"px",a.style.height=n*i+"px"}else a.style.width=e+"px",a.style.height=r+"px"})}function ve(e,t){const a={width:p.width,height:p.height,presentationWidth:e||R.wrapper.offsetWidth,presentationHeight:t||R.wrapper.offsetHeight};return a.presentationWidth-=a.presentationWidth*p.margin,a.presentationHeight-=a.presentationHeight*p.margin,"string"==typeof a.width&&/%$/.test(a.width)&&(a.width=parseInt(a.width,10)/100*a.presentationWidth),"string"==typeof a.height&&/%$/.test(a.height)&&(a.height=parseInt(a.height,10)/100*a.presentationHeight),a}function be(e,t){"object"==typeof e&&"function"==typeof e.setAttribute&&e.setAttribute("data-previous-indexv",t||0)}function ye(e){if("object"==typeof e&&"function"==typeof e.setAttribute&&e.classList.contains("stack")){const t=e.hasAttribute("data-start-indexv")?"data-start-indexv":"data-previous-indexv";return parseInt(e.getAttribute(t)||0,10)}return 0}function Ae(){if(p.overview&&!Le()){x=!0,R.wrapper.classList.add("overview"),bt(),R.slides.appendChild(R.background),i(R.wrapper.querySelectorAll(".slides section")).forEach(e=>{e.classList.contains("stack")||e.addEventListener("click",_t,!0)});const e=70,t=ve();M=t.width+e,N=t.height+e,p.rtl&&(M=-M),je(),we(),Se(),fe(),le("overviewshown",{indexh:v,indexv:b,currentSlide:A})}}function we(){i(R.wrapper.querySelectorAll(".slides>section")).forEach((e,t)=>{e.setAttribute("data-index-h",t),o(e,"translate3d("+t*M+"px, 0, 0)"),e.classList.contains("stack")&&i(e.querySelectorAll("section")).forEach((e,a)=>{e.setAttribute("data-index-h",t),e.setAttribute("data-index-v",a),o(e,"translate3d(0, "+a*N+"px, 0)")})}),i(R.background.childNodes).forEach((e,t)=>{o(e,"translate3d("+t*M+"px, 0, 0)"),i(e.querySelectorAll(".slide-background")).forEach((e,t)=>{o(e,"translate3d(0, "+t*N+"px, 0)")})})}function Se(){const e=Math.min(window.innerWidth,window.innerHeight);se({overview:["scale("+Math.max(e/5,150)/e+")","translateX("+-v*M+"px)","translateY("+-b*N+"px)"].join(" ")})}function Ee(){p.overview&&(x=!1,R.wrapper.classList.remove("overview"),R.wrapper.classList.add("overview-deactivating"),setTimeout(()=>{R.wrapper.classList.remove("overview-deactivating")},1),R.wrapper.appendChild(R.background),i(R.wrapper.querySelectorAll(".slides section")).forEach(e=>{o(e,""),e.removeEventListener("click",_t,!0)}),i(R.background.querySelectorAll(".slide-background")).forEach(e=>{o(e,"")}),se({overview:""}),De(v,b),fe(),vt(),le("overviewhidden",{indexh:v,indexv:b,currentSlide:A}))}function ke(e){"boolean"==typeof e?e?Ae():Ee():Le()?Ee():Ae()}function Le(){return x}function xe(e){let t="/",a=e||A,r=a?a.getAttribute("id"):null;r&&(r=encodeURIComponent(r));let n=at(e);if(p.fragmentInURL||(n.f=void 0),"string"==typeof r&&r.length&&void 0===n.f)t="/"+r;else{let e=p.hashOneBasedIndex?1:0;(n.h>0||n.v>0||void 0!==n.f)&&(t+=n.h+e),(n.v>0||void 0!==n.f)&&(t+="/"+(n.v+e)),void 0!==n.f&&(t+="/"+n.f)}return t}function Me(e=A){return e&&e.parentNode&&!!e.parentNode.nodeName.match(/section/i)}function Ne(){$&&($=!1,R.wrapper.style.cursor="")}function Pe(){!1===$&&($=!0,R.wrapper.style.cursor="none")}function qe(){if(p.pause){const e=R.wrapper.classList.contains("paused");bt(),R.wrapper.classList.add("paused"),!1===e&&le("paused")}}function Ce(){const e=R.wrapper.classList.contains("paused");R.wrapper.classList.remove("paused"),vt(),e&&le("resumed")}function Ie(e){"boolean"==typeof e?e?qe():Ce():Te()?Ce():qe()}function Te(){return R.wrapper.classList.contains("paused")}function Re(e){"boolean"==typeof e?e?At():yt():Y?At():yt()}function De(e,t,r,n){y=A;const s=R.wrapper.querySelectorAll(".slides>section");if(0===s.length)return;void 0!==t||Le()||(t=ye(s[e])),y&&y.parentNode&&y.parentNode.classList.contains("stack")&&be(y.parentNode,b);const o=C.concat();C.length=0;let l=v||0,d=b||0;v=He(".slides>section",void 0===e?v:e),b=He(".slides>section.present>section",void 0===t?b:t),je(),fe(),Le()&&Se();let c=s[v],u=c.querySelectorAll("section");A=u[b]||c,void 0!==r&>(r);let h=v!==l||b!==d;h||(y=null),y&&y!==A&&(y.classList.remove("present"),y.setAttribute("aria-hidden","true"),a.isFirstSlide()&&setTimeout(()=>{i(R.wrapper.querySelectorAll(".slides>section.stack")).forEach(e=>{be(e,0)})},0));e:for(let e=0,t=C.length;e{R.slides.classList.remove("disable-slide-transitions")},0),p.autoAnimate&&B.run(y,A))}function Oe(){ie(),ne(),fe(),F=p.autoSlide,vt(),oe(),R.background.innerHTML="",R.background.classList.add("no-transition"),i(R.wrapper.querySelectorAll(".slides>section")).forEach(e=>{let t=te(e,R.background);i(e.querySelectorAll("section")).forEach(e=>{te(e,t),t.classList.add("stack")})}),p.parallaxBackgroundImage?(R.background.style.backgroundImage='url("'+p.parallaxBackgroundImage+'")',R.background.style.backgroundSize=p.parallaxBackgroundSize,R.background.style.backgroundRepeat=p.parallaxBackgroundRepeat,R.background.style.backgroundPosition=p.parallaxBackgroundPosition,setTimeout(()=>{R.wrapper.classList.add("has-parallax-background")},1)):(R.background.style.backgroundImage="",R.wrapper.classList.remove("has-parallax-background")),tt(),nt().forEach(e=>{let t=i(e.querySelectorAll("section"));t.forEach((e,t)=>{pt(e.querySelectorAll(".fragment"))}),0===t.length&&pt(e.querySelectorAll(".fragment"))}),Ve(),We(),Ue(),je(),Xe(!0),p.showNotes&&R.slides.querySelectorAll("[data-notes], aside.notes").length>0?R.wrapper.classList.add("show-notes"):R.wrapper.classList.remove("show-notes"),$e(),O.formatEmbeddedContent(),!1===p.autoPlayMedia?O.stopEmbeddedContent(A,{unloadIframes:!1}):O.startEmbeddedContent(A),Le()&&we()}function Be(e=A){return pt(e.querySelectorAll(".fragment"))}function ze(){nt().forEach((e,t,a)=>{R.slides.insertBefore(e,a[Math.floor(Math.random()*a.length)])})}function He(e,t){let a=i(R.wrapper.querySelectorAll(e)),r=a.length,n=oe();if(r){p.loop&&(t%=r)<0&&(t=r+t),t=Math.max(Math.min(t,r-1),0);for(let e=0;e{e.classList.add("visible"),e.classList.remove("current-fragment")})):e>t&&(r.classList.add(s?"past":"future"),p.fragments&&i(r.querySelectorAll(".fragment.visible")).forEach(e=>{e.classList.remove("visible","current-fragment")}))}a[t].classList.add("present"),a[t].removeAttribute("hidden"),a[t].removeAttribute("aria-hidden");let e=a[t].getAttribute("data-state");e&&(C=C.concat(e.split(" ")))}else t=0;return t}function je(){let e,t,a=nt(),r=a.length;if(r&&void 0!==v){let n=Le()?10:p.viewDistance;S&&(n=Le()?6:p.mobileViewDistance),oe()&&(n=Number.MAX_VALUE);for(let s=0;sNo notes on this slide.')}function We(){p.progress&&R.progressbar&&(R.progressbar.style.width=Ze()*R.wrapper.offsetWidth+"px")}function Ue(){p.slideNumber&&R.slideNumber&&(R.slideNumber.innerHTML=Fe())}function Fe(e=A){let t,a="h.v";if("function"==typeof p.slideNumber)t=p.slideNumber(e);else switch("string"==typeof p.slideNumber&&(a=p.slideNumber),/c/.test(a)||1!==R.wrapper.querySelectorAll(".slides>section").length||(a="c"),t=[],a){case"c":t.push(Qe(e)+1);break;case"c/t":t.push(Qe(e)+1,"/",lt());break;default:let r=at(e);t.push(r.h+1);let n="h/v"===a?"/":".";Me(e)&&t.push(n,r.v+1)}let r="#"+xe(e);return function(e,t,a,r="#"+xe()){return"number"!=typeof a||isNaN(a)?`\n\t\t\t\t\t${e}\n\t\t\t\t\t`:`\n\t\t\t\t\t${e}\n\t\t\t\t\t${t}\n\t\t\t\t\t${a}\n\t\t\t\t\t`}(t[0],t[1],t[2],r)}function Ve(){let e=_e(),t=Je();[...R.controlsLeft,...R.controlsRight,...R.controlsUp,...R.controlsDown,...R.controlsPrev,...R.controlsNext].forEach(e=>{e.classList.remove("enabled","fragmented"),e.setAttribute("disabled","disabled")}),e.left&&R.controlsLeft.forEach(e=>{e.classList.add("enabled"),e.removeAttribute("disabled")}),e.right&&R.controlsRight.forEach(e=>{e.classList.add("enabled"),e.removeAttribute("disabled")}),e.up&&R.controlsUp.forEach(e=>{e.classList.add("enabled"),e.removeAttribute("disabled")}),e.down&&R.controlsDown.forEach(e=>{e.classList.add("enabled"),e.removeAttribute("disabled")}),(e.left||e.up)&&R.controlsPrev.forEach(e=>{e.classList.add("enabled"),e.removeAttribute("disabled")}),(e.right||e.down)&&R.controlsNext.forEach(e=>{e.classList.add("enabled"),e.removeAttribute("disabled")}),A&&(t.prev&&R.controlsPrev.forEach(e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")}),t.next&&R.controlsNext.forEach(e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")}),Me(A)?(t.prev&&R.controlsUp.forEach(e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")}),t.next&&R.controlsDown.forEach(e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")})):(t.prev&&R.controlsLeft.forEach(e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")}),t.next&&R.controlsRight.forEach(e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")}))),p.controlsTutorial&&(!q&&e.down?R.controlsDownArrow.classList.add("highlight"):(R.controlsDownArrow.classList.remove("highlight"),p.rtl?!P&&e.left&&0===b?R.controlsLeftArrow.classList.add("highlight"):R.controlsLeftArrow.classList.remove("highlight"):!P&&e.right&&0===b?R.controlsRightArrow.classList.add("highlight"):R.controlsRightArrow.classList.remove("highlight")))}function Xe(e=!1){let t=null,a=p.rtl?"future":"past",r=p.rtl?"past":"future";if(i(R.background.childNodes).forEach((n,s)=>{n.classList.remove("past","present","future"),sv?n.classList.add(r):(n.classList.add("present"),t=n),(e||s===v)&&i(n.querySelectorAll(".slide-background")).forEach((e,a)=>{e.classList.remove("past","present","future"),ab?e.classList.add("future"):(e.classList.add("present"),s===v&&(t=e))})}),w&&O.stopEmbeddedContent(w,{unloadIframes:!Ke(w)}),t){O.startEmbeddedContent(t);let e=t.querySelector(".slide-background-content");if(e){let t=e.style.backgroundImage||"";/\.gif/i.test(t)&&(e.style.backgroundImage="",window.getComputedStyle(e).opacity,e.style.backgroundImage=t)}let a=w?w.getAttribute("data-background-hash"):null,r=t.getAttribute("data-background-hash");r&&r===a&&t!==w&&R.background.classList.add("no-transition"),w=t}A&&["has-light-background","has-dark-background"].forEach(e=>{A.classList.contains(e)?R.wrapper.classList.add(e):R.wrapper.classList.remove(e)}),setTimeout(()=>{R.background.classList.remove("no-transition")},1)}function Ye(){if(p.parallaxBackgroundImage){let e,t,a=nt(),r=it(),n=R.background.style.backgroundSize.split(" ");1===n.length?e=t=parseInt(n[0],10):(e=parseInt(n[0],10),t=parseInt(n[1],10));let i,s,o=R.background.offsetWidth,l=a.length;i="number"==typeof p.parallaxBackgroundHorizontal?p.parallaxBackgroundHorizontal:l>1?(e-o)/(l-1):0,s=i*v*-1;let d,c,u=R.background.offsetHeight,h=r.length;d="number"==typeof p.parallaxBackgroundVertical?p.parallaxBackgroundVertical:(t-u)/(h-1),c=h>0?d*b:0,R.background.style.backgroundPosition=s+"px "+-c+"px"}}function Ke(e){let t=p.preloadIframes;return"boolean"!=typeof t&&(t=e.hasAttribute("data-preload")),t}function _e(){let e=R.wrapper.querySelectorAll(".slides>section"),t=R.wrapper.querySelectorAll(".slides>section.present>section"),a={left:v>0,right:v0,down:b1&&(a.left=!0,a.right=!0),t.length>1&&(a.up=!0,a.down=!0)),p.rtl){let e=a.left;a.left=a.right,a.right=e}return a}function Je(){if(A&&p.fragments){let e=A.querySelectorAll(".fragment"),t=A.querySelectorAll(".fragment:not(.visible)");return{prev:e.length-t.length>0,next:!!t.length}}return{prev:!1,next:!1}}function Qe(e=A){let t=nt(),a=0;e:for(let r=0;r0){let a=.9;t+=A.querySelectorAll(".fragment.visible").length/e.length*a}}return Math.min(t/(e-1),1)}function Ge(){return!!window.location.search.match(/receiver/gi)}function et(){let e=window.location.hash,t=e.slice(2).split("/"),r=e.replace(/#|\//gi,"");if(!/^[0-9]*$/.test(t[0])&&r.length){let e;try{e=document.getElementById(decodeURIComponent(r))}catch(e){}let t=!!A&&A.getAttribute("id")===r;if(e){if(!t){let t=a.getIndices(e);De(t.h,t.v)}}else De(v||0,b||0)}else{let e,a=p.hashOneBasedIndex?1:0,r=parseInt(t[0],10)-a||0,n=parseInt(t[1],10)-a||0;p.fragmentInURL&&(e=parseInt(t[2],10),isNaN(e)&&(e=void 0)),r===v&&n===b&&void 0===e||De(r,n,e)}}function tt(e){clearTimeout(j),"number"==typeof e?j=setTimeout(tt,e):A&&(p.history||!window.history?window.location.hash=xe():p.hash?window.history.replaceState(null,null,"#"+xe()):window.history.replaceState(null,null,window.location.pathname+window.location.search))}function at(e){let t,a=v,r=b;if(e){let t=Me(e),n=t?e.parentNode:e,s=i(R.wrapper.querySelectorAll(".slides>section"));a=Math.max(s.indexOf(n),0),r=void 0,t&&(r=Math.max(i(e.parentNode.querySelectorAll("section")).indexOf(e),0))}if(!e&&A){if(A.querySelectorAll(".fragment").length>0){let e=A.querySelector(".current-fragment");t=e&&e.hasAttribute("data-fragment-index")?parseInt(e.getAttribute("data-fragment-index"),10):A.querySelectorAll(".fragment.visible").length-1}}return{h:a,v:r,f:t}}function rt(){return i(R.wrapper.querySelectorAll('.slides section:not(.stack):not([data-visibility="uncounted"])'))}function nt(){return i(R.wrapper.querySelectorAll(".slides>section"))}function it(){return i(R.wrapper.querySelectorAll(".slides>section>section"))}function st(){return nt().length>1}function ot(){return it().length>1}function lt(){return rt().length}function dt(e,t){let a=nt()[e],r=a&&a.querySelectorAll("section");return r&&r.length&&"number"==typeof t?r?r[t]:void 0:a}function ct(e=A){if(e.hasAttribute("data-notes"))return e.getAttribute("data-notes");let t=e.querySelector("aside.notes");return t?t.innerHTML:null}function ut(){let e=at();return{indexh:e.h,indexv:e.v,indexf:e.f,paused:Te(),overview:Le()}}function pt(e,t=!1){e=i(e);let a=[],r=[],n=[];e.forEach(e=>{if(e.hasAttribute("data-fragment-index")){let t=parseInt(e.getAttribute("data-fragment-index"),10);a[t]||(a[t]=[]),a[t].push(e)}else r.push([e])}),a=a.concat(r);let s=0;return a.forEach(e=>{e.forEach(e=>{n.push(e),e.setAttribute("data-fragment-index",s)}),s++}),!0===t?a:n}function ht(e,t){let a={shown:[],hidden:[]};if(A&&p.fragments&&(t=t||pt(A.querySelectorAll(".fragment"))).length){let r=0;if("number"!=typeof e){let t=pt(A.querySelectorAll(".fragment.visible")).pop();t&&(e=parseInt(t.getAttribute("data-fragment-index")||0,10))}i(t).forEach((t,n)=>{t.hasAttribute("data-fragment-index")&&(n=parseInt(t.getAttribute("data-fragment-index"),10)),r=Math.max(r,n),n<=e?(t.classList.contains("visible")||a.shown.push(t),t.classList.add("visible"),t.classList.remove("current-fragment"),R.statusDiv.textContent=Z(t),n===e&&(t.classList.add("current-fragment"),O.startEmbeddedContent(t))):(t.classList.contains("visible")&&a.hidden.push(t),t.classList.remove("visible"),t.classList.remove("current-fragment"))}),e="number"==typeof e?e:-1,e=Math.max(Math.min(e,r),-1),A.setAttribute("data-fragment",e)}return a}function gt(e,t=0){if(A&&p.fragments){let a=pt(A.querySelectorAll(".fragment"));if(a.length){if("number"!=typeof e){let t=pt(A.querySelectorAll(".fragment.visible")).pop();e=t?parseInt(t.getAttribute("data-fragment-index")||0,10):-1}let r=ht(e+=t,a);return r.hidden.length&&le("fragmenthidden",{fragment:r.hidden[0],fragments:r.hidden}),r.shown.length&&le("fragmentshown",{fragment:r.shown[0],fragments:r.shown}),Ve(),We(),p.fragmentInURL&&tt(),!(!r.shown.length&&!r.hidden.length)}}return!1}function ft(){return gt(null,1)}function mt(){return gt(null,-1)}function vt(){if(bt(),A&&!1!==p.autoSlide){let e=A.querySelector(".current-fragment");e||(e=A.querySelector(".fragment"));let t=e?e.getAttribute("data-autoslide"):null,r=A.parentNode?A.parentNode.getAttribute("data-autoslide"):null,n=A.getAttribute("data-autoslide");F=t?parseInt(t,10):n?parseInt(n,10):r?parseInt(r,10):p.autoSlide,0===A.querySelectorAll(".fragment").length&&i(A.querySelectorAll("video, audio")).forEach(e=>{e.hasAttribute("data-autoplay")&&F&&1e3*e.duration/e.playbackRate>F&&(F=1e3*e.duration/e.playbackRate+1e3)}),!F||Y||Te()||Le()||a.isLastSlide()&&!Je().next&&!0!==p.loop||(V=setTimeout(()=>{"function"==typeof p.autoSlideMethod?p.autoSlideMethod():xt(),vt()},F),X=Date.now()),k&&k.setPlaying(-1!==V)}}function bt(){clearTimeout(V),V=-1}function yt(){F&&!Y&&(Y=!0,le("autoslidepaused"),clearTimeout(V),k&&k.setPlaying(!1))}function At(){F&&Y&&(Y=!1,le("autoslideresumed"),vt())}function wt(){P=!0,p.rtl?(Le()||!1===ft())&&_e().left&&De(v+1,"grid"===p.navigationMode?b:void 0):(Le()||!1===mt())&&_e().left&&De(v-1,"grid"===p.navigationMode?b:void 0)}function St(){P=!0,p.rtl?(Le()||!1===mt())&&_e().right&&De(v-1,"grid"===p.navigationMode?b:void 0):(Le()||!1===ft())&&_e().right&&De(v+1,"grid"===p.navigationMode?b:void 0)}function Et(){(Le()||!1===mt())&&_e().up&&De(v,b-1)}function kt(){q=!0,(Le()||!1===ft())&&_e().down&&De(v,b+1)}function Lt(){if(!1===mt())if(_e().up)Et();else{let e;if(e=p.rtl?i(R.wrapper.querySelectorAll(".slides>section.future")).pop():i(R.wrapper.querySelectorAll(".slides>section.past")).pop(),e){let t=e.querySelectorAll("section").length-1||void 0;De(v-1,t)}}}function xt(){if(P=!0,q=!0,!1===ft()){let e=_e();e.down&&e.right&&p.loop&&a.isLastVerticalSlide(A)&&(e.down=!1),e.down?kt():p.rtl?wt():St()}}function Mt(e){for(;e&&"function"==typeof e.hasAttribute;){if(e.hasAttribute("data-prevent-swipe"))return!0;e=e.parentNode}return!1}function Nt(e){p.autoSlideStoppable&&yt()}function Pt(e){Ne(),clearTimeout(W),W=setTimeout(Pe,p.hideCursorTime)}function qt(e){e.shiftKey&&63===e.charCode&&pe()}function Ct(e){if("function"==typeof p.keyboardCondition&&!1===p.keyboardCondition(e))return!0;let t=e.keyCode,r=Y;Nt();let n=document.activeElement&&"inherit"!==document.activeElement.contentEditable,i=document.activeElement&&document.activeElement.tagName&&/input|textarea/i.test(document.activeElement.tagName),s=document.activeElement&&document.activeElement.className&&/speaker-notes/i.test(document.activeElement.className),o=e.shiftKey&&32===e.keyCode,l=e.shiftKey&&37===t,d=e.shiftKey&&39===t,c=!o&&!l&&!d&&(e.shiftKey||e.altKey||e.ctrlKey||e.metaKey);if(n||i||s||c)return;let u,h=[66,86,190,191];if("object"==typeof p.keyboard)for(u in p.keyboard)"togglePause"===p.keyboard[u]&&h.push(parseInt(u,10));if(Te()&&-1===h.indexOf(t))return!1;let g="linear"===p.navigationMode||!st()||!ot(),f=!1;if("object"==typeof p.keyboard)for(u in p.keyboard)if(parseInt(u,10)===t){let t=p.keyboard[u];"function"==typeof t?t.apply(null,[e]):"string"==typeof t&&"function"==typeof a[t]&&a[t].call(),f=!0}if(!1===f)for(u in J)if(parseInt(u,10)===t){let t=J[u].callback;"function"==typeof t?t.apply(null,[e]):"string"==typeof t&&"function"==typeof a[t]&&a[t].call(),f=!0}!1===f&&(f=!0,80===t||33===t?Lt():78===t||34===t?xt():72===t||37===t?l?De(0):!Le()&&g?Lt():wt():76===t||39===t?d?De(Number.MAX_VALUE):!Le()&&g?xt():St():75===t||38===t?!Le()&&g?Lt():Et():74===t||40===t?!Le()&&g?xt():kt():36===t?De(0):35===t?De(Number.MAX_VALUE):32===t?(Le()&&Ee(),e.shiftKey?Lt():xt()):58===t||59===t||66===t||86===t||190===t||191===t?Ie():70===t?(()=>{let e=document.documentElement,t=e.requestFullscreen||e.webkitRequestFullscreen||e.webkitRequestFullScreen||e.mozRequestFullScreen||e.msRequestFullscreen;t&&t.apply(e)})():65===t?p.autoSlideStoppable&&Re(r):f=!1),f?e.preventDefault&&e.preventDefault():27!==t&&79!==t||(R.overlay?ge():ke(),e.preventDefault&&e.preventDefault()),vt()}function It(e){if(Mt(e.target))return!0;K.startX=e.touches[0].clientX,K.startY=e.touches[0].clientY,K.startCount=e.touches.length}function Tt(e){if(Mt(e.target))return!0;if(K.captured)l.match(/android/gi)&&e.preventDefault();else{Nt();let t=e.touches[0].clientX,a=e.touches[0].clientY;if(1===e.touches.length&&2!==K.startCount){let r=t-K.startX,n=a-K.startY;r>K.threshold&&Math.abs(r)>Math.abs(n)?(K.captured=!0,"linear"===p.navigationMode?p.rtl?xt():Lt():wt()):r<-K.threshold&&Math.abs(r)>Math.abs(n)?(K.captured=!0,"linear"===p.navigationMode?p.rtl?Lt():xt():St()):n>K.threshold?(K.captured=!0,"linear"===p.navigationMode?Lt():Et()):n<-K.threshold&&(K.captured=!0,"linear"===p.navigationMode?xt():kt()),p.embedded?(K.captured||Me(A))&&e.preventDefault():e.preventDefault()}}}function Rt(e){K.captured=!1}function Dt(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],It(e))}function Ot(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],Tt(e))}function Bt(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],Rt())}function zt(e){if(Date.now()-H>600){H=Date.now();let t=e.detail||-e.wheelDelta;t>0?xt():t<0&&Lt()}}function Ht(e){Nt(),e.preventDefault();let t=nt().length,a=Math.floor(e.clientX/R.wrapper.offsetWidth*t);p.rtl&&(a=t-a),De(a)}function jt(e){e.preventDefault(),Nt(),"linear"===p.navigationMode?Lt():wt()}function $t(e){e.preventDefault(),Nt(),"linear"===p.navigationMode?xt():St()}function Wt(e){e.preventDefault(),Nt(),Et()}function Ut(e){e.preventDefault(),Nt(),kt()}function Ft(e){e.preventDefault(),Nt(),Lt()}function Vt(e){e.preventDefault(),Nt(),xt()}function Xt(e){et()}function Yt(e){fe()}function Kt(e){!1===document.hidden&&document.activeElement!==document.body&&("function"==typeof document.activeElement.blur&&document.activeElement.blur(),document.body.focus())}function _t(e){if(U&&Le()){e.preventDefault();let t=e.target;for(;t&&!t.nodeName.match(/section/gi);)t=t.parentNode;if(t&&!t.classList.contains("disabled")&&(Ee(),t.nodeName.match(/section/gi))){De(parseInt(t.getAttribute("data-index-h"),10),parseInt(t.getAttribute("data-index-v"),10))}}}function Jt(e){if(e.currentTarget&&e.currentTarget.hasAttribute("href")){let t=e.currentTarget.getAttribute("href");t&&(!function(e){ge(),R.overlay=document.createElement("div"),R.overlay.classList.add("overlay"),R.overlay.classList.add("overlay-preview"),R.wrapper.appendChild(R.overlay),R.overlay.innerHTML=`
\n\t\t\t\t\n\t\t\t\t\n\t\t\t
\n\t\t\t
\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\tUnable to load iframe. This is likely due to the site's policy (x-frame-options).\n\t\t\t\t\n\t\t\t
`,R.overlay.querySelector("iframe").addEventListener("load",e=>{R.overlay.classList.add("loaded")},!1),R.overlay.querySelector(".close").addEventListener("click",e=>{ge(),e.preventDefault()},!1),R.overlay.querySelector(".external").addEventListener("click",e=>{ge()},!1)}(t),e.preventDefault())}}function Qt(e){a.isLastSlide()&&!1===p.loop?(De(0,0),At()):Y?At():yt()}return n(a,{VERSION:"4.0.0-dev",initialize:function(){if(e)return function(){S=/(iphone|ipod|ipad|android)/gi.test(l)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1,E=/chrome/i.test(l)&&!/edge/i.test(l);let e=document.createElement("div");z.zoom="zoom"in e.style&&!S&&(E||/Version\/[\d\.]+.*Safari/.test(l))}(),R.wrapper=e,R.slides=e.querySelector(".slides"),window.addEventListener("load",fe,!1),p={...f,...t,...a.getQueryHash()},D.load(p.dependencies).then(Q),a;console.warn("reveal.js can not initialize without a valid .reveal element.")},configure:re,sync:Oe,syncSlide:function(e=A){ae(e),Be(e),O.load(e),Xe(),$e()},syncFragments:Be,slide:De,left:wt,right:St,up:Et,down:kt,prev:Lt,next:xt,navigateTo:De,navigateLeft:wt,navigateRight:St,navigateUp:Et,navigateDown:kt,navigatePrev:Lt,navigateNext:xt,navigateFragment:gt,prevFragment:mt,nextFragment:ft,layout:fe,shuffle:ze,availableRoutes:_e,availableFragments:Je,toggleHelp:pe,toggleOverview:ke,togglePause:Ie,toggleAutoSlide:Re,isOverview:Le,isPaused:Te,isAutoSliding:function(){return!(!F||Y)},isSpeakerNotes:Ge,loadSlide:()=>O.load,unloadSlide:()=>O.unload,addEventListeners:ne,removeEventListeners:ie,getState:ut,setState:function(e){if("object"==typeof e){De(s(e.indexh),s(e.indexv),s(e.indexf));let t=s(e.paused),a=s(e.overview);"boolean"==typeof t&&t!==Te()&&Ie(t),"boolean"==typeof a&&a!==Le()&&ke(a)}},getSlidePastCount:Qe,getProgress:Ze,getIndices:at,getSlides:rt,getSlidesAttributes:function(){return rt().map(e=>{let t={};for(let a=0;aD.registerPlugin(...e),hasPlugin:(...e)=>D.hasPlugin(...e),getPlugin:(...e)=>D.getPlugin(...e),getPlugins:()=>D.getRegisteredPlugins(),getComputedSlideSize:ve,getPreviousSlide:()=>y,getCurrentSlide:()=>A,getScale:()=>I,getConfig:()=>p,getQueryHash:()=>{let e={};location.search.replace(/[A-Z0-9]+?=([\w\.%-]*)/gi,t=>{e[t.split("=").shift()]=t.split("=").pop()});for(let t in e){let a=e[t];e[t]=s(unescape(a))}return void 0!==e.dependencies&&delete e.dependencies,e},getRevealElement:()=>R.wrapper||document.querySelector(".reveal"),getSlidesElement:()=>R.slides,isFirstSlide:()=>0===v&&0===b,isLastSlide:()=>!!A&&(!A.nextElementSibling&&(!Me(A)||!A.parentNode.nextElementSibling)),isLastVerticalSlide:()=>!(!A||!Me(A))&&!A.nextElementSibling,isReady:()=>L,addEventListener:(e,t,r)=>{a.getRevealElement().addEventListener(e,t,r)},removeEventListener:(e,t,r)=>{a.getRevealElement().removeEventListener(e,t,r)},triggerKey:e=>Ct({keyCode:e}),registerKeyboardShortcut:(e,t)=>_[e]=t})};window.Reveal=v,window.Reveal.initialize=e=>(window.Reveal=new v(document.querySelector(".reveal"),e),window.Reveal.initialize(),new Promise(e=>window.Reveal.addEventListener("ready",e)))}]); \ No newline at end of file +!function(e){var t={};function a(r){if(t[r])return t[r].exports;var n=t[r]={i:r,l:!1,exports:{}};return e[r].call(n.exports,n,n.exports,a),n.l=!0,n.exports}a.m=e,a.c=t,a.d=function(e,t,r){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(a.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)a.d(r,n,function(t){return e[t]}.bind(null,n));return r},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="",a(a.s=0)}([function(e,t,a){"use strict";a.r(t);const r=/registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener/,n=(e,t)=>{for(let a in t)e[a]=t[a];return e},i=e=>Array.prototype.slice.call(e),s=e=>{if("string"==typeof e){if("null"===e)return null;if("true"===e)return!0;if("false"===e)return!1;if(e.match(/^-?[\d\.]+$/))return parseFloat(e)}return e},o=(e,t)=>{e.style.transform=t},l=(e,t)=>{let a=e.parentNode;for(;a;){let e=a.matches||a.matchesSelector||a.msMatchesSelector;if(e&&e.call(a,t))return a;a=a.parentNode}return null},d=e=>{let t=document.createElement("style");return t.type="text/css",e&&e.length>0&&(t.styleSheet?t.styleSheet.cssText=e:t.appendChild(document.createTextNode(e))),document.head.appendChild(t),t},c=navigator.userAgent,u=document.createElement("div"),h=/(iphone|ipod|ipad|android)/gi.test(c)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1,p=/chrome/i.test(c)&&!/edge/i.test(c),g=/android/gi.test(c),f="zoom"in u.style&&!h&&(p||/Version\/[\d\.]+.*Safari/.test(c));class m{constructor(e){this.Reveal=e}shouldPreload(e){let t=this.Reveal.getConfig().preloadIframes;return"boolean"!=typeof t&&(t=e.hasAttribute("data-preload")),t}load(e,t={}){e.style.display=this.Reveal.getConfig().display,i(e.querySelectorAll("img[data-src], video[data-src], audio[data-src], iframe[data-src]")).forEach(e=>{("IFRAME"!==e.tagName||this.shouldPreload(e))&&(e.setAttribute("src",e.getAttribute("data-src")),e.setAttribute("data-lazy-loaded",""),e.removeAttribute("data-src"))}),i(e.querySelectorAll("video, audio")).forEach(e=>{let t=0;i(e.querySelectorAll("source[data-src]")).forEach(e=>{e.setAttribute("src",e.getAttribute("data-src")),e.removeAttribute("data-src"),e.setAttribute("data-lazy-loaded",""),t+=1}),t>0&&e.load()});let a=e.slideBackgroundElement;if(a){a.style.display="block";let r=e.slideBackgroundContentElement,n=e.getAttribute("data-background-iframe");if(!1===a.hasAttribute("data-loaded")){a.setAttribute("data-loaded","true");let i=e.getAttribute("data-background-image"),s=e.getAttribute("data-background-video"),o=e.hasAttribute("data-background-video-loop"),l=e.hasAttribute("data-background-video-muted");if(i)r.style.backgroundImage="url("+encodeURI(i)+")";else if(s&&!this.Reveal.isSpeakerNotes()){let e=document.createElement("video");o&&e.setAttribute("loop",""),l&&(e.muted=!0),h&&(e.muted=!0,e.autoplay=!0,e.setAttribute("playsinline","")),s.split(",").forEach(t=>{e.innerHTML+=''}),r.appendChild(e)}else if(n&&!0!==t.excludeIframes){let e=document.createElement("iframe");e.setAttribute("allowfullscreen",""),e.setAttribute("mozallowfullscreen",""),e.setAttribute("webkitallowfullscreen",""),e.setAttribute("allow","autoplay"),e.setAttribute("data-src",n),e.style.width="100%",e.style.height="100%",e.style.maxHeight="100%",e.style.maxWidth="100%",r.appendChild(e)}}let i=r.querySelector("iframe[data-src]");i&&this.shouldPreload(a)&&!/autoplay=(1|true|yes)/gi.test(n)&&i.getAttribute("src")!==n&&i.setAttribute("src",n)}}unload(e){e.style.display="none";let t=this.Reveal.getSlideBackground(e);t&&(t.style.display="none",i(t.querySelectorAll("iframe[src]")).forEach(e=>{e.removeAttribute("src")})),i(e.querySelectorAll("video[data-lazy-loaded][src], audio[data-lazy-loaded][src], iframe[data-lazy-loaded][src]")).forEach(e=>{e.setAttribute("data-src",e.getAttribute("src")),e.removeAttribute("src")}),i(e.querySelectorAll("video[data-lazy-loaded] source[src], audio source[src]")).forEach(e=>{e.setAttribute("data-src",e.getAttribute("src")),e.removeAttribute("src")})}formatEmbeddedContent(){let e=(e,t,a)=>{i(this.Reveal.getSlidesElement().querySelectorAll("iframe["+e+'*="'+t+'"]')).forEach(t=>{let r=t.getAttribute(e);r&&-1===r.indexOf(a)&&t.setAttribute(e,r+(/\?/.test(r)?"&":"?")+a)})};e("src","youtube.com/embed/","enablejsapi=1"),e("data-src","youtube.com/embed/","enablejsapi=1"),e("src","player.vimeo.com/","api=1"),e("data-src","player.vimeo.com/","api=1")}startEmbeddedContent(e){e&&!this.Reveal.isSpeakerNotes()&&(i(e.querySelectorAll('img[src$=".gif"]')).forEach(e=>{e.setAttribute("src",e.getAttribute("src"))}),i(e.querySelectorAll("video, audio")).forEach(e=>{if(l(e,".fragment")&&!l(e,".fragment.visible"))return;let t=this.Reveal.getConfig().autoPlayMedia;if("boolean"!=typeof t&&(t=e.hasAttribute("data-autoplay")||!!l(e,".slide-background")),t&&"function"==typeof e.play)if(e.readyState>1)this.startEmbeddedMedia({target:e});else if(h){let t=e.play();t&&"function"==typeof t.catch&&!1===e.controls&&t.catch(()=>{e.controls=!0,e.addEventListener("play",()=>{e.controls=!1})})}else e.removeEventListener("loadeddata",this.startEmbeddedMedia),e.addEventListener("loadeddata",this.startEmbeddedMedia)}),i(e.querySelectorAll("iframe[src]")).forEach(e=>{l(e,".fragment")&&!l(e,".fragment.visible")||this.startEmbeddedIframe({target:e})}),i(e.querySelectorAll("iframe[data-src]")).forEach(e=>{l(e,".fragment")&&!l(e,".fragment.visible")||e.getAttribute("src")!==e.getAttribute("data-src")&&(e.removeEventListener("load",this.startEmbeddedIframe),e.addEventListener("load",this.startEmbeddedIframe),e.setAttribute("src",e.getAttribute("data-src")))}))}startEmbeddedMedia(e){let t=!!l(e.target,"html"),a=!!l(e.target,".present");t&&a&&(e.target.currentTime=0,e.target.play()),e.target.removeEventListener("loadeddata",this.startEmbeddedMedia)}startEmbeddedIframe(e){let t=e.target;if(t&&t.contentWindow){let a=!!l(e.target,"html"),r=!!l(e.target,".present");if(a&&r){let e=this.Reveal.getConfig().autoPlayMedia;"boolean"!=typeof e&&(e=t.hasAttribute("data-autoplay")||!!l(t,".slide-background")),/youtube\.com\/embed\//.test(t.getAttribute("src"))&&e?t.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}',"*"):/player\.vimeo\.com\//.test(t.getAttribute("src"))&&e?t.contentWindow.postMessage('{"method":"play"}',"*"):t.contentWindow.postMessage("slide:start","*")}}}stopEmbeddedContent(e,t={}){t=n({unloadIframes:!0},t),e&&e.parentNode&&(i(e.querySelectorAll("video, audio")).forEach(e=>{e.hasAttribute("data-ignore")||"function"!=typeof e.pause||(e.setAttribute("data-paused-by-reveal",""),e.pause())}),i(e.querySelectorAll("iframe")).forEach(e=>{e.contentWindow&&e.contentWindow.postMessage("slide:stop","*"),e.removeEventListener("load",this.startEmbeddedIframe)}),i(e.querySelectorAll('iframe[src*="youtube.com/embed/"]')).forEach(e=>{!e.hasAttribute("data-ignore")&&e.contentWindow&&"function"==typeof e.contentWindow.postMessage&&e.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}',"*")}),i(e.querySelectorAll('iframe[src*="player.vimeo.com/"]')).forEach(e=>{!e.hasAttribute("data-ignore")&&e.contentWindow&&"function"==typeof e.contentWindow.postMessage&&e.contentWindow.postMessage('{"method":"pause"}',"*")}),!0===t.unloadIframes&&i(e.querySelectorAll("iframe[data-src]")).forEach(e=>{e.setAttribute("src","about:blank"),e.removeAttribute("src")}))}}class v{constructor(e){this.Reveal=e,this.autoAnimateCounter=0}run(e,t){if(this.reset(),e.hasAttribute("data-auto-animate")&&t.hasAttribute("data-auto-animate")){this.autoAnimateStyleSheet=this.autoAnimateStyleSheet||d();let a=this.getAutoAnimateOptions(t);e.dataset.autoAnimate="pending",t.dataset.autoAnimate="pending";let r=this.getAutoAnimatableElements(e,t).map(e=>this.getAutoAnimateCSS(e.from,e.to,e.options||{},a,this.autoAnimateCounter++));"false"!==t.dataset.autoAnimateUnmatched&&!0===this.Reveal.getConfig().autoAnimateUnmatched&&(this.getUnmatchedAutoAnimateElements(t).forEach(e=>{e.dataset.autoAnimateTarget="unmatched"}),r.push(`[data-auto-animate="running"] [data-auto-animate-target="unmatched"] { transition: opacity ${.8*a.duration}s ease ${.2*a.duration}s; }`)),this.autoAnimateStyleSheet.innerHTML=r.join(""),requestAnimationFrame(()=>{this.autoAnimateStyleSheet&&(getComputedStyle(this.autoAnimateStyleSheet).fontWeight,t.dataset.autoAnimate="running")}),this.Reveal.dispatchEvent("autoanimate",{fromSlide:e,toSlide:t,sheet:this.autoAnimateStyleSheet})}}reset(){i(this.Reveal.getRevealElement().querySelectorAll('[data-auto-animate]:not([data-auto-animate=""])')).forEach(e=>{e.dataset.autoAnimate=""}),i(this.Reveal.getRevealElement().querySelectorAll("[data-auto-animate-target]")).forEach(e=>{delete e.dataset.autoAnimateTarget}),this.autoAnimateStyleSheet&&this.autoAnimateStyleSheet.parentNode&&(this.autoAnimateStyleSheet.parentNode.removeChild(this.autoAnimateStyleSheet),this.autoAnimateStyleSheet=null)}getAutoAnimateCSS(e,t,a,r,n){e.dataset.autoAnimateTarget="",t.dataset.autoAnimateTarget=n;let i=this.getAutoAnimateOptions(t,r);void 0!==a.delay&&(i.delay=a.delay),void 0!==a.duration&&(i.duration=a.duration),void 0!==a.easing&&(i.easing=a.easing);let s=this.getAutoAnimatableProperties("from",e,a),o=this.getAutoAnimatableProperties("to",t,a);if(!1!==a.translate||!1!==a.scale){let e=this.Reveal.getScale(),t={x:(s.x-o.x)/e,y:(s.y-o.y)/e,scaleX:s.width/o.width,scaleY:s.height/o.height};t.x=Math.round(1e3*t.x)/1e3,t.y=Math.round(1e3*t.y)/1e3,t.scaleX=Math.round(1e3*t.scaleX)/1e3,t.scaleX=Math.round(1e3*t.scaleX)/1e3;let r=!1!==a.translate&&(0!==t.x||0!==t.y),n=!1!==a.scale&&(0!==t.scaleX||0!==t.scaleY);if(r||n){let e=[];r&&e.push(`translate(${t.x}px, ${t.y}px)`),n&&e.push(`scale(${t.scaleX}, ${t.scaleY})`),s.styles.transform=e.join(" "),s.styles["transform-origin"]="top left",o.styles.transform="none"}}for(let e in o.styles){const t=o.styles[e],a=s.styles[e];t===a?delete o.styles[e]:(!0===t.explicitValue&&(o.styles[e]=t.value),!0===a.explicitValue&&(s.styles[e]=a.value))}let l="",d=Object.keys(o.styles);if(d.length>0){s.styles.transition="none",o.styles.transition=`all ${i.duration}s ${i.easing} ${i.delay}s`,o.styles["transition-property"]=d.join(", "),o.styles["will-change"]=d.join(", "),l='[data-auto-animate-target="'+n+'"] {'+Object.keys(s.styles).map(e=>e+": "+s.styles[e]+" !important;").join("")+'}[data-auto-animate="running"] [data-auto-animate-target="'+n+'"] {'+Object.keys(o.styles).map(e=>e+": "+o.styles[e]+" !important;").join("")+"}"}return l}getAutoAnimateOptions(e,t){let a={easing:this.Reveal.getConfig().autoAnimateEasing,duration:this.Reveal.getConfig().autoAnimateDuration,delay:0};if(a=n(a,t),e.closest&&e.parentNode){let t=e.parentNode.closest("[data-auto-animate-target]");t&&(a=this.getAutoAnimateOptions(t,a))}return e.dataset.autoAnimateEasing&&(a.easing=e.dataset.autoAnimateEasing),e.dataset.autoAnimateDuration&&(a.duration=parseFloat(e.dataset.autoAnimateDuration)),e.dataset.autoAnimateDelay&&(a.delay=parseFloat(e.dataset.autoAnimateDelay)),a}getAutoAnimatableProperties(e,t,a){let r={styles:[]};if(!1!==a.translate||!1!==a.scale){let e;e="function"==typeof a.measure?a.measure(t):t.getBoundingClientRect(),r.x=e.x,r.y=e.y,r.width=e.width,r.height=e.height}const n=getComputedStyle(t);return(a.styles||this.Reveal.getConfig().autoAnimateStyles).forEach(t=>{let a;"string"==typeof t&&(t={property:t}),a=void 0!==t.from&&"from"===e?{value:t.from,explicitValue:!0}:void 0!==t.to&&"to"===e?{value:t.to,explicitValue:!0}:n[t.property],""!==a&&(r.styles[t.property]=a)}),r}getAutoAnimatableElements(e,t){let a=("function"==typeof this.Reveal.getConfig().autoAnimateMatcher?this.Reveal.getConfig().autoAnimateMatcher:this.getAutoAnimatePairs).call(this,e,t),r=[];return a.filter((e,t)=>{if(-1===r.indexOf(e.to))return r.push(e.to),!0})}getAutoAnimatePairs(e,t){let a=[];const r="h1, h2, h3, h4, h5, h6, p, li";return this.findAutoAnimateMatches(a,e,t,"[data-id]",e=>e.nodeName+":::"+e.getAttribute("data-id")),this.findAutoAnimateMatches(a,e,t,r,e=>e.nodeName+":::"+e.innerText),this.findAutoAnimateMatches(a,e,t,"img, video, iframe",e=>e.nodeName+":::"+(e.getAttribute("src")||e.getAttribute("data-src"))),this.findAutoAnimateMatches(a,e,t,"pre",e=>e.nodeName+":::"+e.innerText),a.forEach(e=>{e.from.matches(r)?e.options={scale:!1}:e.from.matches("pre")&&(e.options={scale:!1,styles:["width","height"]},this.findAutoAnimateMatches(a,e.from,e.to,".hljs .hljs-ln-code",e=>e.textContent,{scale:!1,styles:[],measure:this.getLocalBoundingBox.bind(this)}),this.findAutoAnimateMatches(a,e.from,e.to,".hljs .hljs-ln-line[data-line-number]",e=>e.getAttribute("data-line-number"),{scale:!1,styles:["width"],measure:this.getLocalBoundingBox.bind(this)}))},this),a}getLocalBoundingBox(e){const t=this.Reveal.getScale();return{x:Math.round(e.offsetLeft*t*100)/100,y:Math.round(e.offsetTop*t*100)/100,width:Math.round(e.offsetWidth*t*100)/100,height:Math.round(e.offsetHeight*t*100)/100}}findAutoAnimateMatches(e,t,a,r,n,i){let s={},o={};[].slice.call(t.querySelectorAll(r)).forEach((e,t)=>{const a=n(e);"string"==typeof a&&a.length&&(s[a]=s[a]||[],s[a].push(e))}),[].slice.call(a.querySelectorAll(r)).forEach((t,a)=>{const r=n(t);let l;if(o[r]=o[r]||[],o[r].push(t),s[r]){const e=o[r].length-1,t=s[r].length-1;s[r][e]?(l=s[r][e],s[r][e]=null):s[r][t]&&(l=s[r][t],s[r][t]=null)}l&&e.push({from:l,to:t,options:i})})}getUnmatchedAutoAnimateElements(e){return[].slice.call(e.children).reduce((e,t)=>{const a=t.querySelector("[data-auto-animate-target]");return t.hasAttribute("data-auto-animate-target")||a||e.push(t),t.querySelector("[data-auto-animate-target]")&&(e=e.concat(this.getUnmatchedAutoAnimateElements(t))),e},[])}}class b{constructor(e){this.Reveal=e}showAll(){i(this.Reveal.getSlidesElement().querySelectorAll(".fragment")).forEach(e=>{e.classList.add("visible"),e.classList.remove("current-fragment")})}availableRoutes(){let e=this.Reveal.getCurrentSlide();if(e&&this.Reveal.getConfig().fragments){let t=e.querySelectorAll(".fragment"),a=e.querySelectorAll(".fragment:not(.visible)");return{prev:t.length-a.length>0,next:!!a.length}}return{prev:!1,next:!1}}sort(e,t=!1){e=i(e);let a=[],r=[],n=[];e.forEach(e=>{if(e.hasAttribute("data-fragment-index")){let t=parseInt(e.getAttribute("data-fragment-index"),10);a[t]||(a[t]=[]),a[t].push(e)}else r.push([e])}),a=a.concat(r);let s=0;return a.forEach(e=>{e.forEach(e=>{n.push(e),e.setAttribute("data-fragment-index",s)}),s++}),!0===t?a:n}sortAll(){this.Reveal.getHorizontalSlides().forEach(e=>{let t=i(e.querySelectorAll("section"));t.forEach((e,t)=>{this.sort(e.querySelectorAll(".fragment"))},this),0===t.length&&this.sort(e.querySelectorAll(".fragment"))})}update(e,t){let a={shown:[],hidden:[]},r=this.Reveal.getCurrentSlide();if(r&&this.Reveal.getConfig().fragments&&(t=t||this.sort(r.querySelectorAll(".fragment"))).length){let n=0;if("number"!=typeof e){let t=this.sort(r.querySelectorAll(".fragment.visible")).pop();t&&(e=parseInt(t.getAttribute("data-fragment-index")||0,10))}i(t).forEach((t,r)=>{t.hasAttribute("data-fragment-index")&&(r=parseInt(t.getAttribute("data-fragment-index"),10)),n=Math.max(n,r),r<=e?(t.classList.contains("visible")||a.shown.push(t),t.classList.add("visible"),t.classList.remove("current-fragment"),this.Reveal.announceStatus(this.Reveal.getStatusText(t)),r===e&&(t.classList.add("current-fragment"),this.Reveal.slideContent.startEmbeddedContent(t))):(t.classList.contains("visible")&&a.hidden.push(t),t.classList.remove("visible"),t.classList.remove("current-fragment"))}),e="number"==typeof e?e:-1,e=Math.max(Math.min(e,n),-1),r.setAttribute("data-fragment",e)}return a}goto(e,t=0){let a=this.Reveal.getCurrentSlide();if(a&&this.Reveal.getConfig().fragments){let r=this.sort(a.querySelectorAll(".fragment"));if(r.length){if("number"!=typeof e){let t=this.sort(a.querySelectorAll(".fragment.visible")).pop();e=t?parseInt(t.getAttribute("data-fragment-index")||0,10):-1}e+=t;let n=this.update(e,r);return n.hidden.length&&this.Reveal.dispatchEvent("fragmenthidden",{fragment:n.hidden[0],fragments:n.hidden}),n.shown.length&&this.Reveal.dispatchEvent("fragmentshown",{fragment:n.shown[0],fragments:n.shown}),this.Reveal.updateControls(),this.Reveal.updateProgress(),this.Reveal.getConfig().fragmentInURL&&this.Reveal.writeURL(),!(!n.shown.length&&!n.hidden.length)}}return!1}next(){return this.goto(null,1)}prev(){return this.goto(null,-1)}}const y=(e,t)=>{const a=document.createElement("script");a.type="text/javascript",a.async=!1,a.defer=!1,a.src=e,"function"==typeof t&&(a.onload=a.onreadystatechange=e=>{("load"===e.type||/loaded|complete/.test(a.readyState))&&(a.onload=a.onreadystatechange=a.onerror=null,t())},a.onerror=e=>{a.onload=a.onreadystatechange=a.onerror=null,t(new Error("Failed loading script: "+a.src+"\n"+e))});const r=document.querySelector("head");r.insertBefore(a,r.lastChild)};class w{constructor(){this.state="idle",this.registeredPlugins={},this.asyncDependencies=[]}load(e){return this.state="loading",new Promise(t=>{let a=[],r=0;e.forEach(e=>{e.condition&&!e.condition()||(e.async?this.asyncDependencies.push(e):a.push(e))}),a.length?(r=a.length,a.forEach(e=>{y(e.src,()=>{"function"==typeof e.callback&&e.callback(),0==--r&&this.initPlugins().then(t)})})):this.initPlugins().then(t)})}initPlugins(){return new Promise(e=>{let t=Object.keys(this.registeredPlugins).length;if(0===t)this.loadAsync().then(e);else{let a=()=>{0==--t&&this.loadAsync().then(e)};for(let e in this.registeredPlugins){let t=this.registeredPlugins[e];if("function"==typeof t.init){let e=t.init();e&&"function"==typeof e.then?e.then(a):a()}else a()}}})}loadAsync(){return this.state="loaded",this.asyncDependencies.length&&this.asyncDependencies.forEach(e=>{y(e.src,e.callback)}),Promise.resolve()}registerPlugin(e,t){void 0===this.registeredPlugins[e]?(this.registeredPlugins[e]=t,"loaded"===this.state&&"function"==typeof t.init&&t.init()):console.warn('reveal.js: "'+e+'" plugin has already been registered')}hasPlugin(e){return!!this.registeredPlugins[e]}getPlugin(e){return this.registeredPlugins[e]}getRegisteredPlugins(){return this.registeredPlugins}}class A{constructor(e,t){this.diameter=100,this.diameter2=this.diameter/2,this.thickness=6,this.playing=!1,this.progress=0,this.progressOffset=1,this.container=e,this.progressCheck=t,this.canvas=document.createElement("canvas"),this.canvas.className="playback",this.canvas.width=this.diameter,this.canvas.height=this.diameter,this.canvas.style.width=this.diameter2+"px",this.canvas.style.height=this.diameter2+"px",this.context=this.canvas.getContext("2d"),this.container.appendChild(this.canvas),this.render()}setPlaying(e){const t=this.playing;this.playing=e,!t&&this.playing?this.animate():this.render()}animate(){const e=this.progress;this.progress=this.progressCheck(),e>.8&&this.progress<.2&&(this.progressOffset=this.progress),this.render(),this.playing&&requestAnimationFrame(this.animate.bind(this))}render(){let e=this.playing?this.progress:0,t=this.diameter2-this.thickness,a=this.diameter2,r=this.diameter2;this.progressOffset+=.1*(1-this.progressOffset);const n=-Math.PI/2+e*(2*Math.PI),i=-Math.PI/2+this.progressOffset*(2*Math.PI);this.context.save(),this.context.clearRect(0,0,this.diameter,this.diameter),this.context.beginPath(),this.context.arc(a,r,t+4,0,2*Math.PI,!1),this.context.fillStyle="rgba( 0, 0, 0, 0.4 )",this.context.fill(),this.context.beginPath(),this.context.arc(a,r,t,0,2*Math.PI,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="rgba( 255, 255, 255, 0.2 )",this.context.stroke(),this.playing&&(this.context.beginPath(),this.context.arc(a,r,t,i,n,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="#fff",this.context.stroke()),this.context.translate(a-14,r-14),this.playing?(this.context.fillStyle="#fff",this.context.fillRect(0,0,10,28),this.context.fillRect(18,0,10,28)):(this.context.beginPath(),this.context.translate(4,0),this.context.moveTo(0,0),this.context.lineTo(24,14),this.context.lineTo(0,28),this.context.fillStyle="#fff",this.context.fill()),this.context.restore()}on(e,t){this.canvas.addEventListener(e,t,!1)}off(e,t){this.canvas.removeEventListener(e,t,!1)}destroy(){this.playing=!1,this.canvas.parentNode&&this.container.removeChild(this.canvas)}}var S={width:960,height:700,margin:.04,minScale:.2,maxScale:2,controls:!0,controlsTutorial:!0,controlsLayout:"bottom-right",controlsBackArrows:"faded",progress:!0,slideNumber:!1,showSlideNumber:"all",hashOneBasedIndex:!1,hash:!1,history:!1,keyboard:!0,keyboardCondition:null,overview:!0,disableLayout:!1,center:!0,touch:!0,loop:!1,rtl:!1,navigationMode:"default",shuffle:!1,fragments:!0,fragmentInURL:!1,embedded:!1,help:!0,pause:!0,showNotes:!1,autoPlayMedia:null,preloadIframes:null,autoAnimate:!0,autoAnimateMatcher:null,autoAnimateEasing:"ease",autoAnimateDuration:1,autoAnimateUnmatched:!0,autoAnimateStyles:["opacity","color","background-color","padding","font-size","line-height","letter-spacing","border-width","border-color","border-radius","outline","outline-offset"],autoSlide:0,autoSlideStoppable:!0,autoSlideMethod:null,defaultTiming:null,mouseWheel:!1,previewLinks:!1,postMessage:!0,postMessageEvents:!1,focusBodyOnPageVisibilityChange:!0,transition:"slide",transitionSpeed:"default",backgroundTransition:"fade",parallaxBackgroundImage:"",parallaxBackgroundSize:"",parallaxBackgroundRepeat:"",parallaxBackgroundPosition:"",parallaxBackgroundHorizontal:null,parallaxBackgroundVertical:null,pdfMaxPagesPerSlide:Number.POSITIVE_INFINITY,pdfSeparateFragments:!0,pdfPageHeightOffset:-1,viewDistance:3,mobileViewDistance:2,display:"block",hideInactiveCursor:!0,hideCursorTime:5e3,dependencies:[]};const E=e=>{let t=e.match(/^#([0-9a-f]{3})$/i);if(t&&t[1])return t=t[1],{r:17*parseInt(t.charAt(0),16),g:17*parseInt(t.charAt(1),16),b:17*parseInt(t.charAt(2),16)};let a=e.match(/^#([0-9a-f]{6})$/i);if(a&&a[1])return a=a[1],{r:parseInt(a.substr(0,2),16),g:parseInt(a.substr(2,2),16),b:parseInt(a.substr(4,2),16)};let r=e.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);if(r)return{r:parseInt(r[1],10),g:parseInt(r[2],10),b:parseInt(r[3],10)};let n=e.match(/^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\,\s*([\d]+|[\d]*.[\d]+)\s*\)$/i);return n?{r:parseInt(n[1],10),g:parseInt(n[2],10),b:parseInt(n[3],10),a:parseFloat(n[4])}:null};var k=function(e,t){const a={};navigator.userAgent;let l,c,u,p,y,k,L,x=!1,M=!1,N=null,P=null,q=!1,C=!1,R=[],I=1,T={layout:"",overview:""},O={},D=new w,B=new m(a),H=new v(a),z=new b(a),j=0,$=0,W=!1,U=0,F=!1,V=0,X=0,Y=-1,K=!1,_={startX:0,startY:0,startCount:0,captured:!1,threshold:40},J={},Q={};function Z(){x=!0,function(){O.slides.classList.add("no-transition"),h?O.wrapper.classList.add("no-hover"):O.wrapper.classList.remove("no-hover");O.background=ae(O.wrapper,"div","backgrounds",null),O.progress=ae(O.wrapper,"div","progress",""),O.progressbar=O.progress.querySelector("span"),O.controls=ae(O.wrapper,"aside","controls",`\n\t\t\t\n\t\t\t\n\t\t\t`),O.slideNumber=ae(O.wrapper,"div","slide-number",""),O.speakerNotes=ae(O.wrapper,"div","speaker-notes",null),O.speakerNotes.setAttribute("data-prevent-swipe",""),O.speakerNotes.setAttribute("tabindex","0"),O.pauseOverlay=ae(O.wrapper,"div","pause-overlay",l.controls?'':null),O.wrapper.setAttribute("role","application"),O.controlsLeft=i(O.wrapper.querySelectorAll(".navigate-left")),O.controlsRight=i(O.wrapper.querySelectorAll(".navigate-right")),O.controlsUp=i(O.wrapper.querySelectorAll(".navigate-up")),O.controlsDown=i(O.wrapper.querySelectorAll(".navigate-down")),O.controlsPrev=i(O.wrapper.querySelectorAll(".navigate-prev")),O.controlsNext=i(O.wrapper.querySelectorAll(".navigate-next")),O.controlsRightArrow=O.controls.querySelector(".navigate-right"),O.controlsLeftArrow=O.controls.querySelector(".navigate-left"),O.controlsDownArrow=O.controls.querySelector(".navigate-down"),O.statusDiv=function(){let e=O.wrapper.querySelector(".aria-status");e||(e=document.createElement("div"),e.style.position="absolute",e.style.height="1px",e.style.width="1px",e.style.overflow="hidden",e.style.clip="rect( 1px, 1px, 1px, 1px )",e.classList.add("aria-status"),e.setAttribute("aria-live","polite"),e.setAttribute("aria-atomic","true"),O.wrapper.appendChild(e));return e}()}(),l.postMessage&&window.addEventListener("message",e=>{let t=e.data;if("string"==typeof t&&"{"===t.charAt(0)&&"}"===t.charAt(t.length-1)&&(t=JSON.parse(t),t.method&&"function"==typeof a[t.method]))if(!1===r.test(t.method)){const e=a[t.method].apply(a,t.args);ue("callback",{method:t.method,result:e})}else console.warn('reveal.js: "'+t.method+'" is is blacklisted from the postMessage API')},!1),setInterval(()=>{0===O.wrapper.scrollTop&&0===O.wrapper.scrollLeft||(O.wrapper.scrollTop=0,O.wrapper.scrollLeft=0)},1e3),nt().forEach(e=>{i(e.querySelectorAll("section")).forEach((e,t)=>{t>0&&(e.classList.remove("present"),e.classList.remove("past"),e.classList.add("future"),e.setAttribute("aria-hidden","true"))})}),ie(),et(),Ke(!0),setTimeout(()=>{O.slides.classList.remove("no-transition"),O.wrapper.classList.add("ready"),ce("ready",{indexh:c,indexv:u,currentSlide:y})},1),de()&&(oe(),"complete"===document.readyState?te():window.addEventListener("load",te))}function G(e){O.statusDiv.textContent=e}function ee(e){let t="";if(3===e.nodeType)t+=e.textContent;else if(1===e.nodeType){let a=e.getAttribute("aria-hidden"),r="none"===window.getComputedStyle(e).display;"true"===a||r||i(e.childNodes).forEach(e=>{t+=ee(e)})}return t=t.trim(),""===t?"":t+" "}function te(){let e=ye(window.innerWidth,window.innerHeight),t=Math.floor(e.width*(1+l.margin)),a=Math.floor(e.height*(1+l.margin)),r=e.width,n=e.height;d("@page{size:"+t+"px "+a+"px; margin: 0px;}"),d(".reveal section>img, .reveal section>video, .reveal section>iframe{max-width: "+r+"px; max-height:"+n+"px}"),document.body.classList.add("print-pdf"),document.body.style.width=t+"px",document.body.style.height=a+"px",be(r,n);let s=l.slideNumber&&/all|print/i.test(l.showSlideNumber);i(O.wrapper.querySelectorAll(".slides section")).forEach((function(e){e.setAttribute("data-slide-number",Xe(e))})),i(O.wrapper.querySelectorAll(".slides section")).forEach((function(e){if(!1===e.classList.contains("stack")){let o=(t-r)/2,d=(a-n)/2,c=e.scrollHeight,u=Math.max(Math.ceil(c/a),1);u=Math.min(u,l.pdfMaxPagesPerSlide),(1===u&&l.center||e.classList.contains("center"))&&(d=Math.max((a-c)/2,0));let h=document.createElement("div");if(h.className="pdf-page",h.style.height=(a+l.pdfPageHeightOffset)*u+"px",e.parentNode.insertBefore(h,e),h.appendChild(e),e.style.left=o+"px",e.style.top=d+"px",e.style.width=r+"px",e.slideBackgroundElement&&h.insertBefore(e.slideBackgroundElement,e),l.showNotes){let a=ct(e);if(a){let e=8,r="string"==typeof l.showNotes?l.showNotes:"inline",n=document.createElement("div");n.classList.add("speaker-notes"),n.classList.add("speaker-notes-pdf"),n.setAttribute("data-layout",r),n.innerHTML=a,"separate-page"===r?h.parentNode.insertBefore(n,h.nextSibling):(n.style.left=e+"px",n.style.bottom=e+"px",n.style.width=t-2*e+"px",h.appendChild(n))}}if(s){let t=document.createElement("div");t.classList.add("slide-number"),t.classList.add("slide-number-pdf"),t.innerHTML=e.getAttribute("data-slide-number"),h.appendChild(t)}if(l.pdfSeparateFragments){let e,t,a=z.sort(h.querySelectorAll(".fragment"),!0);a.forEach((function(a){e&&e.forEach((function(e){e.classList.remove("current-fragment")})),a.forEach((function(e){e.classList.add("visible","current-fragment")}));let r=h.cloneNode(!0);h.parentNode.insertBefore(r,(t||h).nextSibling),e=a,t=r})),a.forEach((function(e){e.forEach((function(e){e.classList.remove("visible","current-fragment")}))}))}else i(h.querySelectorAll(".fragment:not(.fade-out)")).forEach((function(e){e.classList.add("visible")}))}})),ce("pdf-ready")}function ae(e,t,a,r=""){let n=e.querySelectorAll("."+a);for(let t=0;t1&&l.autoSlide&&l.autoSlideStoppable&&(L=new A(O.wrapper,()=>Math.min(Math.max((Date.now()-Y)/V,0),1)),L.on("click",Xt),K=!1),!1===l.fragments&&z.showAll();let i="none";l.slideNumber&&!de()&&("all"===l.showSlideNumber||"speaker"===l.showSlideNumber&&Ge())&&(i="block"),O.slideNumber.style.display=i,"default"!==l.navigationMode?O.wrapper.setAttribute("data-navigation-mode",l.navigationMode):O.wrapper.removeAttribute("data-navigation-mode"),"linear"===l.navigationMode?(J["→ , ↓ , SPACE , N , L , J"]="Next slide",J["← , ↑ , P , H , K"]="Previous slide"):(J["N , SPACE"]="Next slide",J.P="Previous slide",J["← , H"]="Navigate left",J["→ , L"]="Navigate right",J["↑ , K"]="Navigate up",J["↓ , J"]="Navigate down"),J["Home , Shift ←"]="First slide",J["End , Shift →"]="Last slide",J["B , ."]="Pause",J.F="Fullscreen",J["ESC, O"]="Slide overview",He()}function se(){F=!0,window.addEventListener("hashchange",$t,!1),window.addEventListener("resize",Wt,!1),l.touch&&("onpointerdown"in window?(O.wrapper.addEventListener("pointerdown",qt,!1),O.wrapper.addEventListener("pointermove",Ct,!1),O.wrapper.addEventListener("pointerup",Rt,!1)):window.navigator.msPointerEnabled?(O.wrapper.addEventListener("MSPointerDown",qt,!1),O.wrapper.addEventListener("MSPointerMove",Ct,!1),O.wrapper.addEventListener("MSPointerUp",Rt,!1)):(O.wrapper.addEventListener("touchstart",Mt,!1),O.wrapper.addEventListener("touchmove",Nt,!1),O.wrapper.addEventListener("touchend",Pt,!1))),l.keyboard&&(document.addEventListener("keydown",xt,!1),document.addEventListener("keypress",Lt,!1)),l.progress&&O.progress&&O.progress.addEventListener("click",Tt,!1),O.pauseOverlay.addEventListener("click",Ie,!1),l.focusBodyOnPageVisibilityChange&&document.addEventListener("visibilitychange",Ut,!1);let e=["touchstart","click"];g&&(e=["touchstart"]),e.forEach(e=>{O.controlsLeft.forEach(t=>t.addEventListener(e,Ot,!1)),O.controlsRight.forEach(t=>t.addEventListener(e,Dt,!1)),O.controlsUp.forEach(t=>t.addEventListener(e,Bt,!1)),O.controlsDown.forEach(t=>t.addEventListener(e,Ht,!1)),O.controlsPrev.forEach(t=>t.addEventListener(e,zt,!1)),O.controlsNext.forEach(t=>t.addEventListener(e,jt,!1))})}function oe(){F=!1,document.removeEventListener("keydown",xt,!1),document.removeEventListener("keypress",Lt,!1),window.removeEventListener("hashchange",$t,!1),window.removeEventListener("resize",Wt,!1),O.wrapper.removeEventListener("pointerdown",qt,!1),O.wrapper.removeEventListener("pointermove",Ct,!1),O.wrapper.removeEventListener("pointerup",Rt,!1),O.wrapper.removeEventListener("MSPointerDown",qt,!1),O.wrapper.removeEventListener("MSPointerMove",Ct,!1),O.wrapper.removeEventListener("MSPointerUp",Rt,!1),O.wrapper.removeEventListener("touchstart",Mt,!1),O.wrapper.removeEventListener("touchmove",Nt,!1),O.wrapper.removeEventListener("touchend",Pt,!1),O.pauseOverlay.removeEventListener("click",Ie,!1),l.progress&&O.progress&&O.progress.removeEventListener("click",Tt,!1),["touchstart","click"].forEach(e=>{O.controlsLeft.forEach(t=>t.removeEventListener(e,Ot,!1)),O.controlsRight.forEach(t=>t.removeEventListener(e,Dt,!1)),O.controlsUp.forEach(t=>t.removeEventListener(e,Bt,!1)),O.controlsDown.forEach(t=>t.removeEventListener(e,Ht,!1)),O.controlsPrev.forEach(t=>t.removeEventListener(e,zt,!1)),O.controlsNext.forEach(t=>t.removeEventListener(e,jt,!1))})}function le(e){"string"==typeof e.layout&&(T.layout=e.layout),"string"==typeof e.overview&&(T.overview=e.overview),T.layout?o(O.slides,T.layout+" "+T.overview):o(O.slides,T.overview)}function de(){return/print-pdf/gi.test(window.location.search)}function ce(e,t){let a=document.createEvent("HTMLEvents",1,2);a.initEvent(e,!0,!0),n(a,t),O.wrapper.dispatchEvent(a),ue(e)}function ue(e,t){if(l.postMessageEvents&&window.parent!==window.self){let a={namespace:"reveal",eventName:e,state:ut()};n(a,t),window.parent.postMessage(JSON.stringify(a),"*")}}function he(e="a"){i(O.wrapper.querySelectorAll(e)).forEach(e=>{/^(http|www)/gi.test(e.getAttribute("href"))&&e.addEventListener("click",Vt,!1)})}function pe(e="a"){i(O.wrapper.querySelectorAll(e)).forEach(e=>{/^(http|www)/gi.test(e.getAttribute("href"))&&e.removeEventListener("click",Vt,!1)})}function ge(e){"boolean"==typeof e?e?fe():me():O.overlay?me():fe()}function fe(){if(l.help){me(),O.overlay=document.createElement("div"),O.overlay.classList.add("overlay"),O.overlay.classList.add("overlay-help"),O.wrapper.appendChild(O.overlay);let e='

Keyboard Shortcuts


';e+="";for(let t in J)e+=``;for(let t in Q)Q[t].key&&Q[t].description&&(e+=``);e+="
KEYACTION
${t}${J[t]}
${Q[t].key}${Q[t].description}
",O.overlay.innerHTML=`\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
${e}
\n\t\t\t\t
\n\t\t\t`,O.overlay.querySelector(".close").addEventListener("click",e=>{me(),e.preventDefault()},!1)}}function me(){O.overlay&&(O.overlay.parentNode.removeChild(O.overlay),O.overlay=null)}function ve(){if(O.wrapper&&!de()){if(!l.disableLayout){h&&document.documentElement.style.setProperty("--vh",.01*window.innerHeight+"px");const e=ye(),t=I;be(l.width,l.height),O.slides.style.width=e.width+"px",O.slides.style.height=e.height+"px",I=Math.min(e.presentationWidth/e.width,e.presentationHeight/e.height),I=Math.max(I,l.minScale),I=Math.min(I,l.maxScale),1===I?(O.slides.style.zoom="",O.slides.style.left="",O.slides.style.top="",O.slides.style.bottom="",O.slides.style.right="",le({layout:""})):I>1&&f&&window.devicePixelRatio<2?(O.slides.style.zoom=I,O.slides.style.left="",O.slides.style.top="",O.slides.style.bottom="",O.slides.style.right="",le({layout:""})):(O.slides.style.zoom="",O.slides.style.left="50%",O.slides.style.top="50%",O.slides.style.bottom="auto",O.slides.style.right="auto",le({layout:"translate(-50%, -50%) scale("+I+")"}));const a=i(O.wrapper.querySelectorAll(".slides section"));for(let t=0,r=a.length;t .stretch")).forEach(a=>{let r=function(e,t=0){if(e){let a,r=e.style.height;return e.style.height="0px",e.parentNode.style.height="auto",a=t-e.parentNode.offsetHeight,e.style.height=r+"px",e.parentNode.style.removeProperty("height"),a}return t}(a,t);if(/(img|video)/gi.test(a.nodeName)){const t=a.naturalWidth||a.videoWidth,n=a.naturalHeight||a.videoHeight,i=Math.min(e/t,r/n);a.style.width=t*i+"px",a.style.height=n*i+"px"}else a.style.width=e+"px",a.style.height=r+"px"})}function ye(e,t){const a={width:l.width,height:l.height,presentationWidth:e||O.wrapper.offsetWidth,presentationHeight:t||O.wrapper.offsetHeight};return a.presentationWidth-=a.presentationWidth*l.margin,a.presentationHeight-=a.presentationHeight*l.margin,"string"==typeof a.width&&/%$/.test(a.width)&&(a.width=parseInt(a.width,10)/100*a.presentationWidth),"string"==typeof a.height&&/%$/.test(a.height)&&(a.height=parseInt(a.height,10)/100*a.presentationHeight),a}function we(e,t){"object"==typeof e&&"function"==typeof e.setAttribute&&e.setAttribute("data-previous-indexv",t||0)}function Ae(e){if("object"==typeof e&&"function"==typeof e.setAttribute&&e.classList.contains("stack")){const t=e.hasAttribute("data-start-indexv")?"data-start-indexv":"data-previous-indexv";return parseInt(e.getAttribute(t)||0,10)}return 0}function Se(){if(l.overview&&!Me()){M=!0,O.wrapper.classList.add("overview"),pt(),O.slides.appendChild(O.background),i(O.wrapper.querySelectorAll(".slides section")).forEach(e=>{e.classList.contains("stack")||e.addEventListener("click",Ft,!0)});const e=70,t=ye();N=t.width+e,P=t.height+e,l.rtl&&(N=-N),We(),Ee(),ke(),ve(),ce("overviewshown",{indexh:c,indexv:u,currentSlide:y})}}function Ee(){i(O.wrapper.querySelectorAll(".slides>section")).forEach((e,t)=>{e.setAttribute("data-index-h",t),o(e,"translate3d("+t*N+"px, 0, 0)"),e.classList.contains("stack")&&i(e.querySelectorAll("section")).forEach((e,a)=>{e.setAttribute("data-index-h",t),e.setAttribute("data-index-v",a),o(e,"translate3d(0, "+a*P+"px, 0)")})}),i(O.background.childNodes).forEach((e,t)=>{o(e,"translate3d("+t*N+"px, 0, 0)"),i(e.querySelectorAll(".slide-background")).forEach((e,t)=>{o(e,"translate3d(0, "+t*P+"px, 0)")})})}function ke(){const e=Math.min(window.innerWidth,window.innerHeight);le({overview:["scale("+Math.max(e/5,150)/e+")","translateX("+-c*N+"px)","translateY("+-u*P+"px)"].join(" ")})}function Le(){l.overview&&(M=!1,O.wrapper.classList.remove("overview"),O.wrapper.classList.add("overview-deactivating"),setTimeout(()=>{O.wrapper.classList.remove("overview-deactivating")},1),O.wrapper.appendChild(O.background),i(O.wrapper.querySelectorAll(".slides section")).forEach(e=>{o(e,""),e.removeEventListener("click",Ft,!0)}),i(O.background.querySelectorAll(".slide-background")).forEach(e=>{o(e,"")}),le({overview:""}),Be(c,u),ve(),ht(),ce("overviewhidden",{indexh:c,indexv:u,currentSlide:y}))}function xe(e){"boolean"==typeof e?e?Se():Le():Me()?Le():Se()}function Me(){return M}function Ne(e){let t="/",a=e||y,r=a?a.getAttribute("id"):null;r&&(r=encodeURIComponent(r));let n=at(e);if(l.fragmentInURL||(n.f=void 0),"string"==typeof r&&r.length&&void 0===n.f)t="/"+r;else{let e=l.hashOneBasedIndex?1:0;(n.h>0||n.v>0||void 0!==n.f)&&(t+=n.h+e),(n.v>0||void 0!==n.f)&&(t+="/"+(n.v+e)),void 0!==n.f&&(t+="/"+n.f)}return t}function Pe(e=y){return e&&e.parentNode&&!!e.parentNode.nodeName.match(/section/i)}function qe(){W&&(W=!1,O.wrapper.style.cursor="")}function Ce(){!1===W&&(W=!0,O.wrapper.style.cursor="none")}function Re(){if(l.pause){const e=O.wrapper.classList.contains("paused");pt(),O.wrapper.classList.add("paused"),!1===e&&ce("paused")}}function Ie(){const e=O.wrapper.classList.contains("paused");O.wrapper.classList.remove("paused"),ht(),e&&ce("resumed")}function Te(e){"boolean"==typeof e?e?Re():Ie():Oe()?Ie():Re()}function Oe(){return O.wrapper.classList.contains("paused")}function De(e){"boolean"==typeof e?e?ft():gt():K?ft():gt()}function Be(e,t,r,n){p=y;const s=O.wrapper.querySelectorAll(".slides>section");if(0===s.length)return;void 0!==t||Me()||(t=Ae(s[e])),p&&p.parentNode&&p.parentNode.classList.contains("stack")&&we(p.parentNode,u);const o=R.concat();R.length=0;let d=c||0,h=u||0;c=$e(".slides>section",void 0===e?c:e),u=$e(".slides>section.present>section",void 0===t?u:t),We(),ve(),Me()&&ke();let g=s[c],f=g.querySelectorAll("section");y=f[u]||g,void 0!==r&&z.goto(r);let m=c!==d||u!==h;m||(p=null),p&&p!==y&&(p.classList.remove("present"),p.setAttribute("aria-hidden","true"),a.isFirstSlide()&&setTimeout(()=>{i(O.wrapper.querySelectorAll(".slides>section.stack")).forEach(e=>{we(e,0)})},0));e:for(let e=0,t=R.length;e{O.slides.classList.remove("disable-slide-transitions")},0),l.autoAnimate&&H.run(p,y))}function He(){oe(),se(),ve(),V=l.autoSlide,ht(),de(),O.background.innerHTML="",O.background.classList.add("no-transition"),i(O.wrapper.querySelectorAll(".slides>section")).forEach(e=>{let t=re(e,O.background);i(e.querySelectorAll("section")).forEach(e=>{re(e,t),t.classList.add("stack")})}),l.parallaxBackgroundImage?(O.background.style.backgroundImage='url("'+l.parallaxBackgroundImage+'")',O.background.style.backgroundSize=l.parallaxBackgroundSize,O.background.style.backgroundRepeat=l.parallaxBackgroundRepeat,O.background.style.backgroundPosition=l.parallaxBackgroundPosition,setTimeout(()=>{O.wrapper.classList.add("has-parallax-background")},1)):(O.background.style.backgroundImage="",O.wrapper.classList.remove("has-parallax-background")),tt(),z.sortAll(),Ye(),Fe(),Ve(),We(),Ke(!0),l.showNotes&&O.slides.querySelectorAll("[data-notes], aside.notes").length>0?O.wrapper.classList.add("show-notes"):O.wrapper.classList.remove("show-notes"),Ue(),B.formatEmbeddedContent(),!1===l.autoPlayMedia?B.stopEmbeddedContent(y,{unloadIframes:!1}):B.startEmbeddedContent(y),Me()&&Ee()}function ze(e=y){return l.sort(e.querySelectorAll(".fragment"))}function je(){nt().forEach((e,t,a)=>{O.slides.insertBefore(e,a[Math.floor(Math.random()*a.length)])})}function $e(e,t){let a=i(O.wrapper.querySelectorAll(e)),r=a.length,n=de();if(r){l.loop&&(t%=r)<0&&(t=r+t),t=Math.max(Math.min(t,r-1),0);for(let e=0;e{e.classList.add("visible"),e.classList.remove("current-fragment")})):e>t&&(r.classList.add(s?"past":"future"),l.fragments&&i(r.querySelectorAll(".fragment.visible")).forEach(e=>{e.classList.remove("visible","current-fragment")}))}a[t].classList.add("present"),a[t].removeAttribute("hidden"),a[t].removeAttribute("aria-hidden");let e=a[t].getAttribute("data-state");e&&(R=R.concat(e.split(" ")))}else t=0;return t}function We(){let e,t,a=nt(),r=a.length;if(r&&void 0!==c){let n=Me()?10:l.viewDistance;h&&(n=Me()?6:l.mobileViewDistance),de()&&(n=Number.MAX_VALUE);for(let s=0;sNo notes on this slide.')}function Fe(){l.progress&&O.progressbar&&(O.progressbar.style.width=Ze()*O.wrapper.offsetWidth+"px")}function Ve(){l.slideNumber&&O.slideNumber&&(O.slideNumber.innerHTML=Xe())}function Xe(e=y){let t,a="h.v";if("function"==typeof l.slideNumber)t=l.slideNumber(e);else switch("string"==typeof l.slideNumber&&(a=l.slideNumber),/c/.test(a)||1!==O.wrapper.querySelectorAll(".slides>section").length||(a="c"),t=[],a){case"c":t.push(Qe(e)+1);break;case"c/t":t.push(Qe(e)+1,"/",lt());break;default:let r=at(e);t.push(r.h+1);let n="h/v"===a?"/":".";Pe(e)&&t.push(n,r.v+1)}let r="#"+Ne(e);return function(e,t,a,r="#"+Ne()){return"number"!=typeof a||isNaN(a)?`\n\t\t\t\t\t${e}\n\t\t\t\t\t`:`\n\t\t\t\t\t${e}\n\t\t\t\t\t${t}\n\t\t\t\t\t${a}\n\t\t\t\t\t`}(t[0],t[1],t[2],r)}function Ye(){let e=Je(),t=z.availableRoutes();[...O.controlsLeft,...O.controlsRight,...O.controlsUp,...O.controlsDown,...O.controlsPrev,...O.controlsNext].forEach(e=>{e.classList.remove("enabled","fragmented"),e.setAttribute("disabled","disabled")}),e.left&&O.controlsLeft.forEach(e=>{e.classList.add("enabled"),e.removeAttribute("disabled")}),e.right&&O.controlsRight.forEach(e=>{e.classList.add("enabled"),e.removeAttribute("disabled")}),e.up&&O.controlsUp.forEach(e=>{e.classList.add("enabled"),e.removeAttribute("disabled")}),e.down&&O.controlsDown.forEach(e=>{e.classList.add("enabled"),e.removeAttribute("disabled")}),(e.left||e.up)&&O.controlsPrev.forEach(e=>{e.classList.add("enabled"),e.removeAttribute("disabled")}),(e.right||e.down)&&O.controlsNext.forEach(e=>{e.classList.add("enabled"),e.removeAttribute("disabled")}),y&&(t.prev&&O.controlsPrev.forEach(e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")}),t.next&&O.controlsNext.forEach(e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")}),Pe(y)?(t.prev&&O.controlsUp.forEach(e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")}),t.next&&O.controlsDown.forEach(e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")})):(t.prev&&O.controlsLeft.forEach(e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")}),t.next&&O.controlsRight.forEach(e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")}))),l.controlsTutorial&&(!C&&e.down?O.controlsDownArrow.classList.add("highlight"):(O.controlsDownArrow.classList.remove("highlight"),l.rtl?!q&&e.left&&0===u?O.controlsLeftArrow.classList.add("highlight"):O.controlsLeftArrow.classList.remove("highlight"):!q&&e.right&&0===u?O.controlsRightArrow.classList.add("highlight"):O.controlsRightArrow.classList.remove("highlight")))}function Ke(e=!1){let t=null,a=l.rtl?"future":"past",r=l.rtl?"past":"future";if(i(O.background.childNodes).forEach((n,s)=>{n.classList.remove("past","present","future"),sc?n.classList.add(r):(n.classList.add("present"),t=n),(e||s===c)&&i(n.querySelectorAll(".slide-background")).forEach((e,a)=>{e.classList.remove("past","present","future"),au?e.classList.add("future"):(e.classList.add("present"),s===c&&(t=e))})}),k&&B.stopEmbeddedContent(k,{unloadIframes:!B.shouldPreload(k)}),t){B.startEmbeddedContent(t);let e=t.querySelector(".slide-background-content");if(e){let t=e.style.backgroundImage||"";/\.gif/i.test(t)&&(e.style.backgroundImage="",window.getComputedStyle(e).opacity,e.style.backgroundImage=t)}let a=k?k.getAttribute("data-background-hash"):null,r=t.getAttribute("data-background-hash");r&&r===a&&t!==k&&O.background.classList.add("no-transition"),k=t}y&&["has-light-background","has-dark-background"].forEach(e=>{y.classList.contains(e)?O.wrapper.classList.add(e):O.wrapper.classList.remove(e)}),setTimeout(()=>{O.background.classList.remove("no-transition")},1)}function _e(){if(l.parallaxBackgroundImage){let e,t,a=nt(),r=it(),n=O.background.style.backgroundSize.split(" ");1===n.length?e=t=parseInt(n[0],10):(e=parseInt(n[0],10),t=parseInt(n[1],10));let i,s,o=O.background.offsetWidth,d=a.length;i="number"==typeof l.parallaxBackgroundHorizontal?l.parallaxBackgroundHorizontal:d>1?(e-o)/(d-1):0,s=i*c*-1;let h,p,g=O.background.offsetHeight,f=r.length;h="number"==typeof l.parallaxBackgroundVertical?l.parallaxBackgroundVertical:(t-g)/(f-1),p=f>0?h*u:0,O.background.style.backgroundPosition=s+"px "+-p+"px"}}function Je(){let e=O.wrapper.querySelectorAll(".slides>section"),t=O.wrapper.querySelectorAll(".slides>section.present>section"),a={left:c>0,right:c0,down:u1&&(a.left=!0,a.right=!0),t.length>1&&(a.up=!0,a.down=!0)),l.rtl){let e=a.left;a.left=a.right,a.right=e}return a}function Qe(e=y){let t=nt(),a=0;e:for(let r=0;r0){let a=.9;t+=y.querySelectorAll(".fragment.visible").length/e.length*a}}return Math.min(t/(e-1),1)}function Ge(){return!!window.location.search.match(/receiver/gi)}function et(){let e=window.location.hash,t=e.slice(2).split("/"),r=e.replace(/#|\//gi,"");if(!/^[0-9]*$/.test(t[0])&&r.length){let e;try{e=document.getElementById(decodeURIComponent(r))}catch(e){}let t=!!y&&y.getAttribute("id")===r;if(e){if(!t){let t=a.getIndices(e);Be(t.h,t.v)}}else Be(c||0,u||0)}else{let e,a=l.hashOneBasedIndex?1:0,r=parseInt(t[0],10)-a||0,n=parseInt(t[1],10)-a||0;l.fragmentInURL&&(e=parseInt(t[2],10),isNaN(e)&&(e=void 0)),r===c&&n===u&&void 0===e||Be(r,n,e)}}function tt(e){clearTimeout($),"number"==typeof e?$=setTimeout(tt,e):y&&(l.history||!window.history?window.location.hash=Ne():l.hash?window.history.replaceState(null,null,"#"+Ne()):window.history.replaceState(null,null,window.location.pathname+window.location.search))}function at(e){let t,a=c,r=u;if(e){let t=Pe(e),n=t?e.parentNode:e,s=i(O.wrapper.querySelectorAll(".slides>section"));a=Math.max(s.indexOf(n),0),r=void 0,t&&(r=Math.max(i(e.parentNode.querySelectorAll("section")).indexOf(e),0))}if(!e&&y){if(y.querySelectorAll(".fragment").length>0){let e=y.querySelector(".current-fragment");t=e&&e.hasAttribute("data-fragment-index")?parseInt(e.getAttribute("data-fragment-index"),10):y.querySelectorAll(".fragment.visible").length-1}}return{h:a,v:r,f:t}}function rt(){return i(O.wrapper.querySelectorAll('.slides section:not(.stack):not([data-visibility="uncounted"])'))}function nt(){return i(O.wrapper.querySelectorAll(".slides>section"))}function it(){return i(O.wrapper.querySelectorAll(".slides>section>section"))}function st(){return nt().length>1}function ot(){return it().length>1}function lt(){return rt().length}function dt(e,t){let a=nt()[e],r=a&&a.querySelectorAll("section");return r&&r.length&&"number"==typeof t?r?r[t]:void 0:a}function ct(e=y){if(e.hasAttribute("data-notes"))return e.getAttribute("data-notes");let t=e.querySelector("aside.notes");return t?t.innerHTML:null}function ut(){let e=at();return{indexh:e.h,indexv:e.v,indexf:e.f,paused:Oe(),overview:Me()}}function ht(){if(pt(),y&&!1!==l.autoSlide){let e=y.querySelector(".current-fragment");e||(e=y.querySelector(".fragment"));let t=e?e.getAttribute("data-autoslide"):null,r=y.parentNode?y.parentNode.getAttribute("data-autoslide"):null,n=y.getAttribute("data-autoslide");V=t?parseInt(t,10):n?parseInt(n,10):r?parseInt(r,10):l.autoSlide,0===y.querySelectorAll(".fragment").length&&i(y.querySelectorAll("video, audio")).forEach(e=>{e.hasAttribute("data-autoplay")&&V&&1e3*e.duration/e.playbackRate>V&&(V=1e3*e.duration/e.playbackRate+1e3)}),!V||K||Oe()||Me()||a.isLastSlide()&&!z.availableRoutes().next&&!0!==l.loop||(X=setTimeout(()=>{"function"==typeof l.autoSlideMethod?l.autoSlideMethod():At(),ht()},V),Y=Date.now()),L&&L.setPlaying(-1!==X)}}function pt(){clearTimeout(X),X=-1}function gt(){V&&!K&&(K=!0,ce("autoslidepaused"),clearTimeout(X),L&&L.setPlaying(!1))}function ft(){V&&K&&(K=!1,ce("autoslideresumed"),ht())}function mt(){q=!0,l.rtl?(Me()||!1===z.next())&&Je().left&&Be(c+1,"grid"===l.navigationMode?u:void 0):(Me()||!1===z.prev())&&Je().left&&Be(c-1,"grid"===l.navigationMode?u:void 0)}function vt(){q=!0,l.rtl?(Me()||!1===z.prev())&&Je().right&&Be(c-1,"grid"===l.navigationMode?u:void 0):(Me()||!1===z.next())&&Je().right&&Be(c+1,"grid"===l.navigationMode?u:void 0)}function bt(){(Me()||!1===z.prev())&&Je().up&&Be(c,u-1)}function yt(){C=!0,(Me()||!1===z.next())&&Je().down&&Be(c,u+1)}function wt(){if(!1===z.prev())if(Je().up)bt();else{let e;if(e=l.rtl?i(O.wrapper.querySelectorAll(".slides>section.future")).pop():i(O.wrapper.querySelectorAll(".slides>section.past")).pop(),e){let t=e.querySelectorAll("section").length-1||void 0;Be(c-1,t)}}}function At(){if(q=!0,C=!0,!1===z.next()){let e=Je();e.down&&e.right&&l.loop&&a.isLastVerticalSlide(y)&&(e.down=!1),e.down?yt():l.rtl?mt():vt()}}function St(e){for(;e&&"function"==typeof e.hasAttribute;){if(e.hasAttribute("data-prevent-swipe"))return!0;e=e.parentNode}return!1}function Et(e){l.autoSlideStoppable&>()}function kt(e){qe(),clearTimeout(U),U=setTimeout(Ce,l.hideCursorTime)}function Lt(e){e.shiftKey&&63===e.charCode&&ge()}function xt(e){if("function"==typeof l.keyboardCondition&&!1===l.keyboardCondition(e))return!0;let t=e.keyCode,r=K;Et();let n=document.activeElement&&"inherit"!==document.activeElement.contentEditable,i=document.activeElement&&document.activeElement.tagName&&/input|textarea/i.test(document.activeElement.tagName),s=document.activeElement&&document.activeElement.className&&/speaker-notes/i.test(document.activeElement.className),o=e.shiftKey&&32===e.keyCode,d=e.shiftKey&&37===t,c=e.shiftKey&&39===t,u=!o&&!d&&!c&&(e.shiftKey||e.altKey||e.ctrlKey||e.metaKey);if(n||i||s||u)return;let h,p=[66,86,190,191];if("object"==typeof l.keyboard)for(h in l.keyboard)"togglePause"===l.keyboard[h]&&p.push(parseInt(h,10));if(Oe()&&-1===p.indexOf(t))return!1;let g="linear"===l.navigationMode||!st()||!ot(),f=!1;if("object"==typeof l.keyboard)for(h in l.keyboard)if(parseInt(h,10)===t){let t=l.keyboard[h];"function"==typeof t?t.apply(null,[e]):"string"==typeof t&&"function"==typeof a[t]&&a[t].call(),f=!0}if(!1===f)for(h in Q)if(parseInt(h,10)===t){let t=Q[h].callback;"function"==typeof t?t.apply(null,[e]):"string"==typeof t&&"function"==typeof a[t]&&a[t].call(),f=!0}!1===f&&(f=!0,80===t||33===t?wt():78===t||34===t?At():72===t||37===t?d?Be(0):!Me()&&g?wt():mt():76===t||39===t?c?Be(Number.MAX_VALUE):!Me()&&g?At():vt():75===t||38===t?!Me()&&g?wt():bt():74===t||40===t?!Me()&&g?At():yt():36===t?Be(0):35===t?Be(Number.MAX_VALUE):32===t?(Me()&&Le(),e.shiftKey?wt():At()):58===t||59===t||66===t||86===t||190===t||191===t?Te():70===t?(()=>{let e=document.documentElement,t=e.requestFullscreen||e.webkitRequestFullscreen||e.webkitRequestFullScreen||e.mozRequestFullScreen||e.msRequestFullscreen;t&&t.apply(e)})():65===t?l.autoSlideStoppable&&De(r):f=!1),f?e.preventDefault&&e.preventDefault():27!==t&&79!==t||(O.overlay?me():xe(),e.preventDefault&&e.preventDefault()),ht()}function Mt(e){if(St(e.target))return!0;_.startX=e.touches[0].clientX,_.startY=e.touches[0].clientY,_.startCount=e.touches.length}function Nt(e){if(St(e.target))return!0;if(_.captured)g&&e.preventDefault();else{Et();let t=e.touches[0].clientX,a=e.touches[0].clientY;if(1===e.touches.length&&2!==_.startCount){let r=t-_.startX,n=a-_.startY;r>_.threshold&&Math.abs(r)>Math.abs(n)?(_.captured=!0,"linear"===l.navigationMode?l.rtl?At():wt():mt()):r<-_.threshold&&Math.abs(r)>Math.abs(n)?(_.captured=!0,"linear"===l.navigationMode?l.rtl?wt():At():vt()):n>_.threshold?(_.captured=!0,"linear"===l.navigationMode?wt():bt()):n<-_.threshold&&(_.captured=!0,"linear"===l.navigationMode?At():yt()),l.embedded?(_.captured||Pe(y))&&e.preventDefault():e.preventDefault()}}}function Pt(e){_.captured=!1}function qt(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],Mt(e))}function Ct(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],Nt(e))}function Rt(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],Pt())}function It(e){if(Date.now()-j>600){j=Date.now();let t=e.detail||-e.wheelDelta;t>0?At():t<0&&wt()}}function Tt(e){Et(),e.preventDefault();let t=nt().length,a=Math.floor(e.clientX/O.wrapper.offsetWidth*t);l.rtl&&(a=t-a),Be(a)}function Ot(e){e.preventDefault(),Et(),"linear"===l.navigationMode?wt():mt()}function Dt(e){e.preventDefault(),Et(),"linear"===l.navigationMode?At():vt()}function Bt(e){e.preventDefault(),Et(),bt()}function Ht(e){e.preventDefault(),Et(),yt()}function zt(e){e.preventDefault(),Et(),wt()}function jt(e){e.preventDefault(),Et(),At()}function $t(e){et()}function Wt(e){ve()}function Ut(e){!1===document.hidden&&document.activeElement!==document.body&&("function"==typeof document.activeElement.blur&&document.activeElement.blur(),document.body.focus())}function Ft(e){if(F&&Me()){e.preventDefault();let t=e.target;for(;t&&!t.nodeName.match(/section/gi);)t=t.parentNode;if(t&&!t.classList.contains("disabled")&&(Le(),t.nodeName.match(/section/gi))){Be(parseInt(t.getAttribute("data-index-h"),10),parseInt(t.getAttribute("data-index-v"),10))}}}function Vt(e){if(e.currentTarget&&e.currentTarget.hasAttribute("href")){let t=e.currentTarget.getAttribute("href");t&&(!function(e){me(),O.overlay=document.createElement("div"),O.overlay.classList.add("overlay"),O.overlay.classList.add("overlay-preview"),O.wrapper.appendChild(O.overlay),O.overlay.innerHTML=`
\n\t\t\t\t\n\t\t\t\t\n\t\t\t
\n\t\t\t
\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\tUnable to load iframe. This is likely due to the site's policy (x-frame-options).\n\t\t\t\t\n\t\t\t
`,O.overlay.querySelector("iframe").addEventListener("load",e=>{O.overlay.classList.add("loaded")},!1),O.overlay.querySelector(".close").addEventListener("click",e=>{me(),e.preventDefault()},!1),O.overlay.querySelector(".external").addEventListener("click",e=>{me()},!1)}(t),e.preventDefault())}}function Xt(e){a.isLastSlide()&&!1===l.loop?(Be(0,0),ft()):K?ft():gt()}return n(a,{VERSION:"4.0.0-dev",initialize:function(){if(e)return O.wrapper=e,O.slides=e.querySelector(".slides"),window.addEventListener("load",ve,!1),l={...S,...t,...a.getQueryHash()},D.load(l.dependencies).then(Z),a;console.warn("reveal.js can not initialize without a valid .reveal element.")},configure:ie,sync:He,syncSlide:function(e=y){ne(e),ze(e),B.load(e),Ke(),Ue()},syncFragments:ze,slide:Be,left:mt,right:vt,up:bt,down:yt,prev:wt,next:At,navigateTo:Be,navigateLeft:mt,navigateRight:vt,navigateUp:bt,navigateDown:yt,navigatePrev:wt,navigateNext:At,navigateFragment:()=>z.goto,prevFragment:()=>z.prev,nextFragment:()=>z.next,layout:ve,shuffle:je,availableRoutes:Je,availableFragments:()=>z.availableRoutes(),toggleHelp:ge,toggleOverview:xe,togglePause:Te,toggleAutoSlide:De,isOverview:Me,isPaused:Oe,isAutoSliding:function(){return!(!V||K)},isSpeakerNotes:Ge,loadSlide:()=>B.load,unloadSlide:()=>B.unload,addEventListeners:se,removeEventListeners:oe,dispatchEvent:ce,getState:ut,setState:function(e){if("object"==typeof e){Be(s(e.indexh),s(e.indexv),s(e.indexf));let t=s(e.paused),a=s(e.overview);"boolean"==typeof t&&t!==Oe()&&Te(t),"boolean"==typeof a&&a!==Me()&&xe(a)}},getSlidePastCount:Qe,getProgress:Ze,getIndices:at,getSlides:rt,getSlidesAttributes:function(){return rt().map(e=>{let t={};for(let a=0;axt({keyCode:e}),registerKeyboardShortcut:(e,t)=>J[e]=t,addEventListener:(e,t,r)=>{a.getRevealElement().addEventListener(e,t,r)},removeEventListener:(e,t,r)=>{a.getRevealElement().removeEventListener(e,t,r)},registerPlugin:(...e)=>D.registerPlugin(...e),hasPlugin:(...e)=>D.hasPlugin(...e),getPlugin:(...e)=>D.getPlugin(...e),getPlugins:()=>D.getRegisteredPlugins(),getComputedSlideSize:ye,getPreviousSlide:()=>p,getCurrentSlide:()=>y,getScale:()=>I,getConfig:()=>l,getQueryHash:()=>{let e={};location.search.replace(/[A-Z0-9]+?=([\w\.%-]*)/gi,t=>{e[t.split("=").shift()]=t.split("=").pop()});for(let t in e){let a=e[t];e[t]=s(unescape(a))}return void 0!==e.dependencies&&delete e.dependencies,e},getRevealElement:()=>O.wrapper||document.querySelector(".reveal"),getSlidesElement:()=>O.slides,isFirstSlide:()=>0===c&&0===u,isLastSlide:()=>!!y&&(!y.nextElementSibling&&(!Pe(y)||!y.parentNode.nextElementSibling)),isLastVerticalSlide:()=>!(!y||!Pe(y))&&!y.nextElementSibling,isReady:()=>x,announceStatus:G,getStatusText:ee,slideContent:B,updateControls:Ye,updateProgress:Fe,writeURL:tt})};window.Reveal=k,window.Reveal.initialize=e=>(window.Reveal=new k(document.querySelector(".reveal"),e),window.Reveal.initialize(),new Promise(e=>window.Reveal.addEventListener("ready",e)))}]); \ No newline at end of file diff --git a/js/controllers/fragments.js b/js/controllers/fragments.js new file mode 100644 index 0000000..915cb17 --- /dev/null +++ b/js/controllers/fragments.js @@ -0,0 +1,302 @@ +import { extend, toArray } from '../utils/util.js' + +/** + * + */ +export default class Fragments { + + constructor( Reveal ) { + + this.Reveal = Reveal; + + } + + /** + * Shows all fragments in the presentation. Used when + * fragments are disabled presentation-wide. + */ + showAll() { + + toArray( this.Reveal.getSlidesElement().querySelectorAll( '.fragment' ) ).forEach( element => { + element.classList.add( 'visible' ); + element.classList.remove( 'current-fragment' ); + } ); + + } + + /** + * Returns an object describing the available fragment + * directions. + * + * @return {{prev: boolean, next: boolean}} + */ + availableRoutes() { + + let currentSlide = this.Reveal.getCurrentSlide(); + if( currentSlide && this.Reveal.getConfig().fragments ) { + let fragments = currentSlide.querySelectorAll( '.fragment' ); + let hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.visible)' ); + + return { + prev: fragments.length - hiddenFragments.length > 0, + next: !!hiddenFragments.length + }; + } + else { + return { prev: false, next: false }; + } + + } + + /** + * Return a sorted fragments list, ordered by an increasing + * "data-fragment-index" attribute. + * + * Fragments will be revealed in the order that they are returned by + * this function, so you can use the index attributes to control the + * order of fragment appearance. + * + * To maintain a sensible default fragment order, fragments are presumed + * to be passed in document order. This function adds a "fragment-index" + * attribute to each node if such an attribute is not already present, + * and sets that attribute to an integer value which is the position of + * the fragment within the fragments list. + * + * @param {object[]|*} fragments + * @param {boolean} grouped If true the returned array will contain + * nested arrays for all fragments with the same index + * @return {object[]} sorted Sorted array of fragments + */ + sort( fragments, grouped = false ) { + + fragments = toArray( fragments ); + + let ordered = [], + unordered = [], + sorted = []; + + // Group ordered and unordered elements + fragments.forEach( fragment => { + if( fragment.hasAttribute( 'data-fragment-index' ) ) { + let index = parseInt( fragment.getAttribute( 'data-fragment-index' ), 10 ); + + if( !ordered[index] ) { + ordered[index] = []; + } + + ordered[index].push( fragment ); + } + else { + unordered.push( [ fragment ] ); + } + } ); + + // Append fragments without explicit indices in their + // DOM order + ordered = ordered.concat( unordered ); + + // Manually count the index up per group to ensure there + // are no gaps + let index = 0; + + // Push all fragments in their sorted order to an array, + // this flattens the groups + ordered.forEach( group => { + group.forEach( fragment => { + sorted.push( fragment ); + fragment.setAttribute( 'data-fragment-index', index ); + } ); + + index ++; + } ); + + return grouped === true ? ordered : sorted; + + } + + /** + * Sorts and formats all of fragments in the + * presentation. + */ + sortAll() { + + this.Reveal.getHorizontalSlides().forEach( horizontalSlide => { + + let verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ); + verticalSlides.forEach( ( verticalSlide, y ) => { + + this.sort( verticalSlide.querySelectorAll( '.fragment' ) ); + + }, this ); + + if( verticalSlides.length === 0 ) this.sort( horizontalSlide.querySelectorAll( '.fragment' ) ); + + } ); + + } + + /** + * Refreshes the fragments on the current slide so that they + * have the appropriate classes (.visible + .current-fragment). + * + * @param {number} [index] The index of the current fragment + * @param {array} [fragments] Array containing all fragments + * in the current slide + * + * @return {{shown: array, hidden: array}} + */ + update( index, fragments ) { + + let changedFragments = { + shown: [], + hidden: [] + }; + + let currentSlide = this.Reveal.getCurrentSlide(); + if( currentSlide && this.Reveal.getConfig().fragments ) { + + fragments = fragments || this.sort( currentSlide.querySelectorAll( '.fragment' ) ); + + if( fragments.length ) { + + let maxIndex = 0; + + if( typeof index !== 'number' ) { + let currentFragment = this.sort( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop(); + if( currentFragment ) { + index = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 ); + } + } + + toArray( fragments ).forEach( ( el, i ) => { + + if( el.hasAttribute( 'data-fragment-index' ) ) { + i = parseInt( el.getAttribute( 'data-fragment-index' ), 10 ); + } + + maxIndex = Math.max( maxIndex, i ); + + // Visible fragments + if( i <= index ) { + if( !el.classList.contains( 'visible' ) ) changedFragments.shown.push( el ); + el.classList.add( 'visible' ); + el.classList.remove( 'current-fragment' ); + + // Announce the fragments one by one to the Screen Reader + this.Reveal.announceStatus( this.Reveal.getStatusText( el ) ); + + if( i === index ) { + el.classList.add( 'current-fragment' ); + this.Reveal.slideContent.startEmbeddedContent( el ); + } + } + // Hidden fragments + else { + if( el.classList.contains( 'visible' ) ) changedFragments.hidden.push( el ); + el.classList.remove( 'visible' ); + el.classList.remove( 'current-fragment' ); + } + + } ); + + // Write the current fragment index to the slide
. + // This can be used by end users to apply styles based on + // the current fragment index. + index = typeof index === 'number' ? index : -1; + index = Math.max( Math.min( index, maxIndex ), -1 ); + currentSlide.setAttribute( 'data-fragment', index ); + + } + + } + + return changedFragments; + + } + + /** + * Navigate to the specified slide fragment. + * + * @param {?number} index The index of the fragment that + * should be shown, -1 means all are invisible + * @param {number} offset Integer offset to apply to the + * fragment index + * + * @return {boolean} true if a change was made in any + * fragments visibility as part of this call + */ + goto( index, offset = 0 ) { + + let currentSlide = this.Reveal.getCurrentSlide(); + if( currentSlide && this.Reveal.getConfig().fragments ) { + + let fragments = this.sort( currentSlide.querySelectorAll( '.fragment' ) ); + if( fragments.length ) { + + // If no index is specified, find the current + if( typeof index !== 'number' ) { + let lastVisibleFragment = this.sort( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop(); + + if( lastVisibleFragment ) { + index = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 ); + } + else { + index = -1; + } + } + + // Apply the offset if there is one + index += offset; + + let changedFragments = this.update( index, fragments ); + + if( changedFragments.hidden.length ) { + this.Reveal.dispatchEvent( 'fragmenthidden', { fragment: changedFragments.hidden[0], fragments: changedFragments.hidden } ); + } + + if( changedFragments.shown.length ) { + this.Reveal.dispatchEvent( 'fragmentshown', { fragment: changedFragments.shown[0], fragments: changedFragments.shown } ); + } + + this.Reveal.updateControls(); + this.Reveal.updateProgress(); + + if( this.Reveal.getConfig().fragmentInURL ) { + this.Reveal.writeURL(); + } + + return !!( changedFragments.shown.length || changedFragments.hidden.length ); + + } + + } + + return false; + + } + + /** + * Navigate to the next slide fragment. + * + * @return {boolean} true if there was a next fragment, + * false otherwise + */ + next() { + + return this.goto( null, 1 ); + + } + + /** + * Navigate to the previous slide fragment. + * + * @return {boolean} true if there was a previous fragment, + * false otherwise + */ + prev() { + + return this.goto( null, -1 ); + + } + +} \ No newline at end of file diff --git a/js/controllers/slidecontent.js b/js/controllers/slidecontent.js index ec2aa71..f85be49 100644 --- a/js/controllers/slidecontent.js +++ b/js/controllers/slidecontent.js @@ -1,5 +1,6 @@ import { HORIZONTAL_SLIDES_SELECTOR, VERTICAL_SLIDES_SELECTOR } from '../utils/constants.js' import { extend, toArray, closestParent } from '../utils/util.js' +import { isMobile } from '../utils/device.js' /** * Handles loading, unloading and playback of slide @@ -13,6 +14,26 @@ export default class SlideContent { } + /** + * Should the given element be preloaded? + * Decides based on local element attributes and global config. + * + * @param {HTMLElement} element + */ + shouldPreload( element ) { + + // Prefer an explicit global preload setting + let preload = this.Reveal.getConfig().preloadIframes; + + // If no global setting is available, fall back on the element's + // own preload setting + if( typeof preload !== 'boolean' ) { + preload = element.hasAttribute( 'data-preload' ); + } + + return preload; + } + /** * Called when the given slide is within the configured view * distance. Shows the slide element and loads any content @@ -27,7 +48,7 @@ export default class SlideContent { // Media elements with data-src attributes toArray( slide.querySelectorAll( 'img[data-src], video[data-src], audio[data-src], iframe[data-src]' ) ).forEach( element => { - if( element.tagName !== 'IFRAME' || shouldPreload( element ) ) { + if( element.tagName !== 'IFRAME' || this.shouldPreload( element ) ) { element.setAttribute( 'src', element.getAttribute( 'data-src' ) ); element.setAttribute( 'data-lazy-loaded', '' ); element.removeAttribute( 'data-src' ); @@ -89,7 +110,7 @@ export default class SlideContent { // Inline video playback works (at least in Mobile Safari) as // long as the video is muted and the `playsinline` attribute is // present - if( isMobileDevice ) { + if( isMobile ) { video.muted = true; video.autoplay = true; video.setAttribute( 'playsinline', '' ); @@ -126,7 +147,7 @@ export default class SlideContent { if( backgroundIframeElement ) { // Check if this iframe is eligible to be preloaded - if( shouldPreload( background ) && !/autoplay=(1|true|yes)/gi.test( backgroundIframe ) ) { + if( this.shouldPreload( background ) && !/autoplay=(1|true|yes)/gi.test( backgroundIframe ) ) { if( backgroundIframeElement.getAttribute( 'src' ) !== backgroundIframe ) { backgroundIframeElement.setAttribute( 'src', backgroundIframe ); } @@ -222,7 +243,7 @@ export default class SlideContent { } // Prefer an explicit global autoplay setting - let autoplay = config.autoPlayMedia; + let autoplay = this.Reveal.getConfig().autoPlayMedia; // If no global setting is available, fall back on the element's // own autoplay setting @@ -238,7 +259,7 @@ export default class SlideContent { } // Mobile devices never fire a loaded event so instead // of waiting, we initiate playback - else if( isMobileDevice ) { + else if( isMobile ) { let promise = el.play(); // If autoplay does not work, ensure that the controls are visible so @@ -327,7 +348,7 @@ export default class SlideContent { if( isAttachedToDOM && isVisible ) { // Prefer an explicit global autoplay setting - let autoplay = config.autoPlayMedia; + let autoplay = this.Reveal.getConfig().autoPlayMedia; // If no global setting is available, fall back on the element's // own autoplay setting diff --git a/js/reveal.js b/js/reveal.js index a74ac8a..5aff56b 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1,5 +1,6 @@ import SlideContent from './controllers/slidecontent.js' import AutoAnimate from './controllers/autoanimate.js' +import Fragments from './controllers/fragments.js' import Plugins from './controllers/plugins.js' import Playback from './components/playback.js' import defaultConfig from './config.js' @@ -19,6 +20,7 @@ import { closestParent, enterFullscreen } from './utils/util.js' +import { isMobile, isChrome, isAndroid, supportsZoom } from './utils/device.js' import { colorToRgb, colorBrightness } from './utils/color.js' /** @@ -88,18 +90,12 @@ export default function( revealElement, options ) { // Controls auto-animations between slides autoAnimate = new AutoAnimate( Reveal ), + // Controls navigation between slide fragments + fragments = new Fragments( Reveal ), + // List of asynchronously loaded reveal.js dependencies asyncDependencies = [], - // Features supported by the browser, see #checkCapabilities() - features = {}, - - // Client is a mobile device, see #checkCapabilities() - isMobileDevice, - - // Client is a desktop Chrome, see #checkCapabilities() - isChrome, - // Throttles mouse wheel navigation lastMouseWheelStep = 0, @@ -150,8 +146,6 @@ export default function( revealElement, options ) { return; } - checkCapabilities(); - // Cache references to key DOM elements dom.wrapper = revealElement; dom.slides = revealElement.querySelector( '.slides' ); @@ -169,25 +163,6 @@ export default function( revealElement, options ) { } - /** - * Inspect the client to see what features it supports. - */ - function checkCapabilities() { - - isMobileDevice = /(iphone|ipod|ipad|android)/gi.test( UA ) || - ( navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 ); // iPadOS - isChrome = /chrome/i.test( UA ) && !/edge/i.test( UA ); - - let testElement = document.createElement( 'div' ); - - // Flags if we should use zoom instead of transform to scale - // up slides. Zoom produces crisper results but has a lot of - // xbrowser quirks so we only use it in whitelsited browsers. - features.zoom = 'zoom' in testElement.style && !isMobileDevice && - ( isChrome || /Version\/[\d\.]+.*Safari/.test( UA ) ); - - } - /** * Starts up reveal.js by binding input events and navigating * to the current URL deeplink if there is one. @@ -258,20 +233,13 @@ export default function( revealElement, options ) { // Prevent transitions while we're loading dom.slides.classList.add( 'no-transition' ); - if( isMobileDevice ) { + if( isMobile ) { dom.wrapper.classList.add( 'no-hover' ); } else { dom.wrapper.classList.remove( 'no-hover' ); } - if( /iphone/gi.test( UA ) ) { - dom.wrapper.classList.add( 'ua-iphone' ); - } - else { - dom.wrapper.classList.remove( 'ua-iphone' ); - } - // Background element dom.background = createSingletonNode( dom.wrapper, 'div', 'backgrounds', null ); @@ -341,6 +309,15 @@ export default function( revealElement, options ) { } + /** + * Announces the given text to screen readers. + */ + function announceStatus( value ) { + + dom.statusDiv.textContent = value; + + } + /** * Converts the given HTML element into a string of text * that can be announced to a screen reader. Hidden @@ -492,7 +469,7 @@ export default function( revealElement, options ) { // Each fragment 'group' is an array containing one or more // fragments. Multiple fragments that appear at the same time // are part of the same group. - let fragmentGroups = sortFragments( page.querySelectorAll( '.fragment' ), true ); + let fragmentGroups = fragments.sort( page.querySelectorAll( '.fragment' ), true ); let previousFragmentStep; let previousPage; @@ -954,10 +931,7 @@ export default function( revealElement, options ) { // When fragments are turned off they should be visible if( config.fragments === false ) { - toArray( dom.slides.querySelectorAll( '.fragment' ) ).forEach( element => { - element.classList.add( 'visible' ); - element.classList.remove( 'current-fragment' ); - } ); + fragments.showAll(); } // Slide numbers @@ -1057,7 +1031,7 @@ export default function( revealElement, options ) { // Only support touch for Android, fixes double navigations in // stock browser - if( UA.match( /android/gi ) ) { + if( isAndroid ) { pointerEvents = [ 'touchstart' ]; } @@ -1418,7 +1392,7 @@ export default function( revealElement, options ) { // property where 100x adds up to the correct height. // // https://css-tricks.com/the-trick-to-viewport-units-on-mobile/ - if( isMobileDevice ) { + if( isMobile ) { document.documentElement.style.setProperty( '--vh', ( window.innerHeight * 0.01 ) + 'px' ); } @@ -1454,7 +1428,7 @@ export default function( revealElement, options ) { // effects are minor differences in text layout and iframe // viewports changing size. A 200x200 iframe viewport in a // 2x zoomed presentation ends up having a 400x400 viewport. - if( scale > 1 && features.zoom && window.devicePixelRatio < 2 ) { + if( scale > 1 && supportsZoom && window.devicePixelRatio < 2 ) { dom.slides.style.zoom = scale; dom.slides.style.left = ''; dom.slides.style.top = ''; @@ -2060,7 +2034,7 @@ export default function( revealElement, options ) { // Show fragment, if specified if( typeof f !== 'undefined' ) { - navigateFragment( f ); + fragments.goto( f ); } // Dispatch an event if the slide changed @@ -2126,8 +2100,8 @@ export default function( revealElement, options ) { slideContent.startEmbeddedContent( currentSlide ); } - // Announce the current slide contents, for screen readers - dom.statusDiv.textContent = getStatusText( currentSlide ); + // Announce the current slide contents to screen readers + announceStatus( getStatusText( currentSlide ) ); updateControls(); updateProgress(); @@ -2135,7 +2109,8 @@ export default function( revealElement, options ) { updateParallax(); updateSlideNumber(); updateNotes(); - updateFragments(); + + fragments.update(); // Update the URL hash writeURL(); @@ -2190,7 +2165,7 @@ export default function( revealElement, options ) { // Write the current hash to the URL writeURL(); - sortAllFragments(); + fragments.sortAll(); updateControls(); updateProgress(); @@ -2248,7 +2223,7 @@ export default function( revealElement, options ) { */ function syncFragments( slide = currentSlide ) { - return sortFragments( slide.querySelectorAll( '.fragment' ) ); + return config.sort( slide.querySelectorAll( '.fragment' ) ); } @@ -2275,27 +2250,6 @@ export default function( revealElement, options ) { } - /** - * Sorts and formats all of fragments in the - * presentation. - */ - function sortAllFragments() { - - getHorizontalSlides().forEach( horizontalSlide => { - - let verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ); - verticalSlides.forEach( ( verticalSlide, y ) => { - - sortFragments( verticalSlide.querySelectorAll( '.fragment' ) ); - - } ); - - if( verticalSlides.length === 0 ) sortFragments( horizontalSlide.querySelectorAll( '.fragment' ) ); - - } ); - - } - /** * Randomly shuffles all slides in the deck. */ @@ -2438,7 +2392,7 @@ export default function( revealElement, options ) { // Shorten the view distance on devices that typically have // less resources - if( isMobileDevice ) { + if( isMobile ) { viewDistance = isOverview() ? 6 : config.mobileViewDistance; } @@ -2657,7 +2611,7 @@ export default function( revealElement, options ) { function updateControls() { let routes = availableRoutes(); - let fragments = availableFragments(); + let fragmentsRoutes = fragments.availableRoutes(); // Remove the 'enabled' class from all directions [...dom.controlsLeft, ...dom.controlsRight, ...dom.controlsUp, ...dom.controlsDown, ...dom.controlsPrev, ...dom.controlsNext].forEach( node => { @@ -2681,23 +2635,22 @@ export default function( revealElement, options ) { if( currentSlide ) { // Always apply fragment decorator to prev/next buttons - if( fragments.prev ) dom.controlsPrev.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); - if( fragments.next ) dom.controlsNext.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( fragmentsRoutes.prev ) dom.controlsPrev.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( fragmentsRoutes.next ) dom.controlsNext.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); // Apply fragment decorators to directional buttons based on // what slide axis they are in if( isVerticalSlide( currentSlide ) ) { - if( fragments.prev ) dom.controlsUp.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); - if( fragments.next ) dom.controlsDown.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( fragmentsRoutes.prev ) dom.controlsUp.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( fragmentsRoutes.next ) dom.controlsDown.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); } else { - if( fragments.prev ) dom.controlsLeft.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); - if( fragments.next ) dom.controlsRight.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( fragmentsRoutes.prev ) dom.controlsLeft.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( fragmentsRoutes.next ) dom.controlsRight.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); } } - if( config.controlsTutorial ) { // Highlight control arrows with an animation to ensure @@ -2790,7 +2743,7 @@ export default function( revealElement, options ) { // Stop content inside of previous backgrounds if( previousBackground ) { - slideContent.stopEmbeddedContent( previousBackground, { unloadIframes: !shouldPreload( previousBackground ) } ); + slideContent.stopEmbeddedContent( previousBackground, { unloadIframes: !slideContent.shouldPreload( previousBackground ) } ); } @@ -2901,26 +2854,6 @@ export default function( revealElement, options ) { } - /** - * Should the given element be preloaded? - * Decides based on local element attributes and global config. - * - * @param {HTMLElement} element - */ - function shouldPreload( element ) { - - // Prefer an explicit global preload setting - let preload = config.preloadIframes; - - // If no global setting is available, fall back on the element's - // own preload setting - if( typeof preload !== 'boolean' ) { - preload = element.hasAttribute( 'data-preload' ); - } - - return preload; - } - /** * Determine what available routes there are for navigation. * @@ -2963,29 +2896,6 @@ export default function( revealElement, options ) { } - /** - * Returns an object describing the available fragment - * directions. - * - * @return {{prev: boolean, next: boolean}} - */ - function availableFragments() { - - if( currentSlide && config.fragments ) { - let fragments = currentSlide.querySelectorAll( '.fragment' ); - let hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.visible)' ); - - return { - prev: fragments.length - hiddenFragments.length > 0, - next: !!hiddenFragments.length - }; - } - else { - return { prev: false, next: false }; - } - - } - /** * Returns the number of past slides. This can be used as a global * flattened index for slides. @@ -3433,234 +3343,6 @@ export default function( revealElement, options ) { } - /** - * Return a sorted fragments list, ordered by an increasing - * "data-fragment-index" attribute. - * - * Fragments will be revealed in the order that they are returned by - * this function, so you can use the index attributes to control the - * order of fragment appearance. - * - * To maintain a sensible default fragment order, fragments are presumed - * to be passed in document order. This function adds a "fragment-index" - * attribute to each node if such an attribute is not already present, - * and sets that attribute to an integer value which is the position of - * the fragment within the fragments list. - * - * @param {object[]|*} fragments - * @param {boolean} grouped If true the returned array will contain - * nested arrays for all fragments with the same index - * @return {object[]} sorted Sorted array of fragments - */ - function sortFragments( fragments, grouped = false ) { - - fragments = toArray( fragments ); - - let ordered = [], - unordered = [], - sorted = []; - - // Group ordered and unordered elements - fragments.forEach( fragment => { - if( fragment.hasAttribute( 'data-fragment-index' ) ) { - let index = parseInt( fragment.getAttribute( 'data-fragment-index' ), 10 ); - - if( !ordered[index] ) { - ordered[index] = []; - } - - ordered[index].push( fragment ); - } - else { - unordered.push( [ fragment ] ); - } - } ); - - // Append fragments without explicit indices in their - // DOM order - ordered = ordered.concat( unordered ); - - // Manually count the index up per group to ensure there - // are no gaps - let index = 0; - - // Push all fragments in their sorted order to an array, - // this flattens the groups - ordered.forEach( group => { - group.forEach( fragment => { - sorted.push( fragment ); - fragment.setAttribute( 'data-fragment-index', index ); - } ); - - index ++; - } ); - - return grouped === true ? ordered : sorted; - - } - - /** - * Refreshes the fragments on the current slide so that they - * have the appropriate classes (.visible + .current-fragment). - * - * @param {number} [index] The index of the current fragment - * @param {array} [fragments] Array containing all fragments - * in the current slide - * - * @return {{shown: array, hidden: array}} - */ - function updateFragments( index, fragments ) { - - let changedFragments = { - shown: [], - hidden: [] - }; - - if( currentSlide && config.fragments ) { - - fragments = fragments || sortFragments( currentSlide.querySelectorAll( '.fragment' ) ); - - if( fragments.length ) { - - let maxIndex = 0; - - if( typeof index !== 'number' ) { - let currentFragment = sortFragments( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop(); - if( currentFragment ) { - index = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 ); - } - } - - toArray( fragments ).forEach( ( el, i ) => { - - if( el.hasAttribute( 'data-fragment-index' ) ) { - i = parseInt( el.getAttribute( 'data-fragment-index' ), 10 ); - } - - maxIndex = Math.max( maxIndex, i ); - - // Visible fragments - if( i <= index ) { - if( !el.classList.contains( 'visible' ) ) changedFragments.shown.push( el ); - el.classList.add( 'visible' ); - el.classList.remove( 'current-fragment' ); - - // Announce the fragments one by one to the Screen Reader - dom.statusDiv.textContent = getStatusText( el ); - - if( i === index ) { - el.classList.add( 'current-fragment' ); - slideContent.startEmbeddedContent( el ); - } - } - // Hidden fragments - else { - if( el.classList.contains( 'visible' ) ) changedFragments.hidden.push( el ); - el.classList.remove( 'visible' ); - el.classList.remove( 'current-fragment' ); - } - - } ); - - // Write the current fragment index to the slide
. - // This can be used by end users to apply styles based on - // the current fragment index. - index = typeof index === 'number' ? index : -1; - index = Math.max( Math.min( index, maxIndex ), -1 ); - currentSlide.setAttribute( 'data-fragment', index ); - - } - - } - - return changedFragments; - - } - - /** - * Navigate to the specified slide fragment. - * - * @param {?number} index The index of the fragment that - * should be shown, -1 means all are invisible - * @param {number} offset Integer offset to apply to the - * fragment index - * - * @return {boolean} true if a change was made in any - * fragments visibility as part of this call - */ - function navigateFragment( index, offset = 0 ) { - - if( currentSlide && config.fragments ) { - - let fragments = sortFragments( currentSlide.querySelectorAll( '.fragment' ) ); - if( fragments.length ) { - - // If no index is specified, find the current - if( typeof index !== 'number' ) { - let lastVisibleFragment = sortFragments( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop(); - - if( lastVisibleFragment ) { - index = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 ); - } - else { - index = -1; - } - } - - // Apply the offset if there is one - index += offset; - - let changedFragments = updateFragments( index, fragments ); - - if( changedFragments.hidden.length ) { - dispatchEvent( 'fragmenthidden', { fragment: changedFragments.hidden[0], fragments: changedFragments.hidden } ); - } - - if( changedFragments.shown.length ) { - dispatchEvent( 'fragmentshown', { fragment: changedFragments.shown[0], fragments: changedFragments.shown } ); - } - - updateControls(); - updateProgress(); - - if( config.fragmentInURL ) { - writeURL(); - } - - return !!( changedFragments.shown.length || changedFragments.hidden.length ); - - } - - } - - return false; - - } - - /** - * Navigate to the next slide fragment. - * - * @return {boolean} true if there was a next fragment, - * false otherwise - */ - function nextFragment() { - - return navigateFragment( null, 1 ); - - } - - /** - * Navigate to the previous slide fragment. - * - * @return {boolean} true if there was a previous fragment, - * false otherwise - */ - function prevFragment() { - - return navigateFragment( null, -1 ); - - } - /** * Cues a new automated slide if enabled in the config. */ @@ -3719,7 +3401,7 @@ export default function( revealElement, options ) { // - The presentation isn't paused // - The overview isn't active // - The presentation isn't over - if( autoSlide && !autoSlidePaused && !isPaused() && !isOverview() && ( !Reveal.isLastSlide() || availableFragments().next || config.loop === true ) ) { + if( autoSlide && !autoSlidePaused && !isPaused() && !isOverview() && ( !Reveal.isLastSlide() || fragments.availableRoutes().next || config.loop === true ) ) { autoSlideTimeout = setTimeout( () => { if( typeof config.autoSlideMethod === 'function' ) { config.autoSlideMethod() @@ -3780,12 +3462,12 @@ export default function( revealElement, options ) { // Reverse for RTL if( config.rtl ) { - if( ( isOverview() || nextFragment() === false ) && availableRoutes().left ) { + if( ( isOverview() || fragments.next() === false ) && availableRoutes().left ) { slide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined ); } } // Normal navigation - else if( ( isOverview() || prevFragment() === false ) && availableRoutes().left ) { + else if( ( isOverview() || fragments.prev() === false ) && availableRoutes().left ) { slide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined ); } @@ -3797,12 +3479,12 @@ export default function( revealElement, options ) { // Reverse for RTL if( config.rtl ) { - if( ( isOverview() || prevFragment() === false ) && availableRoutes().right ) { + if( ( isOverview() || fragments.prev() === false ) && availableRoutes().right ) { slide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined ); } } // Normal navigation - else if( ( isOverview() || nextFragment() === false ) && availableRoutes().right ) { + else if( ( isOverview() || fragments.next() === false ) && availableRoutes().right ) { slide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined ); } @@ -3811,7 +3493,7 @@ export default function( revealElement, options ) { function navigateUp() { // Prioritize hiding fragments - if( ( isOverview() || prevFragment() === false ) && availableRoutes().up ) { + if( ( isOverview() || fragments.prev() === false ) && availableRoutes().up ) { slide( indexh, indexv - 1 ); } @@ -3822,7 +3504,7 @@ export default function( revealElement, options ) { hasNavigatedVertically = true; // Prioritize revealing fragments - if( ( isOverview() || nextFragment() === false ) && availableRoutes().down ) { + if( ( isOverview() || fragments.next() === false ) && availableRoutes().down ) { slide( indexh, indexv + 1 ); } @@ -3837,7 +3519,7 @@ export default function( revealElement, options ) { function navigatePrev() { // Prioritize revealing fragments - if( prevFragment() === false ) { + if( fragments.prev() === false ) { if( availableRoutes().up ) { navigateUp(); } @@ -3871,7 +3553,7 @@ export default function( revealElement, options ) { hasNavigatedVertically = true; // Prioritize revealing fragments - if( nextFragment() === false ) { + if( fragments.next() === false ) { let routes = availableRoutes(); @@ -4293,7 +3975,7 @@ export default function( revealElement, options ) { } // There's a bug with swiping on some Android devices unless // the default action is always prevented - else if( UA.match( /android/gi ) ) { + else if( isAndroid ) { event.preventDefault(); } @@ -4562,9 +4244,9 @@ export default function( revealElement, options ) { navigateNext: navigateNext, // Fragment methods - navigateFragment, - prevFragment, - nextFragment, + navigateFragment: () => fragments.goto, + prevFragment: () => fragments.prev, + nextFragment: () => fragments.next, // Forces an update in slide layout layout, @@ -4576,7 +4258,7 @@ export default function( revealElement, options ) { availableRoutes, // Returns an object with the available fragments as booleans (prev/next) - availableFragments, + availableFragments: () => fragments.availableRoutes(), // Toggles a help overlay with keyboard shortcuts toggleHelp, @@ -4650,6 +4332,20 @@ export default function( revealElement, options ) { addKeyBinding, removeKeyBinding, + // Programmatically triggers a keyboard event + triggerKey: keyCode => onDocumentKeyDown( { keyCode } ), + + // Registers a new shortcut to include in the help overlay + registerKeyboardShortcut: ( key, value ) => keyboardShortcuts[key] = value, + + // Forward event binding to the reveal DOM element + addEventListener: ( type, listener, useCapture ) => { + Reveal.getRevealElement().addEventListener( type, listener, useCapture ); + }, + removeEventListener: ( type, listener, useCapture ) => { + Reveal.getRevealElement().removeEventListener( type, listener, useCapture ); + }, + // API for registering and retrieving plugins registerPlugin: (...args) => plugins.registerPlugin( ...args ), hasPlugin: (...args) => plugins.hasPlugin( ...args ), @@ -4732,19 +4428,18 @@ export default function( revealElement, options ) { // Checks if reveal.js has been loaded and is ready for use isReady: () => ready, - // Forward event binding to the reveal DOM element - addEventListener: ( type, listener, useCapture ) => { - Reveal.getRevealElement().addEventListener( type, listener, useCapture ); - }, - removeEventListener: ( type, listener, useCapture ) => { - Reveal.getRevealElement().removeEventListener( type, listener, useCapture ); - }, - // Programmatically triggers a keyboard event - triggerKey: keyCode => onDocumentKeyDown( { keyCode } ), + // Methods for announcing content to screen readers + announceStatus, + getStatusText, + + // Expose direct access to controllers via the API + slideContent, + + updateControls, + updateProgress, + writeURL - // Registers a new shortcut to include in the help overlay - registerKeyboardShortcut: ( key, value ) => keyboardShortcuts[key] = value } ); }; \ No newline at end of file diff --git a/js/utils/device.js b/js/utils/device.js new file mode 100644 index 0000000..c6b4095 --- /dev/null +++ b/js/utils/device.js @@ -0,0 +1,15 @@ +const UA = navigator.userAgent; +const testElement = document.createElement( 'div' ); + +export const isMobile = /(iphone|ipod|ipad|android)/gi.test( UA ) || + ( navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 ); // iPadOS + +export const isChrome = /chrome/i.test( UA ) && !/edge/i.test( UA ); + +export const isAndroid = /android/gi.test( UA ); + +// Flags if we should use zoom instead of transform to scale +// up slides. Zoom produces crisper results but has a lot of +// xbrowser quirks so we only use it in whitelsited browsers. +export const supportsZoom = 'zoom' in testElement.style && !isMobile && + ( isChrome || /Version\/[\d\.]+.*Safari/.test( UA ) ); \ No newline at end of file diff --git a/test/test.html b/test/test.html index 5f64d6e..7751f20 100644 --- a/test/test.html +++ b/test/test.html @@ -78,7 +78,619 @@ - + diff --git a/test/test.js b/test/test.js deleted file mode 100644 index a6bb0cc..0000000 --- a/test/test.js +++ /dev/null @@ -1,612 +0,0 @@ -// These tests expect the DOM to contain a presentation -// with the following slide structure: -// -// 1 -// 2 - Three sub-slides -// 3 - Three fragment elements -// 3 - Two fragments with same data-fragment-index -// 4 - -Reveal.initialize().then( function() { - - // --------------------------------------------------------------- - // DOM TESTS - - QUnit.module( 'DOM' ); - - QUnit.test( 'Initial slides classes', function( assert ) { - var horizontalSlides = document.querySelectorAll( '.reveal .slides>section' ) - - assert.strictEqual( document.querySelectorAll( '.reveal .slides section.past' ).length, 0, 'no .past slides' ); - assert.strictEqual( document.querySelectorAll( '.reveal .slides section.present' ).length, 1, 'one .present slide' ); - assert.strictEqual( document.querySelectorAll( '.reveal .slides>section.future' ).length, horizontalSlides.length - 1, 'remaining horizontal slides are .future' ); - - assert.strictEqual( document.querySelectorAll( '.reveal .slides section.stack' ).length, 2, 'two .stacks' ); - - assert.ok( document.querySelectorAll( '.reveal .slides section.stack' )[0].querySelectorAll( '.future' ).length > 0, 'vertical slides are given .future' ); - }); - - // --------------------------------------------------------------- - // API TESTS - - QUnit.module( 'API' ); - - QUnit.test( 'Reveal.isReady', function( assert ) { - assert.strictEqual( Reveal.isReady(), true, 'returns true' ); - }); - - QUnit.test( 'Reveal.isOverview', function( assert ) { - assert.strictEqual( Reveal.isOverview(), false, 'false by default' ); - - Reveal.toggleOverview(); - assert.strictEqual( Reveal.isOverview(), true, 'true after toggling on' ); - - Reveal.toggleOverview(); - assert.strictEqual( Reveal.isOverview(), false, 'false after toggling off' ); - }); - - QUnit.test( 'Reveal.isPaused', function( assert ) { - assert.strictEqual( Reveal.isPaused(), false, 'false by default' ); - - Reveal.togglePause(); - assert.strictEqual( Reveal.isPaused(), true, 'true after pausing' ); - - Reveal.togglePause(); - assert.strictEqual( Reveal.isPaused(), false, 'false after resuming' ); - }); - - QUnit.test( 'Reveal.isFirstSlide', function( assert ) { - Reveal.slide( 0, 0 ); - assert.strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' ); - - Reveal.slide( 1, 0 ); - assert.strictEqual( Reveal.isFirstSlide(), false, 'false after Reveal.slide( 1, 0 )' ); - - Reveal.slide( 0, 0 ); - assert.strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' ); - }); - - QUnit.test( 'Reveal.isFirstSlide after vertical slide', function( assert ) { - Reveal.slide( 1, 1 ); - Reveal.slide( 0, 0 ); - assert.strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 1, 1 ) and then Reveal.slide( 0, 0 )' ); - }); - - QUnit.test( 'Reveal.isLastSlide', function( assert ) { - Reveal.slide( 0, 0 ); - assert.strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' ); - - var lastSlideIndex = document.querySelectorAll( '.reveal .slides>section' ).length - 1; - - Reveal.slide( lastSlideIndex, 0 ); - assert.strictEqual( Reveal.isLastSlide(), true, 'true after Reveal.slide( '+ lastSlideIndex +', 0 )' ); - - Reveal.slide( 0, 0 ); - assert.strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' ); - }); - - QUnit.test( 'Reveal.isLastSlide after vertical slide', function( assert ) { - var lastSlideIndex = document.querySelectorAll( '.reveal .slides>section' ).length - 1; - - Reveal.slide( 1, 1 ); - Reveal.slide( lastSlideIndex ); - assert.strictEqual( Reveal.isLastSlide(), true, 'true after Reveal.slide( 1, 1 ) and then Reveal.slide( '+ lastSlideIndex +', 0 )' ); - }); - - QUnit.test( 'Reveal.getTotalSlides', function( assert ) { - assert.strictEqual( Reveal.getTotalSlides(), 8, 'eight slides in total' ); - }); - - QUnit.test( 'Reveal.getIndices', function( assert ) { - var indices = Reveal.getIndices(); - - assert.ok( indices.hasOwnProperty( 'h' ), 'h exists' ); - assert.ok( indices.hasOwnProperty( 'v' ), 'v exists' ); - assert.ok( indices.hasOwnProperty( 'f' ), 'f exists' ); - - Reveal.slide( 1, 0 ); - assert.strictEqual( Reveal.getIndices().h, 1, 'h 1' ); - assert.strictEqual( Reveal.getIndices().v, 0, 'v 0' ); - - Reveal.slide( 1, 2 ); - assert.strictEqual( Reveal.getIndices().h, 1, 'h 1' ); - assert.strictEqual( Reveal.getIndices().v, 2, 'v 2' ); - - Reveal.slide( 0, 0 ); - assert.strictEqual( Reveal.getIndices().h, 0, 'h 0' ); - assert.strictEqual( Reveal.getIndices().v, 0, 'v 0' ); - }); - - QUnit.test( 'Reveal.getSlide', function( assert ) { - assert.equal( Reveal.getSlide( 0 ), document.querySelector( '.reveal .slides>section:first-child' ), 'gets correct first slide' ); - assert.equal( Reveal.getSlide( 1 ), document.querySelector( '.reveal .slides>section:nth-child(2)' ), 'no v index returns stack' ); - assert.equal( Reveal.getSlide( 1, 0 ), document.querySelector( '.reveal .slides>section:nth-child(2)>section:nth-child(1)' ), 'v index 0 returns first vertical child' ); - assert.equal( Reveal.getSlide( 1, 1 ), document.querySelector( '.reveal .slides>section:nth-child(2)>section:nth-child(2)' ), 'v index 1 returns second vertical child' ); - - assert.strictEqual( Reveal.getSlide( 100 ), undefined, 'undefined when out of horizontal bounds' ); - assert.strictEqual( Reveal.getSlide( 1, 100 ), undefined, 'undefined when out of vertical bounds' ); - }); - - QUnit.test( 'Reveal.getSlideBackground', function( assert ) { - assert.equal( Reveal.getSlideBackground( 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:first-child' ), 'gets correct first background' ); - assert.equal( Reveal.getSlideBackground( 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2)' ), 'no v index returns stack' ); - assert.equal( Reveal.getSlideBackground( 1, 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(2)' ), 'v index 0 returns first vertical child' ); - assert.equal( Reveal.getSlideBackground( 1, 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(3)' ), 'v index 1 returns second vertical child' ); - - assert.strictEqual( Reveal.getSlideBackground( 100 ), undefined, 'undefined when out of horizontal bounds' ); - assert.strictEqual( Reveal.getSlideBackground( 1, 100 ), undefined, 'undefined when out of vertical bounds' ); - }); - - QUnit.test( 'Reveal.getSlideNotes', function( assert ) { - Reveal.slide( 0, 0 ); - assert.ok( Reveal.getSlideNotes() === 'speaker notes 1', 'works with