1 line
302 KiB
Plaintext
1 line
302 KiB
Plaintext
{"version":3,"file":"reveal.es5.js","sources":["../js/utils/constants.js","../js/utils/util.js","../js/utils/device.js","../js/controllers/slidecontent.js","../js/controllers/slidenumber.js","../js/utils/color.js","../js/controllers/backgrounds.js","../js/controllers/autoanimate.js","../js/controllers/fragments.js","../js/controllers/overview.js","../js/controllers/keyboard.js","../js/controllers/location.js","../js/controllers/controls.js","../js/controllers/progress.js","../js/controllers/pointer.js","../js/utils/loader.js","../js/controllers/plugins.js","../js/controllers/print.js","../js/controllers/touch.js","../js/controllers/notes.js","../js/components/playback.js","../js/config.js","../js/reveal.js","../js/index.js"],"sourcesContent":["\nexport const SLIDES_SELECTOR = '.slides section';\nexport const HORIZONTAL_SLIDES_SELECTOR = '.slides>section';\nexport const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section';\n\n// Methods that may not be invoked via the postMessage API\nexport const POST_MESSAGE_METHOD_BLACKLIST = /registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener/;\n\n// Regex for retrieving the fragment style from a class attribute\nexport const FRAGMENT_STYLE_REGEX = /fade-(down|up|right|left|out|in-then-out|in-then-semi-out)|semi-fade-out|current-visible|shrink|grow/;","/**\n * Extend object a with the properties of object b.\n * If there's a conflict, object b takes precedence.\n *\n * @param {object} a\n * @param {object} b\n */\nexport const extend = ( a, b ) => {\n\n\tfor( let i in b ) {\n\t\ta[ i ] = b[ i ];\n\t}\n\n\treturn a;\n\n}\n\n/**\n * querySelectorAll but returns an Array.\n */\nexport const queryAll = ( el, selector ) => {\n\n\treturn Array.from( el.querySelectorAll( selector ) );\n\n}\n\n/**\n * Utility for deserializing a value.\n *\n * @param {*} value\n * @return {*}\n */\nexport const deserialize = ( value ) => {\n\n\tif( typeof value === 'string' ) {\n\t\tif( value === 'null' ) return null;\n\t\telse if( value === 'true' ) return true;\n\t\telse if( value === 'false' ) return false;\n\t\telse if( value.match( /^-?[\\d\\.]+$/ ) ) return parseFloat( value );\n\t}\n\n\treturn value;\n\n}\n\n/**\n * Measures the distance in pixels between point a\n * and point b.\n *\n * @param {object} a point with x/y properties\n * @param {object} b point with x/y properties\n *\n * @return {number}\n */\nexport const distanceBetween = ( a, b ) => {\n\n\tlet dx = a.x - b.x,\n\t\tdy = a.y - b.y;\n\n\treturn Math.sqrt( dx*dx + dy*dy );\n\n}\n\n/**\n * Applies a CSS transform to the target element.\n *\n * @param {HTMLElement} element\n * @param {string} transform\n */\nexport const transformElement = ( element, transform ) => {\n\n\telement.style.transform = transform;\n\n}\n\n/**\n * Find the closest parent that matches the given\n * selector.\n *\n * @param {HTMLElement} target The child element\n * @param {String} selector The CSS selector to match\n * the parents against\n *\n * @return {HTMLElement} The matched parent or null\n * if no matching parent was found\n */\nexport const closestParent = ( target, selector ) => {\n\n\tlet parent = target.parentNode;\n\n\twhile( parent ) {\n\n\t\t// There's some overhead doing this each time, we don't\n\t\t// want to rewrite the element prototype but should still\n\t\t// be enough to feature detect once at startup...\n\t\tlet matchesMethod = parent.matches || parent.matchesSelector || parent.msMatchesSelector;\n\n\t\t// If we find a match, we're all set\n\t\tif( matchesMethod && matchesMethod.call( parent, selector ) ) {\n\t\t\treturn parent;\n\t\t}\n\n\t\t// Keep searching\n\t\tparent = parent.parentNode;\n\n\t}\n\n\treturn null;\n\n}\n\n/**\n * Handling the fullscreen functionality via the fullscreen API\n *\n * @see http://fullscreen.spec.whatwg.org/\n * @see https://developer.mozilla.org/en-US/docs/DOM/Using_fullscreen_mode\n */\nexport const enterFullscreen = () => {\n\n\tlet element = document.documentElement;\n\n\t// Check which implementation is available\n\tlet requestMethod = element.requestFullscreen ||\n\t\t\t\t\t\telement.webkitRequestFullscreen ||\n\t\t\t\t\t\telement.webkitRequestFullScreen ||\n\t\t\t\t\t\telement.mozRequestFullScreen ||\n\t\t\t\t\t\telement.msRequestFullscreen;\n\n\tif( requestMethod ) {\n\t\trequestMethod.apply( element );\n\t}\n\n}\n\n/**\n * Creates an HTML element and returns a reference to it.\n * If the element already exists the existing instance will\n * be returned.\n *\n * @param {HTMLElement} container\n * @param {string} tagname\n * @param {string} classname\n * @param {string} innerHTML\n *\n * @return {HTMLElement}\n */\nexport const createSingletonNode = ( container, tagname, classname, innerHTML='' ) => {\n\n\t// Find all nodes matching the description\n\tlet nodes = container.querySelectorAll( '.' + classname );\n\n\t// Check all matches to find one which is a direct child of\n\t// the specified container\n\tfor( let i = 0; i < nodes.length; i++ ) {\n\t\tlet testNode = nodes[i];\n\t\tif( testNode.parentNode === container ) {\n\t\t\treturn testNode;\n\t\t}\n\t}\n\n\t// If no node was found, create it now\n\tlet node = document.createElement( tagname );\n\tnode.className = classname;\n\tnode.innerHTML = innerHTML;\n\tcontainer.appendChild( node );\n\n\treturn node;\n\n}\n\n/**\n * Injects the given CSS styles into the DOM.\n *\n * @param {string} value\n */\nexport const createStyleSheet = ( value ) => {\n\n\tlet tag = document.createElement( 'style' );\n\ttag.type = 'text/css';\n\n\tif( value && value.length > 0 ) {\n\t\tif( tag.styleSheet ) {\n\t\t\ttag.styleSheet.cssText = value;\n\t\t}\n\t\telse {\n\t\t\ttag.appendChild( document.createTextNode( value ) );\n\t\t}\n\t}\n\n\tdocument.head.appendChild( tag );\n\n\treturn tag;\n\n}\n\n/**\n * Returns a key:value hash of all query params.\n */\nexport const getQueryHash = () => {\n\n\tlet query = {};\n\n\tlocation.search.replace( /[A-Z0-9]+?=([\\w\\.%-]*)/gi, a => {\n\t\tquery[ a.split( '=' ).shift() ] = a.split( '=' ).pop();\n\t} );\n\n\t// Basic deserialization\n\tfor( let i in query ) {\n\t\tlet value = query[ i ];\n\n\t\tquery[ i ] = deserialize( unescape( value ) );\n\t}\n\n\t// Do not accept new dependencies via query config to avoid\n\t// the potential of malicious script injection\n\tif( typeof query['dependencies'] !== 'undefined' ) delete query['dependencies'];\n\n\treturn query;\n\n}\n\n/**\n * Returns the remaining height within the parent of the\n * target element.\n *\n * remaining height = [ configured parent height ] - [ current parent height ]\n *\n * @param {HTMLElement} element\n * @param {number} [height]\n */\nexport const getRemainingHeight = ( element, height = 0 ) => {\n\n\tif( element ) {\n\t\tlet newHeight, oldHeight = element.style.height;\n\n\t\t// Change the .stretch element height to 0 in order find the height of all\n\t\t// the other elements\n\t\telement.style.height = '0px';\n\n\t\t// In Overview mode, the parent (.slide) height is set of 700px.\n\t\t// Restore it temporarily to its natural height.\n\t\telement.parentNode.style.height = 'auto';\n\n\t\tnewHeight = height - element.parentNode.offsetHeight;\n\n\t\t// Restore the old height, just in case\n\t\telement.style.height = oldHeight + 'px';\n\n\t\t// Clear the parent (.slide) height. .removeProperty works in IE9+\n\t\telement.parentNode.style.removeProperty('height');\n\n\t\treturn newHeight;\n\t}\n\n\treturn height;\n\n}","const UA = navigator.userAgent;\nconst testElement = document.createElement( 'div' );\n\nexport const isMobile = /(iphone|ipod|ipad|android)/gi.test( UA ) ||\n\t\t\t\t\t\t( navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 ); // iPadOS\n\nexport const isChrome = /chrome/i.test( UA ) && !/edge/i.test( UA );\n\nexport const isAndroid = /android/gi.test( UA );\n\n// Flags if we should use zoom instead of transform to scale\n// up slides. Zoom produces crisper results but has a lot of\n// xbrowser quirks so we only use it in whitelisted browsers.\nexport const supportsZoom = 'zoom' in testElement.style && !isMobile &&\n\t\t\t\t( isChrome || /Version\\/[\\d\\.]+.*Safari/.test( UA ) );\n\nexport const supportsHistoryAPI = typeof window.history.replaceState === 'function' && !/PhantomJS/.test( UA );","import { HORIZONTAL_SLIDES_SELECTOR, VERTICAL_SLIDES_SELECTOR } from '../utils/constants.js'\nimport { extend, queryAll, closestParent } from '../utils/util.js'\nimport { isMobile } from '../utils/device.js'\n\n/**\n * Handles loading, unloading and playback of slide\n * content such as images, videos and iframes.\n */\nexport default class SlideContent {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.startEmbeddedIframe = this.startEmbeddedIframe.bind( this );\n\n\t}\n\n\t/**\n\t * Should the given element be preloaded?\n\t * Decides based on local element attributes and global config.\n\t *\n\t * @param {HTMLElement} element\n\t */\n\tshouldPreload( element ) {\n\n\t\t// Prefer an explicit global preload setting\n\t\tlet preload = this.Reveal.getConfig().preloadIframes;\n\n\t\t// If no global setting is available, fall back on the element's\n\t\t// own preload setting\n\t\tif( typeof preload !== 'boolean' ) {\n\t\t\tpreload = element.hasAttribute( 'data-preload' );\n\t\t}\n\n\t\treturn preload;\n\t}\n\n\t/**\n\t * Called when the given slide is within the configured view\n\t * distance. Shows the slide element and loads any content\n\t * that is set to load lazily (data-src).\n\t *\n\t * @param {HTMLElement} slide Slide to show\n\t */\n\tload( slide, options = {} ) {\n\n\t\t// Show the slide element\n\t\tslide.style.display = this.Reveal.getConfig().display;\n\n\t\t// Media elements with data-src attributes\n\t\tqueryAll( slide, 'img[data-src], video[data-src], audio[data-src], iframe[data-src]' ).forEach( element => {\n\t\t\tif( element.tagName !== 'IFRAME' || this.shouldPreload( element ) ) {\n\t\t\t\telement.setAttribute( 'src', element.getAttribute( 'data-src' ) );\n\t\t\t\telement.setAttribute( 'data-lazy-loaded', '' );\n\t\t\t\telement.removeAttribute( 'data-src' );\n\t\t\t}\n\t\t} );\n\n\t\t// Media elements with <source> children\n\t\tqueryAll( slide, 'video, audio' ).forEach( media => {\n\t\t\tlet sources = 0;\n\n\t\t\tqueryAll( media, 'source[data-src]' ).forEach( source => {\n\t\t\t\tsource.setAttribute( 'src', source.getAttribute( 'data-src' ) );\n\t\t\t\tsource.removeAttribute( 'data-src' );\n\t\t\t\tsource.setAttribute( 'data-lazy-loaded', '' );\n\t\t\t\tsources += 1;\n\t\t\t} );\n\n\t\t\t// If we rewrote sources for this video/audio element, we need\n\t\t\t// to manually tell it to load from its new origin\n\t\t\tif( sources > 0 ) {\n\t\t\t\tmedia.load();\n\t\t\t}\n\t\t} );\n\n\n\t\t// Show the corresponding background element\n\t\tlet background = slide.slideBackgroundElement;\n\t\tif( background ) {\n\t\t\tbackground.style.display = 'block';\n\n\t\t\tlet backgroundContent = slide.slideBackgroundContentElement;\n\t\t\tlet backgroundIframe = slide.getAttribute( 'data-background-iframe' );\n\n\t\t\t// If the background contains media, load it\n\t\t\tif( background.hasAttribute( 'data-loaded' ) === false ) {\n\t\t\t\tbackground.setAttribute( 'data-loaded', 'true' );\n\n\t\t\t\tlet backgroundImage = slide.getAttribute( 'data-background-image' ),\n\t\t\t\t\tbackgroundVideo = slide.getAttribute( 'data-background-video' ),\n\t\t\t\t\tbackgroundVideoLoop = slide.hasAttribute( 'data-background-video-loop' ),\n\t\t\t\t\tbackgroundVideoMuted = slide.hasAttribute( 'data-background-video-muted' );\n\n\t\t\t\t// Images\n\t\t\t\tif( backgroundImage ) {\n\t\t\t\t\tbackgroundContent.style.backgroundImage = 'url('+ encodeURI( backgroundImage ) +')';\n\t\t\t\t}\n\t\t\t\t// Videos\n\t\t\t\telse if ( backgroundVideo && !this.Reveal.isSpeakerNotes() ) {\n\t\t\t\t\tlet video = document.createElement( 'video' );\n\n\t\t\t\t\tif( backgroundVideoLoop ) {\n\t\t\t\t\t\tvideo.setAttribute( 'loop', '' );\n\t\t\t\t\t}\n\n\t\t\t\t\tif( backgroundVideoMuted ) {\n\t\t\t\t\t\tvideo.muted = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Inline video playback works (at least in Mobile Safari) as\n\t\t\t\t\t// long as the video is muted and the `playsinline` attribute is\n\t\t\t\t\t// present\n\t\t\t\t\tif( isMobile ) {\n\t\t\t\t\t\tvideo.muted = true;\n\t\t\t\t\t\tvideo.autoplay = true;\n\t\t\t\t\t\tvideo.setAttribute( 'playsinline', '' );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support comma separated lists of video sources\n\t\t\t\t\tbackgroundVideo.split( ',' ).forEach( source => {\n\t\t\t\t\t\tvideo.innerHTML += '<source src=\"'+ source +'\">';\n\t\t\t\t\t} );\n\n\t\t\t\t\tbackgroundContent.appendChild( video );\n\t\t\t\t}\n\t\t\t\t// Iframes\n\t\t\t\telse if( backgroundIframe && options.excludeIframes !== true ) {\n\t\t\t\t\tlet iframe = document.createElement( 'iframe' );\n\t\t\t\t\tiframe.setAttribute( 'allowfullscreen', '' );\n\t\t\t\t\tiframe.setAttribute( 'mozallowfullscreen', '' );\n\t\t\t\t\tiframe.setAttribute( 'webkitallowfullscreen', '' );\n\t\t\t\t\tiframe.setAttribute( 'allow', 'autoplay' );\n\n\t\t\t\t\tiframe.setAttribute( 'data-src', backgroundIframe );\n\n\t\t\t\t\tiframe.style.width = '100%';\n\t\t\t\t\tiframe.style.height = '100%';\n\t\t\t\t\tiframe.style.maxHeight = '100%';\n\t\t\t\t\tiframe.style.maxWidth = '100%';\n\n\t\t\t\t\tbackgroundContent.appendChild( iframe );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start loading preloadable iframes\n\t\t\tlet backgroundIframeElement = backgroundContent.querySelector( 'iframe[data-src]' );\n\t\t\tif( backgroundIframeElement ) {\n\n\t\t\t\t// Check if this iframe is eligible to be preloaded\n\t\t\t\tif( this.shouldPreload( background ) && !/autoplay=(1|true|yes)/gi.test( backgroundIframe ) ) {\n\t\t\t\t\tif( backgroundIframeElement.getAttribute( 'src' ) !== backgroundIframe ) {\n\t\t\t\t\t\tbackgroundIframeElement.setAttribute( 'src', backgroundIframe );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Unloads and hides the given slide. This is called when the\n\t * slide is moved outside of the configured view distance.\n\t *\n\t * @param {HTMLElement} slide\n\t */\n\tunload( slide ) {\n\n\t\t// Hide the slide element\n\t\tslide.style.display = 'none';\n\n\t\t// Hide the corresponding background element\n\t\tlet background = this.Reveal.getSlideBackground( slide );\n\t\tif( background ) {\n\t\t\tbackground.style.display = 'none';\n\n\t\t\t// Unload any background iframes\n\t\t\tqueryAll( background, 'iframe[src]' ).forEach( element => {\n\t\t\t\telement.removeAttribute( 'src' );\n\t\t\t} );\n\t\t}\n\n\t\t// Reset lazy-loaded media elements with src attributes\n\t\tqueryAll( slide, 'video[data-lazy-loaded][src], audio[data-lazy-loaded][src], iframe[data-lazy-loaded][src]' ).forEach( element => {\n\t\t\telement.setAttribute( 'data-src', element.getAttribute( 'src' ) );\n\t\t\telement.removeAttribute( 'src' );\n\t\t} );\n\n\t\t// Reset lazy-loaded media elements with <source> children\n\t\tqueryAll( slide, 'video[data-lazy-loaded] source[src], audio source[src]' ).forEach( source => {\n\t\t\tsource.setAttribute( 'data-src', source.getAttribute( 'src' ) );\n\t\t\tsource.removeAttribute( 'src' );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Enforces origin-specific format rules for embedded media.\n\t */\n\tformatEmbeddedContent() {\n\n\t\tlet _appendParamToIframeSource = ( sourceAttribute, sourceURL, param ) => {\n\t\t\tqueryAll( this.Reveal.getSlidesElement(), 'iframe['+ sourceAttribute +'*=\"'+ sourceURL +'\"]' ).forEach( el => {\n\t\t\t\tlet src = el.getAttribute( sourceAttribute );\n\t\t\t\tif( src && src.indexOf( param ) === -1 ) {\n\t\t\t\t\tel.setAttribute( sourceAttribute, src + ( !/\\?/.test( src ) ? '?' : '&' ) + param );\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\n\t\t// YouTube frames must include \"?enablejsapi=1\"\n\t\t_appendParamToIframeSource( 'src', 'youtube.com/embed/', 'enablejsapi=1' );\n\t\t_appendParamToIframeSource( 'data-src', 'youtube.com/embed/', 'enablejsapi=1' );\n\n\t\t// Vimeo frames must include \"?api=1\"\n\t\t_appendParamToIframeSource( 'src', 'player.vimeo.com/', 'api=1' );\n\t\t_appendParamToIframeSource( 'data-src', 'player.vimeo.com/', 'api=1' );\n\n\t}\n\n\t/**\n\t * Start playback of any embedded content inside of\n\t * the given element.\n\t *\n\t * @param {HTMLElement} element\n\t */\n\tstartEmbeddedContent( element ) {\n\n\t\tif( element && !this.Reveal.isSpeakerNotes() ) {\n\n\t\t\t// Restart GIFs\n\t\t\tqueryAll( element, 'img[src$=\".gif\"]' ).forEach( el => {\n\t\t\t\t// Setting the same unchanged source like this was confirmed\n\t\t\t\t// to work in Chrome, FF & Safari\n\t\t\t\tel.setAttribute( 'src', el.getAttribute( 'src' ) );\n\t\t\t} );\n\n\t\t\t// HTML5 media elements\n\t\t\tqueryAll( element, 'video, audio' ).forEach( el => {\n\t\t\t\tif( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Prefer an explicit global autoplay setting\n\t\t\t\tlet autoplay = this.Reveal.getConfig().autoPlayMedia;\n\n\t\t\t\t// If no global setting is available, fall back on the element's\n\t\t\t\t// own autoplay setting\n\t\t\t\tif( typeof autoplay !== 'boolean' ) {\n\t\t\t\t\tautoplay = el.hasAttribute( 'data-autoplay' ) || !!closestParent( el, '.slide-background' );\n\t\t\t\t}\n\n\t\t\t\tif( autoplay && typeof el.play === 'function' ) {\n\n\t\t\t\t\t// If the media is ready, start playback\n\t\t\t\t\tif( el.readyState > 1 ) {\n\t\t\t\t\t\tthis.startEmbeddedMedia( { target: el } );\n\t\t\t\t\t}\n\t\t\t\t\t// Mobile devices never fire a loaded event so instead\n\t\t\t\t\t// of waiting, we initiate playback\n\t\t\t\t\telse if( isMobile ) {\n\t\t\t\t\t\tlet promise = el.play();\n\n\t\t\t\t\t\t// If autoplay does not work, ensure that the controls are visible so\n\t\t\t\t\t\t// that the viewer can start the media on their own\n\t\t\t\t\t\tif( promise && typeof promise.catch === 'function' && el.controls === false ) {\n\t\t\t\t\t\t\tpromise.catch( () => {\n\t\t\t\t\t\t\t\tel.controls = true;\n\n\t\t\t\t\t\t\t\t// Once the video does start playing, hide the controls again\n\t\t\t\t\t\t\t\tel.addEventListener( 'play', () => {\n\t\t\t\t\t\t\t\t\tel.controls = false;\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// If the media isn't loaded, wait before playing\n\t\t\t\t\telse {\n\t\t\t\t\t\tel.removeEventListener( 'loadeddata', this.startEmbeddedMedia ); // remove first to avoid dupes\n\t\t\t\t\t\tel.addEventListener( 'loadeddata', this.startEmbeddedMedia );\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// Normal iframes\n\t\t\tqueryAll( element, 'iframe[src]' ).forEach( el => {\n\t\t\t\tif( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.startEmbeddedIframe( { target: el } );\n\t\t\t} );\n\n\t\t\t// Lazy loading iframes\n\t\t\tqueryAll( element, 'iframe[data-src]' ).forEach( el => {\n\t\t\t\tif( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif( el.getAttribute( 'src' ) !== el.getAttribute( 'data-src' ) ) {\n\t\t\t\t\tel.removeEventListener( 'load', this.startEmbeddedIframe ); // remove first to avoid dupes\n\t\t\t\t\tel.addEventListener( 'load', this.startEmbeddedIframe );\n\t\t\t\t\tel.setAttribute( 'src', el.getAttribute( 'data-src' ) );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Starts playing an embedded video/audio element after\n\t * it has finished loading.\n\t *\n\t * @param {object} event\n\t */\n\tstartEmbeddedMedia( event ) {\n\n\t\tlet isAttachedToDOM = !!closestParent( event.target, 'html' ),\n\t\t\tisVisible \t\t= !!closestParent( event.target, '.present' );\n\n\t\tif( isAttachedToDOM && isVisible ) {\n\t\t\tevent.target.currentTime = 0;\n\t\t\tevent.target.play();\n\t\t}\n\n\t\tevent.target.removeEventListener( 'loadeddata', this.startEmbeddedMedia );\n\n\t}\n\n\t/**\n\t * \"Starts\" the content of an embedded iframe using the\n\t * postMessage API.\n\t *\n\t * @param {object} event\n\t */\n\tstartEmbeddedIframe( event ) {\n\n\t\tlet iframe = event.target;\n\n\t\tif( iframe && iframe.contentWindow ) {\n\n\t\t\tlet isAttachedToDOM = !!closestParent( event.target, 'html' ),\n\t\t\t\tisVisible \t\t= !!closestParent( event.target, '.present' );\n\n\t\t\tif( isAttachedToDOM && isVisible ) {\n\n\t\t\t\t// Prefer an explicit global autoplay setting\n\t\t\t\tlet autoplay = this.Reveal.getConfig().autoPlayMedia;\n\n\t\t\t\t// If no global setting is available, fall back on the element's\n\t\t\t\t// own autoplay setting\n\t\t\t\tif( typeof autoplay !== 'boolean' ) {\n\t\t\t\t\tautoplay = iframe.hasAttribute( 'data-autoplay' ) || !!closestParent( iframe, '.slide-background' );\n\t\t\t\t}\n\n\t\t\t\t// YouTube postMessage API\n\t\t\t\tif( /youtube\\.com\\/embed\\//.test( iframe.getAttribute( 'src' ) ) && autoplay ) {\n\t\t\t\t\tiframe.contentWindow.postMessage( '{\"event\":\"command\",\"func\":\"playVideo\",\"args\":\"\"}', '*' );\n\t\t\t\t}\n\t\t\t\t// Vimeo postMessage API\n\t\t\t\telse if( /player\\.vimeo\\.com\\//.test( iframe.getAttribute( 'src' ) ) && autoplay ) {\n\t\t\t\t\tiframe.contentWindow.postMessage( '{\"method\":\"play\"}', '*' );\n\t\t\t\t}\n\t\t\t\t// Generic postMessage API\n\t\t\t\telse {\n\t\t\t\t\tiframe.contentWindow.postMessage( 'slide:start', '*' );\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Stop playback of any embedded content inside of\n\t * the targeted slide.\n\t *\n\t * @param {HTMLElement} element\n\t */\n\tstopEmbeddedContent( element, options = {} ) {\n\n\t\toptions = extend( {\n\t\t\t// Defaults\n\t\t\tunloadIframes: true\n\t\t}, options );\n\n\t\tif( element && element.parentNode ) {\n\t\t\t// HTML5 media elements\n\t\t\tqueryAll( element, 'video, audio' ).forEach( el => {\n\t\t\t\tif( !el.hasAttribute( 'data-ignore' ) && typeof el.pause === 'function' ) {\n\t\t\t\t\tel.setAttribute('data-paused-by-reveal', '');\n\t\t\t\t\tel.pause();\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// Generic postMessage API for non-lazy loaded iframes\n\t\t\tqueryAll( element, 'iframe' ).forEach( el => {\n\t\t\t\tif( el.contentWindow ) el.contentWindow.postMessage( 'slide:stop', '*' );\n\t\t\t\tel.removeEventListener( 'load', this.startEmbeddedIframe );\n\t\t\t});\n\n\t\t\t// YouTube postMessage API\n\t\t\tqueryAll( element, 'iframe[src*=\"youtube.com/embed/\"]' ).forEach( el => {\n\t\t\t\tif( !el.hasAttribute( 'data-ignore' ) && el.contentWindow && typeof el.contentWindow.postMessage === 'function' ) {\n\t\t\t\t\tel.contentWindow.postMessage( '{\"event\":\"command\",\"func\":\"pauseVideo\",\"args\":\"\"}', '*' );\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Vimeo postMessage API\n\t\t\tqueryAll( element, 'iframe[src*=\"player.vimeo.com/\"]' ).forEach( el => {\n\t\t\t\tif( !el.hasAttribute( 'data-ignore' ) && el.contentWindow && typeof el.contentWindow.postMessage === 'function' ) {\n\t\t\t\t\tel.contentWindow.postMessage( '{\"method\":\"pause\"}', '*' );\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif( options.unloadIframes === true ) {\n\t\t\t\t// Unload lazy-loaded iframes\n\t\t\t\tqueryAll( element, 'iframe[data-src]' ).forEach( el => {\n\t\t\t\t\t// Only removing the src doesn't actually unload the frame\n\t\t\t\t\t// in all browsers (Firefox) so we set it to blank first\n\t\t\t\t\tel.setAttribute( 'src', 'about:blank' );\n\t\t\t\t\tel.removeAttribute( 'src' );\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\n\t}\n\n}","/**\n * Handles the display of reveal.js' optional slide number.\n */\nexport default class SlideNumber {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\trender() {\n\n\t\tthis.element = document.createElement( 'div' );\n\t\tthis.element.className = 'slide-number';\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tlet slideNumberDisplay = 'none';\n\t\tif( config.slideNumber && !this.Reveal.isPrintingPDF() ) {\n\t\t\tif( config.showSlideNumber === 'all' ) {\n\t\t\t\tslideNumberDisplay = 'block';\n\t\t\t}\n\t\t\telse if( config.showSlideNumber === 'speaker' && this.Reveal.isSpeakerNotes() ) {\n\t\t\t\tslideNumberDisplay = 'block';\n\t\t\t}\n\t\t}\n\n\t\tthis.element.style.display = slideNumberDisplay;\n\n\t}\n\n\t/**\n\t * Updates the slide number to match the current slide.\n\t */\n\tupdate() {\n\n\t\t// Update slide number if enabled\n\t\tif( this.Reveal.getConfig().slideNumber && this.element ) {\n\t\t\tthis.element.innerHTML = this.getSlideNumber();\n\t\t}\n\n\t}\n\n\t/**\n\t * Returns the HTML string corresponding to the current slide\n\t * number, including formatting.\n\t */\n\tgetSlideNumber( slide = this.Reveal.getCurrentSlide() ) {\n\n\t\tlet config = this.Reveal.getConfig();\n\t\tlet value;\n\t\tlet format = 'h.v';\n\n\t\tif ( typeof config.slideNumber === 'function' ) {\n\t\t\tvalue = config.slideNumber( slide );\n\t\t} else {\n\t\t\t// Check if a custom number format is available\n\t\t\tif( typeof config.slideNumber === 'string' ) {\n\t\t\t\tformat = config.slideNumber;\n\t\t\t}\n\n\t\t\t// If there are ONLY vertical slides in this deck, always use\n\t\t\t// a flattened slide number\n\t\t\tif( !/c/.test( format ) && this.Reveal.getHorizontalSlides().length === 1 ) {\n\t\t\t\tformat = 'c';\n\t\t\t}\n\n\t\t\tvalue = [];\n\t\t\tswitch( format ) {\n\t\t\t\tcase 'c':\n\t\t\t\t\tvalue.push( this.Reveal.getSlidePastCount( slide ) + 1 );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'c/t':\n\t\t\t\t\tvalue.push( this.Reveal.getSlidePastCount( slide ) + 1, '/', this.Reveal.getTotalSlides() );\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tlet indices = this.Reveal.getIndices( slide );\n\t\t\t\t\tvalue.push( indices.h + 1 );\n\t\t\t\t\tlet sep = format === 'h/v' ? '/' : '.';\n\t\t\t\t\tif( this.Reveal.isVerticalSlide( slide ) ) value.push( sep, indices.v + 1 );\n\t\t\t}\n\t\t}\n\n\t\tlet url = '#' + this.Reveal.location.getHash( slide );\n\t\treturn this.formatNumber( value[0], value[1], value[2], url );\n\n\t}\n\n\t/**\n\t * Applies HTML formatting to a slide number before it's\n\t * written to the DOM.\n\t *\n\t * @param {number} a Current slide\n\t * @param {string} delimiter Character to separate slide numbers\n\t * @param {(number|*)} b Total slides\n\t * @param {HTMLElement} [url='#'+locationHash()] The url to link to\n\t * @return {string} HTML string fragment\n\t */\n\tformatNumber( a, delimiter, b, url = '#' + this.Reveal.location.getHash() ) {\n\n\t\tif( typeof b === 'number' && !isNaN( b ) ) {\n\t\t\treturn `<a href=\"${url}\">\n\t\t\t\t\t<span class=\"slide-number-a\">${a}</span>\n\t\t\t\t\t<span class=\"slide-number-delimiter\">${delimiter}</span>\n\t\t\t\t\t<span class=\"slide-number-b\">${b}</span>\n\t\t\t\t\t</a>`;\n\t\t}\n\t\telse {\n\t\t\treturn `<a href=\"${url}\">\n\t\t\t\t\t<span class=\"slide-number-a\">${a}</span>\n\t\t\t\t\t</a>`;\n\t\t}\n\n\t}\n\n}","/**\n * Converts various color input formats to an {r:0,g:0,b:0} object.\n *\n * @param {string} color The string representation of a color\n * @example\n * colorToRgb('#000');\n * @example\n * colorToRgb('#000000');\n * @example\n * colorToRgb('rgb(0,0,0)');\n * @example\n * colorToRgb('rgba(0,0,0)');\n *\n * @return {{r: number, g: number, b: number, [a]: number}|null}\n */\nexport const colorToRgb = ( color ) => {\n\n\tlet hex3 = color.match( /^#([0-9a-f]{3})$/i );\n\tif( hex3 && hex3[1] ) {\n\t\thex3 = hex3[1];\n\t\treturn {\n\t\t\tr: parseInt( hex3.charAt( 0 ), 16 ) * 0x11,\n\t\t\tg: parseInt( hex3.charAt( 1 ), 16 ) * 0x11,\n\t\t\tb: parseInt( hex3.charAt( 2 ), 16 ) * 0x11\n\t\t};\n\t}\n\n\tlet hex6 = color.match( /^#([0-9a-f]{6})$/i );\n\tif( hex6 && hex6[1] ) {\n\t\thex6 = hex6[1];\n\t\treturn {\n\t\t\tr: parseInt( hex6.substr( 0, 2 ), 16 ),\n\t\t\tg: parseInt( hex6.substr( 2, 2 ), 16 ),\n\t\t\tb: parseInt( hex6.substr( 4, 2 ), 16 )\n\t\t};\n\t}\n\n\tlet rgb = color.match( /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i );\n\tif( rgb ) {\n\t\treturn {\n\t\t\tr: parseInt( rgb[1], 10 ),\n\t\t\tg: parseInt( rgb[2], 10 ),\n\t\t\tb: parseInt( rgb[3], 10 )\n\t\t};\n\t}\n\n\tlet rgba = color.match( /^rgba\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\,\\s*([\\d]+|[\\d]*.[\\d]+)\\s*\\)$/i );\n\tif( rgba ) {\n\t\treturn {\n\t\t\tr: parseInt( rgba[1], 10 ),\n\t\t\tg: parseInt( rgba[2], 10 ),\n\t\t\tb: parseInt( rgba[3], 10 ),\n\t\t\ta: parseFloat( rgba[4] )\n\t\t};\n\t}\n\n\treturn null;\n\n}\n\n/**\n * Calculates brightness on a scale of 0-255.\n *\n * @param {string} color See colorToRgb for supported formats.\n * @see {@link colorToRgb}\n */\nexport const colorBrightness = ( color ) => {\n\n\tif( typeof color === 'string' ) color = colorToRgb( color );\n\n\tif( color ) {\n\t\treturn ( color.r * 299 + color.g * 587 + color.b * 114 ) / 1000;\n\t}\n\n\treturn null;\n\n}","import { queryAll } from '../utils/util.js'\nimport { colorToRgb, colorBrightness } from '../utils/color.js'\n\n/**\n * Creates and updates slide backgrounds.\n */\nexport default class Backgrounds {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\trender() {\n\n\t\tthis.element = document.createElement( 'div' );\n\t\tthis.element.className = 'backgrounds';\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t}\n\n\t/**\n\t * Creates the slide background elements and appends them\n\t * to the background container. One element is created per\n\t * slide no matter if the given slide has visible background.\n\t */\n\tcreate() {\n\n\t\tlet printMode = this.Reveal.isPrintingPDF();\n\n\t\t// Clear prior backgrounds\n\t\tthis.element.innerHTML = '';\n\t\tthis.element.classList.add( 'no-transition' );\n\n\t\t// Iterate over all horizontal slides\n\t\tthis.Reveal.getHorizontalSlides().forEach( slideh => {\n\n\t\t\tlet backgroundStack = this.createBackground( slideh, this.element );\n\n\t\t\t// Iterate over all vertical slides\n\t\t\tqueryAll( slideh, 'section' ).forEach( slidev => {\n\n\t\t\t\tthis.createBackground( slidev, backgroundStack );\n\n\t\t\t\tbackgroundStack.classList.add( 'stack' );\n\n\t\t\t} );\n\n\t\t} );\n\n\t\t// Add parallax background if specified\n\t\tif( this.Reveal.getConfig().parallaxBackgroundImage ) {\n\n\t\t\tthis.element.style.backgroundImage = 'url(\"' + this.Reveal.getConfig().parallaxBackgroundImage + '\")';\n\t\t\tthis.element.style.backgroundSize = this.Reveal.getConfig().parallaxBackgroundSize;\n\t\t\tthis.element.style.backgroundRepeat = this.Reveal.getConfig().parallaxBackgroundRepeat;\n\t\t\tthis.element.style.backgroundPosition = this.Reveal.getConfig().parallaxBackgroundPosition;\n\n\t\t\t// Make sure the below properties are set on the element - these properties are\n\t\t\t// needed for proper transitions to be set on the element via CSS. To remove\n\t\t\t// annoying background slide-in effect when the presentation starts, apply\n\t\t\t// these properties after short time delay\n\t\t\tsetTimeout( () => {\n\t\t\t\tthis.Reveal.getRevealElement().classList.add( 'has-parallax-background' );\n\t\t\t}, 1 );\n\n\t\t}\n\t\telse {\n\n\t\t\tthis.element.style.backgroundImage = '';\n\t\t\tthis.Reveal.getRevealElement().classList.remove( 'has-parallax-background' );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Creates a background for the given slide.\n\t *\n\t * @param {HTMLElement} slide\n\t * @param {HTMLElement} container The element that the background\n\t * should be appended to\n\t * @return {HTMLElement} New background div\n\t */\n\tcreateBackground( slide, container ) {\n\n\t\t// Main slide background element\n\t\tlet element = document.createElement( 'div' );\n\t\telement.className = 'slide-background ' + slide.className.replace( /present|past|future/, '' );\n\n\t\t// Inner background element that wraps images/videos/iframes\n\t\tlet contentElement = document.createElement( 'div' );\n\t\tcontentElement.className = 'slide-background-content';\n\n\t\telement.appendChild( contentElement );\n\t\tcontainer.appendChild( element );\n\n\t\tslide.slideBackgroundElement = element;\n\t\tslide.slideBackgroundContentElement = contentElement;\n\n\t\t// Syncs the background to reflect all current background settings\n\t\tthis.sync( slide );\n\n\t\treturn element;\n\n\t}\n\n\t/**\n\t * Renders all of the visual properties of a slide background\n\t * based on the various background attributes.\n\t *\n\t * @param {HTMLElement} slide\n\t */\n\tsync( slide ) {\n\n\t\tlet element = slide.slideBackgroundElement,\n\t\t\tcontentElement = slide.slideBackgroundContentElement;\n\n\t\t// Reset the prior background state in case this is not the\n\t\t// initial sync\n\t\tslide.classList.remove( 'has-dark-background' );\n\t\tslide.classList.remove( 'has-light-background' );\n\n\t\telement.removeAttribute( 'data-loaded' );\n\t\telement.removeAttribute( 'data-background-hash' );\n\t\telement.removeAttribute( 'data-background-size' );\n\t\telement.removeAttribute( 'data-background-transition' );\n\t\telement.style.backgroundColor = '';\n\n\t\tcontentElement.style.backgroundSize = '';\n\t\tcontentElement.style.backgroundRepeat = '';\n\t\tcontentElement.style.backgroundPosition = '';\n\t\tcontentElement.style.backgroundImage = '';\n\t\tcontentElement.style.opacity = '';\n\t\tcontentElement.innerHTML = '';\n\n\t\tlet data = {\n\t\t\tbackground: slide.getAttribute( 'data-background' ),\n\t\t\tbackgroundSize: slide.getAttribute( 'data-background-size' ),\n\t\t\tbackgroundImage: slide.getAttribute( 'data-background-image' ),\n\t\t\tbackgroundVideo: slide.getAttribute( 'data-background-video' ),\n\t\t\tbackgroundIframe: slide.getAttribute( 'data-background-iframe' ),\n\t\t\tbackgroundColor: slide.getAttribute( 'data-background-color' ),\n\t\t\tbackgroundRepeat: slide.getAttribute( 'data-background-repeat' ),\n\t\t\tbackgroundPosition: slide.getAttribute( 'data-background-position' ),\n\t\t\tbackgroundTransition: slide.getAttribute( 'data-background-transition' ),\n\t\t\tbackgroundOpacity: slide.getAttribute( 'data-background-opacity' )\n\t\t};\n\n\t\tif( data.background ) {\n\t\t\t// Auto-wrap image urls in url(...)\n\t\t\tif( /^(http|file|\\/\\/)/gi.test( data.background ) || /\\.(svg|png|jpg|jpeg|gif|bmp)([?#\\s]|$)/gi.test( data.background ) ) {\n\t\t\t\tslide.setAttribute( 'data-background-image', data.background );\n\t\t\t}\n\t\t\telse {\n\t\t\t\telement.style.background = data.background;\n\t\t\t}\n\t\t}\n\n\t\t// Create a hash for this combination of background settings.\n\t\t// This is used to determine when two slide backgrounds are\n\t\t// the same.\n\t\tif( data.background || data.backgroundColor || data.backgroundImage || data.backgroundVideo || data.backgroundIframe ) {\n\t\t\telement.setAttribute( 'data-background-hash', data.background +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundSize +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundImage +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundVideo +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundIframe +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundColor +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundRepeat +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundPosition +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundTransition +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundOpacity );\n\t\t}\n\n\t\t// Additional and optional background properties\n\t\tif( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize );\n\t\tif( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;\n\t\tif( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );\n\n\t\tif( slide.hasAttribute( 'data-preload' ) ) element.setAttribute( 'data-preload', '' );\n\n\t\t// Background image options are set on the content wrapper\n\t\tif( data.backgroundSize ) contentElement.style.backgroundSize = data.backgroundSize;\n\t\tif( data.backgroundRepeat ) contentElement.style.backgroundRepeat = data.backgroundRepeat;\n\t\tif( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition;\n\t\tif( data.backgroundOpacity ) contentElement.style.opacity = data.backgroundOpacity;\n\n\t\t// If this slide has a background color, we add a class that\n\t\t// signals if it is light or dark. If the slide has no background\n\t\t// color, no class will be added\n\t\tlet contrastColor = data.backgroundColor;\n\n\t\t// If no bg color was found, check the computed background\n\t\tif( !contrastColor ) {\n\t\t\tlet computedBackgroundStyle = window.getComputedStyle( element );\n\t\t\tif( computedBackgroundStyle && computedBackgroundStyle.backgroundColor ) {\n\t\t\t\tcontrastColor = computedBackgroundStyle.backgroundColor;\n\t\t\t}\n\t\t}\n\n\t\tif( contrastColor ) {\n\t\t\tlet rgb = colorToRgb( contrastColor );\n\n\t\t\t// Ignore fully transparent backgrounds. Some browsers return\n\t\t\t// rgba(0,0,0,0) when reading the computed background color of\n\t\t\t// an element with no background\n\t\t\tif( rgb && rgb.a !== 0 ) {\n\t\t\t\tif( colorBrightness( contrastColor ) < 128 ) {\n\t\t\t\t\tslide.classList.add( 'has-dark-background' );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tslide.classList.add( 'has-light-background' );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Updates the background elements to reflect the current\n\t * slide.\n\t *\n\t * @param {boolean} includeAll If true, the backgrounds of\n\t * all vertical slides (not just the present) will be updated.\n\t */\n\tupdate( includeAll = false ) {\n\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\t\tlet indices = this.Reveal.getIndices();\n\n\t\tlet currentBackground = null;\n\n\t\t// Reverse past/future classes when in RTL mode\n\t\tlet horizontalPast = this.Reveal.getConfig().rtl ? 'future' : 'past',\n\t\t\thorizontalFuture = this.Reveal.getConfig().rtl ? 'past' : 'future';\n\n\t\t// Update the classes of all backgrounds to match the\n\t\t// states of their slides (past/present/future)\n\t\tArray.from( this.element.childNodes ).forEach( ( backgroundh, h ) => {\n\n\t\t\tbackgroundh.classList.remove( 'past', 'present', 'future' );\n\n\t\t\tif( h < indices.h ) {\n\t\t\t\tbackgroundh.classList.add( horizontalPast );\n\t\t\t}\n\t\t\telse if ( h > indices.h ) {\n\t\t\t\tbackgroundh.classList.add( horizontalFuture );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbackgroundh.classList.add( 'present' );\n\n\t\t\t\t// Store a reference to the current background element\n\t\t\t\tcurrentBackground = backgroundh;\n\t\t\t}\n\n\t\t\tif( includeAll || h === indices.h ) {\n\t\t\t\tqueryAll( backgroundh, '.slide-background' ).forEach( ( backgroundv, v ) => {\n\n\t\t\t\t\tbackgroundv.classList.remove( 'past', 'present', 'future' );\n\n\t\t\t\t\tif( v < indices.v ) {\n\t\t\t\t\t\tbackgroundv.classList.add( 'past' );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( v > indices.v ) {\n\t\t\t\t\t\tbackgroundv.classList.add( 'future' );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tbackgroundv.classList.add( 'present' );\n\n\t\t\t\t\t\t// Only if this is the present horizontal and vertical slide\n\t\t\t\t\t\tif( h === indices.h ) currentBackground = backgroundv;\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\t\t\t}\n\n\t\t} );\n\n\t\t// Stop content inside of previous backgrounds\n\t\tif( this.previousBackground ) {\n\n\t\t\tthis.Reveal.slideContent.stopEmbeddedContent( this.previousBackground, { unloadIframes: !this.Reveal.slideContent.shouldPreload( this.previousBackground ) } );\n\n\t\t}\n\n\t\t// Start content in the current background\n\t\tif( currentBackground ) {\n\n\t\t\tthis.Reveal.slideContent.startEmbeddedContent( currentBackground );\n\n\t\t\tlet currentBackgroundContent = currentBackground.querySelector( '.slide-background-content' );\n\t\t\tif( currentBackgroundContent ) {\n\n\t\t\t\tlet backgroundImageURL = currentBackgroundContent.style.backgroundImage || '';\n\n\t\t\t\t// Restart GIFs (doesn't work in Firefox)\n\t\t\t\tif( /\\.gif/i.test( backgroundImageURL ) ) {\n\t\t\t\t\tcurrentBackgroundContent.style.backgroundImage = '';\n\t\t\t\t\twindow.getComputedStyle( currentBackgroundContent ).opacity;\n\t\t\t\t\tcurrentBackgroundContent.style.backgroundImage = backgroundImageURL;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Don't transition between identical backgrounds. This\n\t\t\t// prevents unwanted flicker.\n\t\t\tlet previousBackgroundHash = this.previousBackground ? this.previousBackground.getAttribute( 'data-background-hash' ) : null;\n\t\t\tlet currentBackgroundHash = currentBackground.getAttribute( 'data-background-hash' );\n\t\t\tif( currentBackgroundHash && currentBackgroundHash === previousBackgroundHash && currentBackground !== this.previousBackground ) {\n\t\t\t\tthis.element.classList.add( 'no-transition' );\n\t\t\t}\n\n\t\t\tthis.previousBackground = currentBackground;\n\n\t\t}\n\n\t\t// If there's a background brightness flag for this slide,\n\t\t// bubble it to the .reveal container\n\t\tif( currentSlide ) {\n\t\t\t[ 'has-light-background', 'has-dark-background' ].forEach( classToBubble => {\n\t\t\t\tif( currentSlide.classList.contains( classToBubble ) ) {\n\t\t\t\t\tthis.Reveal.getRevealElement().classList.add( classToBubble );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.getRevealElement().classList.remove( classToBubble );\n\t\t\t\t}\n\t\t\t}, this );\n\t\t}\n\n\t\t// Allow the first background to apply without transition\n\t\tsetTimeout( () => {\n\t\t\tthis.element.classList.remove( 'no-transition' );\n\t\t}, 1 );\n\n\t}\n\n\t/**\n\t * Updates the position of the parallax background based\n\t * on the current slide index.\n\t */\n\tupdateParallax() {\n\n\t\tlet indices = this.Reveal.getIndices();\n\n\t\tif( this.Reveal.getConfig().parallaxBackgroundImage ) {\n\n\t\t\tlet horizontalSlides = this.Reveal.getHorizontalSlides(),\n\t\t\t\tverticalSlides = this.Reveal.getVerticalSlides();\n\n\t\t\tlet backgroundSize = this.element.style.backgroundSize.split( ' ' ),\n\t\t\t\tbackgroundWidth, backgroundHeight;\n\n\t\t\tif( backgroundSize.length === 1 ) {\n\t\t\t\tbackgroundWidth = backgroundHeight = parseInt( backgroundSize[0], 10 );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbackgroundWidth = parseInt( backgroundSize[0], 10 );\n\t\t\t\tbackgroundHeight = parseInt( backgroundSize[1], 10 );\n\t\t\t}\n\n\t\t\tlet slideWidth = this.element.offsetWidth,\n\t\t\t\thorizontalSlideCount = horizontalSlides.length,\n\t\t\t\thorizontalOffsetMultiplier,\n\t\t\t\thorizontalOffset;\n\n\t\t\tif( typeof this.Reveal.getConfig().parallaxBackgroundHorizontal === 'number' ) {\n\t\t\t\thorizontalOffsetMultiplier = this.Reveal.getConfig().parallaxBackgroundHorizontal;\n\t\t\t}\n\t\t\telse {\n\t\t\t\thorizontalOffsetMultiplier = horizontalSlideCount > 1 ? ( backgroundWidth - slideWidth ) / ( horizontalSlideCount-1 ) : 0;\n\t\t\t}\n\n\t\t\thorizontalOffset = horizontalOffsetMultiplier * indices.h * -1;\n\n\t\t\tlet slideHeight = this.element.offsetHeight,\n\t\t\t\tverticalSlideCount = verticalSlides.length,\n\t\t\t\tverticalOffsetMultiplier,\n\t\t\t\tverticalOffset;\n\n\t\t\tif( typeof this.Reveal.getConfig().parallaxBackgroundVertical === 'number' ) {\n\t\t\t\tverticalOffsetMultiplier = this.Reveal.getConfig().parallaxBackgroundVertical;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tverticalOffsetMultiplier = ( backgroundHeight - slideHeight ) / ( verticalSlideCount-1 );\n\t\t\t}\n\n\t\t\tverticalOffset = verticalSlideCount > 0 ? verticalOffsetMultiplier * indices.v : 0;\n\n\t\t\tthis.element.style.backgroundPosition = horizontalOffset + 'px ' + -verticalOffset + 'px';\n\n\t\t}\n\n\t}\n\n}","import { queryAll, extend, createStyleSheet } from '../utils/util.js'\nimport { FRAGMENT_STYLE_REGEX } from '../utils/constants.js'\n\n/**\n * Automatically animates matching elements across\n * slides with the [data-auto-animate] attribute.\n */\nexport default class AutoAnimate {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\t// Counter used to generate unique IDs for auto-animated elements\n\t\tthis.autoAnimateCounter = 0;\n\n\t}\n\n\t/**\n\t * Runs an auto-animation between the given slides.\n\t *\n\t * @param {HTMLElement} fromSlide\n\t * @param {HTMLElement} toSlide\n\t */\n\trun( fromSlide, toSlide ) {\n\n\t\t// Clean up after prior animations\n\t\tthis.reset();\n\n\t\t// Ensure that both slides are auto-animate targets\n\t\tif( fromSlide.hasAttribute( 'data-auto-animate' ) && toSlide.hasAttribute( 'data-auto-animate' ) ) {\n\n\t\t\t// Create a new auto-animate sheet\n\t\t\tthis.autoAnimateStyleSheet = this.autoAnimateStyleSheet || createStyleSheet();\n\n\t\t\tlet animationOptions = this.getAutoAnimateOptions( toSlide );\n\n\t\t\t// Set our starting state\n\t\t\tfromSlide.dataset.autoAnimate = 'pending';\n\t\t\ttoSlide.dataset.autoAnimate = 'pending';\n\n\t\t\t// Flag the navigation direction, needed for fragment buildup\n\t\t\tlet allSlides = this.Reveal.getSlides();\n\t\t\tanimationOptions.slideDirection = allSlides.indexOf( toSlide ) > allSlides.indexOf( fromSlide ) ? 'forward' : 'backward';\n\n\t\t\t// Inject our auto-animate styles for this transition\n\t\t\tlet css = this.getAutoAnimatableElements( fromSlide, toSlide ).map( elements => {\n\t\t\t\treturn this.autoAnimateElements( elements.from, elements.to, elements.options || {}, animationOptions, this.autoAnimateCounter++ );\n\t\t\t} );\n\n\t\t\t// Animate unmatched elements, if enabled\n\t\t\tif( toSlide.dataset.autoAnimateUnmatched !== 'false' && this.Reveal.getConfig().autoAnimateUnmatched === true ) {\n\n\t\t\t\t// Our default timings for unmatched elements\n\t\t\t\tlet defaultUnmatchedDuration = animationOptions.duration * 0.8,\n\t\t\t\t\tdefaultUnmatchedDelay = animationOptions.duration * 0.2;\n\n\t\t\t\tthis.getUnmatchedAutoAnimateElements( toSlide ).forEach( unmatchedElement => {\n\n\t\t\t\t\tlet unmatchedOptions = this.getAutoAnimateOptions( unmatchedElement, animationOptions );\n\t\t\t\t\tlet id = 'unmatched';\n\n\t\t\t\t\t// If there is a duration or delay set specifically for this\n\t\t\t\t\t// element our unmatched elements should adhere to those\n\t\t\t\t\tif( unmatchedOptions.duration !== animationOptions.duration || unmatchedOptions.delay !== animationOptions.delay ) {\n\t\t\t\t\t\tid = 'unmatched-' + this.autoAnimateCounter++;\n\t\t\t\t\t\tcss.push( `[data-auto-animate=\"running\"] [data-auto-animate-target=\"${id}\"] { transition: opacity ${unmatchedOptions.duration}s ease ${unmatchedOptions.delay}s; }` );\n\t\t\t\t\t}\n\n\t\t\t\t\tunmatchedElement.dataset.autoAnimateTarget = id;\n\n\t\t\t\t}, this );\n\n\t\t\t\t// Our default transition for unmatched elements\n\t\t\t\tcss.push( `[data-auto-animate=\"running\"] [data-auto-animate-target=\"unmatched\"] { transition: opacity ${defaultUnmatchedDuration}s ease ${defaultUnmatchedDelay}s; }` );\n\n\t\t\t}\n\n\t\t\t// Setting the whole chunk of CSS at once is the most\n\t\t\t// efficient way to do this. Using sheet.insertRule\n\t\t\t// is multiple factors slower.\n\t\t\tthis.autoAnimateStyleSheet.innerHTML = css.join( '' );\n\n\t\t\t// Start the animation next cycle\n\t\t\trequestAnimationFrame( () => {\n\t\t\t\tif( this.autoAnimateStyleSheet ) {\n\t\t\t\t\t// This forces our newly injected styles to be applied in Firefox\n\t\t\t\t\tgetComputedStyle( this.autoAnimateStyleSheet ).fontWeight;\n\n\t\t\t\t\ttoSlide.dataset.autoAnimate = 'running';\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\ttype: 'autoanimate',\n\t\t\t\tdata: {\n\t\t\t\t\tfromSlide,\n\t\t\t\t\ttoSlide,\n\t\t\t\t\tsheet: this.autoAnimateStyleSheet\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Rolls back all changes that we've made to the DOM so\n\t * that as part of animating.\n\t */\n\treset() {\n\n\t\t// Reset slides\n\t\tqueryAll( this.Reveal.getRevealElement(), '[data-auto-animate]:not([data-auto-animate=\"\"])' ).forEach( element => {\n\t\t\telement.dataset.autoAnimate = '';\n\t\t} );\n\n\t\t// Reset elements\n\t\tqueryAll( this.Reveal.getRevealElement(), '[data-auto-animate-target]' ).forEach( element => {\n\t\t\tdelete element.dataset.autoAnimateTarget;\n\t\t} );\n\n\t\t// Remove the animation sheet\n\t\tif( this.autoAnimateStyleSheet && this.autoAnimateStyleSheet.parentNode ) {\n\t\t\tthis.autoAnimateStyleSheet.parentNode.removeChild( this.autoAnimateStyleSheet );\n\t\t\tthis.autoAnimateStyleSheet = null;\n\t\t}\n\n\t}\n\n\t/**\n\t * Creates a FLIP animation where the `to` element starts out\n\t * in the `from` element position and animates to its original\n\t * state.\n\t *\n\t * @param {HTMLElement} from\n\t * @param {HTMLElement} to\n\t * @param {Object} elementOptions Options for this element pair\n\t * @param {Object} animationOptions Options set at the slide level\n\t * @param {String} id Unique ID that we can use to identify this\n\t * auto-animate element in the DOM\n\t */\n\tautoAnimateElements( from, to, elementOptions, animationOptions, id ) {\n\n\t\t// 'from' elements are given a data-auto-animate-target with no value,\n\t\t// 'to' elements are are given a data-auto-animate-target with an ID\n\t\tfrom.dataset.autoAnimateTarget = '';\n\t\tto.dataset.autoAnimateTarget = id;\n\n\t\t// Each element may override any of the auto-animate options\n\t\t// like transition easing, duration and delay via data-attributes\n\t\tlet options = this.getAutoAnimateOptions( to, animationOptions );\n\n\t\t// If we're using a custom element matcher the element options\n\t\t// may contain additional transition overrides\n\t\tif( typeof elementOptions.delay !== 'undefined' ) options.delay = elementOptions.delay;\n\t\tif( typeof elementOptions.duration !== 'undefined' ) options.duration = elementOptions.duration;\n\t\tif( typeof elementOptions.easing !== 'undefined' ) options.easing = elementOptions.easing;\n\n\t\tlet fromProps = this.getAutoAnimatableProperties( 'from', from, elementOptions ),\n\t\t\ttoProps = this.getAutoAnimatableProperties( 'to', to, elementOptions );\n\n\t\t// Maintain fragment visibility for matching elements when\n\t\t// we're navigating forwards, this way the viewer won't need\n\t\t// to step through the same fragments twice\n\t\tif( to.classList.contains( 'fragment' ) ) {\n\n\t\t\t// Don't auto-animate the opacity of fragments to avoid\n\t\t\t// conflicts with fragment animations\n\t\t\tdelete toProps.styles['opacity'];\n\n\t\t\tif( from.classList.contains( 'fragment' ) ) {\n\n\t\t\t\tlet fromFragmentStyle = ( from.className.match( FRAGMENT_STYLE_REGEX ) || [''] )[0];\n\t\t\t\tlet toFragmentStyle = ( to.className.match( FRAGMENT_STYLE_REGEX ) || [''] )[0];\n\n\t\t\t\t// Only skip the fragment if the fragment animation style\n\t\t\t\t// remains unchanged\n\t\t\t\tif( fromFragmentStyle === toFragmentStyle && animationOptions.slideDirection === 'forward' ) {\n\t\t\t\t\tto.classList.add( 'visible', 'disabled' );\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// If translation and/or scaling are enabled, css transform\n\t\t// the 'to' element so that it matches the position and size\n\t\t// of the 'from' element\n\t\tif( elementOptions.translate !== false || elementOptions.scale !== false ) {\n\n\t\t\tlet presentationScale = this.Reveal.getScale();\n\n\t\t\tlet delta = {\n\t\t\t\tx: ( fromProps.x - toProps.x ) / presentationScale,\n\t\t\t\ty: ( fromProps.y - toProps.y ) / presentationScale,\n\t\t\t\tscaleX: fromProps.width / toProps.width,\n\t\t\t\tscaleY: fromProps.height / toProps.height\n\t\t\t};\n\n\t\t\t// Limit decimal points to avoid 0.0001px blur and stutter\n\t\t\tdelta.x = Math.round( delta.x * 1000 ) / 1000;\n\t\t\tdelta.y = Math.round( delta.y * 1000 ) / 1000;\n\t\t\tdelta.scaleX = Math.round( delta.scaleX * 1000 ) / 1000;\n\t\t\tdelta.scaleX = Math.round( delta.scaleX * 1000 ) / 1000;\n\n\t\t\tlet translate = elementOptions.translate !== false && ( delta.x !== 0 || delta.y !== 0 ),\n\t\t\t\tscale = elementOptions.scale !== false && ( delta.scaleX !== 0 || delta.scaleY !== 0 );\n\n\t\t\t// No need to transform if nothing's changed\n\t\t\tif( translate || scale ) {\n\n\t\t\t\tlet transform = [];\n\n\t\t\t\tif( translate ) transform.push( `translate(${delta.x}px, ${delta.y}px)` );\n\t\t\t\tif( scale ) transform.push( `scale(${delta.scaleX}, ${delta.scaleY})` );\n\n\t\t\t\tfromProps.styles['transform'] = transform.join( ' ' );\n\t\t\t\tfromProps.styles['transform-origin'] = 'top left';\n\n\t\t\t\ttoProps.styles['transform'] = 'none';\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Delete all unchanged 'to' styles\n\t\tfor( let propertyName in toProps.styles ) {\n\t\t\tconst toValue = toProps.styles[propertyName];\n\t\t\tconst fromValue = fromProps.styles[propertyName];\n\n\t\t\tif( toValue === fromValue ) {\n\t\t\t\tdelete toProps.styles[propertyName];\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// If these property values were set via a custom matcher providing\n\t\t\t\t// an explicit 'from' and/or 'to' value, we always inject those values.\n\t\t\t\tif( toValue.explicitValue === true ) {\n\t\t\t\t\ttoProps.styles[propertyName] = toValue.value;\n\t\t\t\t}\n\n\t\t\t\tif( fromValue.explicitValue === true ) {\n\t\t\t\t\tfromProps.styles[propertyName] = fromValue.value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet css = '';\n\n\t\tlet toStyleProperties = Object.keys( toProps.styles );\n\n\t\t// Only create animate this element IF at least one style\n\t\t// property has changed\n\t\tif( toStyleProperties.length > 0 ) {\n\n\t\t\t// Instantly move to the 'from' state\n\t\t\tfromProps.styles['transition'] = 'none';\n\n\t\t\t// Animate towards the 'to' state\n\t\t\ttoProps.styles['transition'] = `all ${options.duration}s ${options.easing} ${options.delay}s`;\n\t\t\ttoProps.styles['transition-property'] = toStyleProperties.join( ', ' );\n\t\t\ttoProps.styles['will-change'] = toStyleProperties.join( ', ' );\n\n\t\t\t// Build up our custom CSS. We need to override inline styles\n\t\t\t// so we need to make our styles vErY IMPORTANT!1!!\n\t\t\tlet fromCSS = Object.keys( fromProps.styles ).map( propertyName => {\n\t\t\t\treturn propertyName + ': ' + fromProps.styles[propertyName] + ' !important;';\n\t\t\t} ).join( '' );\n\n\t\t\tlet toCSS = Object.keys( toProps.styles ).map( propertyName => {\n\t\t\t\treturn propertyName + ': ' + toProps.styles[propertyName] + ' !important;';\n\t\t\t} ).join( '' );\n\n\t\t\tcss = \t'[data-auto-animate-target=\"'+ id +'\"] {'+ fromCSS +'}' +\n\t\t\t\t\t'[data-auto-animate=\"running\"] [data-auto-animate-target=\"'+ id +'\"] {'+ toCSS +'}';\n\n\t\t}\n\n\t\treturn css;\n\n\t}\n\n\t/**\n\t * Returns the auto-animate options for the given element.\n\t *\n\t * @param {HTMLElement} element Element to pick up options\n\t * from, either a slide or an animation target\n\t * @param {Object} [inheritedOptions] Optional set of existing\n\t * options\n\t */\n\tgetAutoAnimateOptions( element, inheritedOptions ) {\n\n\t\tlet options = {\n\t\t\teasing: this.Reveal.getConfig().autoAnimateEasing,\n\t\t\tduration: this.Reveal.getConfig().autoAnimateDuration,\n\t\t\tdelay: 0\n\t\t};\n\n\t\toptions = extend( options, inheritedOptions );\n\n\t\t// Inherit options from parent elements\n\t\tif( element.closest && element.parentNode ) {\n\t\t\tlet autoAnimatedParent = element.parentNode.closest( '[data-auto-animate-target]' );\n\t\t\tif( autoAnimatedParent ) {\n\t\t\t\toptions = this.getAutoAnimateOptions( autoAnimatedParent, options );\n\t\t\t}\n\t\t}\n\n\t\tif( element.dataset.autoAnimateEasing ) {\n\t\t\toptions.easing = element.dataset.autoAnimateEasing;\n\t\t}\n\n\t\tif( element.dataset.autoAnimateDuration ) {\n\t\t\toptions.duration = parseFloat( element.dataset.autoAnimateDuration );\n\t\t}\n\n\t\tif( element.dataset.autoAnimateDelay ) {\n\t\t\toptions.delay = parseFloat( element.dataset.autoAnimateDelay );\n\t\t}\n\n\t\treturn options;\n\n\t}\n\n\t/**\n\t * Returns an object containing all of the properties\n\t * that can be auto-animated for the given element and\n\t * their current computed values.\n\t *\n\t * @param {String} direction 'from' or 'to'\n\t */\n\tgetAutoAnimatableProperties( direction, element, elementOptions ) {\n\n\t\tlet properties = { styles: [] };\n\n\t\t// Position and size\n\t\tif( elementOptions.translate !== false || elementOptions.scale !== false ) {\n\t\t\tlet bounds;\n\n\t\t\t// Custom auto-animate may optionally return a custom tailored\n\t\t\t// measurement function\n\t\t\tif( typeof elementOptions.measure === 'function' ) {\n\t\t\t\tbounds = elementOptions.measure( element );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbounds = element.getBoundingClientRect();\n\t\t\t}\n\n\t\t\tproperties.x = bounds.x;\n\t\t\tproperties.y = bounds.y;\n\t\t\tproperties.width = bounds.width;\n\t\t\tproperties.height = bounds.height;\n\t\t}\n\n\t\tconst computedStyles = getComputedStyle( element );\n\n\t\t// CSS styles\n\t\t( elementOptions.styles || this.Reveal.getConfig().autoAnimateStyles ).forEach( style => {\n\t\t\tlet value;\n\n\t\t\t// `style` is either the property name directly, or an object\n\t\t\t// definition of a style property\n\t\t\tif( typeof style === 'string' ) style = { property: style };\n\n\t\t\tif( typeof style.from !== 'undefined' && direction === 'from' ) {\n\t\t\t\tvalue = { value: style.from, explicitValue: true };\n\t\t\t}\n\t\t\telse if( typeof style.to !== 'undefined' && direction === 'to' ) {\n\t\t\t\tvalue = { value: style.to, explicitValue: true };\n\t\t\t}\n\t\t\telse {\n\t\t\t\tvalue = computedStyles[style.property];\n\t\t\t}\n\n\t\t\tif( value !== '' ) {\n\t\t\t\tproperties.styles[style.property] = value;\n\t\t\t}\n\t\t} );\n\n\t\treturn properties;\n\n\t}\n\n\t/**\n\t * Get a list of all element pairs that we can animate\n\t * between the given slides.\n\t *\n\t * @param {HTMLElement} fromSlide\n\t * @param {HTMLElement} toSlide\n\t *\n\t * @return {Array} Each value is an array where [0] is\n\t * the element we're animating from and [1] is the\n\t * element we're animating to\n\t */\n\tgetAutoAnimatableElements( fromSlide, toSlide ) {\n\n\t\tlet matcher = typeof this.Reveal.getConfig().autoAnimateMatcher === 'function' ? this.Reveal.getConfig().autoAnimateMatcher : this.getAutoAnimatePairs;\n\n\t\tlet pairs = matcher.call( this, fromSlide, toSlide );\n\n\t\tlet reserved = [];\n\n\t\t// Remove duplicate pairs\n\t\treturn pairs.filter( ( pair, index ) => {\n\t\t\tif( reserved.indexOf( pair.to ) === -1 ) {\n\t\t\t\treserved.push( pair.to );\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} );\n\n\t}\n\n\t/**\n\t * Identifies matching elements between slides.\n\t *\n\t * You can specify a custom matcher function by using\n\t * the `autoAnimateMatcher` config option.\n\t */\n\tgetAutoAnimatePairs( fromSlide, toSlide ) {\n\n\t\tlet pairs = [];\n\n\t\tconst codeNodes = 'pre';\n\t\tconst textNodes = 'h1, h2, h3, h4, h5, h6, p, li';\n\t\tconst mediaNodes = 'img, video, iframe';\n\n\t\t// Eplicit matches via data-id\n\t\tthis.findAutoAnimateMatches( pairs, fromSlide, toSlide, '[data-id]', node => {\n\t\t\treturn node.nodeName + ':::' + node.getAttribute( 'data-id' );\n\t\t} );\n\n\t\t// Text\n\t\tthis.findAutoAnimateMatches( pairs, fromSlide, toSlide, textNodes, node => {\n\t\t\treturn node.nodeName + ':::' + node.innerText;\n\t\t} );\n\n\t\t// Media\n\t\tthis.findAutoAnimateMatches( pairs, fromSlide, toSlide, mediaNodes, node => {\n\t\t\treturn node.nodeName + ':::' + ( node.getAttribute( 'src' ) || node.getAttribute( 'data-src' ) );\n\t\t} );\n\n\t\t// Code\n\t\tthis.findAutoAnimateMatches( pairs, fromSlide, toSlide, codeNodes, node => {\n\t\t\treturn node.nodeName + ':::' + node.innerText;\n\t\t} );\n\n\t\tpairs.forEach( pair => {\n\n\t\t\t// Disable scale transformations on text nodes, we transiition\n\t\t\t// each individual text property instead\n\t\t\tif( pair.from.matches( textNodes ) ) {\n\t\t\t\tpair.options = { scale: false };\n\t\t\t}\n\t\t\t// Animate individual lines of code\n\t\t\telse if( pair.from.matches( codeNodes ) ) {\n\n\t\t\t\t// Transition the code block's width and height instead of scaling\n\t\t\t\t// to prevent its content from being squished\n\t\t\t\tpair.options = { scale: false, styles: [ 'width', 'height' ] };\n\n\t\t\t\t// Lines of code\n\t\t\t\tthis.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-code', node => {\n\t\t\t\t\treturn node.textContent;\n\t\t\t\t}, {\n\t\t\t\t\tscale: false,\n\t\t\t\t\tstyles: [],\n\t\t\t\t\tmeasure: this.getLocalBoundingBox.bind( this )\n\t\t\t\t} );\n\n\t\t\t\t// Line numbers\n\t\t\t\tthis.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-line[data-line-number]', node => {\n\t\t\t\t\treturn node.getAttribute( 'data-line-number' );\n\t\t\t\t}, {\n\t\t\t\t\tscale: false,\n\t\t\t\t\tstyles: [ 'width' ],\n\t\t\t\t\tmeasure: this.getLocalBoundingBox.bind( this )\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t}, this );\n\n\t\treturn pairs;\n\n\t}\n\n\t/**\n\t * Helper method which returns a bounding box based on\n\t * the given elements offset coordinates.\n\t *\n\t * @param {HTMLElement} element\n\t * @return {Object} x, y, width, height\n\t */\n\tgetLocalBoundingBox( element ) {\n\n\t\tconst presentationScale = this.Reveal.getScale();\n\n\t\treturn {\n\t\t\tx: Math.round( ( element.offsetLeft * presentationScale ) * 100 ) / 100,\n\t\t\ty: Math.round( ( element.offsetTop * presentationScale ) * 100 ) / 100,\n\t\t\twidth: Math.round( ( element.offsetWidth * presentationScale ) * 100 ) / 100,\n\t\t\theight: Math.round( ( element.offsetHeight * presentationScale ) * 100 ) / 100\n\t\t};\n\n\t}\n\n\t/**\n\t * Finds matching elements between two slides.\n\t *\n\t * @param {Array} pairs \tList of pairs to push matches to\n\t * @param {HTMLElement} fromScope Scope within the from element exists\n\t * @param {HTMLElement} toScope Scope within the to element exists\n\t * @param {String} selector CSS selector of the element to match\n\t * @param {Function} serializer A function that accepts an element and returns\n\t * a stringified ID based on its contents\n\t * @param {Object} animationOptions Optional config options for this pair\n\t */\n\tfindAutoAnimateMatches( pairs, fromScope, toScope, selector, serializer, animationOptions ) {\n\n\t\tlet fromMatches = {};\n\t\tlet toMatches = {};\n\n\t\t[].slice.call( fromScope.querySelectorAll( selector ) ).forEach( ( element, i ) => {\n\t\t\tconst key = serializer( element );\n\t\t\tif( typeof key === 'string' && key.length ) {\n\t\t\t\tfromMatches[key] = fromMatches[key] || [];\n\t\t\t\tfromMatches[key].push( element );\n\t\t\t}\n\t\t} );\n\n\t\t[].slice.call( toScope.querySelectorAll( selector ) ).forEach( ( element, i ) => {\n\t\t\tconst key = serializer( element );\n\t\t\ttoMatches[key] = toMatches[key] || [];\n\t\t\ttoMatches[key].push( element );\n\n\t\t\tlet fromElement;\n\n\t\t\t// Retrieve the 'from' element\n\t\t\tif( fromMatches[key] ) {\n\t\t\t\tconst pimaryIndex = toMatches[key].length - 1;\n\t\t\t\tconst secondaryIndex = fromMatches[key].length - 1;\n\n\t\t\t\t// If there are multiple identical from elements, retrieve\n\t\t\t\t// the one at the same index as our to-element.\n\t\t\t\tif( fromMatches[key][ pimaryIndex ] ) {\n\t\t\t\t\tfromElement = fromMatches[key][ pimaryIndex ];\n\t\t\t\t\tfromMatches[key][ pimaryIndex ] = null;\n\t\t\t\t}\n\t\t\t\t// If there are no matching from-elements at the same index,\n\t\t\t\t// use the last one.\n\t\t\t\telse if( fromMatches[key][ secondaryIndex ] ) {\n\t\t\t\t\tfromElement = fromMatches[key][ secondaryIndex ];\n\t\t\t\t\tfromMatches[key][ secondaryIndex ] = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we've got a matching pair, push it to the list of pairs\n\t\t\tif( fromElement ) {\n\t\t\t\tpairs.push({\n\t\t\t\t\tfrom: fromElement,\n\t\t\t\t\tto: element,\n\t\t\t\t\toptions: animationOptions\n\t\t\t\t});\n\t\t\t}\n\t\t} );\n\n\t}\n\n\t/**\n\t * Returns a all elements within the given scope that should\n\t * be considered unmatched in an auto-animate transition. If\n\t * fading of unmatched elements is turned on, these elements\n\t * will fade when going between auto-animate slides.\n\t *\n\t * Note that parents of auto-animate targets are NOT considerd\n\t * unmatched since fading them would break the auto-animation.\n\t *\n\t * @param {HTMLElement} rootElement\n\t * @return {Array}\n\t */\n\tgetUnmatchedAutoAnimateElements( rootElement ) {\n\n\t\treturn [].slice.call( rootElement.children ).reduce( ( result, element ) => {\n\n\t\t\tconst containsAnimatedElements = element.querySelector( '[data-auto-animate-target]' );\n\n\t\t\t// The element is unmatched if\n\t\t\t// - It is not an auto-animate target\n\t\t\t// - It does not contain any auto-animate targets\n\t\t\tif( !element.hasAttribute( 'data-auto-animate-target' ) && !containsAnimatedElements ) {\n\t\t\t\tresult.push( element );\n\t\t\t}\n\n\t\t\tif( element.querySelector( '[data-auto-animate-target]' ) ) {\n\t\t\t\tresult = result.concat( this.getUnmatchedAutoAnimateElements( element ) );\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}, [] );\n\n\t}\n\n}","import { extend, queryAll } from '../utils/util.js'\n\n/**\n * Handles sorting and navigation of slide fragments.\n * Fragments are elements within a slide that are\n * revealed/animated incrementally.\n */\nexport default class Fragments {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tif( config.fragments === false ) {\n\t\t\tthis.disable();\n\t\t}\n\t\telse if( oldConfig.fragments === false ) {\n\t\t\tthis.enable();\n\t\t}\n\n\t}\n\n\t/**\n\t * If fragments are disabled in the deck, they should all be\n\t * visible rather than stepped through.\n\t */\n\tdisable() {\n\n\t\tqueryAll( this.Reveal.getSlidesElement(), '.fragment' ).forEach( element => {\n\t\t\telement.classList.add( 'visible' );\n\t\t\telement.classList.remove( 'current-fragment' );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Reverse of #disable(). Only called if fragments have\n\t * previously been disabled.\n\t */\n\tenable() {\n\n\t\tqueryAll( this.Reveal.getSlidesElement(), '.fragment' ).forEach( element => {\n\t\t\telement.classList.remove( 'visible' );\n\t\t\telement.classList.remove( 'current-fragment' );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Returns an object describing the available fragment\n\t * directions.\n\t *\n\t * @return {{prev: boolean, next: boolean}}\n\t */\n\tavailableRoutes() {\n\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\t\tif( currentSlide && this.Reveal.getConfig().fragments ) {\n\t\t\tlet fragments = currentSlide.querySelectorAll( '.fragment:not(.disabled)' );\n\t\t\tlet hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.disabled):not(.visible)' );\n\n\t\t\treturn {\n\t\t\t\tprev: fragments.length - hiddenFragments.length > 0,\n\t\t\t\tnext: !!hiddenFragments.length\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\treturn { prev: false, next: false };\n\t\t}\n\n\t}\n\n\t/**\n\t * Return a sorted fragments list, ordered by an increasing\n\t * \"data-fragment-index\" attribute.\n\t *\n\t * Fragments will be revealed in the order that they are returned by\n\t * this function, so you can use the index attributes to control the\n\t * order of fragment appearance.\n\t *\n\t * To maintain a sensible default fragment order, fragments are presumed\n\t * to be passed in document order. This function adds a \"fragment-index\"\n\t * attribute to each node if such an attribute is not already present,\n\t * and sets that attribute to an integer value which is the position of\n\t * the fragment within the fragments list.\n\t *\n\t * @param {object[]|*} fragments\n\t * @param {boolean} grouped If true the returned array will contain\n\t * nested arrays for all fragments with the same index\n\t * @return {object[]} sorted Sorted array of fragments\n\t */\n\tsort( fragments, grouped = false ) {\n\n\t\tfragments = Array.from( fragments );\n\n\t\tlet ordered = [],\n\t\t\tunordered = [],\n\t\t\tsorted = [];\n\n\t\t// Group ordered and unordered elements\n\t\tfragments.forEach( fragment => {\n\t\t\tif( fragment.hasAttribute( 'data-fragment-index' ) ) {\n\t\t\t\tlet index = parseInt( fragment.getAttribute( 'data-fragment-index' ), 10 );\n\n\t\t\t\tif( !ordered[index] ) {\n\t\t\t\t\tordered[index] = [];\n\t\t\t\t}\n\n\t\t\t\tordered[index].push( fragment );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tunordered.push( [ fragment ] );\n\t\t\t}\n\t\t} );\n\n\t\t// Append fragments without explicit indices in their\n\t\t// DOM order\n\t\tordered = ordered.concat( unordered );\n\n\t\t// Manually count the index up per group to ensure there\n\t\t// are no gaps\n\t\tlet index = 0;\n\n\t\t// Push all fragments in their sorted order to an array,\n\t\t// this flattens the groups\n\t\tordered.forEach( group => {\n\t\t\tgroup.forEach( fragment => {\n\t\t\t\tsorted.push( fragment );\n\t\t\t\tfragment.setAttribute( 'data-fragment-index', index );\n\t\t\t} );\n\n\t\t\tindex ++;\n\t\t} );\n\n\t\treturn grouped === true ? ordered : sorted;\n\n\t}\n\n\t/**\n\t * Sorts and formats all of fragments in the\n\t * presentation.\n\t */\n\tsortAll() {\n\n\t\tthis.Reveal.getHorizontalSlides().forEach( horizontalSlide => {\n\n\t\t\tlet verticalSlides = queryAll( horizontalSlide, 'section' );\n\t\t\tverticalSlides.forEach( ( verticalSlide, y ) => {\n\n\t\t\t\tthis.sort( verticalSlide.querySelectorAll( '.fragment' ) );\n\n\t\t\t}, this );\n\n\t\t\tif( verticalSlides.length === 0 ) this.sort( horizontalSlide.querySelectorAll( '.fragment' ) );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Refreshes the fragments on the current slide so that they\n\t * have the appropriate classes (.visible + .current-fragment).\n\t *\n\t * @param {number} [index] The index of the current fragment\n\t * @param {array} [fragments] Array containing all fragments\n\t * in the current slide\n\t *\n\t * @return {{shown: array, hidden: array}}\n\t */\n\tupdate( index, fragments ) {\n\n\t\tlet changedFragments = {\n\t\t\tshown: [],\n\t\t\thidden: []\n\t\t};\n\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\t\tif( currentSlide && this.Reveal.getConfig().fragments ) {\n\n\t\t\tfragments = fragments || this.sort( currentSlide.querySelectorAll( '.fragment' ) );\n\n\t\t\tif( fragments.length ) {\n\n\t\t\t\tlet maxIndex = 0;\n\n\t\t\t\tif( typeof index !== 'number' ) {\n\t\t\t\t\tlet currentFragment = this.sort( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop();\n\t\t\t\t\tif( currentFragment ) {\n\t\t\t\t\t\tindex = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tArray.from( fragments ).forEach( ( el, i ) => {\n\n\t\t\t\t\tif( el.hasAttribute( 'data-fragment-index' ) ) {\n\t\t\t\t\t\ti = parseInt( el.getAttribute( 'data-fragment-index' ), 10 );\n\t\t\t\t\t}\n\n\t\t\t\t\tmaxIndex = Math.max( maxIndex, i );\n\n\t\t\t\t\t// Visible fragments\n\t\t\t\t\tif( i <= index ) {\n\t\t\t\t\t\tlet wasVisible = el.classList.contains( 'visible' )\n\t\t\t\t\t\tel.classList.add( 'visible' );\n\t\t\t\t\t\tel.classList.remove( 'current-fragment' );\n\n\t\t\t\t\t\tif( i === index ) {\n\t\t\t\t\t\t\t// Announce the fragments one by one to the Screen Reader\n\t\t\t\t\t\t\tthis.Reveal.announceStatus( this.Reveal.getStatusText( el ) );\n\n\t\t\t\t\t\t\tel.classList.add( 'current-fragment' );\n\t\t\t\t\t\t\tthis.Reveal.slideContent.startEmbeddedContent( el );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( !wasVisible ) {\n\t\t\t\t\t\t\tchangedFragments.shown.push( el )\n\t\t\t\t\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\t\t\t\t\ttarget: el,\n\t\t\t\t\t\t\t\ttype: 'visible',\n\t\t\t\t\t\t\t\tbubbles: false\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Hidden fragments\n\t\t\t\t\telse {\n\t\t\t\t\t\tlet wasVisible = el.classList.contains( 'visible' )\n\t\t\t\t\t\tel.classList.remove( 'visible' );\n\t\t\t\t\t\tel.classList.remove( 'current-fragment' );\n\n\t\t\t\t\t\tif( wasVisible ) {\n\t\t\t\t\t\t\tchangedFragments.hidden.push( el );\n\t\t\t\t\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\t\t\t\t\ttarget: el,\n\t\t\t\t\t\t\t\ttype: 'hidden',\n\t\t\t\t\t\t\t\tbubbles: false\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\t// Write the current fragment index to the slide <section>.\n\t\t\t\t// This can be used by end users to apply styles based on\n\t\t\t\t// the current fragment index.\n\t\t\t\tindex = typeof index === 'number' ? index : -1;\n\t\t\t\tindex = Math.max( Math.min( index, maxIndex ), -1 );\n\t\t\t\tcurrentSlide.setAttribute( 'data-fragment', index );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn changedFragments;\n\n\t}\n\n\t/**\n\t * Formats the fragments on the given slide so that they have\n\t * valid indices. Call this if fragments are changed in the DOM\n\t * after reveal.js has already initialized.\n\t *\n\t * @param {HTMLElement} slide\n\t * @return {Array} a list of the HTML fragments that were synced\n\t */\n\tsync( slide = this.Reveal.getCurrentSlide() ) {\n\n\t\treturn this.sort( slide.querySelectorAll( '.fragment' ) );\n\n\t}\n\n\t/**\n\t * Navigate to the specified slide fragment.\n\t *\n\t * @param {?number} index The index of the fragment that\n\t * should be shown, -1 means all are invisible\n\t * @param {number} offset Integer offset to apply to the\n\t * fragment index\n\t *\n\t * @return {boolean} true if a change was made in any\n\t * fragments visibility as part of this call\n\t */\n\tgoto( index, offset = 0 ) {\n\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\t\tif( currentSlide && this.Reveal.getConfig().fragments ) {\n\n\t\t\tlet fragments = this.sort( currentSlide.querySelectorAll( '.fragment:not(.disabled)' ) );\n\t\t\tif( fragments.length ) {\n\n\t\t\t\t// If no index is specified, find the current\n\t\t\t\tif( typeof index !== 'number' ) {\n\t\t\t\t\tlet lastVisibleFragment = this.sort( currentSlide.querySelectorAll( '.fragment:not(.disabled).visible' ) ).pop();\n\n\t\t\t\t\tif( lastVisibleFragment ) {\n\t\t\t\t\t\tindex = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tindex = -1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply the offset if there is one\n\t\t\t\tindex += offset;\n\n\t\t\t\tlet changedFragments = this.update( index, fragments );\n\n\t\t\t\tif( changedFragments.hidden.length ) {\n\t\t\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\t\t\ttype: 'fragmenthidden',\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tfragment: changedFragments.hidden[0],\n\t\t\t\t\t\t\tfragments: changedFragments.hidden\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif( changedFragments.shown.length ) {\n\t\t\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\t\t\ttype: 'fragmentshown',\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tfragment: changedFragments.shown[0],\n\t\t\t\t\t\t\tfragments: changedFragments.shown\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tthis.Reveal.controls.update();\n\t\t\t\tthis.Reveal.progress.update();\n\n\t\t\t\tif( this.Reveal.getConfig().fragmentInURL ) {\n\t\t\t\t\tthis.Reveal.location.writeURL();\n\t\t\t\t}\n\n\t\t\t\treturn !!( changedFragments.shown.length || changedFragments.hidden.length );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\t/**\n\t * Navigate to the next slide fragment.\n\t *\n\t * @return {boolean} true if there was a next fragment,\n\t * false otherwise\n\t */\n\tnext() {\n\n\t\treturn this.goto( null, 1 );\n\n\t}\n\n\t/**\n\t * Navigate to the previous slide fragment.\n\t *\n\t * @return {boolean} true if there was a previous fragment,\n\t * false otherwise\n\t */\n\tprev() {\n\n\t\treturn this.goto( null, -1 );\n\n\t}\n\n}","import { SLIDES_SELECTOR } from '../utils/constants.js'\nimport { extend, queryAll, transformElement } from '../utils/util.js'\n\n/**\n * Handles all logic related to the overview mode\n * (birds-eye view of all slides).\n */\nexport default class Overview {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.active = false;\n\n\t\tthis.onSlideClicked = this.onSlideClicked.bind( this );\n\n\t}\n\n\t/**\n\t * Displays the overview of slides (quick nav) by scaling\n\t * down and arranging all slide elements.\n\t */\n\tactivate() {\n\n\t\t// Only proceed if enabled in config\n\t\tif( this.Reveal.getConfig().overview && !this.isActive() ) {\n\n\t\t\tthis.active = true;\n\n\t\t\tthis.Reveal.getRevealElement().classList.add( 'overview' );\n\n\t\t\t// Don't auto-slide while in overview mode\n\t\t\tthis.Reveal.cancelAutoSlide();\n\n\t\t\t// Move the backgrounds element into the slide container to\n\t\t\t// that the same scaling is applied\n\t\t\tthis.Reveal.getSlidesElement().appendChild( this.Reveal.getBackgroundsElement() );\n\n\t\t\t// Clicking on an overview slide navigates to it\n\t\t\tqueryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ).forEach( slide => {\n\t\t\t\tif( !slide.classList.contains( 'stack' ) ) {\n\t\t\t\t\tslide.addEventListener( 'click', this.onSlideClicked, true );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// Calculate slide sizes\n\t\t\tconst margin = 70;\n\t\t\tconst slideSize = this.Reveal.getComputedSlideSize();\n\t\t\tthis.overviewSlideWidth = slideSize.width + margin;\n\t\t\tthis.overviewSlideHeight = slideSize.height + margin;\n\n\t\t\t// Reverse in RTL mode\n\t\t\tif( this.Reveal.getConfig().rtl ) {\n\t\t\t\tthis.overviewSlideWidth = -this.overviewSlideWidth;\n\t\t\t}\n\n\t\t\tthis.Reveal.updateSlidesVisibility();\n\n\t\t\tthis.layout();\n\t\t\tthis.update();\n\n\t\t\tthis.Reveal.layout();\n\n\t\t\tconst indices = this.Reveal.getIndices();\n\n\t\t\t// Notify observers of the overview showing\n\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\ttype: 'overviewshown',\n\t\t\t\tdata: {\n\t\t\t\t\t'indexh': indices.h,\n\t\t\t\t\t'indexv': indices.v,\n\t\t\t\t\t'currentSlide': this.Reveal.getCurrentSlide()\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Uses CSS transforms to position all slides in a grid for\n\t * display inside of the overview mode.\n\t */\n\tlayout() {\n\n\t\t// Layout slides\n\t\tthis.Reveal.getHorizontalSlides().forEach( ( hslide, h ) => {\n\t\t\thslide.setAttribute( 'data-index-h', h );\n\t\t\ttransformElement( hslide, 'translate3d(' + ( h * this.overviewSlideWidth ) + 'px, 0, 0)' );\n\n\t\t\tif( hslide.classList.contains( 'stack' ) ) {\n\n\t\t\t\tqueryAll( hslide, 'section' ).forEach( ( vslide, v ) => {\n\t\t\t\t\tvslide.setAttribute( 'data-index-h', h );\n\t\t\t\t\tvslide.setAttribute( 'data-index-v', v );\n\n\t\t\t\t\ttransformElement( vslide, 'translate3d(0, ' + ( v * this.overviewSlideHeight ) + 'px, 0)' );\n\t\t\t\t} );\n\n\t\t\t}\n\t\t} );\n\n\t\t// Layout slide backgrounds\n\t\tArray.from( this.Reveal.getBackgroundsElement().childNodes ).forEach( ( hbackground, h ) => {\n\t\t\ttransformElement( hbackground, 'translate3d(' + ( h * this.overviewSlideWidth ) + 'px, 0, 0)' );\n\n\t\t\tqueryAll( hbackground, '.slide-background' ).forEach( ( vbackground, v ) => {\n\t\t\t\ttransformElement( vbackground, 'translate3d(0, ' + ( v * this.overviewSlideHeight ) + 'px, 0)' );\n\t\t\t} );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Moves the overview viewport to the current slides.\n\t * Called each time the current slide changes.\n\t */\n\tupdate() {\n\n\t\tconst vmin = Math.min( window.innerWidth, window.innerHeight );\n\t\tconst scale = Math.max( vmin / 5, 150 ) / vmin;\n\t\tconst indices = this.Reveal.getIndices();\n\n\t\tthis.Reveal.transformSlides( {\n\t\t\toverview: [\n\t\t\t\t'scale('+ scale +')',\n\t\t\t\t'translateX('+ ( -indices.h * this.overviewSlideWidth ) +'px)',\n\t\t\t\t'translateY('+ ( -indices.v * this.overviewSlideHeight ) +'px)'\n\t\t\t].join( ' ' )\n\t\t} );\n\n\t}\n\n\t/**\n\t * Exits the slide overview and enters the currently\n\t * active slide.\n\t */\n\tdeactivate() {\n\n\t\t// Only proceed if enabled in config\n\t\tif( this.Reveal.getConfig().overview ) {\n\n\t\t\tthis.active = false;\n\n\t\t\tthis.Reveal.getRevealElement().classList.remove( 'overview' );\n\n\t\t\t// Temporarily add a class so that transitions can do different things\n\t\t\t// depending on whether they are exiting/entering overview, or just\n\t\t\t// moving from slide to slide\n\t\t\tthis.Reveal.getRevealElement().classList.add( 'overview-deactivating' );\n\n\t\t\tsetTimeout( () => {\n\t\t\t\tthis.Reveal.getRevealElement().classList.remove( 'overview-deactivating' );\n\t\t\t}, 1 );\n\n\t\t\t// Move the background element back out\n\t\t\tthis.Reveal.getRevealElement().appendChild( this.Reveal.getBackgroundsElement() );\n\n\t\t\t// Clean up changes made to slides\n\t\t\tqueryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ).forEach( slide => {\n\t\t\t\ttransformElement( slide, '' );\n\n\t\t\t\tslide.removeEventListener( 'click', this.onSlideClicked, true );\n\t\t\t} );\n\n\t\t\t// Clean up changes made to backgrounds\n\t\t\tqueryAll( this.Reveal.getBackgroundsElement(), '.slide-background' ).forEach( background => {\n\t\t\t\ttransformElement( background, '' );\n\t\t\t} );\n\n\t\t\tthis.Reveal.transformSlides( { overview: '' } );\n\n\t\t\tconst indices = this.Reveal.getIndices();\n\n\t\t\tthis.Reveal.slide( indices.h, indices.v );\n\t\t\tthis.Reveal.layout();\n\t\t\tthis.Reveal.cueAutoSlide();\n\n\t\t\t// Notify observers of the overview hiding\n\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\ttype: 'overviewhidden',\n\t\t\t\tdata: {\n\t\t\t\t\t'indexh': indices.h,\n\t\t\t\t\t'indexv': indices.v,\n\t\t\t\t\t'currentSlide': this.Reveal.getCurrentSlide()\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\t}\n\n\t/**\n\t * Toggles the slide overview mode on and off.\n\t *\n\t * @param {Boolean} [override] Flag which overrides the\n\t * toggle logic and forcibly sets the desired state. True means\n\t * overview is open, false means it's closed.\n\t */\n\ttoggle( override ) {\n\n\t\tif( typeof override === 'boolean' ) {\n\t\t\toverride ? this.activate() : this.deactivate();\n\t\t}\n\t\telse {\n\t\t\tthis.isActive() ? this.deactivate() : this.activate();\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks if the overview is currently active.\n\t *\n\t * @return {Boolean} true if the overview is active,\n\t * false otherwise\n\t */\n\tisActive() {\n\n\t\treturn this.active;\n\n\t}\n\n\t/**\n\t * Invoked when a slide is and we're in the overview.\n\t *\n\t * @param {object} event\n\t */\n\tonSlideClicked( event ) {\n\n\t\tif( this.isActive() ) {\n\t\t\tevent.preventDefault();\n\n\t\t\tlet element = event.target;\n\n\t\t\twhile( element && !element.nodeName.match( /section/gi ) ) {\n\t\t\t\telement = element.parentNode;\n\t\t\t}\n\n\t\t\tif( element && !element.classList.contains( 'disabled' ) ) {\n\n\t\t\t\tthis.deactivate();\n\n\t\t\t\tif( element.nodeName.match( /section/gi ) ) {\n\t\t\t\t\tlet h = parseInt( element.getAttribute( 'data-index-h' ), 10 ),\n\t\t\t\t\t\tv = parseInt( element.getAttribute( 'data-index-v' ), 10 );\n\n\t\t\t\t\tthis.Reveal.slide( h, v );\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t}\n\n}","import { enterFullscreen } from '../utils/util.js'\n\n/**\n * Handles all reveal.js keyboard interactions.\n */\nexport default class Keyboard {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\t// A key:value map of keyboard keys and descriptions of\n\t\t// the actions they trigger\n\t\tthis.shortcuts = {};\n\n\t\t// Holds custom key code mappings\n\t\tthis.bindings = {};\n\n\t\tthis.onDocumentKeyDown = this.onDocumentKeyDown.bind( this );\n\t\tthis.onDocumentKeyPress = this.onDocumentKeyPress.bind( this );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tif( config.navigationMode === 'linear' ) {\n\t\t\tthis.shortcuts['→ , ↓ , SPACE , N , L , J'] = 'Next slide';\n\t\t\tthis.shortcuts['← , ↑ , P , H , K'] = 'Previous slide';\n\t\t}\n\t\telse {\n\t\t\tthis.shortcuts['N , SPACE'] = 'Next slide';\n\t\t\tthis.shortcuts['P'] = 'Previous slide';\n\t\t\tthis.shortcuts['← , H'] = 'Navigate left';\n\t\t\tthis.shortcuts['→ , L'] = 'Navigate right';\n\t\t\tthis.shortcuts['↑ , K'] = 'Navigate up';\n\t\t\tthis.shortcuts['↓ , J'] = 'Navigate down';\n\t\t}\n\n\t\tthis.shortcuts['Home , Shift ←'] = 'First slide';\n\t\tthis.shortcuts['End , Shift →'] = 'Last slide';\n\t\tthis.shortcuts['B , .'] = 'Pause';\n\t\tthis.shortcuts['F'] = 'Fullscreen';\n\t\tthis.shortcuts['ESC, O'] = 'Slide overview';\n\n\t}\n\n\t/**\n\t * Starts listening for keyboard events.\n\t */\n\tbind() {\n\n\t\tdocument.addEventListener( 'keydown', this.onDocumentKeyDown, false );\n\t\tdocument.addEventListener( 'keypress', this.onDocumentKeyPress, false );\n\n\t}\n\n\t/**\n\t * Stops listening for keyboard events.\n\t */\n\tunbind() {\n\n\t\tdocument.removeEventListener( 'keydown', this.onDocumentKeyDown, false );\n\t\tdocument.removeEventListener( 'keypress', this.onDocumentKeyPress, false );\n\n\t}\n\n\t/**\n\t * Add a custom key binding with optional description to\n\t * be added to the help screen.\n\t */\n\taddKeyBinding( binding, callback ) {\n\n\t\tif( typeof binding === 'object' && binding.keyCode ) {\n\t\t\tthis.bindings[binding.keyCode] = {\n\t\t\t\tcallback: callback,\n\t\t\t\tkey: binding.key,\n\t\t\t\tdescription: binding.description\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\tthis.bindings[binding] = {\n\t\t\t\tcallback: callback,\n\t\t\t\tkey: null,\n\t\t\t\tdescription: null\n\t\t\t};\n\t\t}\n\n\t}\n\n\t/**\n\t * Removes the specified custom key binding.\n\t */\n\tremoveKeyBinding( keyCode ) {\n\n\t\tdelete this.bindings[keyCode];\n\n\t}\n\n\t/**\n\t * Programmatically triggers a keyboard event\n\t *\n\t * @param {int} keyCode\n\t */\n\ttriggerKey( keyCode ) {\n\n\t\tthis.onDocumentKeyDown( { keyCode } );\n\n\t}\n\n\t/**\n\t * Registers a new shortcut to include in the help overlay\n\t *\n\t * @param {String} key\n\t * @param {String} value\n\t */\n\tregisterKeyboardShortcut( key, value ) {\n\n\t\tthis.shortcuts[key] = value;\n\n\t}\n\n\t/**\n\t * Handler for the document level 'keypress' event.\n\t *\n\t * @param {object} event\n\t */\n\tonDocumentKeyPress( event ) {\n\n\t\t// Check if the pressed key is question mark\n\t\tif( event.shiftKey && event.charCode === 63 ) {\n\t\t\tthis.Reveal.toggleHelp();\n\t\t}\n\n\t}\n\n\t/**\n\t * Handler for the document level 'keydown' event.\n\t *\n\t * @param {object} event\n\t */\n\tonDocumentKeyDown( event ) {\n\n\t\tlet config = this.Reveal.getConfig();\n\n\t\t// If there's a condition specified and it returns false,\n\t\t// ignore this event\n\t\tif( typeof config.keyboardCondition === 'function' && config.keyboardCondition(event) === false ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Shorthand\n\t\tlet keyCode = event.keyCode;\n\n\t\t// Remember if auto-sliding was paused so we can toggle it\n\t\tlet autoSlideWasPaused = !this.Reveal.isAutoSliding();\n\n\t\tthis.Reveal.onUserInput( event );\n\n\t\t// Is there a focused element that could be using the keyboard?\n\t\tlet activeElementIsCE = document.activeElement && document.activeElement.contentEditable !== 'inherit';\n\t\tlet activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName );\n\t\tlet activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className);\n\n\t\t// Whitelist specific modified + keycode combinations\n\t\tlet prevSlideShortcut = event.shiftKey && event.keyCode === 32;\n\t\tlet firstSlideShortcut = event.shiftKey && keyCode === 37;\n\t\tlet lastSlideShortcut = event.shiftKey && keyCode === 39;\n\n\t\t// Prevent all other events when a modifier is pressed\n\t\tlet unusedModifier = \t!prevSlideShortcut && !firstSlideShortcut && !lastSlideShortcut &&\n\t\t\t\t\t\t\t\t( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey );\n\n\t\t// Disregard the event if there's a focused element or a\n\t\t// keyboard modifier key is present\n\t\tif( activeElementIsCE || activeElementIsInput || activeElementIsNotes || unusedModifier ) return;\n\n\t\t// While paused only allow resume keyboard events; 'b', 'v', '.'\n\t\tlet resumeKeyCodes = [66,86,190,191];\n\t\tlet key;\n\n\t\t// Custom key bindings for togglePause should be able to resume\n\t\tif( typeof config.keyboard === 'object' ) {\n\t\t\tfor( key in config.keyboard ) {\n\t\t\t\tif( config.keyboard[key] === 'togglePause' ) {\n\t\t\t\t\tresumeKeyCodes.push( parseInt( key, 10 ) );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif( this.Reveal.isPaused() && resumeKeyCodes.indexOf( keyCode ) === -1 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Use linear navigation if we're configured to OR if\n\t\t// the presentation is one-dimensional\n\t\tlet useLinearMode = config.navigationMode === 'linear' || !this.Reveal.hasHorizontalSlides() || !this.Reveal.hasVerticalSlides();\n\n\t\tlet triggered = false;\n\n\t\t// 1. User defined key bindings\n\t\tif( typeof config.keyboard === 'object' ) {\n\n\t\t\tfor( key in config.keyboard ) {\n\n\t\t\t\t// Check if this binding matches the pressed key\n\t\t\t\tif( parseInt( key, 10 ) === keyCode ) {\n\n\t\t\t\t\tlet value = config.keyboard[ key ];\n\n\t\t\t\t\t// Callback function\n\t\t\t\t\tif( typeof value === 'function' ) {\n\t\t\t\t\t\tvalue.apply( null, [ event ] );\n\t\t\t\t\t}\n\t\t\t\t\t// String shortcuts to reveal.js API\n\t\t\t\t\telse if( typeof value === 'string' && typeof this.Reveal[ value ] === 'function' ) {\n\t\t\t\t\t\tthis.Reveal[ value ].call();\n\t\t\t\t\t}\n\n\t\t\t\t\ttriggered = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// 2. Registered custom key bindings\n\t\tif( triggered === false ) {\n\n\t\t\tfor( key in this.bindings ) {\n\n\t\t\t\t// Check if this binding matches the pressed key\n\t\t\t\tif( parseInt( key, 10 ) === keyCode ) {\n\n\t\t\t\t\tlet action = this.bindings[ key ].callback;\n\n\t\t\t\t\t// Callback function\n\t\t\t\t\tif( typeof action === 'function' ) {\n\t\t\t\t\t\taction.apply( null, [ event ] );\n\t\t\t\t\t}\n\t\t\t\t\t// String shortcuts to reveal.js API\n\t\t\t\t\telse if( typeof action === 'string' && typeof this.Reveal[ action ] === 'function' ) {\n\t\t\t\t\t\tthis.Reveal[ action ].call();\n\t\t\t\t\t}\n\n\t\t\t\t\ttriggered = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 3. System defined key bindings\n\t\tif( triggered === false ) {\n\n\t\t\t// Assume true and try to prove false\n\t\t\ttriggered = true;\n\n\t\t\t// P, PAGE UP\n\t\t\tif( keyCode === 80 || keyCode === 33 ) {\n\t\t\t\tthis.Reveal.prev();\n\t\t\t}\n\t\t\t// N, PAGE DOWN\n\t\t\telse if( keyCode === 78 || keyCode === 34 ) {\n\t\t\t\tthis.Reveal.next();\n\t\t\t}\n\t\t\t// H, LEFT\n\t\t\telse if( keyCode === 72 || keyCode === 37 ) {\n\t\t\t\tif( firstSlideShortcut ) {\n\t\t\t\t\tthis.Reveal.slide( 0 );\n\t\t\t\t}\n\t\t\t\telse if( !this.Reveal.overview.isActive() && useLinearMode ) {\n\t\t\t\t\tthis.Reveal.prev();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.left();\n\t\t\t\t}\n\t\t\t}\n\t\t\t// L, RIGHT\n\t\t\telse if( keyCode === 76 || keyCode === 39 ) {\n\t\t\t\tif( lastSlideShortcut ) {\n\t\t\t\t\tthis.Reveal.slide( Number.MAX_VALUE );\n\t\t\t\t}\n\t\t\t\telse if( !this.Reveal.overview.isActive() && useLinearMode ) {\n\t\t\t\t\tthis.Reveal.next();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.right();\n\t\t\t\t}\n\t\t\t}\n\t\t\t// K, UP\n\t\t\telse if( keyCode === 75 || keyCode === 38 ) {\n\t\t\t\tif( !this.Reveal.overview.isActive() && useLinearMode ) {\n\t\t\t\t\tthis.Reveal.prev();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.up();\n\t\t\t\t}\n\t\t\t}\n\t\t\t// J, DOWN\n\t\t\telse if( keyCode === 74 || keyCode === 40 ) {\n\t\t\t\tif( !this.Reveal.overview.isActive() && useLinearMode ) {\n\t\t\t\t\tthis.Reveal.next();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.down();\n\t\t\t\t}\n\t\t\t}\n\t\t\t// HOME\n\t\t\telse if( keyCode === 36 ) {\n\t\t\t\tthis.Reveal.slide( 0 );\n\t\t\t}\n\t\t\t// END\n\t\t\telse if( keyCode === 35 ) {\n\t\t\t\tthis.Reveal.slide( Number.MAX_VALUE );\n\t\t\t}\n\t\t\t// SPACE\n\t\t\telse if( keyCode === 32 ) {\n\t\t\t\tif( this.Reveal.overview.isActive() ) {\n\t\t\t\t\tthis.Reveal.overview.deactivate();\n\t\t\t\t}\n\t\t\t\tif( event.shiftKey ) {\n\t\t\t\t\tthis.Reveal.prev();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.next();\n\t\t\t\t}\n\t\t\t}\n\t\t\t// TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS \"BLACK SCREEN\" BUTTON\n\t\t\telse if( keyCode === 58 || keyCode === 59 || keyCode === 66 || keyCode === 86 || keyCode === 190 || keyCode === 191 ) {\n\t\t\t\tthis.Reveal.togglePause();\n\t\t\t}\n\t\t\t// F\n\t\t\telse if( keyCode === 70 ) {\n\t\t\t\tenterFullscreen();\n\t\t\t}\n\t\t\t// A\n\t\t\telse if( keyCode === 65 ) {\n\t\t\t\tif ( config.autoSlideStoppable ) {\n\t\t\t\t\tthis.Reveal.toggleAutoSlide( autoSlideWasPaused );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttriggered = false;\n\t\t\t}\n\n\t\t}\n\n\t\t// If the input resulted in a triggered action we should prevent\n\t\t// the browsers default behavior\n\t\tif( triggered ) {\n\t\t\tevent.preventDefault && event.preventDefault();\n\t\t}\n\t\t// ESC or O key\n\t\telse if( keyCode === 27 || keyCode === 79 ) {\n\t\t\tif( this.Reveal.closeOverlay() === false ) {\n\t\t\t\tthis.Reveal.overview.toggle();\n\t\t\t}\n\n\t\t\tevent.preventDefault && event.preventDefault();\n\t\t}\n\n\t\t// If auto-sliding is enabled we need to cue up\n\t\t// another timeout\n\t\tthis.Reveal.cueAutoSlide();\n\n\t}\n\n}","import { supportsHistoryAPI } from '../utils/device.js'\n\n/**\n * Reads and writes the URL based on reveal.js' current state.\n */\nexport default class Location {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\t// Delays updates to the URL due to a Chrome thumbnailer bug\n\t\tthis.writeURLTimeout = 0;\n\n\t}\n\n\t/**\n\t * Reads the current URL (hash) and navigates accordingly.\n\t */\n\treadURL() {\n\n\t\tlet config = this.Reveal.getConfig();\n\t\tlet indices = this.Reveal.getIndices();\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\n\t\tlet hash = window.location.hash;\n\n\t\t// Attempt to parse the hash as either an index or name\n\t\tlet bits = hash.slice( 2 ).split( '/' ),\n\t\t\tname = hash.replace( /#|\\//gi, '' );\n\n\t\t// If the first bit is not fully numeric and there is a name we\n\t\t// can assume that this is a named link\n\t\tif( !/^[0-9]*$/.test( bits[0] ) && name.length ) {\n\t\t\tlet element;\n\n\t\t\t// Ensure the named link is a valid HTML ID attribute\n\t\t\ttry {\n\t\t\t\telement = document.getElementById( decodeURIComponent( name ) );\n\t\t\t}\n\t\t\tcatch ( error ) { }\n\n\t\t\t// Ensure that we're not already on a slide with the same name\n\t\t\tlet isSameNameAsCurrentSlide = currentSlide ? currentSlide.getAttribute( 'id' ) === name : false;\n\n\t\t\tif( element ) {\n\t\t\t\t// If the slide exists and is not the current slide...\n\t\t\t\tif ( !isSameNameAsCurrentSlide ) {\n\t\t\t\t\t// ...find the position of the named slide and navigate to it\n\t\t\t\t\tlet elementIndex = this.Reveal.getIndices(element);\n\t\t\t\t\tthis.Reveal.slide(elementIndex.h, elementIndex.v);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If the slide doesn't exist, navigate to the current slide\n\t\t\telse {\n\t\t\t\tthis.Reveal.slide( indices.h || 0, indices.v || 0 );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tlet hashIndexBase = config.hashOneBasedIndex ? 1 : 0;\n\n\t\t\t// Read the index components of the hash\n\t\t\tlet h = ( parseInt( bits[0], 10 ) - hashIndexBase ) || 0,\n\t\t\t\tv = ( parseInt( bits[1], 10 ) - hashIndexBase ) || 0,\n\t\t\t\tf;\n\n\t\t\tif( config.fragmentInURL ) {\n\t\t\t\tf = parseInt( bits[2], 10 );\n\t\t\t\tif( isNaN( f ) ) {\n\t\t\t\t\tf = undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif( h !== indices.h || v !== indices.v || f !== undefined ) {\n\t\t\t\tthis.Reveal.slide( h, v, f );\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Updates the page URL (hash) to reflect the current\n\t * state.\n\t *\n\t * @param {number} delay The time in ms to wait before\n\t * writing the hash\n\t */\n\twriteURL( delay ) {\n\n\t\tlet config = this.Reveal.getConfig();\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\n\t\t// Make sure there's never more than one timeout running\n\t\tclearTimeout( this.writeURLTimeout );\n\n\t\t// If a delay is specified, timeout this call\n\t\tif( typeof delay === 'number' ) {\n\t\t\tthis.writeURLTimeout = setTimeout( this.writeURL, delay );\n\t\t}\n\t\telse if( currentSlide ) {\n\t\t\t// If we're configured to push to history OR the history\n\t\t\t// API is not avaialble.\n\t\t\tif( config.history || supportsHistoryAPI === false ) {\n\t\t\t\twindow.location.hash = this.getHash();\n\t\t\t}\n\t\t\t// If we're configured to reflect the current slide in the\n\t\t\t// URL without pushing to history.\n\t\t\telse if( config.hash ) {\n\t\t\t\twindow.history.replaceState( null, null, '#' + this.getHash() );\n\t\t\t}\n\t\t\t// If history and hash are both disabled, a hash may still\n\t\t\t// be added to the URL by clicking on a href with a hash\n\t\t\t// target. Counter this by always removing the hash.\n\t\t\telse {\n\t\t\t\twindow.history.replaceState( null, null, window.location.pathname + window.location.search );\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Return a hash URL that will resolve to the given slide location.\n\t *\n\t * @param {HTMLElement} [slide=currentSlide] The slide to link to\n\t */\n\tgetHash( slide ) {\n\n\t\tlet url = '/';\n\n\t\t// Attempt to create a named link based on the slide's ID\n\t\tlet s = slide || this.Reveal.getCurrentSlide();\n\t\tlet id = s ? s.getAttribute( 'id' ) : null;\n\t\tif( id ) {\n\t\t\tid = encodeURIComponent( id );\n\t\t}\n\n\t\tlet index = this.Reveal.getIndices( slide );\n\t\tif( !this.Reveal.getConfig().fragmentInURL ) {\n\t\t\tindex.f = undefined;\n\t\t}\n\n\t\t// If the current slide has an ID, use that as a named link,\n\t\t// but we don't support named links with a fragment index\n\t\tif( typeof id === 'string' && id.length && index.f === undefined ) {\n\t\t\turl = '/' + id;\n\t\t}\n\t\t// Otherwise use the /h/v index\n\t\telse {\n\t\t\tlet hashIndexBase = this.Reveal.getConfig().hashOneBasedIndex ? 1 : 0;\n\t\t\tif( index.h > 0 || index.v > 0 || index.f !== undefined ) url += index.h + hashIndexBase;\n\t\t\tif( index.v > 0 || index.f !== undefined ) url += '/' + (index.v + hashIndexBase );\n\t\t\tif( index.f !== undefined ) url += '/' + index.f;\n\t\t}\n\n\t\treturn url;\n\n\t}\n\n}","import { queryAll } from '../utils/util.js'\nimport { isAndroid } from '../utils/device.js'\n\n/**\n * Manages our presentation controls. This includes both\n * the built-in control arrows as well as event monitoring\n * of any elements within the presentation with either of the\n * following helper classes:\n * - .navigate-up\n * - .navigate-right\n * - .navigate-down\n * - .navigate-left\n * - .navigate-next\n * - .navigate-prev\n */\nexport default class Controls {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.onNavigateLeftClicked = this.onNavigateLeftClicked.bind( this );\n\t\tthis.onNavigateRightClicked = this.onNavigateRightClicked.bind( this );\n\t\tthis.onNavigateUpClicked = this.onNavigateUpClicked.bind( this );\n\t\tthis.onNavigateDownClicked = this.onNavigateDownClicked.bind( this );\n\t\tthis.onNavigatePrevClicked = this.onNavigatePrevClicked.bind( this );\n\t\tthis.onNavigateNextClicked = this.onNavigateNextClicked.bind( this );\n\n\t}\n\n\trender() {\n\n\t\tconst rtl = this.Reveal.getConfig().rtl;\n\t\tconst revealElement = this.Reveal.getRevealElement();\n\n\t\tthis.element = document.createElement( 'aside' );\n\t\tthis.element.className = 'controls';\n\t\tthis.element.innerHTML =\n\t\t\t`<button class=\"navigate-left\" aria-label=\"${ rtl ? 'next slide' : 'previous slide' }\"><div class=\"controls-arrow\"></div></button>\n\t\t\t<button class=\"navigate-right\" aria-label=\"${ rtl ? 'previous slide' : 'next slide' }\"><div class=\"controls-arrow\"></div></button>\n\t\t\t<button class=\"navigate-up\" aria-label=\"above slide\"><div class=\"controls-arrow\"></div></button>\n\t\t\t<button class=\"navigate-down\" aria-label=\"below slide\"><div class=\"controls-arrow\"></div></button>`;\n\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t\t// There can be multiple instances of controls throughout the page\n\t\tthis.controlsLeft = queryAll( revealElement, '.navigate-left' );\n\t\tthis.controlsRight = queryAll( revealElement, '.navigate-right' );\n\t\tthis.controlsUp = queryAll( revealElement, '.navigate-up' );\n\t\tthis.controlsDown = queryAll( revealElement, '.navigate-down' );\n\t\tthis.controlsPrev = queryAll( revealElement, '.navigate-prev' );\n\t\tthis.controlsNext = queryAll( revealElement, '.navigate-next' );\n\n\t\t// The left, right and down arrows in the standard reveal.js controls\n\t\tthis.controlsRightArrow = this.element.querySelector( '.navigate-right' );\n\t\tthis.controlsLeftArrow = this.element.querySelector( '.navigate-left' );\n\t\tthis.controlsDownArrow = this.element.querySelector( '.navigate-down' );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tthis.element.style.display = config.controls ? 'block' : 'none';\n\n\t\tthis.element.setAttribute( 'data-controls-layout', config.controlsLayout );\n\t\tthis.element.setAttribute( 'data-controls-back-arrows', config.controlsBackArrows );\n\n\t}\n\n\tbind() {\n\n\t\t// Listen to both touch and click events, in case the device\n\t\t// supports both\n\t\tlet pointerEvents = [ 'touchstart', 'click' ];\n\n\t\t// Only support touch for Android, fixes double navigations in\n\t\t// stock browser\n\t\tif( isAndroid ) {\n\t\t\tpointerEvents = [ 'touchstart' ];\n\t\t}\n\n\t\tpointerEvents.forEach( eventName => {\n\t\t\tthis.controlsLeft.forEach( el => el.addEventListener( eventName, this.onNavigateLeftClicked, false ) );\n\t\t\tthis.controlsRight.forEach( el => el.addEventListener( eventName, this.onNavigateRightClicked, false ) );\n\t\t\tthis.controlsUp.forEach( el => el.addEventListener( eventName, this.onNavigateUpClicked, false ) );\n\t\t\tthis.controlsDown.forEach( el => el.addEventListener( eventName, this.onNavigateDownClicked, false ) );\n\t\t\tthis.controlsPrev.forEach( el => el.addEventListener( eventName, this.onNavigatePrevClicked, false ) );\n\t\t\tthis.controlsNext.forEach( el => el.addEventListener( eventName, this.onNavigateNextClicked, false ) );\n\t\t} );\n\n\t}\n\n\tunbind() {\n\n\t\t[ 'touchstart', 'click' ].forEach( eventName => {\n\t\t\tthis.controlsLeft.forEach( el => el.removeEventListener( eventName, this.onNavigateLeftClicked, false ) );\n\t\t\tthis.controlsRight.forEach( el => el.removeEventListener( eventName, this.onNavigateRightClicked, false ) );\n\t\t\tthis.controlsUp.forEach( el => el.removeEventListener( eventName, this.onNavigateUpClicked, false ) );\n\t\t\tthis.controlsDown.forEach( el => el.removeEventListener( eventName, this.onNavigateDownClicked, false ) );\n\t\t\tthis.controlsPrev.forEach( el => el.removeEventListener( eventName, this.onNavigatePrevClicked, false ) );\n\t\t\tthis.controlsNext.forEach( el => el.removeEventListener( eventName, this.onNavigateNextClicked, false ) );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Updates the state of all control/navigation arrows.\n\t */\n\tupdate() {\n\n\t\tlet routes = this.Reveal.availableRoutes();\n\n\t\t// Remove the 'enabled' class from all directions\n\t\t[...this.controlsLeft, ...this.controlsRight, ...this.controlsUp, ...this.controlsDown, ...this.controlsPrev, ...this.controlsNext].forEach( node => {\n\t\t\tnode.classList.remove( 'enabled', 'fragmented' );\n\n\t\t\t// Set 'disabled' attribute on all directions\n\t\t\tnode.setAttribute( 'disabled', 'disabled' );\n\t\t} );\n\n\t\t// Add the 'enabled' class to the available routes; remove 'disabled' attribute to enable buttons\n\t\tif( routes.left ) this.controlsLeft.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\tif( routes.right ) this.controlsRight.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\tif( routes.up ) this.controlsUp.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\tif( routes.down ) this.controlsDown.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\n\t\t// Prev/next buttons\n\t\tif( routes.left || routes.up ) this.controlsPrev.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\tif( routes.right || routes.down ) this.controlsNext.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\n\t\t// Highlight fragment directions\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\t\tif( currentSlide ) {\n\n\t\t\tlet fragmentsRoutes = this.Reveal.fragments.availableRoutes();\n\n\t\t\t// Always apply fragment decorator to prev/next buttons\n\t\t\tif( fragmentsRoutes.prev ) this.controlsPrev.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\tif( fragmentsRoutes.next ) this.controlsNext.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\n\t\t\t// Apply fragment decorators to directional buttons based on\n\t\t\t// what slide axis they are in\n\t\t\tif( this.Reveal.isVerticalSlide( currentSlide ) ) {\n\t\t\t\tif( fragmentsRoutes.prev ) this.controlsUp.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\t\tif( fragmentsRoutes.next ) this.controlsDown.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif( fragmentsRoutes.prev ) this.controlsLeft.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\t\tif( fragmentsRoutes.next ) this.controlsRight.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\t}\n\n\t\t}\n\n\t\tif( this.Reveal.getConfig().controlsTutorial ) {\n\n\t\t\tlet indices = this.Reveal.getIndices();\n\n\t\t\t// Highlight control arrows with an animation to ensure\n\t\t\t// that the viewer knows how to navigate\n\t\t\tif( !this.Reveal.hasNavigatedVertically() && routes.down ) {\n\t\t\t\tthis.controlsDownArrow.classList.add( 'highlight' );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.controlsDownArrow.classList.remove( 'highlight' );\n\n\t\t\t\tif( this.Reveal.getConfig().rtl ) {\n\n\t\t\t\t\tif( !this.Reveal.hasNavigatedHorizontally() && routes.left && indices.v === 0 ) {\n\t\t\t\t\t\tthis.controlsLeftArrow.classList.add( 'highlight' );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.controlsLeftArrow.classList.remove( 'highlight' );\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif( !this.Reveal.hasNavigatedHorizontally() && routes.right && indices.v === 0 ) {\n\t\t\t\t\t\tthis.controlsRightArrow.classList.add( 'highlight' );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.controlsRightArrow.classList.remove( 'highlight' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Event handlers for navigation control buttons.\n\t */\n\tonNavigateLeftClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tif( this.Reveal.getConfig().navigationMode === 'linear' ) {\n\t\t\tthis.Reveal.prev();\n\t\t}\n\t\telse {\n\t\t\tthis.Reveal.left();\n\t\t}\n\n\t}\n\n\tonNavigateRightClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tif( this.Reveal.getConfig().navigationMode === 'linear' ) {\n\t\t\tthis.Reveal.next();\n\t\t}\n\t\telse {\n\t\t\tthis.Reveal.right();\n\t\t}\n\n\t}\n\n\tonNavigateUpClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tthis.Reveal.up();\n\n\t}\n\n\tonNavigateDownClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tthis.Reveal.down();\n\n\t}\n\n\tonNavigatePrevClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tthis.Reveal.prev();\n\n\t}\n\n\tonNavigateNextClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tthis.Reveal.next();\n\n\t}\n\n\n}","/**\n * Creates a visual progress bar for the presentation.\n */\nexport default class Progress {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.onProgressClicked = this.onProgressClicked.bind( this );\n\n\t}\n\n\trender() {\n\n\t\tthis.element = document.createElement( 'div' );\n\t\tthis.element.className = 'progress';\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t\tthis.bar = document.createElement( 'span' );\n\t\tthis.element.appendChild( this.bar );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tthis.element.style.display = config.progress ? 'block' : 'none';\n\n\t}\n\n\tbind() {\n\n\t\tif( this.Reveal.getConfig().progress && this.element ) {\n\t\t\tthis.element.addEventListener( 'click', this.onProgressClicked, false );\n\t\t}\n\n\t}\n\n\tunbind() {\n\n\t\tif ( this.Reveal.getConfig().progress && this.element ) {\n\t\t\tthis.element.removeEventListener( 'click', this.onProgressClicked, false );\n\t\t}\n\n\t}\n\n\t/**\n\t * Updates the progress bar to reflect the current slide.\n\t */\n\tupdate() {\n\n\t\t// Update progress if enabled\n\t\tif( this.Reveal.getConfig().progress && this.bar ) {\n\n\t\t\tthis.bar.style.width = this.Reveal.getProgress() * this.getMaxWidth() + 'px';\n\n\t\t}\n\n\t}\n\n\tgetMaxWidth() {\n\n\t\treturn this.Reveal.getRevealElement().offsetWidth;\n\n\t}\n\n\t/**\n\t * Clicking on the progress bar results in a navigation to the\n\t * closest approximate horizontal slide using this equation:\n\t *\n\t * ( clickX / presentationWidth ) * numberOfSlides\n\t *\n\t * @param {object} event\n\t */\n\tonProgressClicked( event ) {\n\n\t\tthis.Reveal.onUserInput( event );\n\n\t\tevent.preventDefault();\n\n\t\tlet slidesTotal = this.Reveal.getHorizontalSlides().length;\n\t\tlet slideIndex = Math.floor( ( event.clientX / this.getMaxWidth() ) * slidesTotal );\n\n\t\tif( this.Reveal.getConfig().rtl ) {\n\t\t\tslideIndex = slidesTotal - slideIndex;\n\t\t}\n\n\t\tthis.Reveal.slide( slideIndex );\n\n\t}\n\n\n}","/**\n * Handles hiding of the pointer/cursor when inactive.\n */\nexport default class Pointer {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\t// Throttles mouse wheel navigation\n\t\tthis.lastMouseWheelStep = 0;\n\n\t\t// Is the mouse pointer currently hidden from view\n\t\tthis.cursorHidden = false;\n\n\t\t// Timeout used to determine when the cursor is inactive\n\t\tthis.cursorInactiveTimeout = 0;\n\n\t\tthis.onDocumentCursorActive = this.onDocumentCursorActive.bind( this );\n\t\tthis.onDocumentMouseScroll = this.onDocumentMouseScroll.bind( this );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tif( config.mouseWheel ) {\n\t\t\tdocument.addEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false ); // FF\n\t\t\tdocument.addEventListener( 'mousewheel', this.onDocumentMouseScroll, false );\n\t\t}\n\t\telse {\n\t\t\tdocument.removeEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false ); // FF\n\t\t\tdocument.removeEventListener( 'mousewheel', this.onDocumentMouseScroll, false );\n\t\t}\n\n\t\t// Auto-hide the mouse pointer when its inactive\n\t\tif( config.hideInactiveCursor ) {\n\t\t\tdocument.addEventListener( 'mousemove', this.onDocumentCursorActive, false );\n\t\t\tdocument.addEventListener( 'mousedown', this.onDocumentCursorActive, false );\n\t\t}\n\t\telse {\n\t\t\tthis.showCursor();\n\n\t\t\tdocument.removeEventListener( 'mousemove', this.onDocumentCursorActive, false );\n\t\t\tdocument.removeEventListener( 'mousedown', this.onDocumentCursorActive, false );\n\t\t}\n\n\t}\n\n\t/**\n\t * Shows the mouse pointer after it has been hidden with\n\t * #hideCursor.\n\t */\n\tshowCursor() {\n\n\t\tif( this.cursorHidden ) {\n\t\t\tthis.cursorHidden = false;\n\t\t\tthis.Reveal.getRevealElement().style.cursor = '';\n\t\t}\n\n\t}\n\n\t/**\n\t * Hides the mouse pointer when it's on top of the .reveal\n\t * container.\n\t */\n\thideCursor() {\n\n\t\tif( this.cursorHidden === false ) {\n\t\t\tthis.cursorHidden = true;\n\t\t\tthis.Reveal.getRevealElement().style.cursor = 'none';\n\t\t}\n\n\t}\n\n\t/**\n\t * Called whenever there is mouse input at the document level\n\t * to determine if the cursor is active or not.\n\t *\n\t * @param {object} event\n\t */\n\tonDocumentCursorActive( event ) {\n\n\t\tthis.showCursor();\n\n\t\tclearTimeout( this.cursorInactiveTimeout );\n\n\t\tthis.cursorInactiveTimeout = setTimeout( this.hideCursor.bind( this ), this.Reveal.getConfig().hideCursorTime );\n\n\t}\n\n\t/**\n\t * Handles mouse wheel scrolling, throttled to avoid skipping\n\t * multiple slides.\n\t *\n\t * @param {object} event\n\t */\n\tonDocumentMouseScroll( event ) {\n\n\t\tif( Date.now() - this.lastMouseWheelStep > 1000 ) {\n\n\t\t\tthis.lastMouseWheelStep = Date.now();\n\n\t\t\tlet delta = event.detail || -event.wheelDelta;\n\t\t\tif( delta > 0 ) {\n\t\t\t\tthis.Reveal.next();\n\t\t\t}\n\t\t\telse if( delta < 0 ) {\n\t\t\t\tthis.Reveal.prev();\n\t\t\t}\n\n\t\t}\n\n\t}\n\n}","/**\n * Loads a JavaScript file from the given URL and executes it.\n *\n * @param {string} url Address of the .js file to load\n * @param {function} callback Method to invoke when the script\n * has loaded and executed\n */\nexport const loadScript = ( url, callback ) => {\n\n\tconst script = document.createElement( 'script' );\n\tscript.type = 'text/javascript';\n\tscript.async = false;\n\tscript.defer = false;\n\tscript.src = url;\n\n\tif( typeof callback === 'function' ) {\n\n\t\t// Success callback\n\t\tscript.onload = script.onreadystatechange = event => {\n\t\t\tif( event.type === 'load' || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t// Kill event listeners\n\t\t\t\tscript.onload = script.onreadystatechange = script.onerror = null;\n\n\t\t\t\tcallback();\n\n\t\t\t}\n\t\t};\n\n\t\t// Error callback\n\t\tscript.onerror = err => {\n\n\t\t\t// Kill event listeners\n\t\t\tscript.onload = script.onreadystatechange = script.onerror = null;\n\n\t\t\tcallback( new Error( 'Failed loading script: ' + script.src + '\\n' + err ) );\n\n\t\t};\n\n\t}\n\n\t// Append the script at the end of <head>\n\tconst head = document.querySelector( 'head' );\n\thead.insertBefore( script, head.lastChild );\n\n}","import { loadScript } from '../utils/loader.js'\n\n/**\n * Manages loading and registering of reveal.js plugins.\n */\nexport default class Plugins {\n\n\tconstructor( reveal ) {\n\n\t\tthis.Reveal = reveal;\n\n\t\t// Flags our current state (idle -> loading -> loaded)\n\t\tthis.state = 'idle';\n\n\t\t// An id:instance map of currently registed plugins\n\t\tthis.registeredPlugins = {};\n\n\t\tthis.asyncDependencies = [];\n\n\t}\n\n\t/**\n\t * Loads reveal.js dependencies, registers and\n\t * initializes plugins.\n\t *\n\t * Plugins are direct references to a reveal.js plugin\n\t * object that we register and initialize after any\n\t * synchronous dependencies have loaded.\n\t *\n\t * Dependencies are defined via the 'dependencies' config\n\t * option and will be loaded prior to starting reveal.js.\n\t * Some dependencies may have an 'async' flag, if so they\n\t * will load after reveal.js has been started up.\n\t */\n\tload( plugins, dependencies ) {\n\n\t\tthis.state = 'loading';\n\n\t\tplugins.forEach( this.registerPlugin.bind( this ) );\n\n\t\treturn new Promise( resolve => {\n\n\t\t\tlet scripts = [],\n\t\t\t\tscriptsToLoad = 0;\n\n\t\t\tdependencies.forEach( s => {\n\t\t\t\t// Load if there's no condition or the condition is truthy\n\t\t\t\tif( !s.condition || s.condition() ) {\n\t\t\t\t\tif( s.async ) {\n\t\t\t\t\t\tthis.asyncDependencies.push( s );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tscripts.push( s );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tif( scripts.length ) {\n\t\t\t\tscriptsToLoad = scripts.length;\n\n\t\t\t\tconst scriptLoadedCallback = (s) => {\n\t\t\t\t\tif( s && typeof s.callback === 'function' ) s.callback();\n\n\t\t\t\t\tif( --scriptsToLoad === 0 ) {\n\t\t\t\t\t\tthis.initPlugins().then( resolve );\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Load synchronous scripts\n\t\t\t\tscripts.forEach( s => {\n\t\t\t\t\tif( typeof s.id === 'string' ) {\n\t\t\t\t\t\tthis.registerPlugin( s );\n\t\t\t\t\t\tscriptLoadedCallback( s );\n\t\t\t\t\t}\n\t\t\t\t\telse if( typeof s.src === 'string' ) {\n\t\t\t\t\t\tloadScript( s.src, () => scriptLoadedCallback(s) );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tconsole.warn( 'Unrecognized plugin format', s );\n\t\t\t\t\t\tscriptLoadedCallback();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.initPlugins().then( resolve );\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Initializes our plugins and waits for them to be ready\n\t * before proceeding.\n\t */\n\tinitPlugins() {\n\n\t\treturn new Promise( resolve => {\n\n\t\t\tlet pluginValues = Object.values( this.registeredPlugins );\n\t\t\tlet pluginsToInitialize = pluginValues.length;\n\n\t\t\t// If there are no plugins, skip this step\n\t\t\tif( pluginsToInitialize === 0 ) {\n\t\t\t\tthis.loadAsync().then( resolve );\n\t\t\t}\n\t\t\t// ... otherwise initialize plugins\n\t\t\telse {\n\n\t\t\t\tlet initNextPlugin;\n\n\t\t\t\tlet afterPlugInitialized = () => {\n\t\t\t\t\tif( --pluginsToInitialize === 0 ) {\n\t\t\t\t\t\tthis.loadAsync().then( resolve );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tinitNextPlugin();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tlet i = 0;\n\n\t\t\t\t// Initialize plugins serially\n\t\t\t\tinitNextPlugin = () => {\n\n\t\t\t\t\tlet plugin = pluginValues[i++];\n\n\t\t\t\t\t// If the plugin has an 'init' method, invoke it\n\t\t\t\t\tif( typeof plugin.init === 'function' ) {\n\t\t\t\t\t\tlet promise = plugin.init( this.Reveal );\n\n\t\t\t\t\t\t// If the plugin returned a Promise, wait for it\n\t\t\t\t\t\tif( promise && typeof promise.then === 'function' ) {\n\t\t\t\t\t\t\tpromise.then( afterPlugInitialized );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tafterPlugInitialized();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tafterPlugInitialized();\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tinitNextPlugin();\n\n\t\t\t}\n\n\t\t} )\n\n\t}\n\n\t/**\n\t * Loads all async reveal.js dependencies.\n\t */\n\tloadAsync() {\n\n\t\tthis.state = 'loaded';\n\n\t\tif( this.asyncDependencies.length ) {\n\t\t\tthis.asyncDependencies.forEach( s => {\n\t\t\t\tloadScript( s.src, s.callback );\n\t\t\t} );\n\t\t}\n\n\t\treturn Promise.resolve();\n\n\t}\n\n\t/**\n\t * Registers a new plugin with this reveal.js instance.\n\t *\n\t * reveal.js waits for all regisered plugins to initialize\n\t * before considering itself ready, as long as the plugin\n\t * is registered before calling `Reveal.initialize()`.\n\t */\n\tregisterPlugin( plugin ) {\n\n\t\t// Backwards compatibility to make reveal.js ~3.9.0\n\t\t// plugins work with reveal.js 4.0.0\n\t\tif( arguments.length === 2 && typeof arguments[0] === 'string' ) {\n\t\t\tplugin = arguments[1];\n\t\t\tplugin.id = arguments[0];\n\t\t}\n\n\t\tlet id = plugin.id;\n\n\t\tif( typeof id !== 'string' ) {\n\t\t\tconsole.warn( 'Unrecognized plugin format; can\\'t find plugin.id', plugin );\n\t\t}\n\t\telse if( this.registeredPlugins[id] === undefined ) {\n\t\t\tthis.registeredPlugins[id] = plugin;\n\n\t\t\t// If a plugin is registered after reveal.js is loaded,\n\t\t\t// initialize it right away\n\t\t\tif( this.state === 'loaded' && typeof plugin.init === 'function' ) {\n\t\t\t\tplugin.init( this.Reveal );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tconsole.warn( 'reveal.js: \"'+ id +'\" plugin has already been registered' );\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks if a specific plugin has been registered.\n\t *\n\t * @param {String} id Unique plugin identifier\n\t */\n\thasPlugin( id ) {\n\n\t\treturn !!this.registeredPlugins[id];\n\n\t}\n\n\t/**\n\t * Returns the specific plugin instance, if a plugin\n\t * with the given ID has been registered.\n\t *\n\t * @param {String} id Unique plugin identifier\n\t */\n\tgetPlugin( id ) {\n\n\t\treturn this.registeredPlugins[id];\n\n\t}\n\n\tgetRegisteredPlugins() {\n\n\t\treturn this.registeredPlugins;\n\n\t}\n\n}\n","import { SLIDES_SELECTOR } from '../utils/constants.js'\nimport { queryAll, createStyleSheet } from '../utils/util.js'\n\n/**\n * Setups up our presentation for printing/exporting to PDF.\n */\nexport default class Print {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\t/**\n\t * Configures the presentation for printing to a static\n\t * PDF.\n\t */\n\tsetupPDF() {\n\n\t\tlet config = this.Reveal.getConfig();\n\n\t\tlet slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );\n\n\t\t// Dimensions of the PDF pages\n\t\tlet pageWidth = Math.floor( slideSize.width * ( 1 + config.margin ) ),\n\t\t\tpageHeight = Math.floor( slideSize.height * ( 1 + config.margin ) );\n\n\t\t// Dimensions of slides within the pages\n\t\tlet slideWidth = slideSize.width,\n\t\t\tslideHeight = slideSize.height;\n\n\t\t// Let the browser know what page size we want to print\n\t\tcreateStyleSheet( '@page{size:'+ pageWidth +'px '+ pageHeight +'px; margin: 0px;}' );\n\n\t\t// Limit the size of certain elements to the dimensions of the slide\n\t\tcreateStyleSheet( '.reveal section>img, .reveal section>video, .reveal section>iframe{max-width: '+ slideWidth +'px; max-height:'+ slideHeight +'px}' );\n\n\t\tdocument.documentElement.classList.add( 'print-pdf' );\n\t\tdocument.body.style.width = pageWidth + 'px';\n\t\tdocument.body.style.height = pageHeight + 'px';\n\n\t\t// Make sure stretch elements fit on slide\n\t\tthis.Reveal.layoutSlideContents( slideWidth, slideHeight );\n\n\t\t// Compute slide numbers now, before we start duplicating slides\n\t\tlet doingSlideNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber );\n\t\tqueryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ).forEach( function( slide ) {\n\t\t\tslide.setAttribute( 'data-slide-number', this.Reveal.slideNumber.getSlideNumber( slide ) );\n\t\t}, this );\n\n\t\t// Slide and slide background layout\n\t\tqueryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ).forEach( function( slide ) {\n\n\t\t\t// Vertical stacks are not centred since their section\n\t\t\t// children will be\n\t\t\tif( slide.classList.contains( 'stack' ) === false ) {\n\t\t\t\t// Center the slide inside of the page, giving the slide some margin\n\t\t\t\tlet left = ( pageWidth - slideWidth ) / 2,\n\t\t\t\t\ttop = ( pageHeight - slideHeight ) / 2;\n\n\t\t\t\tlet contentHeight = slide.scrollHeight;\n\t\t\t\tlet numberOfPages = Math.max( Math.ceil( contentHeight / pageHeight ), 1 );\n\n\t\t\t\t// Adhere to configured pages per slide limit\n\t\t\t\tnumberOfPages = Math.min( numberOfPages, config.pdfMaxPagesPerSlide );\n\n\t\t\t\t// Center slides vertically\n\t\t\t\tif( numberOfPages === 1 && config.center || slide.classList.contains( 'center' ) ) {\n\t\t\t\t\ttop = Math.max( ( pageHeight - contentHeight ) / 2, 0 );\n\t\t\t\t}\n\n\t\t\t\t// Wrap the slide in a page element and hide its overflow\n\t\t\t\t// so that no page ever flows onto another\n\t\t\t\tlet page = document.createElement( 'div' );\n\t\t\t\tpage.className = 'pdf-page';\n\t\t\t\tpage.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px';\n\t\t\t\tslide.parentNode.insertBefore( page, slide );\n\t\t\t\tpage.appendChild( slide );\n\n\t\t\t\t// Position the slide inside of the page\n\t\t\t\tslide.style.left = left + 'px';\n\t\t\t\tslide.style.top = top + 'px';\n\t\t\t\tslide.style.width = slideWidth + 'px';\n\n\t\t\t\tif( slide.slideBackgroundElement ) {\n\t\t\t\t\tpage.insertBefore( slide.slideBackgroundElement, slide );\n\t\t\t\t}\n\n\t\t\t\t// Inject notes if `showNotes` is enabled\n\t\t\t\tif( config.showNotes ) {\n\n\t\t\t\t\t// Are there notes for this slide?\n\t\t\t\t\tlet notes = getSlideNotes( slide );\n\t\t\t\t\tif( notes ) {\n\n\t\t\t\t\t\tlet notesSpacing = 8;\n\t\t\t\t\t\tlet notesLayout = typeof config.showNotes === 'string' ? config.showNotes : 'inline';\n\t\t\t\t\t\tlet notesElement = document.createElement( 'div' );\n\t\t\t\t\t\tnotesElement.classList.add( 'speaker-notes' );\n\t\t\t\t\t\tnotesElement.classList.add( 'speaker-notes-pdf' );\n\t\t\t\t\t\tnotesElement.setAttribute( 'data-layout', notesLayout );\n\t\t\t\t\t\tnotesElement.innerHTML = notes;\n\n\t\t\t\t\t\tif( notesLayout === 'separate-page' ) {\n\t\t\t\t\t\t\tpage.parentNode.insertBefore( notesElement, page.nextSibling );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tnotesElement.style.left = notesSpacing + 'px';\n\t\t\t\t\t\t\tnotesElement.style.bottom = notesSpacing + 'px';\n\t\t\t\t\t\t\tnotesElement.style.width = ( pageWidth - notesSpacing*2 ) + 'px';\n\t\t\t\t\t\t\tpage.appendChild( notesElement );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Inject slide numbers if `slideNumbers` are enabled\n\t\t\t\tif( doingSlideNumbers ) {\n\t\t\t\t\tlet numberElement = document.createElement( 'div' );\n\t\t\t\t\tnumberElement.classList.add( 'slide-number' );\n\t\t\t\t\tnumberElement.classList.add( 'slide-number-pdf' );\n\t\t\t\t\tnumberElement.innerHTML = slide.getAttribute( 'data-slide-number' );\n\t\t\t\t\tpage.appendChild( numberElement );\n\t\t\t\t}\n\n\t\t\t\t// Copy page and show fragments one after another\n\t\t\t\tif( config.pdfSeparateFragments ) {\n\n\t\t\t\t\t// Each fragment 'group' is an array containing one or more\n\t\t\t\t\t// fragments. Multiple fragments that appear at the same time\n\t\t\t\t\t// are part of the same group.\n\t\t\t\t\tlet fragmentGroups = this.Reveal.fragments.sort( page.querySelectorAll( '.fragment' ), true );\n\n\t\t\t\t\tlet previousFragmentStep;\n\t\t\t\t\tlet previousPage;\n\n\t\t\t\t\tfragmentGroups.forEach( function( fragments ) {\n\n\t\t\t\t\t\t// Remove 'current-fragment' from the previous group\n\t\t\t\t\t\tif( previousFragmentStep ) {\n\t\t\t\t\t\t\tpreviousFragmentStep.forEach( function( fragment ) {\n\t\t\t\t\t\t\t\tfragment.classList.remove( 'current-fragment' );\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Show the fragments for the current index\n\t\t\t\t\t\tfragments.forEach( function( fragment ) {\n\t\t\t\t\t\t\tfragment.classList.add( 'visible', 'current-fragment' );\n\t\t\t\t\t\t}, this );\n\n\t\t\t\t\t\t// Create a separate page for the current fragment state\n\t\t\t\t\t\tlet clonedPage = page.cloneNode( true );\n\t\t\t\t\t\tpage.parentNode.insertBefore( clonedPage, ( previousPage || page ).nextSibling );\n\n\t\t\t\t\t\tpreviousFragmentStep = fragments;\n\t\t\t\t\t\tpreviousPage = clonedPage;\n\n\t\t\t\t\t}, this );\n\n\t\t\t\t\t// Reset the first/original page so that all fragments are hidden\n\t\t\t\t\tfragmentGroups.forEach( function( fragments ) {\n\t\t\t\t\t\tfragments.forEach( function( fragment ) {\n\t\t\t\t\t\t\tfragment.classList.remove( 'visible', 'current-fragment' );\n\t\t\t\t\t\t} );\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\t\t\t\t// Show all fragments\n\t\t\t\telse {\n\t\t\t\t\tqueryAll( page, '.fragment:not(.fade-out)' ).forEach( function( fragment ) {\n\t\t\t\t\t\tfragment.classList.add( 'visible' );\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}, this );\n\n\t\t// Notify subscribers that the PDF layout is good to go\n\t\tthis.Reveal.dispatchEvent({ type: 'pdf-ready' });\n\n\t}\n\n\t/**\n\t * Checks if this instance is being used to print a PDF.\n\t */\n\tisPrintingPDF() {\n\n\t\treturn ( /print-pdf/gi ).test( window.location.search );\n\n\t}\n\n}","const SWIPE_THRESHOLD = 40;\n\n/**\n * Controls all touch interactions and navigations for\n * a presentation.\n */\nexport default class Touch {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\t// Holds information about the currently ongoing touch interaction\n\t\tthis.touchStartX = 0;\n\t\tthis.touchStartY = 0;\n\t\tthis.touchStartCount = 0;\n\t\tthis.touchCaptured = false;\n\n\t\tthis.onPointerDown = this.onPointerDown.bind( this );\n\t\tthis.onPointerMove = this.onPointerMove.bind( this );\n\t\tthis.onPointerUp = this.onPointerUp.bind( this );\n\t\tthis.onTouchStart = this.onTouchStart.bind( this );\n\t\tthis.onTouchMove = this.onTouchMove.bind( this );\n\t\tthis.onTouchEnd = this.onTouchEnd.bind( this );\n\n\t}\n\n\t/**\n\t *\n\t */\n\tbind() {\n\n\t\tvar revealElement = this.Reveal.getRevealElement();\n\n\t\tif( 'onpointerdown' in window ) {\n\t\t\t// Use W3C pointer events\n\t\t\trevealElement.addEventListener( 'pointerdown', this.onPointerDown, false );\n\t\t\trevealElement.addEventListener( 'pointermove', this.onPointerMove, false );\n\t\t\trevealElement.addEventListener( 'pointerup', this.onPointerUp, false );\n\t\t}\n\t\telse if( window.navigator.msPointerEnabled ) {\n\t\t\t// IE 10 uses prefixed version of pointer events\n\t\t\trevealElement.addEventListener( 'MSPointerDown', this.onPointerDown, false );\n\t\t\trevealElement.addEventListener( 'MSPointerMove', this.onPointerMove, false );\n\t\t\trevealElement.addEventListener( 'MSPointerUp', this.onPointerUp, false );\n\t\t}\n\t\telse {\n\t\t\t// Fall back to touch events\n\t\t\trevealElement.addEventListener( 'touchstart', this.onTouchStart, false );\n\t\t\trevealElement.addEventListener( 'touchmove', this.onTouchMove, false );\n\t\t\trevealElement.addEventListener( 'touchend', this.onTouchEnd, false );\n\t\t}\n\n\t}\n\n\t/**\n\t *\n\t */\n\tunbind() {\n\n\t\tvar revealElement = this.Reveal.getRevealElement();\n\n\t\trevealElement.removeEventListener( 'pointerdown', this.onPointerDown, false );\n\t\trevealElement.removeEventListener( 'pointermove', this.onPointerMove, false );\n\t\trevealElement.removeEventListener( 'pointerup', this.onPointerUp, false );\n\n\t\trevealElement.removeEventListener( 'MSPointerDown', this.onPointerDown, false );\n\t\trevealElement.removeEventListener( 'MSPointerMove', this.onPointerMove, false );\n\t\trevealElement.removeEventListener( 'MSPointerUp', this.onPointerUp, false );\n\n\t\trevealElement.removeEventListener( 'touchstart', this.onTouchStart, false );\n\t\trevealElement.removeEventListener( 'touchmove', this.onTouchMove, false );\n\t\trevealElement.removeEventListener( 'touchend', this.onTouchEnd, false );\n\n\t}\n\n\t/**\n\t * Checks if the target element prevents the triggering of\n\t * swipe navigation.\n\t */\n\tisSwipePrevented( target ) {\n\n\t\twhile( target && typeof target.hasAttribute === 'function' ) {\n\t\t\tif( target.hasAttribute( 'data-prevent-swipe' ) ) return true;\n\t\t\ttarget = target.parentNode;\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\t/**\n\t * Handler for the 'touchstart' event, enables support for\n\t * swipe and pinch gestures.\n\t *\n\t * @param {object} event\n\t */\n\tonTouchStart( event ) {\n\n\t\tif( this.isSwipePrevented( event.target ) ) return true;\n\n\t\tthis.touchStartX = event.touches[0].clientX;\n\t\tthis.touchStartY = event.touches[0].clientY;\n\t\tthis.touchStartCount = event.touches.length;\n\n\t}\n\n\t/**\n\t * Handler for the 'touchmove' event.\n\t *\n\t * @param {object} event\n\t */\n\tonTouchMove( event ) {\n\n\t\tif( this.isSwipePrevented( event.target ) ) return true;\n\n\t\tlet config = this.Reveal.getConfig();\n\n\t\t// Each touch should only trigger one action\n\t\tif( !this.touchCaptured ) {\n\t\t\tthis.Reveal.onUserInput( event );\n\n\t\t\tlet currentX = event.touches[0].clientX;\n\t\t\tlet currentY = event.touches[0].clientY;\n\n\t\t\t// There was only one touch point, look for a swipe\n\t\t\tif( event.touches.length === 1 && this.touchStartCount !== 2 ) {\n\n\t\t\t\tlet deltaX = currentX - this.touchStartX,\n\t\t\t\t\tdeltaY = currentY - this.touchStartY;\n\n\t\t\t\tif( deltaX > SWIPE_THRESHOLD && Math.abs( deltaX ) > Math.abs( deltaY ) ) {\n\t\t\t\t\tthis.touchCaptured = true;\n\t\t\t\t\tif( config.navigationMode === 'linear' ) {\n\t\t\t\t\t\tif( config.rtl ) {\n\t\t\t\t\t\t\tthis.Reveal.next();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tthis.Reveal.prev()();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.Reveal.left();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( deltaX < -SWIPE_THRESHOLD && Math.abs( deltaX ) > Math.abs( deltaY ) ) {\n\t\t\t\t\tthis.touchCaptured = true;\n\t\t\t\t\tif( config.navigationMode === 'linear' ) {\n\t\t\t\t\t\tif( config.rtl ) {\n\t\t\t\t\t\t\tthis.Reveal.prev()();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tthis.Reveal.next();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.Reveal.right();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( deltaY > SWIPE_THRESHOLD ) {\n\t\t\t\t\tthis.touchCaptured = true;\n\t\t\t\t\tif( config.navigationMode === 'linear' ) {\n\t\t\t\t\t\tthis.Reveal.prev()();\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.Reveal.up();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( deltaY < -SWIPE_THRESHOLD ) {\n\t\t\t\t\tthis.touchCaptured = true;\n\t\t\t\t\tif( config.navigationMode === 'linear' ) {\n\t\t\t\t\t\tthis.Reveal.next();\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.Reveal.down();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If we're embedded, only block touch events if they have\n\t\t\t\t// triggered an action\n\t\t\t\tif( config.embedded ) {\n\t\t\t\t\tif( this.touchCaptured || this.Reveal.isVerticalSlide( currentSlide ) ) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Not embedded? Block them all to avoid needless tossing\n\t\t\t\t// around of the viewport in iOS\n\t\t\t\telse {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t\t// There's a bug with swiping on some Android devices unless\n\t\t// the default action is always prevented\n\t\telse if( isAndroid ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\n\t}\n\n\t/**\n\t * Handler for the 'touchend' event.\n\t *\n\t * @param {object} event\n\t */\n\tonTouchEnd( event ) {\n\n\t\tthis.touchCaptured = false;\n\n\t}\n\n\t/**\n\t * Convert pointer down to touch start.\n\t *\n\t * @param {object} event\n\t */\n\tonPointerDown( event ) {\n\n\t\tif( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === \"touch\" ) {\n\t\t\tevent.touches = [{ clientX: event.clientX, clientY: event.clientY }];\n\t\t\tthis.onTouchStart( event );\n\t\t}\n\n\t}\n\n\t/**\n\t * Convert pointer move to touch move.\n\t *\n\t * @param {object} event\n\t */\n\tonPointerMove( event ) {\n\n\t\tif( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === \"touch\" ) {\n\t\t\tevent.touches = [{ clientX: event.clientX, clientY: event.clientY }];\n\t\t\tthis.onTouchMove( event );\n\t\t}\n\n\t}\n\n\t/**\n\t * Convert pointer up to touch end.\n\t *\n\t * @param {object} event\n\t */\n\tonPointerUp( event ) {\n\n\t\tif( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === \"touch\" ) {\n\t\t\tevent.touches = [{ clientX: event.clientX, clientY: event.clientY }];\n\t\t\tthis.onTouchEnd( event );\n\t\t}\n\n\t}\n\n}","/**\n * Handles the showing and \n */\nexport default class Notes {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\trender() {\n\n\t\tthis.element = document.createElement( 'div' );\n\t\tthis.element.className = 'speaker-notes';\n\t\tthis.element.setAttribute( 'data-prevent-swipe', '' );\n\t\tthis.element.setAttribute( 'tabindex', '0' );\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tif( config.showNotes ) {\n\t\t\tthis.element.setAttribute( 'data-layout', typeof config.showNotes === 'string' ? config.showNotes : 'inline' );\n\t\t}\n\n\t}\n\n\t/**\n\t * Pick up notes from the current slide and display them\n\t * to the viewer.\n\t *\n\t * @see {@link config.showNotes}\n\t */\n\tupdate() {\n\n\t\tif( this.Reveal.getConfig().showNotes && this.element && this.Reveal.getCurrentSlide() && !this.Reveal.print.isPrintingPDF() ) {\n\n\t\t\tthis.element.innerHTML = this.getSlideNotes() || '<span class=\"notes-placeholder\">No notes on this slide.</span>';\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Updates the visibility of the speaker notes sidebar that\n\t * is used to share annotated slides. The notes sidebar is\n\t * only visible if showNotes is true and there are notes on\n\t * one or more slides in the deck.\n\t */\n\tupdateVisibility() {\n\n\t\tif( this.Reveal.getConfig().showNotes && this.hasNotes() ) {\n\t\t\tthis.Reveal.getRevealElement().classList.add( 'show-notes' );\n\t\t}\n\t\telse {\n\t\t\tthis.Reveal.getRevealElement().classList.remove( 'show-notes' );\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks if there are speaker notes for ANY slide in the\n\t * presentation.\n\t */\n\thasNotes() {\n\n\t\treturn this.Reveal.getSlidesElement().querySelectorAll( '[data-notes], aside.notes' ).length > 0;\n\n\t}\n\n\t/**\n\t * Checks if this presentation is running inside of the\n\t * speaker notes window.\n\t *\n\t * @return {boolean}\n\t */\n\tisSpeakerNotesWindow() {\n\n\t\treturn !!window.location.search.match( /receiver/gi );\n\n\t}\n\n\t/**\n\t * Retrieves the speaker notes from a slide. Notes can be\n\t * defined in two ways:\n\t * 1. As a data-notes attribute on the slide <section>\n\t * 2. As an <aside class=\"notes\"> inside of the slide\n\t *\n\t * @param {HTMLElement} [slide=currentSlide]\n\t * @return {(string|null)}\n\t */\n\tgetSlideNotes( slide = this.Reveal.getCurrentSlide() ) {\n\n\t\t// Notes can be specified via the data-notes attribute...\n\t\tif( slide.hasAttribute( 'data-notes' ) ) {\n\t\t\treturn slide.getAttribute( 'data-notes' );\n\t\t}\n\n\t\t// ... or using an <aside class=\"notes\"> element\n\t\tlet notesElement = slide.querySelector( 'aside.notes' );\n\t\tif( notesElement ) {\n\t\t\treturn notesElement.innerHTML;\n\t\t}\n\n\t\treturn null;\n\n\t}\n\n}","/**\n * UI component that lets the use control auto-slide\n * playback via play/pause.\n */\nexport default class Playback {\n\n\t/**\n\t * @param {HTMLElement} container The component will append\n\t * itself to this\n\t * @param {function} progressCheck A method which will be\n\t * called frequently to get the current playback progress on\n\t * a range of 0-1\n\t */\n\tconstructor( container, progressCheck ) {\n\n\t\t// Cosmetics\n\t\tthis.diameter = 100;\n\t\tthis.diameter2 = this.diameter/2;\n\t\tthis.thickness = 6;\n\n\t\t// Flags if we are currently playing\n\t\tthis.playing = false;\n\n\t\t// Current progress on a 0-1 range\n\t\tthis.progress = 0;\n\n\t\t// Used to loop the animation smoothly\n\t\tthis.progressOffset = 1;\n\n\t\tthis.container = container;\n\t\tthis.progressCheck = progressCheck;\n\n\t\tthis.canvas = document.createElement( 'canvas' );\n\t\tthis.canvas.className = 'playback';\n\t\tthis.canvas.width = this.diameter;\n\t\tthis.canvas.height = this.diameter;\n\t\tthis.canvas.style.width = this.diameter2 + 'px';\n\t\tthis.canvas.style.height = this.diameter2 + 'px';\n\t\tthis.context = this.canvas.getContext( '2d' );\n\n\t\tthis.container.appendChild( this.canvas );\n\n\t\tthis.render();\n\n\t}\n\n\tsetPlaying( value ) {\n\n\t\tconst wasPlaying = this.playing;\n\n\t\tthis.playing = value;\n\n\t\t// Start repainting if we weren't already\n\t\tif( !wasPlaying && this.playing ) {\n\t\t\tthis.animate();\n\t\t}\n\t\telse {\n\t\t\tthis.render();\n\t\t}\n\n\t}\n\n\tanimate() {\n\n\t\tconst progressBefore = this.progress;\n\n\t\tthis.progress = this.progressCheck();\n\n\t\t// When we loop, offset the progress so that it eases\n\t\t// smoothly rather than immediately resetting\n\t\tif( progressBefore > 0.8 && this.progress < 0.2 ) {\n\t\t\tthis.progressOffset = this.progress;\n\t\t}\n\n\t\tthis.render();\n\n\t\tif( this.playing ) {\n\t\t\trequestAnimationFrame( this.animate.bind( this ) );\n\t\t}\n\n\t}\n\n\t/**\n\t * Renders the current progress and playback state.\n\t */\n\trender() {\n\n\t\tlet progress = this.playing ? this.progress : 0,\n\t\t\tradius = ( this.diameter2 ) - this.thickness,\n\t\t\tx = this.diameter2,\n\t\t\ty = this.diameter2,\n\t\t\ticonSize = 28;\n\n\t\t// Ease towards 1\n\t\tthis.progressOffset += ( 1 - this.progressOffset ) * 0.1;\n\n\t\tconst endAngle = ( - Math.PI / 2 ) + ( progress * ( Math.PI * 2 ) );\n\t\tconst startAngle = ( - Math.PI / 2 ) + ( this.progressOffset * ( Math.PI * 2 ) );\n\n\t\tthis.context.save();\n\t\tthis.context.clearRect( 0, 0, this.diameter, this.diameter );\n\n\t\t// Solid background color\n\t\tthis.context.beginPath();\n\t\tthis.context.arc( x, y, radius + 4, 0, Math.PI * 2, false );\n\t\tthis.context.fillStyle = 'rgba( 0, 0, 0, 0.4 )';\n\t\tthis.context.fill();\n\n\t\t// Draw progress track\n\t\tthis.context.beginPath();\n\t\tthis.context.arc( x, y, radius, 0, Math.PI * 2, false );\n\t\tthis.context.lineWidth = this.thickness;\n\t\tthis.context.strokeStyle = 'rgba( 255, 255, 255, 0.2 )';\n\t\tthis.context.stroke();\n\n\t\tif( this.playing ) {\n\t\t\t// Draw progress on top of track\n\t\t\tthis.context.beginPath();\n\t\t\tthis.context.arc( x, y, radius, startAngle, endAngle, false );\n\t\t\tthis.context.lineWidth = this.thickness;\n\t\t\tthis.context.strokeStyle = '#fff';\n\t\t\tthis.context.stroke();\n\t\t}\n\n\t\tthis.context.translate( x - ( iconSize / 2 ), y - ( iconSize / 2 ) );\n\n\t\t// Draw play/pause icons\n\t\tif( this.playing ) {\n\t\t\tthis.context.fillStyle = '#fff';\n\t\t\tthis.context.fillRect( 0, 0, iconSize / 2 - 4, iconSize );\n\t\t\tthis.context.fillRect( iconSize / 2 + 4, 0, iconSize / 2 - 4, iconSize );\n\t\t}\n\t\telse {\n\t\t\tthis.context.beginPath();\n\t\t\tthis.context.translate( 4, 0 );\n\t\t\tthis.context.moveTo( 0, 0 );\n\t\t\tthis.context.lineTo( iconSize - 4, iconSize / 2 );\n\t\t\tthis.context.lineTo( 0, iconSize );\n\t\t\tthis.context.fillStyle = '#fff';\n\t\t\tthis.context.fill();\n\t\t}\n\n\t\tthis.context.restore();\n\n\t}\n\n\ton( type, listener ) {\n\t\tthis.canvas.addEventListener( type, listener, false );\n\t}\n\n\toff( type, listener ) {\n\t\tthis.canvas.removeEventListener( type, listener, false );\n\t}\n\n\tdestroy() {\n\n\t\tthis.playing = false;\n\n\t\tif( this.canvas.parentNode ) {\n\t\t\tthis.container.removeChild( this.canvas );\n\t\t}\n\n\t}\n\n}","/**\n * The default reveal.js config object.\n */\nexport default {\n\n\t// The \"normal\" size of the presentation, aspect ratio will be preserved\n\t// when the presentation is scaled to fit different resolutions\n\twidth: 960,\n\theight: 700,\n\n\t// Factor of the display size that should remain empty around the content\n\tmargin: 0.04,\n\n\t// Bounds for smallest/largest possible scale to apply to content\n\tminScale: 0.2,\n\tmaxScale: 2.0,\n\n\t// Display presentation control arrows\n\tcontrols: true,\n\n\t// Help the user learn the controls by providing hints, for example by\n\t// bouncing the down arrow when they first encounter a vertical slide\n\tcontrolsTutorial: true,\n\n\t// Determines where controls appear, \"edges\" or \"bottom-right\"\n\tcontrolsLayout: 'bottom-right',\n\n\t// Visibility rule for backwards navigation arrows; \"faded\", \"hidden\"\n\t// or \"visible\"\n\tcontrolsBackArrows: 'faded',\n\n\t// Display a presentation progress bar\n\tprogress: true,\n\n\t// Display the page number of the current slide\n\t// - true: Show slide number\n\t// - false: Hide slide number\n\t//\n\t// Can optionally be set as a string that specifies the number formatting:\n\t// - \"h.v\":\t Horizontal . vertical slide number (default)\n\t// - \"h/v\":\t Horizontal / vertical slide number\n\t// - \"c\":\t Flattened slide number\n\t// - \"c/t\":\t Flattened slide number / total slides\n\t//\n\t// Alternatively, you can provide a function that returns the slide\n\t// number for the current slide. The function should take in a slide\n\t// object and return an array with one string [slideNumber] or\n\t// three strings [n1,delimiter,n2]. See #formatSlideNumber().\n\tslideNumber: false,\n\n\t// Can be used to limit the contexts in which the slide number appears\n\t// - \"all\": Always show the slide number\n\t// - \"print\": Only when printing to PDF\n\t// - \"speaker\": Only in the speaker view\n\tshowSlideNumber: 'all',\n\n\t// Use 1 based indexing for # links to match slide number (default is zero\n\t// based)\n\thashOneBasedIndex: false,\n\n\t// Add the current slide number to the URL hash so that reloading the\n\t// page/copying the URL will return you to the same slide\n\thash: false,\n\n\t// Push each slide change to the browser history. Implies `hash: true`\n\thistory: false,\n\n\t// Enable keyboard shortcuts for navigation\n\tkeyboard: true,\n\n\t// Optional function that blocks keyboard events when retuning false\n\tkeyboardCondition: null,\n\n\t// Enable the slide overview mode\n\toverview: true,\n\n\t// Disables the default reveal.js slide layout so that you can use\n\t// custom CSS layout\n\tdisableLayout: false,\n\n\t// Vertical centering of slides\n\tcenter: true,\n\n\t// Enables touch navigation on devices with touch input\n\ttouch: true,\n\n\t// Loop the presentation\n\tloop: false,\n\n\t// Change the presentation direction to be RTL\n\trtl: false,\n\n\t// Changes the behavior of our navigation directions.\n\t//\n\t// \"default\"\n\t// Left/right arrow keys step between horizontal slides, up/down\n\t// arrow keys step between vertical slides. Space key steps through\n\t// all slides (both horizontal and vertical).\n\t//\n\t// \"linear\"\n\t// Removes the up/down arrows. Left/right arrows step through all\n\t// slides (both horizontal and vertical).\n\t//\n\t// \"grid\"\n\t// When this is enabled, stepping left/right from a vertical stack\n\t// to an adjacent vertical stack will land you at the same vertical\n\t// index.\n\t//\n\t// Consider a deck with six slides ordered in two vertical stacks:\n\t// 1.1 2.1\n\t// 1.2 2.2\n\t// 1.3 2.3\n\t//\n\t// If you're on slide 1.3 and navigate right, you will normally move\n\t// from 1.3 -> 2.1. If \"grid\" is used, the same navigation takes you\n\t// from 1.3 -> 2.3.\n\tnavigationMode: 'default',\n\n\t// Randomizes the order of slides each time the presentation loads\n\tshuffle: false,\n\n\t// Turns fragments on and off globally\n\tfragments: true,\n\n\t// Flags whether to include the current fragment in the URL,\n\t// so that reloading brings you to the same fragment position\n\tfragmentInURL: false,\n\n\t// Flags if the presentation is running in an embedded mode,\n\t// i.e. contained within a limited portion of the screen\n\tembedded: false,\n\n\t// Flags if we should show a help overlay when the question-mark\n\t// key is pressed\n\thelp: true,\n\n\t// Flags if it should be possible to pause the presentation (blackout)\n\tpause: true,\n\n\t// Flags if speaker notes should be visible to all viewers\n\tshowNotes: false,\n\n\t// Global override for autolaying embedded media (video/audio/iframe)\n\t// - null: Media will only autoplay if data-autoplay is present\n\t// - true: All media will autoplay, regardless of individual setting\n\t// - false: No media will autoplay, regardless of individual setting\n\tautoPlayMedia: null,\n\n\t// Global override for preloading lazy-loaded iframes\n\t// - null: Iframes with data-src AND data-preload will be loaded when within\n\t// the viewDistance, iframes with only data-src will be loaded when visible\n\t// - true: All iframes with data-src will be loaded when within the viewDistance\n\t// - false: All iframes with data-src will be loaded only when visible\n\tpreloadIframes: null,\n\n\t// Can be used to globally disable auto-animation\n\tautoAnimate: true,\n\n\t// Optionally provide a custom element matcher that will be\n\t// used to dictate which elements we can animate between.\n\tautoAnimateMatcher: null,\n\n\t// Default settings for our auto-animate transitions, can be\n\t// overridden per-slide or per-element via data arguments\n\tautoAnimateEasing: 'ease',\n\tautoAnimateDuration: 1.0,\n\tautoAnimateUnmatched: true,\n\n\t// CSS properties that can be auto-animated. Position & scale\n\t// is matched separately so there's no need to include styles\n\t// like top/right/bottom/left, width/height or margin.\n\tautoAnimateStyles: [\n\t\t'opacity',\n\t\t'color',\n\t\t'background-color',\n\t\t'padding',\n\t\t'font-size',\n\t\t'line-height',\n\t\t'letter-spacing',\n\t\t'border-width',\n\t\t'border-color',\n\t\t'border-radius',\n\t\t'outline',\n\t\t'outline-offset'\n\t],\n\n\t// Controls automatic progression to the next slide\n\t// - 0: Auto-sliding only happens if the data-autoslide HTML attribute\n\t// is present on the current slide or fragment\n\t// - 1+: All slides will progress automatically at the given interval\n\t// - false: No auto-sliding, even if data-autoslide is present\n\tautoSlide: 0,\n\n\t// Stop auto-sliding after user input\n\tautoSlideStoppable: true,\n\n\t// Use this method for navigation when auto-sliding (defaults to navigateNext)\n\tautoSlideMethod: null,\n\n\t// Specify the average time in seconds that you think you will spend\n\t// presenting each slide. This is used to show a pacing timer in the\n\t// speaker view\n\tdefaultTiming: null,\n\n\t// Enable slide navigation via mouse wheel\n\tmouseWheel: false,\n\n\t// Opens links in an iframe preview overlay\n\t// Add `data-preview-link` and `data-preview-link=\"false\"` to customise each link\n\t// individually\n\tpreviewLinks: false,\n\n\t// Exposes the reveal.js API through window.postMessage\n\tpostMessage: true,\n\n\t// Dispatches all reveal.js events to the parent window through postMessage\n\tpostMessageEvents: false,\n\n\t// Focuses body when page changes visibility to ensure keyboard shortcuts work\n\tfocusBodyOnPageVisibilityChange: true,\n\n\t// Transition style\n\ttransition: 'slide', // none/fade/slide/convex/concave/zoom\n\n\t// Transition speed\n\ttransitionSpeed: 'default', // default/fast/slow\n\n\t// Transition style for full page slide backgrounds\n\tbackgroundTransition: 'fade', // none/fade/slide/convex/concave/zoom\n\n\t// Parallax background image\n\tparallaxBackgroundImage: '', // CSS syntax, e.g. \"a.jpg\"\n\n\t// Parallax background size\n\tparallaxBackgroundSize: '', // CSS syntax, e.g. \"3000px 2000px\"\n\n\t// Parallax background repeat\n\tparallaxBackgroundRepeat: '', // repeat/repeat-x/repeat-y/no-repeat/initial/inherit\n\n\t// Parallax background position\n\tparallaxBackgroundPosition: '', // CSS syntax, e.g. \"top left\"\n\n\t// Amount of pixels to move the parallax background per slide step\n\tparallaxBackgroundHorizontal: null,\n\tparallaxBackgroundVertical: null,\n\n\t// The maximum number of pages a single slide can expand onto when printing\n\t// to PDF, unlimited by default\n\tpdfMaxPagesPerSlide: Number.POSITIVE_INFINITY,\n\n\t// Prints each fragment on a separate slide\n\tpdfSeparateFragments: true,\n\n\t// Offset used to reduce the height of content within exported PDF pages.\n\t// This exists to account for environment differences based on how you\n\t// print to PDF. CLI printing options, like phantomjs and wkpdf, can end\n\t// on precisely the total height of the document whereas in-browser\n\t// printing has to end one pixel before.\n\tpdfPageHeightOffset: -1,\n\n\t// Number of slides away from the current that are visible\n\tviewDistance: 3,\n\n\t// Number of slides away from the current that are visible on mobile\n\t// devices. It is advisable to set this to a lower number than\n\t// viewDistance in order to save resources.\n\tmobileViewDistance: 2,\n\n\t// The display mode that will be used to show slides\n\tdisplay: 'block',\n\n\t// Hide cursor if inactive\n\thideInactiveCursor: true,\n\n\t// Time before the cursor is hidden (in ms)\n\thideCursorTime: 5000,\n\n\t// Script dependencies to load\n\tdependencies: [],\n\n\t// Plugin objects to register and use for this presentation\n\tplugins: []\n\n}","import SlideContent from './controllers/slidecontent.js'\nimport SlideNumber from './controllers/slidenumber.js'\nimport Backgrounds from './controllers/backgrounds.js'\nimport AutoAnimate from './controllers/autoanimate.js'\nimport Fragments from './controllers/fragments.js'\nimport Overview from './controllers/overview.js'\nimport Keyboard from './controllers/keyboard.js'\nimport Location from './controllers/location.js'\nimport Controls from './controllers/controls.js'\nimport Progress from './controllers/progress.js'\nimport Pointer from './controllers/pointer.js'\nimport Plugins from './controllers/plugins.js'\nimport Print from './controllers/print.js'\nimport Touch from './controllers/touch.js'\nimport Notes from './controllers/notes.js'\nimport Playback from './components/playback.js'\nimport defaultConfig from './config.js'\nimport * as Util from './utils/util.js'\nimport * as Device from './utils/device.js'\nimport {\n\tSLIDES_SELECTOR,\n\tHORIZONTAL_SLIDES_SELECTOR,\n\tVERTICAL_SLIDES_SELECTOR,\n\tPOST_MESSAGE_METHOD_BLACKLIST\n} from './utils/constants.js'\n\n/**\n * reveal.js\n * https://revealjs.com\n * MIT licensed\n *\n * Copyright (C) 2020 Hakim El Hattab, https://hakim.se\n */\nexport default function( revealElement, options ) {\n\n\t// Support initialization with no args, one arg\n\t// [options] or two args [revealElement, options]\n\tif( arguments.length < 2 ) {\n\t\toptions = arguments[0];\n\t\trevealElement = document.querySelector( '.reveal' );\n\t}\n\n\tconst Reveal = {};\n\n\t// The reveal.js version\n\tconst VERSION = '4.0.0-dev';\n\n\t// Configuration defaults, can be overridden at initialization time\n\tlet config,\n\n\t\t// Flags if reveal.js is loaded (has dispatched the 'ready' event)\n\t\tready = false,\n\n\t\t// The horizontal and vertical index of the currently active slide\n\t\tindexh,\n\t\tindexv,\n\n\t\t// The previous and current slide HTML elements\n\t\tpreviousSlide,\n\t\tcurrentSlide,\n\n\t\t// Remember which directions that the user has navigated towards\n\t\tnavigationHistory = {\n\t\t\thasNavigatedHorizontally: false,\n\t\t\thasNavigatedVertically: false\n\t\t},\n\n\t\t// Slides may have a data-state attribute which we pick up and apply\n\t\t// as a class to the body. This list contains the combined state of\n\t\t// all current slides.\n\t\tstate = [],\n\n\t\t// The current scale of the presentation (see width/height config)\n\t\tscale = 1,\n\n\t\t// CSS transform that is currently applied to the slides container,\n\t\t// split into two groups\n\t\tslidesTransform = { layout: '', overview: '' },\n\n\t\t// Cached references to DOM elements\n\t\tdom = {},\n\n\t\t// Flags if the interaction event listeners are bound\n\t\teventsAreBound = false,\n\n\t\t// The current slide transition state; idle or running\n\t\ttransition = 'idle',\n\n\t\t// The current auto-slide duration\n\t\tautoSlide = 0,\n\n\t\t// Auto slide properties\n\t\tautoSlidePlayer,\n\t\tautoSlideTimeout = 0,\n\t\tautoSlideStartTime = -1,\n\t\tautoSlidePaused = false,\n\n\t\t// Controllers for different aspects of our presentation. They're\n\t\t// all given direct references to this Reveal instance since there\n\t\t// may be multiple presentations running in parallel.\n\t\tslideContent = new SlideContent( Reveal ),\n\t\tslideNumber = new SlideNumber( Reveal ),\n\t\tautoAnimate = new AutoAnimate( Reveal ),\n\t\tbackgrounds = new Backgrounds( Reveal ),\n\t\tfragments = new Fragments( Reveal ),\n\t\toverview = new Overview( Reveal ),\n\t\tkeyboard = new Keyboard( Reveal ),\n\t\tlocation = new Location( Reveal ),\n\t\tcontrols = new Controls( Reveal ),\n\t\tprogress = new Progress( Reveal ),\n\t\tpointer = new Pointer( Reveal ),\n\t\tplugins = new Plugins( Reveal ),\n\t\tprint = new Print( Reveal ),\n\t\ttouch = new Touch( Reveal ),\n\t\tnotes = new Notes( Reveal );\n\n\t/**\n\t * Starts up the presentation.\n\t */\n\tfunction initialize( initOptions ) {\n\n\t\t// Cache references to key DOM elements\n\t\tdom.wrapper = revealElement;\n\t\tdom.slides = revealElement.querySelector( '.slides' );\n\n\t\t// Compose our config object\n\t\tconfig = { ...defaultConfig, ...options, ...initOptions, ...Util.getQueryHash() };\n\n\t\tsetViewport();\n\n\t\t// Force a layout when the whole page, incl fonts, has loaded\n\t\twindow.addEventListener( 'load', layout, false );\n\n\t\t// Register plugins and load dependencies, then move on to #start()\n\t\tplugins.load( config.plugins, config.dependencies ).then( start );\n\n\t\treturn new Promise( resolve => Reveal.on( 'ready', resolve ) );\n\n\t}\n\n\t/**\n\t * Encase the presentation in a reveal.js viewport. The\n\t * extent of the viewport differs based on configuration.\n\t */\n\tfunction setViewport() {\n\n\t\t// Embedded decks use the reveal element as their viewport\n\t\tif( config.embedded === true ) {\n\t\t\tif( revealElement.closest( '.reveal-viewport' ) === null ) {\n\t\t\t\trevealElement.classList.add( 'reveal-viewport' );\n\t\t\t}\n\t\t}\n\t\t// Full-page decks use the body as their viewport\n\t\telse {\n\t\t\tdocument.body.classList.add( 'reveal-viewport' );\n\t\t\tdocument.documentElement.classList.add( 'reveal-full-page' );\n\t\t}\n\n\t}\n\n\t/**\n\t * Starts up reveal.js by binding input events and navigating\n\t * to the current URL deeplink if there is one.\n\t */\n\tfunction start() {\n\n\t\tready = true;\n\n\t\t// Make sure we've got all the DOM elements we need\n\t\tsetupDOM();\n\n\t\t// Listen to messages posted to this window\n\t\tsetupPostMessage();\n\n\t\t// Prevent the slides from being scrolled out of view\n\t\tsetupScrollPrevention();\n\n\t\t// Resets all vertical slides so that only the first is visible\n\t\tresetVerticalSlides();\n\n\t\t// Updates the presentation to match the current configuration values\n\t\tconfigure();\n\n\t\t// Read the initial hash\n\t\tlocation.readURL();\n\n\t\t// Create slide backgrounds\n\t\tbackgrounds.update( true );\n\n\t\t// Notify listeners that the presentation is ready but use a 1ms\n\t\t// timeout to ensure it's not fired synchronously after #initialize()\n\t\tsetTimeout( () => {\n\t\t\t// Enable transitions now that we're loaded\n\t\t\tdom.slides.classList.remove( 'no-transition' );\n\n\t\t\tdom.wrapper.classList.add( 'ready' );\n\n\t\t\tdispatchEvent({\n\t\t\t\ttype: 'ready',\n\t\t\t\tdata: {\n\t\t\t\t\tindexh,\n\t\t\t\t\tindexv,\n\t\t\t\t\tcurrentSlide\n\t\t\t\t}\n\t\t\t});\n\t\t}, 1 );\n\n\t\t// Special setup and config is required when printing to PDF\n\t\tif( print.isPrintingPDF() ) {\n\t\t\tremoveEventListeners();\n\n\t\t\t// The document needs to have loaded for the PDF layout\n\t\t\t// measurements to be accurate\n\t\t\tif( document.readyState === 'complete' ) {\n\t\t\t\tprint.setupPDF();\n\t\t\t}\n\t\t\telse {\n\t\t\t\twindow.addEventListener( 'load', print.setupPDF );\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Finds and stores references to DOM elements which are\n\t * required by the presentation. If a required element is\n\t * not found, it is created.\n\t */\n\tfunction setupDOM() {\n\n\t\t// Prevent transitions while we're loading\n\t\tdom.slides.classList.add( 'no-transition' );\n\n\t\tif( Device.isMobile ) {\n\t\t\tdom.wrapper.classList.add( 'no-hover' );\n\t\t}\n\t\telse {\n\t\t\tdom.wrapper.classList.remove( 'no-hover' );\n\t\t}\n\n\t\tbackgrounds.render();\n\t\tslideNumber.render();\n\t\tcontrols.render();\n\t\tprogress.render();\n\t\tnotes.render();\n\n\t\t// Overlay graphic which is displayed during the paused mode\n\t\tdom.pauseOverlay = Util.createSingletonNode( dom.wrapper, 'div', 'pause-overlay', config.controls ? '<button class=\"resume-button\">Resume presentation</button>' : null );\n\n\t\tdom.statusElement = createStatusElement();\n\n\t\tdom.wrapper.setAttribute( 'role', 'application' );\n\t}\n\n\t/**\n\t * Creates a hidden div with role aria-live to announce the\n\t * current slide content. Hide the div off-screen to make it\n\t * available only to Assistive Technologies.\n\t *\n\t * @return {HTMLElement}\n\t */\n\tfunction createStatusElement() {\n\n\t\tlet statusElement = dom.wrapper.querySelector( '.aria-status' );\n\t\tif( !statusElement ) {\n\t\t\tstatusElement = document.createElement( 'div' );\n\t\t\tstatusElement.style.position = 'absolute';\n\t\t\tstatusElement.style.height = '1px';\n\t\t\tstatusElement.style.width = '1px';\n\t\t\tstatusElement.style.overflow = 'hidden';\n\t\t\tstatusElement.style.clip = 'rect( 1px, 1px, 1px, 1px )';\n\t\t\tstatusElement.classList.add( 'aria-status' );\n\t\t\tstatusElement.setAttribute( 'aria-live', 'polite' );\n\t\t\tstatusElement.setAttribute( 'aria-atomic','true' );\n\t\t\tdom.wrapper.appendChild( statusElement );\n\t\t}\n\t\treturn statusElement;\n\n\t}\n\n\t/**\n\t * Announces the given text to screen readers.\n\t */\n\tfunction announceStatus( value ) {\n\n\t\tdom.statusElement.textContent = value;\n\n\t}\n\n\t/**\n\t * Converts the given HTML element into a string of text\n\t * that can be announced to a screen reader. Hidden\n\t * elements are excluded.\n\t */\n\tfunction getStatusText( node ) {\n\n\t\tlet text = '';\n\n\t\t// Text node\n\t\tif( node.nodeType === 3 ) {\n\t\t\ttext += node.textContent;\n\t\t}\n\t\t// Element node\n\t\telse if( node.nodeType === 1 ) {\n\n\t\t\tlet isAriaHidden = node.getAttribute( 'aria-hidden' );\n\t\t\tlet isDisplayHidden = window.getComputedStyle( node )['display'] === 'none';\n\t\t\tif( isAriaHidden !== 'true' && !isDisplayHidden ) {\n\n\t\t\t\tArray.from( node.childNodes ).forEach( child => {\n\t\t\t\t\ttext += getStatusText( child );\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t}\n\n\t\ttext = text.trim();\n\n\t\treturn text === '' ? '' : text + ' ';\n\n\t}\n\n\t/**\n\t * This is an unfortunate necessity. Some actions – such as\n\t * an input field being focused in an iframe or using the\n\t * keyboard to expand text selection beyond the bounds of\n\t * a slide – can trigger our content to be pushed out of view.\n\t * This scrolling can not be prevented by hiding overflow in\n\t * CSS (we already do) so we have to resort to repeatedly\n\t * checking if the slides have been offset :(\n\t */\n\tfunction setupScrollPrevention() {\n\n\t\tsetInterval( () => {\n\t\t\tif( dom.wrapper.scrollTop !== 0 || dom.wrapper.scrollLeft !== 0 ) {\n\t\t\t\tdom.wrapper.scrollTop = 0;\n\t\t\t\tdom.wrapper.scrollLeft = 0;\n\t\t\t}\n\t\t}, 1000 );\n\n\t}\n\n\t/**\n\t * Registers a listener to postMessage events, this makes it\n\t * possible to call all reveal.js API methods from another\n\t * window. For example:\n\t *\n\t * revealWindow.postMessage( JSON.stringify({\n\t * method: 'slide',\n\t * args: [ 2 ]\n\t * }), '*' );\n\t */\n\tfunction setupPostMessage() {\n\n\t\tif( config.postMessage ) {\n\t\t\twindow.addEventListener( 'message', event => {\n\t\t\t\tlet data = event.data;\n\n\t\t\t\t// Make sure we're dealing with JSON\n\t\t\t\tif( typeof data === 'string' && data.charAt( 0 ) === '{' && data.charAt( data.length - 1 ) === '}' ) {\n\t\t\t\t\tdata = JSON.parse( data );\n\n\t\t\t\t\t// Check if the requested method can be found\n\t\t\t\t\tif( data.method && typeof Reveal[data.method] === 'function' ) {\n\n\t\t\t\t\t\tif( POST_MESSAGE_METHOD_BLACKLIST.test( data.method ) === false ) {\n\n\t\t\t\t\t\t\tconst result = Reveal[data.method].apply( Reveal, data.args );\n\n\t\t\t\t\t\t\t// Dispatch a postMessage event with the returned value from\n\t\t\t\t\t\t\t// our method invocation for getter functions\n\t\t\t\t\t\t\tdispatchPostMessage( 'callback', { method: data.method, result: result } );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tconsole.warn( 'reveal.js: \"'+ data.method +'\" is is blacklisted from the postMessage API' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, false );\n\t\t}\n\n\t}\n\n\t/**\n\t * Applies the configuration settings from the config\n\t * object. May be called multiple times.\n\t *\n\t * @param {object} options\n\t */\n\tfunction configure( options ) {\n\n\t\tconst oldConfig = { ...config }\n\n\t\t// New config options may be passed when this method\n\t\t// is invoked through the API after initialization\n\t\tif( typeof options === 'object' ) Util.extend( config, options );\n\n\t\t// Abort if reveal.js hasn't finished loading, config\n\t\t// changes will be applied automatically once ready\n\t\tif( Reveal.isReady() === false ) return;\n\n\t\tconst numberOfSlides = dom.wrapper.querySelectorAll( SLIDES_SELECTOR ).length;\n\n\t\t// The transition is added as a class on the .reveal element\n\t\tdom.wrapper.classList.remove( oldConfig.transition );\n\t\tdom.wrapper.classList.add( config.transition );\n\n\t\tdom.wrapper.setAttribute( 'data-transition-speed', config.transitionSpeed );\n\t\tdom.wrapper.setAttribute( 'data-background-transition', config.backgroundTransition );\n\n\t\tif( config.shuffle ) {\n\t\t\tshuffle();\n\t\t}\n\n\t\tif( config.rtl ) {\n\t\t\tdom.wrapper.classList.add( 'rtl' );\n\t\t}\n\t\telse {\n\t\t\tdom.wrapper.classList.remove( 'rtl' );\n\t\t}\n\n\t\tif( config.center ) {\n\t\t\tdom.wrapper.classList.add( 'center' );\n\t\t}\n\t\telse {\n\t\t\tdom.wrapper.classList.remove( 'center' );\n\t\t}\n\n\t\t// Exit the paused mode if it was configured off\n\t\tif( config.pause === false ) {\n\t\t\tresume();\n\t\t}\n\n\t\t// Iframe link previews\n\t\tif( config.previewLinks ) {\n\t\t\tenablePreviewLinks();\n\t\t\tdisablePreviewLinks( '[data-preview-link=false]' );\n\t\t}\n\t\telse {\n\t\t\tdisablePreviewLinks();\n\t\t\tenablePreviewLinks( '[data-preview-link]:not([data-preview-link=false])' );\n\t\t}\n\n\t\t// Reset all changes made by auto-animations\n\t\tautoAnimate.reset();\n\n\t\t// Remove existing auto-slide controls\n\t\tif( autoSlidePlayer ) {\n\t\t\tautoSlidePlayer.destroy();\n\t\t\tautoSlidePlayer = null;\n\t\t}\n\n\t\t// Generate auto-slide controls if needed\n\t\tif( numberOfSlides > 1 && config.autoSlide && config.autoSlideStoppable ) {\n\t\t\tautoSlidePlayer = new Playback( dom.wrapper, () => {\n\t\t\t\treturn Math.min( Math.max( ( Date.now() - autoSlideStartTime ) / autoSlide, 0 ), 1 );\n\t\t\t} );\n\n\t\t\tautoSlidePlayer.on( 'click', onAutoSlidePlayerClick );\n\t\t\tautoSlidePaused = false;\n\t\t}\n\n\t\t// Add the navigation mode to the DOM so we can adjust styling\n\t\tif( config.navigationMode !== 'default' ) {\n\t\t\tdom.wrapper.setAttribute( 'data-navigation-mode', config.navigationMode );\n\t\t}\n\t\telse {\n\t\t\tdom.wrapper.removeAttribute( 'data-navigation-mode' );\n\t\t}\n\n\t\tnotes.configure( config, oldConfig );\n\t\tpointer.configure( config, oldConfig );\n\t\tcontrols.configure( config, oldConfig );\n\t\tprogress.configure( config, oldConfig );\n\t\tkeyboard.configure( config, oldConfig );\n\t\tfragments.configure( config, oldConfig );\n\t\tslideNumber.configure( config, oldConfig );\n\n\t\tsync();\n\n\t}\n\n\t/**\n\t * Binds all event listeners.\n\t */\n\tfunction addEventListeners() {\n\n\t\teventsAreBound = true;\n\n\t\twindow.addEventListener( 'hashchange', onWindowHashChange, false );\n\t\twindow.addEventListener( 'resize', onWindowResize, false );\n\n\t\tif( config.touch ) touch.bind();\n\t\tif( config.keyboard ) keyboard.bind();\n\t\tif( config.progress ) progress.bind();\n\t\tcontrols.bind();\n\n\t\tdom.slides.addEventListener( 'transitionend', onTransitionEnd, false );\n\t\tdom.pauseOverlay.addEventListener( 'click', resume, false );\n\n\t\tif( config.focusBodyOnPageVisibilityChange ) {\n\t\t\tdocument.addEventListener( 'visibilitychange', onPageVisibilityChange, false );\n\t\t}\n\n\t}\n\n\t/**\n\t * Unbinds all event listeners.\n\t */\n\tfunction removeEventListeners() {\n\n\t\teventsAreBound = false;\n\n\t\ttouch.unbind();\n\t\tkeyboard.unbind();\n\t\tcontrols.unbind();\n\t\tprogress.unbind();\n\n\t\twindow.removeEventListener( 'hashchange', onWindowHashChange, false );\n\t\twindow.removeEventListener( 'resize', onWindowResize, false );\n\n\t\tdom.slides.removeEventListener( 'transitionend', onTransitionEnd, false );\n\t\tdom.pauseOverlay.removeEventListener( 'click', resume, false );\n\n\t}\n\n\t/**\n\t * Adds a listener to one of our custom reveal.js events,\n\t * like slidechanged.\n\t */\n\tfunction on( type, listener, useCapture ) {\n\n\t\trevealElement.addEventListener( type, listener, useCapture );\n\n\t}\n\n\t/**\n\t * Unsubscribes from a reveal.js event.\n\t */\n\tfunction off( type, listener, useCapture ) {\n\n\t\trevealElement.removeEventListener( type, listener, useCapture );\n\n\t}\n\n\t/**\n\t * Applies CSS transforms to the slides container. The container\n\t * is transformed from two separate sources: layout and the overview\n\t * mode.\n\t *\n\t * @param {object} transforms\n\t */\n\tfunction transformSlides( transforms ) {\n\n\t\t// Pick up new transforms from arguments\n\t\tif( typeof transforms.layout === 'string' ) slidesTransform.layout = transforms.layout;\n\t\tif( typeof transforms.overview === 'string' ) slidesTransform.overview = transforms.overview;\n\n\t\t// Apply the transforms to the slides container\n\t\tif( slidesTransform.layout ) {\n\t\t\tUtil.transformElement( dom.slides, slidesTransform.layout + ' ' + slidesTransform.overview );\n\t\t}\n\t\telse {\n\t\t\tUtil.transformElement( dom.slides, slidesTransform.overview );\n\t\t}\n\n\t}\n\n\t/**\n\t * Dispatches an event of the specified type from the\n\t * reveal DOM element.\n\t */\n\tfunction dispatchEvent({ target=dom.wrapper, type, data, bubbles=true }) {\n\n\t\tlet event = document.createEvent( 'HTMLEvents', 1, 2 );\n\t\tevent.initEvent( type, bubbles, true );\n\t\tUtil.extend( event, data );\n\t\ttarget.dispatchEvent( event );\n\n\t\tif( target === dom.wrapper ) {\n\t\t\t// If we're in an iframe, post each reveal.js event to the\n\t\t\t// parent window. Used by the notes plugin\n\t\t\tdispatchPostMessage( type );\n\t\t}\n\n\t}\n\n\t/**\n\t * Dispatched a postMessage of the given type from our window.\n\t */\n\tfunction dispatchPostMessage( type, data ) {\n\n\t\tif( config.postMessageEvents && window.parent !== window.self ) {\n\t\t\tlet message = {\n\t\t\t\tnamespace: 'reveal',\n\t\t\t\teventName: type,\n\t\t\t\tstate: getState()\n\t\t\t};\n\n\t\t\tUtil.extend( message, data );\n\n\t\t\twindow.parent.postMessage( JSON.stringify( message ), '*' );\n\t\t}\n\n\t}\n\n\t/**\n\t * Bind preview frame links.\n\t *\n\t * @param {string} [selector=a] - selector for anchors\n\t */\n\tfunction enablePreviewLinks( selector = 'a' ) {\n\n\t\tArray.from( dom.wrapper.querySelectorAll( selector ) ).forEach( element => {\n\t\t\tif( /^(http|www)/gi.test( element.getAttribute( 'href' ) ) ) {\n\t\t\t\telement.addEventListener( 'click', onPreviewLinkClicked, false );\n\t\t\t}\n\t\t} );\n\n\t}\n\n\t/**\n\t * Unbind preview frame links.\n\t */\n\tfunction disablePreviewLinks( selector = 'a' ) {\n\n\t\tArray.from( dom.wrapper.querySelectorAll( selector ) ).forEach( element => {\n\t\t\tif( /^(http|www)/gi.test( element.getAttribute( 'href' ) ) ) {\n\t\t\t\telement.removeEventListener( 'click', onPreviewLinkClicked, false );\n\t\t\t}\n\t\t} );\n\n\t}\n\n\t/**\n\t * Opens a preview window for the target URL.\n\t *\n\t * @param {string} url - url for preview iframe src\n\t */\n\tfunction showPreview( url ) {\n\n\t\tcloseOverlay();\n\n\t\tdom.overlay = document.createElement( 'div' );\n\t\tdom.overlay.classList.add( 'overlay' );\n\t\tdom.overlay.classList.add( 'overlay-preview' );\n\t\tdom.wrapper.appendChild( dom.overlay );\n\n\t\tdom.overlay.innerHTML =\n\t\t\t`<header>\n\t\t\t\t<a class=\"close\" href=\"#\"><span class=\"icon\"></span></a>\n\t\t\t\t<a class=\"external\" href=\"${url}\" target=\"_blank\"><span class=\"icon\"></span></a>\n\t\t\t</header>\n\t\t\t<div class=\"spinner\"></div>\n\t\t\t<div class=\"viewport\">\n\t\t\t\t<iframe src=\"${url}\"></iframe>\n\t\t\t\t<small class=\"viewport-inner\">\n\t\t\t\t\t<span class=\"x-frame-error\">Unable to load iframe. This is likely due to the site's policy (x-frame-options).</span>\n\t\t\t\t</small>\n\t\t\t</div>`;\n\n\t\tdom.overlay.querySelector( 'iframe' ).addEventListener( 'load', event => {\n\t\t\tdom.overlay.classList.add( 'loaded' );\n\t\t}, false );\n\n\t\tdom.overlay.querySelector( '.close' ).addEventListener( 'click', event => {\n\t\t\tcloseOverlay();\n\t\t\tevent.preventDefault();\n\t\t}, false );\n\n\t\tdom.overlay.querySelector( '.external' ).addEventListener( 'click', event => {\n\t\t\tcloseOverlay();\n\t\t}, false );\n\n\t}\n\n\t/**\n\t * Open or close help overlay window.\n\t *\n\t * @param {Boolean} [override] Flag which overrides the\n\t * toggle logic and forcibly sets the desired state. True means\n\t * help is open, false means it's closed.\n\t */\n\tfunction toggleHelp( override ){\n\n\t\tif( typeof override === 'boolean' ) {\n\t\t\toverride ? showHelp() : closeOverlay();\n\t\t}\n\t\telse {\n\t\t\tif( dom.overlay ) {\n\t\t\t\tcloseOverlay();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tshowHelp();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Opens an overlay window with help material.\n\t */\n\tfunction showHelp() {\n\n\t\tif( config.help ) {\n\n\t\t\tcloseOverlay();\n\n\t\t\tdom.overlay = document.createElement( 'div' );\n\t\t\tdom.overlay.classList.add( 'overlay' );\n\t\t\tdom.overlay.classList.add( 'overlay-help' );\n\t\t\tdom.wrapper.appendChild( dom.overlay );\n\n\t\t\tlet html = '<p class=\"title\">Keyboard Shortcuts</p><br/>';\n\n\t\t\thtml += '<table><th>KEY</th><th>ACTION</th>';\n\t\t\tfor( let key in keyboard.shortcuts ) {\n\t\t\t\thtml += `<tr><td>${key}</td><td>${keyboard.shortcuts[ key ]}</td></tr>`;\n\t\t\t}\n\n\t\t\t// Add custom key bindings that have associated descriptions\n\t\t\tfor( let binding in keyboard.registeredKeyBindings ) {\n\t\t\t\tif( keyboard.registeredKeyBindings[binding].key && keyboard.registeredKeyBindings[binding].description ) {\n\t\t\t\t\thtml += `<tr><td>${keyboard.registeredKeyBindings[binding].key}</td><td>${keyboard.registeredKeyBindings[binding].description}</td></tr>`;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\thtml += '</table>';\n\n\t\t\tdom.overlay.innerHTML = `\n\t\t\t\t<header>\n\t\t\t\t\t<a class=\"close\" href=\"#\"><span class=\"icon\"></span></a>\n\t\t\t\t</header>\n\t\t\t\t<div class=\"viewport\">\n\t\t\t\t\t<div class=\"viewport-inner\">${html}</div>\n\t\t\t\t</div>\n\t\t\t`;\n\n\t\t\tdom.overlay.querySelector( '.close' ).addEventListener( 'click', event => {\n\t\t\t\tcloseOverlay();\n\t\t\t\tevent.preventDefault();\n\t\t\t}, false );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Closes any currently open overlay.\n\t */\n\tfunction closeOverlay() {\n\n\t\tif( dom.overlay ) {\n\t\t\tdom.overlay.parentNode.removeChild( dom.overlay );\n\t\t\tdom.overlay = null;\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\t/**\n\t * Applies JavaScript-controlled layout rules to the\n\t * presentation.\n\t */\n\tfunction layout() {\n\n\t\tif( dom.wrapper && !print.isPrintingPDF() ) {\n\n\t\t\tif( !config.disableLayout ) {\n\n\t\t\t\t// On some mobile devices '100vh' is taller than the visible\n\t\t\t\t// viewport which leads to part of the presentation being\n\t\t\t\t// cut off. To work around this we define our own '--vh' custom\n\t\t\t\t// property where 100x adds up to the correct height.\n\t\t\t\t//\n\t\t\t\t// https://css-tricks.com/the-trick-to-viewport-units-on-mobile/\n\t\t\t\tif( Device.isMobile ) {\n\t\t\t\t\tdocument.documentElement.style.setProperty( '--vh', ( window.innerHeight * 0.01 ) + 'px' );\n\t\t\t\t}\n\n\t\t\t\tconst size = getComputedSlideSize();\n\n\t\t\t\tconst oldScale = scale;\n\n\t\t\t\t// Layout the contents of the slides\n\t\t\t\tlayoutSlideContents( config.width, config.height );\n\n\t\t\t\tdom.slides.style.width = size.width + 'px';\n\t\t\t\tdom.slides.style.height = size.height + 'px';\n\n\t\t\t\t// Determine scale of content to fit within available space\n\t\t\t\tscale = Math.min( size.presentationWidth / size.width, size.presentationHeight / size.height );\n\n\t\t\t\t// Respect max/min scale settings\n\t\t\t\tscale = Math.max( scale, config.minScale );\n\t\t\t\tscale = Math.min( scale, config.maxScale );\n\n\t\t\t\t// Don't apply any scaling styles if scale is 1\n\t\t\t\tif( scale === 1 ) {\n\t\t\t\t\tdom.slides.style.zoom = '';\n\t\t\t\t\tdom.slides.style.left = '';\n\t\t\t\t\tdom.slides.style.top = '';\n\t\t\t\t\tdom.slides.style.bottom = '';\n\t\t\t\t\tdom.slides.style.right = '';\n\t\t\t\t\ttransformSlides( { layout: '' } );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// Zoom Scaling\n\t\t\t\t\t// Content remains crisp no matter how much we scale. Side\n\t\t\t\t\t// effects are minor differences in text layout and iframe\n\t\t\t\t\t// viewports changing size. A 200x200 iframe viewport in a\n\t\t\t\t\t// 2x zoomed presentation ends up having a 400x400 viewport.\n\t\t\t\t\tif( scale > 1 && Device.supportsZoom && window.devicePixelRatio < 2 ) {\n\t\t\t\t\t\tdom.slides.style.zoom = scale;\n\t\t\t\t\t\tdom.slides.style.left = '';\n\t\t\t\t\t\tdom.slides.style.top = '';\n\t\t\t\t\t\tdom.slides.style.bottom = '';\n\t\t\t\t\t\tdom.slides.style.right = '';\n\t\t\t\t\t\ttransformSlides( { layout: '' } );\n\t\t\t\t\t}\n\t\t\t\t\t// Transform Scaling\n\t\t\t\t\t// Content layout remains the exact same when scaled up.\n\t\t\t\t\t// Side effect is content becoming blurred, especially with\n\t\t\t\t\t// high scale values on ldpi screens.\n\t\t\t\t\telse {\n\t\t\t\t\t\tdom.slides.style.zoom = '';\n\t\t\t\t\t\tdom.slides.style.left = '50%';\n\t\t\t\t\t\tdom.slides.style.top = '50%';\n\t\t\t\t\t\tdom.slides.style.bottom = 'auto';\n\t\t\t\t\t\tdom.slides.style.right = 'auto';\n\t\t\t\t\t\ttransformSlides( { layout: 'translate(-50%, -50%) scale('+ scale +')' } );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Select all slides, vertical and horizontal\n\t\t\t\tconst slides = Array.from( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) );\n\n\t\t\t\tfor( let i = 0, len = slides.length; i < len; i++ ) {\n\t\t\t\t\tconst slide = slides[ i ];\n\n\t\t\t\t\t// Don't bother updating invisible slides\n\t\t\t\t\tif( slide.style.display === 'none' ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif( config.center || slide.classList.contains( 'center' ) ) {\n\t\t\t\t\t\t// Vertical stacks are not centred since their section\n\t\t\t\t\t\t// children will be\n\t\t\t\t\t\tif( slide.classList.contains( 'stack' ) ) {\n\t\t\t\t\t\t\tslide.style.top = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tslide.style.top = Math.max( ( size.height - slide.scrollHeight ) / 2, 0 ) + 'px';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tslide.style.top = '';\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif( oldScale !== scale ) {\n\t\t\t\t\tdispatchEvent({\n\t\t\t\t\t\ttype: 'resize',\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\toldScale,\n\t\t\t\t\t\t\tscale,\n\t\t\t\t\t\t\tsize\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tprogress.update();\n\t\t\tbackgrounds.updateParallax();\n\n\t\t\tif( overview.isActive() ) {\n\t\t\t\toverview.update();\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Applies layout logic to the contents of all slides in\n\t * the presentation.\n\t *\n\t * @param {string|number} width\n\t * @param {string|number} height\n\t */\n\tfunction layoutSlideContents( width, height ) {\n\n\t\t// Handle sizing of elements with the 'stretch' class\n\t\tUtil.queryAll( dom.slides, 'section > .stretch' ).forEach( element => {\n\n\t\t\t// Determine how much vertical space we can use\n\t\t\tlet remainingHeight = Util.getRemainingHeight( element, height );\n\n\t\t\t// Consider the aspect ratio of media elements\n\t\t\tif( /(img|video)/gi.test( element.nodeName ) ) {\n\t\t\t\tconst nw = element.naturalWidth || element.videoWidth,\n\t\t\t\t\t nh = element.naturalHeight || element.videoHeight;\n\n\t\t\t\tconst es = Math.min( width / nw, remainingHeight / nh );\n\n\t\t\t\telement.style.width = ( nw * es ) + 'px';\n\t\t\t\telement.style.height = ( nh * es ) + 'px';\n\n\t\t\t}\n\t\t\telse {\n\t\t\t\telement.style.width = width + 'px';\n\t\t\t\telement.style.height = remainingHeight + 'px';\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Calculates the computed pixel size of our slides. These\n\t * values are based on the width and height configuration\n\t * options.\n\t *\n\t * @param {number} [presentationWidth=dom.wrapper.offsetWidth]\n\t * @param {number} [presentationHeight=dom.wrapper.offsetHeight]\n\t */\n\tfunction getComputedSlideSize( presentationWidth, presentationHeight ) {\n\n\t\tconst size = {\n\t\t\t// Slide size\n\t\t\twidth: config.width,\n\t\t\theight: config.height,\n\n\t\t\t// Presentation size\n\t\t\tpresentationWidth: presentationWidth || dom.wrapper.offsetWidth,\n\t\t\tpresentationHeight: presentationHeight || dom.wrapper.offsetHeight\n\t\t};\n\n\t\t// Reduce available space by margin\n\t\tsize.presentationWidth -= ( size.presentationWidth * config.margin );\n\t\tsize.presentationHeight -= ( size.presentationHeight * config.margin );\n\n\t\t// Slide width may be a percentage of available width\n\t\tif( typeof size.width === 'string' && /%$/.test( size.width ) ) {\n\t\t\tsize.width = parseInt( size.width, 10 ) / 100 * size.presentationWidth;\n\t\t}\n\n\t\t// Slide height may be a percentage of available height\n\t\tif( typeof size.height === 'string' && /%$/.test( size.height ) ) {\n\t\t\tsize.height = parseInt( size.height, 10 ) / 100 * size.presentationHeight;\n\t\t}\n\n\t\treturn size;\n\n\t}\n\n\t/**\n\t * Stores the vertical index of a stack so that the same\n\t * vertical slide can be selected when navigating to and\n\t * from the stack.\n\t *\n\t * @param {HTMLElement} stack The vertical stack element\n\t * @param {string|number} [v=0] Index to memorize\n\t */\n\tfunction setPreviousVerticalIndex( stack, v ) {\n\n\t\tif( typeof stack === 'object' && typeof stack.setAttribute === 'function' ) {\n\t\t\tstack.setAttribute( 'data-previous-indexv', v || 0 );\n\t\t}\n\n\t}\n\n\t/**\n\t * Retrieves the vertical index which was stored using\n\t * #setPreviousVerticalIndex() or 0 if no previous index\n\t * exists.\n\t *\n\t * @param {HTMLElement} stack The vertical stack element\n\t */\n\tfunction getPreviousVerticalIndex( stack ) {\n\n\t\tif( typeof stack === 'object' && typeof stack.setAttribute === 'function' && stack.classList.contains( 'stack' ) ) {\n\t\t\t// Prefer manually defined start-indexv\n\t\t\tconst attributeName = stack.hasAttribute( 'data-start-indexv' ) ? 'data-start-indexv' : 'data-previous-indexv';\n\n\t\t\treturn parseInt( stack.getAttribute( attributeName ) || 0, 10 );\n\t\t}\n\n\t\treturn 0;\n\n\t}\n\n\t/**\n\t * Checks if the current or specified slide is vertical\n\t * (nested within another slide).\n\t *\n\t * @param {HTMLElement} [slide=currentSlide] The slide to check\n\t * orientation of\n\t * @return {Boolean}\n\t */\n\tfunction isVerticalSlide( slide = currentSlide ) {\n\n\t\treturn slide && slide.parentNode && !!slide.parentNode.nodeName.match( /section/i );\n\n\t}\n\n\t/**\n\t * Returns true if we're on the last slide in the current\n\t * vertical stack.\n\t */\n\tfunction isLastVerticalSlide() {\n\n\t\tif( currentSlide && isVerticalSlide( currentSlide ) ) {\n\t\t\t// Does this slide have a next sibling?\n\t\t\tif( currentSlide.nextElementSibling ) return false;\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\t/**\n\t * Returns true if we're currently on the first slide in\n\t * the presentation.\n\t */\n\tfunction isFirstSlide() {\n\n\t\treturn indexh === 0 && indexv === 0;\n\n\t}\n\n\t/**\n\t * Returns true if we're currently on the last slide in\n\t * the presenation. If the last slide is a stack, we only\n\t * consider this the last slide if it's at the end of the\n\t * stack.\n\t */\n\tfunction isLastSlide() {\n\n\t\tif( currentSlide ) {\n\t\t\t// Does this slide have a next sibling?\n\t\t\tif( currentSlide.nextElementSibling ) return false;\n\n\t\t\t// If it's vertical, does its parent have a next sibling?\n\t\t\tif( isVerticalSlide( currentSlide ) && currentSlide.parentNode.nextElementSibling ) return false;\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\t/**\n\t * Enters the paused mode which fades everything on screen to\n\t * black.\n\t */\n\tfunction pause() {\n\n\t\tif( config.pause ) {\n\t\t\tconst wasPaused = dom.wrapper.classList.contains( 'paused' );\n\n\t\t\tcancelAutoSlide();\n\t\t\tdom.wrapper.classList.add( 'paused' );\n\n\t\t\tif( wasPaused === false ) {\n\t\t\t\tdispatchEvent({ type: 'paused' });\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Exits from the paused mode.\n\t */\n\tfunction resume() {\n\n\t\tconst wasPaused = dom.wrapper.classList.contains( 'paused' );\n\t\tdom.wrapper.classList.remove( 'paused' );\n\n\t\tcueAutoSlide();\n\n\t\tif( wasPaused ) {\n\t\t\tdispatchEvent({ type: 'resumed' });\n\t\t}\n\n\t}\n\n\t/**\n\t * Toggles the paused mode on and off.\n\t */\n\tfunction togglePause( override ) {\n\n\t\tif( typeof override === 'boolean' ) {\n\t\t\toverride ? pause() : resume();\n\t\t}\n\t\telse {\n\t\t\tisPaused() ? resume() : pause();\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks if we are currently in the paused mode.\n\t *\n\t * @return {Boolean}\n\t */\n\tfunction isPaused() {\n\n\t\treturn dom.wrapper.classList.contains( 'paused' );\n\n\t}\n\n\t/**\n\t * Toggles the auto slide mode on and off.\n\t *\n\t * @param {Boolean} [override] Flag which sets the desired state.\n\t * True means autoplay starts, false means it stops.\n\t */\n\n\tfunction toggleAutoSlide( override ) {\n\n\t\tif( typeof override === 'boolean' ) {\n\t\t\toverride ? resumeAutoSlide() : pauseAutoSlide();\n\t\t}\n\n\t\telse {\n\t\t\tautoSlidePaused ? resumeAutoSlide() : pauseAutoSlide();\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks if the auto slide mode is currently on.\n\t *\n\t * @return {Boolean}\n\t */\n\tfunction isAutoSliding() {\n\n\t\treturn !!( autoSlide && !autoSlidePaused );\n\n\t}\n\n\t/**\n\t * Steps from the current point in the presentation to the\n\t * slide which matches the specified horizontal and vertical\n\t * indices.\n\t *\n\t * @param {number} [h=indexh] Horizontal index of the target slide\n\t * @param {number} [v=indexv] Vertical index of the target slide\n\t * @param {number} [f] Index of a fragment within the\n\t * target slide to activate\n\t * @param {number} [o] Origin for use in multimaster environments\n\t */\n\tfunction slide( h, v, f, o ) {\n\n\t\t// Remember where we were at before\n\t\tpreviousSlide = currentSlide;\n\n\t\t// Query all horizontal slides in the deck\n\t\tconst horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );\n\n\t\t// Abort if there are no slides\n\t\tif( horizontalSlides.length === 0 ) return;\n\n\t\t// If no vertical index is specified and the upcoming slide is a\n\t\t// stack, resume at its previous vertical index\n\t\tif( v === undefined && !overview.isActive() ) {\n\t\t\tv = getPreviousVerticalIndex( horizontalSlides[ h ] );\n\t\t}\n\n\t\t// If we were on a vertical stack, remember what vertical index\n\t\t// it was on so we can resume at the same position when returning\n\t\tif( previousSlide && previousSlide.parentNode && previousSlide.parentNode.classList.contains( 'stack' ) ) {\n\t\t\tsetPreviousVerticalIndex( previousSlide.parentNode, indexv );\n\t\t}\n\n\t\t// Remember the state before this slide\n\t\tconst stateBefore = state.concat();\n\n\t\t// Reset the state array\n\t\tstate.length = 0;\n\n\t\tlet indexhBefore = indexh || 0,\n\t\t\tindexvBefore = indexv || 0;\n\n\t\t// Activate and transition to the new slide\n\t\tindexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h );\n\t\tindexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v );\n\n\t\t// Dispatch an event if the slide changed\n\t\tlet slideChanged = ( indexh !== indexhBefore || indexv !== indexvBefore );\n\n\t\t// Ensure that the previous slide is never the same as the current\n\t\tif( !slideChanged ) previousSlide = null;\n\n\t\t// Find the current horizontal slide and any possible vertical slides\n\t\t// within it\n\t\tlet currentHorizontalSlide = horizontalSlides[ indexh ],\n\t\t\tcurrentVerticalSlides = currentHorizontalSlide.querySelectorAll( 'section' );\n\n\t\t// Store references to the previous and current slides\n\t\tcurrentSlide = currentVerticalSlides[ indexv ] || currentHorizontalSlide;\n\n\t\tlet autoAnimateTransition = false;\n\n\t\t// Detect if we're moving between two auto-animated slides\n\t\tif( slideChanged && previousSlide && currentSlide && !overview.isActive() ) {\n\n\t\t\t// If this is an auto-animated transition, we disable the\n\t\t\t// regular slide transition\n\t\t\t//\n\t\t\t// Note 20-03-2020:\n\t\t\t// This needs to happen before we update slide visibility,\n\t\t\t// otherwise transitions will still run in Safari.\n\t\t\tif( previousSlide.hasAttribute( 'data-auto-animate' ) && currentSlide.hasAttribute( 'data-auto-animate' ) ) {\n\t\t\t\tautoAnimateTransition = true;\n\t\t\t\tdom.slides.classList.add( 'disable-slide-transitions' );\n\t\t\t}\n\n\t\t\ttransition = 'running';\n\n\t\t}\n\n\t\t// Update the visibility of slides now that the indices have changed\n\t\tupdateSlidesVisibility();\n\n\t\tlayout();\n\n\t\t// Update the overview if it's currently active\n\t\tif( overview.isActive() ) {\n\t\t\toverview.update();\n\t\t}\n\n\t\t// Show fragment, if specified\n\t\tif( typeof f !== 'undefined' ) {\n\t\t\tfragments.goto( f );\n\t\t}\n\n\t\t// Solves an edge case where the previous slide maintains the\n\t\t// 'present' class when navigating between adjacent vertical\n\t\t// stacks\n\t\tif( previousSlide && previousSlide !== currentSlide ) {\n\t\t\tpreviousSlide.classList.remove( 'present' );\n\t\t\tpreviousSlide.setAttribute( 'aria-hidden', 'true' );\n\n\t\t\t// Reset all slides upon navigate to home\n\t\t\tif( isFirstSlide() ) {\n\t\t\t\t// Launch async task\n\t\t\t\tsetTimeout( () => {\n\t\t\t\t\tgetVerticalStacks().forEach( slide => {\n\t\t\t\t\t\tsetPreviousVerticalIndex( slide, 0 );\n\t\t\t\t\t} );\n\t\t\t\t}, 0 );\n\t\t\t}\n\t\t}\n\n\t\t// Apply the new state\n\t\tstateLoop: for( let i = 0, len = state.length; i < len; i++ ) {\n\t\t\t// Check if this state existed on the previous slide. If it\n\t\t\t// did, we will avoid adding it repeatedly\n\t\t\tfor( let j = 0; j < stateBefore.length; j++ ) {\n\t\t\t\tif( stateBefore[j] === state[i] ) {\n\t\t\t\t\tstateBefore.splice( j, 1 );\n\t\t\t\t\tcontinue stateLoop;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdocument.documentElement.classList.add( state[i] );\n\n\t\t\t// Dispatch custom event matching the state's name\n\t\t\tdispatchEvent({ type: state[i] });\n\t\t}\n\n\t\t// Clean up the remains of the previous state\n\t\twhile( stateBefore.length ) {\n\t\t\tdocument.documentElement.classList.remove( stateBefore.pop() );\n\t\t}\n\n\t\tif( slideChanged ) {\n\t\t\tdispatchEvent({\n\t\t\t\ttype: 'slidechanged',\n\t\t\t\tdata: {\n\t\t\t\t\tindexh,\n\t\t\t\t\tindexv,\n\t\t\t\t\tpreviousSlide,\n\t\t\t\t\tcurrentSlide,\n\t\t\t\t\torigin: o\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\t// Handle embedded content\n\t\tif( slideChanged || !previousSlide ) {\n\t\t\tslideContent.stopEmbeddedContent( previousSlide );\n\t\t\tslideContent.startEmbeddedContent( currentSlide );\n\t\t}\n\n\t\t// Announce the current slide contents to screen readers\n\t\tannounceStatus( getStatusText( currentSlide ) );\n\n\t\tprogress.update();\n\t\tcontrols.update();\n\t\tnotes.update();\n\t\tbackgrounds.update();\n\t\tbackgrounds.updateParallax();\n\t\tslideNumber.update();\n\t\tfragments.update();\n\n\t\t// Update the URL hash\n\t\tlocation.writeURL();\n\n\t\tcueAutoSlide();\n\n\t\t// Auto-animation\n\t\tif( autoAnimateTransition ) {\n\n\t\t\tsetTimeout( () => {\n\t\t\t\tdom.slides.classList.remove( 'disable-slide-transitions' );\n\t\t\t}, 0 );\n\n\t\t\tif( config.autoAnimate ) {\n\t\t\t\t// Run the auto-animation between our slides\n\t\t\t\tautoAnimate.run( previousSlide, currentSlide );\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Syncs the presentation with the current DOM. Useful\n\t * when new slides or control elements are added or when\n\t * the configuration has changed.\n\t */\n\tfunction sync() {\n\n\t\t// Subscribe to input\n\t\tremoveEventListeners();\n\t\taddEventListeners();\n\n\t\t// Force a layout to make sure the current config is accounted for\n\t\tlayout();\n\n\t\t// Reflect the current autoSlide value\n\t\tautoSlide = config.autoSlide;\n\n\t\t// Start auto-sliding if it's enabled\n\t\tcueAutoSlide();\n\n\t\t// Re-create all slide backgrounds\n\t\tbackgrounds.create();\n\n\t\t// Write the current hash to the URL\n\t\tlocation.writeURL();\n\n\t\tfragments.sortAll();\n\n\t\tcontrols.update();\n\t\tprogress.update();\n\n\t\tupdateSlidesVisibility();\n\n\t\tnotes.update();\n\t\tnotes.updateVisibility();\n\t\tbackgrounds.update( true );\n\t\tslideNumber.update();\n\t\tslideContent.formatEmbeddedContent();\n\n\t\t// Start or stop embedded content depending on global config\n\t\tif( config.autoPlayMedia === false ) {\n\t\t\tslideContent.stopEmbeddedContent( currentSlide, { unloadIframes: false } );\n\t\t}\n\t\telse {\n\t\t\tslideContent.startEmbeddedContent( currentSlide );\n\t\t}\n\n\t\tif( overview.isActive() ) {\n\t\t\toverview.layout();\n\t\t}\n\n\t}\n\n\t/**\n\t * Updates reveal.js to keep in sync with new slide attributes. For\n\t * example, if you add a new `data-background-image` you can call\n\t * this to have reveal.js render the new background image.\n\t *\n\t * Similar to #sync() but more efficient when you only need to\n\t * refresh a specific slide.\n\t *\n\t * @param {HTMLElement} slide\n\t */\n\tfunction syncSlide( slide = currentSlide ) {\n\n\t\tbackgrounds.sync( slide );\n\t\tfragments.sync( slide );\n\n\t\tslideContent.load( slide );\n\n\t\tbackgrounds.update();\n\t\tnotes.update();\n\n\t}\n\n\t/**\n\t * Resets all vertical slides so that only the first\n\t * is visible.\n\t */\n\tfunction resetVerticalSlides() {\n\n\t\tgetHorizontalSlides().forEach( horizontalSlide => {\n\n\t\t\tUtil.queryAll( horizontalSlide, 'section' ).forEach( ( verticalSlide, y ) => {\n\n\t\t\t\tif( y > 0 ) {\n\t\t\t\t\tverticalSlide.classList.remove( 'present' );\n\t\t\t\t\tverticalSlide.classList.remove( 'past' );\n\t\t\t\t\tverticalSlide.classList.add( 'future' );\n\t\t\t\t\tverticalSlide.setAttribute( 'aria-hidden', 'true' );\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Randomly shuffles all slides in the deck.\n\t */\n\tfunction shuffle() {\n\n\t\tgetHorizontalSlides().forEach( ( slide, i, slides ) => {\n\n\t\t\t// Insert this slide next to another random slide. This may\n\t\t\t// cause the slide to insert before itself but that's fine.\n\t\t\tdom.slides.insertBefore( slide, slides[ Math.floor( Math.random() * slides.length ) ] );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Updates one dimension of slides by showing the slide\n\t * with the specified index.\n\t *\n\t * @param {string} selector A CSS selector that will fetch\n\t * the group of slides we are working with\n\t * @param {number} index The index of the slide that should be\n\t * shown\n\t *\n\t * @return {number} The index of the slide that is now shown,\n\t * might differ from the passed in index if it was out of\n\t * bounds.\n\t */\n\tfunction updateSlides( selector, index ) {\n\n\t\t// Select all slides and convert the NodeList result to\n\t\t// an array\n\t\tlet slides = Util.queryAll( dom.wrapper, selector ),\n\t\t\tslidesLength = slides.length;\n\n\t\tlet printMode = print.isPrintingPDF();\n\n\t\tif( slidesLength ) {\n\n\t\t\t// Should the index loop?\n\t\t\tif( config.loop ) {\n\t\t\t\tindex %= slidesLength;\n\n\t\t\t\tif( index < 0 ) {\n\t\t\t\t\tindex = slidesLength + index;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Enforce max and minimum index bounds\n\t\t\tindex = Math.max( Math.min( index, slidesLength - 1 ), 0 );\n\n\t\t\tfor( let i = 0; i < slidesLength; i++ ) {\n\t\t\t\tlet element = slides[i];\n\n\t\t\t\tlet reverse = config.rtl && !isVerticalSlide( element );\n\n\t\t\t\telement.classList.remove( 'past', 'present', 'future' );\n\n\t\t\t\t// http://www.w3.org/html/wg/drafts/html/master/editing.html#the-hidden-attribute\n\t\t\t\telement.setAttribute( 'hidden', '' );\n\t\t\t\telement.setAttribute( 'aria-hidden', 'true' );\n\n\t\t\t\t// If this element contains vertical slides\n\t\t\t\tif( element.querySelector( 'section' ) ) {\n\t\t\t\t\telement.classList.add( 'stack' );\n\t\t\t\t}\n\n\t\t\t\t// If we're printing static slides, all slides are \"present\"\n\t\t\t\tif( printMode ) {\n\t\t\t\t\telement.classList.add( 'present' );\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif( i < index ) {\n\t\t\t\t\t// Any element previous to index is given the 'past' class\n\t\t\t\t\telement.classList.add( reverse ? 'future' : 'past' );\n\n\t\t\t\t\tif( config.fragments ) {\n\t\t\t\t\t\t// Show all fragments in prior slides\n\t\t\t\t\t\tUtil.queryAll( element, '.fragment' ).forEach( fragment => {\n\t\t\t\t\t\t\tfragment.classList.add( 'visible' );\n\t\t\t\t\t\t\tfragment.classList.remove( 'current-fragment' );\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( i > index ) {\n\t\t\t\t\t// Any element subsequent to index is given the 'future' class\n\t\t\t\t\telement.classList.add( reverse ? 'past' : 'future' );\n\n\t\t\t\t\tif( config.fragments ) {\n\t\t\t\t\t\t// Hide all fragments in future slides\n\t\t\t\t\t\tUtil.queryAll( element, '.fragment.visible' ).forEach( fragment => {\n\t\t\t\t\t\t\tfragment.classList.remove( 'visible', 'current-fragment' );\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet slide = slides[index];\n\t\t\tlet wasPresent = slide.classList.contains( 'present' );\n\n\t\t\t// Mark the current slide as present\n\t\t\tslide.classList.add( 'present' );\n\t\t\tslide.removeAttribute( 'hidden' );\n\t\t\tslide.removeAttribute( 'aria-hidden' );\n\n\t\t\tif( !wasPresent ) {\n\t\t\t\t// Dispatch an event indicating the slide is now visible\n\t\t\t\tdispatchEvent({\n\t\t\t\t\ttarget: slide,\n\t\t\t\t\ttype: 'visible',\n\t\t\t\t\tbubbles: false\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// If this slide has a state associated with it, add it\n\t\t\t// onto the current state of the deck\n\t\t\tlet slideState = slide.getAttribute( 'data-state' );\n\t\t\tif( slideState ) {\n\t\t\t\tstate = state.concat( slideState.split( ' ' ) );\n\t\t\t}\n\n\t\t}\n\t\telse {\n\t\t\t// Since there are no slides we can't be anywhere beyond the\n\t\t\t// zeroth index\n\t\t\tindex = 0;\n\t\t}\n\n\t\treturn index;\n\n\t}\n\n\t/**\n\t * Optimization method; hide all slides that are far away\n\t * from the present slide.\n\t */\n\tfunction updateSlidesVisibility() {\n\n\t\t// Select all slides and convert the NodeList result to\n\t\t// an array\n\t\tlet horizontalSlides = getHorizontalSlides(),\n\t\t\thorizontalSlidesLength = horizontalSlides.length,\n\t\t\tdistanceX,\n\t\t\tdistanceY;\n\n\t\tif( horizontalSlidesLength && typeof indexh !== 'undefined' ) {\n\n\t\t\t// The number of steps away from the present slide that will\n\t\t\t// be visible\n\t\t\tlet viewDistance = overview.isActive() ? 10 : config.viewDistance;\n\n\t\t\t// Shorten the view distance on devices that typically have\n\t\t\t// less resources\n\t\t\tif( Device.isMobile ) {\n\t\t\t\tviewDistance = overview.isActive() ? 6 : config.mobileViewDistance;\n\t\t\t}\n\n\t\t\t// All slides need to be visible when exporting to PDF\n\t\t\tif( print.isPrintingPDF() ) {\n\t\t\t\tviewDistance = Number.MAX_VALUE;\n\t\t\t}\n\n\t\t\tfor( let x = 0; x < horizontalSlidesLength; x++ ) {\n\t\t\t\tlet horizontalSlide = horizontalSlides[x];\n\n\t\t\t\tlet verticalSlides = Util.queryAll( horizontalSlide, 'section' ),\n\t\t\t\t\tverticalSlidesLength = verticalSlides.length;\n\n\t\t\t\t// Determine how far away this slide is from the present\n\t\t\t\tdistanceX = Math.abs( ( indexh || 0 ) - x ) || 0;\n\n\t\t\t\t// If the presentation is looped, distance should measure\n\t\t\t\t// 1 between the first and last slides\n\t\t\t\tif( config.loop ) {\n\t\t\t\t\tdistanceX = Math.abs( ( ( indexh || 0 ) - x ) % ( horizontalSlidesLength - viewDistance ) ) || 0;\n\t\t\t\t}\n\n\t\t\t\t// Show the horizontal slide if it's within the view distance\n\t\t\t\tif( distanceX < viewDistance ) {\n\t\t\t\t\tslideContent.load( horizontalSlide );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tslideContent.unload( horizontalSlide );\n\t\t\t\t}\n\n\t\t\t\tif( verticalSlidesLength ) {\n\n\t\t\t\t\tlet oy = getPreviousVerticalIndex( horizontalSlide );\n\n\t\t\t\t\tfor( let y = 0; y < verticalSlidesLength; y++ ) {\n\t\t\t\t\t\tlet verticalSlide = verticalSlides[y];\n\n\t\t\t\t\t\tdistanceY = x === ( indexh || 0 ) ? Math.abs( ( indexv || 0 ) - y ) : Math.abs( y - oy );\n\n\t\t\t\t\t\tif( distanceX + distanceY < viewDistance ) {\n\t\t\t\t\t\t\tslideContent.load( verticalSlide );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tslideContent.unload( verticalSlide );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Flag if there are ANY vertical slides, anywhere in the deck\n\t\t\tif( hasVerticalSlides() ) {\n\t\t\t\tdom.wrapper.classList.add( 'has-vertical-slides' );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tdom.wrapper.classList.remove( 'has-vertical-slides' );\n\t\t\t}\n\n\t\t\t// Flag if there are ANY horizontal slides, anywhere in the deck\n\t\t\tif( hasHorizontalSlides() ) {\n\t\t\t\tdom.wrapper.classList.add( 'has-horizontal-slides' );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tdom.wrapper.classList.remove( 'has-horizontal-slides' );\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Determine what available routes there are for navigation.\n\t *\n\t * @return {{left: boolean, right: boolean, up: boolean, down: boolean}}\n\t */\n\tfunction availableRoutes() {\n\n\t\tlet horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ),\n\t\t\tverticalSlides = dom.wrapper.querySelectorAll( VERTICAL_SLIDES_SELECTOR );\n\n\t\tlet routes = {\n\t\t\tleft: indexh > 0,\n\t\t\tright: indexh < horizontalSlides.length - 1,\n\t\t\tup: indexv > 0,\n\t\t\tdown: indexv < verticalSlides.length - 1\n\t\t};\n\n\t\t// Looped presentations can always be navigated as long as\n\t\t// there are slides available\n\t\tif( config.loop ) {\n\t\t\tif( horizontalSlides.length > 1 ) {\n\t\t\t\troutes.left = true;\n\t\t\t\troutes.right = true;\n\t\t\t}\n\n\t\t\tif( verticalSlides.length > 1 ) {\n\t\t\t\troutes.up = true;\n\t\t\t\troutes.down = true;\n\t\t\t}\n\t\t}\n\n\t\tif ( horizontalSlides.length > 1 && config.navigationMode === 'linear' ) {\n\t\t\troutes.right = routes.right || routes.down;\n\t\t\troutes.left = routes.left || routes.up;\n\t\t}\n\n\t\t// Reverse horizontal controls for rtl\n\t\tif( config.rtl ) {\n\t\t\tlet left = routes.left;\n\t\t\troutes.left = routes.right;\n\t\t\troutes.right = left;\n\t\t}\n\n\t\treturn routes;\n\n\t}\n\n\t/**\n\t * Returns the number of past slides. This can be used as a global\n\t * flattened index for slides.\n\t *\n\t * @param {HTMLElement} [slide=currentSlide] The slide we're counting before\n\t *\n\t * @return {number} Past slide count\n\t */\n\tfunction getSlidePastCount( slide = currentSlide ) {\n\n\t\tlet horizontalSlides = getHorizontalSlides();\n\n\t\t// The number of past slides\n\t\tlet pastCount = 0;\n\n\t\t// Step through all slides and count the past ones\n\t\tmainLoop: for( let i = 0; i < horizontalSlides.length; i++ ) {\n\n\t\t\tlet horizontalSlide = horizontalSlides[i];\n\t\t\tlet verticalSlides = horizontalSlide.querySelectorAll( 'section' );\n\n\t\t\tfor( let j = 0; j < verticalSlides.length; j++ ) {\n\n\t\t\t\t// Stop as soon as we arrive at the present\n\t\t\t\tif( verticalSlides[j] === slide ) {\n\t\t\t\t\tbreak mainLoop;\n\t\t\t\t}\n\n\t\t\t\t// Don't count slides with the \"uncounted\" class\n\t\t\t\tif( verticalSlides[j].dataset.visibility !== 'uncounted' ) {\n\t\t\t\t\tpastCount++;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Stop as soon as we arrive at the present\n\t\t\tif( horizontalSlide === slide ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Don't count the wrapping section for vertical slides and\n\t\t\t// slides marked as uncounted\n\t\t\tif( horizontalSlide.classList.contains( 'stack' ) === false && !horizontalSlide.dataset.visibility !== 'uncounted' ) {\n\t\t\t\tpastCount++;\n\t\t\t}\n\n\t\t}\n\n\t\treturn pastCount;\n\n\t}\n\n\t/**\n\t * Returns a value ranging from 0-1 that represents\n\t * how far into the presentation we have navigated.\n\t *\n\t * @return {number}\n\t */\n\tfunction getProgress() {\n\n\t\t// The number of past and total slides\n\t\tlet totalCount = getTotalSlides();\n\t\tlet pastCount = getSlidePastCount();\n\n\t\tif( currentSlide ) {\n\n\t\t\tlet allFragments = currentSlide.querySelectorAll( '.fragment' );\n\n\t\t\t// If there are fragments in the current slide those should be\n\t\t\t// accounted for in the progress.\n\t\t\tif( allFragments.length > 0 ) {\n\t\t\t\tlet visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' );\n\n\t\t\t\t// This value represents how big a portion of the slide progress\n\t\t\t\t// that is made up by its fragments (0-1)\n\t\t\t\tlet fragmentWeight = 0.9;\n\n\t\t\t\t// Add fragment progress to the past slide count\n\t\t\t\tpastCount += ( visibleFragments.length / allFragments.length ) * fragmentWeight;\n\t\t\t}\n\n\t\t}\n\n\t\treturn Math.min( pastCount / ( totalCount - 1 ), 1 );\n\n\t}\n\n\t/**\n\t * Retrieves the h/v location and fragment of the current,\n\t * or specified, slide.\n\t *\n\t * @param {HTMLElement} [slide] If specified, the returned\n\t * index will be for this slide rather than the currently\n\t * active one\n\t *\n\t * @return {{h: number, v: number, f: number}}\n\t */\n\tfunction getIndices( slide ) {\n\n\t\t// By default, return the current indices\n\t\tlet h = indexh,\n\t\t\tv = indexv,\n\t\t\tf;\n\n\t\t// If a slide is specified, return the indices of that slide\n\t\tif( slide ) {\n\t\t\tlet isVertical = isVerticalSlide( slide );\n\t\t\tlet slideh = isVertical ? slide.parentNode : slide;\n\n\t\t\t// Select all horizontal slides\n\t\t\tlet horizontalSlides = getHorizontalSlides();\n\n\t\t\t// Now that we know which the horizontal slide is, get its index\n\t\t\th = Math.max( horizontalSlides.indexOf( slideh ), 0 );\n\n\t\t\t// Assume we're not vertical\n\t\t\tv = undefined;\n\n\t\t\t// If this is a vertical slide, grab the vertical index\n\t\t\tif( isVertical ) {\n\t\t\t\tv = Math.max( Util.queryAll( slide.parentNode, 'section' ).indexOf( slide ), 0 );\n\t\t\t}\n\t\t}\n\n\t\tif( !slide && currentSlide ) {\n\t\t\tlet hasFragments = currentSlide.querySelectorAll( '.fragment' ).length > 0;\n\t\t\tif( hasFragments ) {\n\t\t\t\tlet currentFragment = currentSlide.querySelector( '.current-fragment' );\n\t\t\t\tif( currentFragment && currentFragment.hasAttribute( 'data-fragment-index' ) ) {\n\t\t\t\t\tf = parseInt( currentFragment.getAttribute( 'data-fragment-index' ), 10 );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tf = currentSlide.querySelectorAll( '.fragment.visible' ).length - 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { h, v, f };\n\n\t}\n\n\t/**\n\t * Retrieves all slides in this presentation.\n\t */\n\tfunction getSlides() {\n\n\t\treturn Util.queryAll( dom.wrapper, SLIDES_SELECTOR + ':not(.stack):not([data-visibility=\"uncounted\"])' );\n\n\t}\n\n\t/**\n\t * Returns a list of all horizontal slides in the deck. Each\n\t * vertical stack is included as one horizontal slide in the\n\t * resulting array.\n\t */\n\tfunction getHorizontalSlides() {\n\n\t\treturn Util.queryAll( dom.wrapper, HORIZONTAL_SLIDES_SELECTOR );\n\n\t}\n\n\t/**\n\t * Returns all vertical slides that exist within this deck.\n\t */\n\tfunction getVerticalSlides() {\n\n\t\treturn Util.queryAll( dom.wrapper, '.slides>section>section' );\n\n\t}\n\n\t/**\n\t * Returns all vertical stacks (each stack can contain multiple slides).\n\t */\n\tfunction getVerticalStacks() {\n\n\t\treturn Util.queryAll( dom.wrapper, HORIZONTAL_SLIDES_SELECTOR + '.stack');\n\n\t}\n\n\t/**\n\t * Returns true if there are at least two horizontal slides.\n\t */\n\tfunction hasHorizontalSlides() {\n\n\t\treturn getHorizontalSlides().length > 1;\n\t}\n\n\t/**\n\t * Returns true if there are at least two vertical slides.\n\t */\n\tfunction hasVerticalSlides() {\n\n\t\treturn getVerticalSlides().length > 1;\n\n\t}\n\n\t/**\n\t * Returns an array of objects where each object represents the\n\t * attributes on its respective slide.\n\t */\n\tfunction getSlidesAttributes() {\n\n\t\treturn getSlides().map( slide => {\n\n\t\t\tlet attributes = {};\n\t\t\tfor( let i = 0; i < slide.attributes.length; i++ ) {\n\t\t\t\tlet attribute = slide.attributes[ i ];\n\t\t\t\tattributes[ attribute.name ] = attribute.value;\n\t\t\t}\n\t\t\treturn attributes;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Retrieves the total number of slides in this presentation.\n\t *\n\t * @return {number}\n\t */\n\tfunction getTotalSlides() {\n\n\t\treturn getSlides().length;\n\n\t}\n\n\t/**\n\t * Returns the slide element matching the specified index.\n\t *\n\t * @return {HTMLElement}\n\t */\n\tfunction getSlide( x, y ) {\n\n\t\tlet horizontalSlide = getHorizontalSlides()[ x ];\n\t\tlet verticalSlides = horizontalSlide && horizontalSlide.querySelectorAll( 'section' );\n\n\t\tif( verticalSlides && verticalSlides.length && typeof y === 'number' ) {\n\t\t\treturn verticalSlides ? verticalSlides[ y ] : undefined;\n\t\t}\n\n\t\treturn horizontalSlide;\n\n\t}\n\n\t/**\n\t * Returns the background element for the given slide.\n\t * All slides, even the ones with no background properties\n\t * defined, have a background element so as long as the\n\t * index is valid an element will be returned.\n\t *\n\t * @param {mixed} x Horizontal background index OR a slide\n\t * HTML element\n\t * @param {number} y Vertical background index\n\t * @return {(HTMLElement[]|*)}\n\t */\n\tfunction getSlideBackground( x, y ) {\n\n\t\tlet slide = typeof x === 'number' ? getSlide( x, y ) : x;\n\t\tif( slide ) {\n\t\t\treturn slide.slideBackgroundElement;\n\t\t}\n\n\t\treturn undefined;\n\n\t}\n\n\t/**\n\t * Retrieves the current state of the presentation as\n\t * an object. This state can then be restored at any\n\t * time.\n\t *\n\t * @return {{indexh: number, indexv: number, indexf: number, paused: boolean, overview: boolean}}\n\t */\n\tfunction getState() {\n\n\t\tlet indices = getIndices();\n\n\t\treturn {\n\t\t\tindexh: indices.h,\n\t\t\tindexv: indices.v,\n\t\t\tindexf: indices.f,\n\t\t\tpaused: isPaused(),\n\t\t\toverview: overview.isActive()\n\t\t};\n\n\t}\n\n\t/**\n\t * Restores the presentation to the given state.\n\t *\n\t * @param {object} state As generated by getState()\n\t * @see {@link getState} generates the parameter `state`\n\t */\n\tfunction setState( state ) {\n\n\t\tif( typeof state === 'object' ) {\n\t\t\tslide( Util.deserialize( state.indexh ), Util.deserialize( state.indexv ), Util.deserialize( state.indexf ) );\n\n\t\t\tlet pausedFlag = Util.deserialize( state.paused ),\n\t\t\t\toverviewFlag = Util.deserialize( state.overview );\n\n\t\t\tif( typeof pausedFlag === 'boolean' && pausedFlag !== isPaused() ) {\n\t\t\t\ttogglePause( pausedFlag );\n\t\t\t}\n\n\t\t\tif( typeof overviewFlag === 'boolean' && overviewFlag !== overview.isActive() ) {\n\t\t\t\toverview.toggle( overviewFlag );\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Cues a new automated slide if enabled in the config.\n\t */\n\tfunction cueAutoSlide() {\n\n\t\tcancelAutoSlide();\n\n\t\tif( currentSlide && config.autoSlide !== false ) {\n\n\t\t\tlet fragment = currentSlide.querySelector( '.current-fragment' );\n\n\t\t\t// When the slide first appears there is no \"current\" fragment so\n\t\t\t// we look for a data-autoslide timing on the first fragment\n\t\t\tif( !fragment ) fragment = currentSlide.querySelector( '.fragment' );\n\n\t\t\tlet fragmentAutoSlide = fragment ? fragment.getAttribute( 'data-autoslide' ) : null;\n\t\t\tlet parentAutoSlide = currentSlide.parentNode ? currentSlide.parentNode.getAttribute( 'data-autoslide' ) : null;\n\t\t\tlet slideAutoSlide = currentSlide.getAttribute( 'data-autoslide' );\n\n\t\t\t// Pick value in the following priority order:\n\t\t\t// 1. Current fragment's data-autoslide\n\t\t\t// 2. Current slide's data-autoslide\n\t\t\t// 3. Parent slide's data-autoslide\n\t\t\t// 4. Global autoSlide setting\n\t\t\tif( fragmentAutoSlide ) {\n\t\t\t\tautoSlide = parseInt( fragmentAutoSlide, 10 );\n\t\t\t}\n\t\t\telse if( slideAutoSlide ) {\n\t\t\t\tautoSlide = parseInt( slideAutoSlide, 10 );\n\t\t\t}\n\t\t\telse if( parentAutoSlide ) {\n\t\t\t\tautoSlide = parseInt( parentAutoSlide, 10 );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tautoSlide = config.autoSlide;\n\t\t\t}\n\n\t\t\t// If there are media elements with data-autoplay,\n\t\t\t// automatically set the autoSlide duration to the\n\t\t\t// length of that media. Not applicable if the slide\n\t\t\t// is divided up into fragments.\n\t\t\t// playbackRate is accounted for in the duration.\n\t\t\tif( currentSlide.querySelectorAll( '.fragment' ).length === 0 ) {\n\t\t\t\tUtil.queryAll( currentSlide, 'video, audio' ).forEach( el => {\n\t\t\t\t\tif( el.hasAttribute( 'data-autoplay' ) ) {\n\t\t\t\t\t\tif( autoSlide && (el.duration * 1000 / el.playbackRate ) > autoSlide ) {\n\t\t\t\t\t\t\tautoSlide = ( el.duration * 1000 / el.playbackRate ) + 1000;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Cue the next auto-slide if:\n\t\t\t// - There is an autoSlide value\n\t\t\t// - Auto-sliding isn't paused by the user\n\t\t\t// - The presentation isn't paused\n\t\t\t// - The overview isn't active\n\t\t\t// - The presentation isn't over\n\t\t\tif( autoSlide && !autoSlidePaused && !isPaused() && !overview.isActive() && ( !isLastSlide() || fragments.availableRoutes().next || config.loop === true ) ) {\n\t\t\t\tautoSlideTimeout = setTimeout( () => {\n\t\t\t\t\tif( typeof config.autoSlideMethod === 'function' ) {\n\t\t\t\t\t\tconfig.autoSlideMethod()\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tnavigateNext();\n\t\t\t\t\t}\n\t\t\t\t\tcueAutoSlide();\n\t\t\t\t}, autoSlide );\n\t\t\t\tautoSlideStartTime = Date.now();\n\t\t\t}\n\n\t\t\tif( autoSlidePlayer ) {\n\t\t\t\tautoSlidePlayer.setPlaying( autoSlideTimeout !== -1 );\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Cancels any ongoing request to auto-slide.\n\t */\n\tfunction cancelAutoSlide() {\n\n\t\tclearTimeout( autoSlideTimeout );\n\t\tautoSlideTimeout = -1;\n\n\t}\n\n\tfunction pauseAutoSlide() {\n\n\t\tif( autoSlide && !autoSlidePaused ) {\n\t\t\tautoSlidePaused = true;\n\t\t\tdispatchEvent({ type: 'autoslidepaused' });\n\t\t\tclearTimeout( autoSlideTimeout );\n\n\t\t\tif( autoSlidePlayer ) {\n\t\t\t\tautoSlidePlayer.setPlaying( false );\n\t\t\t}\n\t\t}\n\n\t}\n\n\tfunction resumeAutoSlide() {\n\n\t\tif( autoSlide && autoSlidePaused ) {\n\t\t\tautoSlidePaused = false;\n\t\t\tdispatchEvent({ type: 'autoslideresumed' });\n\t\t\tcueAutoSlide();\n\t\t}\n\n\t}\n\n\tfunction navigateLeft() {\n\n\t\tnavigationHistory.hasNavigatedHorizontally = true;\n\n\t\t// Reverse for RTL\n\t\tif( config.rtl ) {\n\t\t\tif( ( overview.isActive() || fragments.next() === false ) && availableRoutes().left ) {\n\t\t\t\tslide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined );\n\t\t\t}\n\t\t}\n\t\t// Normal navigation\n\t\telse if( ( overview.isActive() || fragments.prev() === false ) && availableRoutes().left ) {\n\t\t\tslide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined );\n\t\t}\n\n\t}\n\n\tfunction navigateRight() {\n\n\t\tnavigationHistory.hasNavigatedHorizontally = true;\n\n\t\t// Reverse for RTL\n\t\tif( config.rtl ) {\n\t\t\tif( ( overview.isActive() || fragments.prev() === false ) && availableRoutes().right ) {\n\t\t\t\tslide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined );\n\t\t\t}\n\t\t}\n\t\t// Normal navigation\n\t\telse if( ( overview.isActive() || fragments.next() === false ) && availableRoutes().right ) {\n\t\t\tslide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined );\n\t\t}\n\n\t}\n\n\tfunction navigateUp() {\n\n\t\t// Prioritize hiding fragments\n\t\tif( ( overview.isActive() || fragments.prev() === false ) && availableRoutes().up ) {\n\t\t\tslide( indexh, indexv - 1 );\n\t\t}\n\n\t}\n\n\tfunction navigateDown() {\n\n\t\tnavigationHistory.hasNavigatedVertically = true;\n\n\t\t// Prioritize revealing fragments\n\t\tif( ( overview.isActive() || fragments.next() === false ) && availableRoutes().down ) {\n\t\t\tslide( indexh, indexv + 1 );\n\t\t}\n\n\t}\n\n\t/**\n\t * Navigates backwards, prioritized in the following order:\n\t * 1) Previous fragment\n\t * 2) Previous vertical slide\n\t * 3) Previous horizontal slide\n\t */\n\tfunction navigatePrev() {\n\n\t\t// Prioritize revealing fragments\n\t\tif( fragments.prev() === false ) {\n\t\t\tif( availableRoutes().up ) {\n\t\t\t\tnavigateUp();\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Fetch the previous horizontal slide, if there is one\n\t\t\t\tlet previousSlide;\n\n\t\t\t\tif( config.rtl ) {\n\t\t\t\t\tpreviousSlide = Util.queryAll( dom.wrapper, HORIZONTAL_SLIDES_SELECTOR + '.future' ).pop();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tpreviousSlide = Util.queryAll( dom.wrapper, HORIZONTAL_SLIDES_SELECTOR + '.past' ).pop();\n\t\t\t\t}\n\n\t\t\t\tif( previousSlide ) {\n\t\t\t\t\tlet v = ( previousSlide.querySelectorAll( 'section' ).length - 1 ) || undefined;\n\t\t\t\t\tlet h = indexh - 1;\n\t\t\t\t\tslide( h, v );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * The reverse of #navigatePrev().\n\t */\n\tfunction navigateNext() {\n\n\t\tnavigationHistory.hasNavigatedHorizontally = true;\n\t\tnavigationHistory.hasNavigatedVertically = true;\n\n\t\t// Prioritize revealing fragments\n\t\tif( fragments.next() === false ) {\n\n\t\t\tlet routes = availableRoutes();\n\n\t\t\t// When looping is enabled `routes.down` is always available\n\t\t\t// so we need a separate check for when we've reached the\n\t\t\t// end of a stack and should move horizontally\n\t\t\tif( routes.down && routes.right && config.loop && isLastVerticalSlide( currentSlide ) ) {\n\t\t\t\troutes.down = false;\n\t\t\t}\n\n\t\t\tif( routes.down ) {\n\t\t\t\tnavigateDown();\n\t\t\t}\n\t\t\telse if( config.rtl ) {\n\t\t\t\tnavigateLeft();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnavigateRight();\n\t\t\t}\n\t\t}\n\n\t}\n\n\n\t// --------------------------------------------------------------------//\n\t// ----------------------------- EVENTS -------------------------------//\n\t// --------------------------------------------------------------------//\n\n\t/**\n\t * Called by all event handlers that are based on user\n\t * input.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onUserInput( event ) {\n\n\t\tif( config.autoSlideStoppable ) {\n\t\t\tpauseAutoSlide();\n\t\t}\n\n\t}\n\n\t/**\n\t * Event listener for transition end on the current slide.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onTransitionEnd( event ) {\n\n\t\tif( transition === 'running' && /section/gi.test( event.target.nodeName ) ) {\n\t\t\ttransition = 'idle';\n\t\t\tdispatchEvent({\n\t\t\t\ttype: 'slidetransitionend',\n\t\t\t\tdata: { indexh, indexv, previousSlide, currentSlide }\n\t\t\t});\n\t\t}\n\n\t}\n\n\t/**\n\t * Handler for the window level 'hashchange' event.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onWindowHashChange( event ) {\n\n\t\tlocation.readURL();\n\n\t}\n\n\t/**\n\t * Handler for the window level 'resize' event.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onWindowResize( event ) {\n\n\t\tlayout();\n\n\t}\n\n\t/**\n\t * Handle for the window level 'visibilitychange' event.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onPageVisibilityChange( event ) {\n\n\t\t// If, after clicking a link or similar and we're coming back,\n\t\t// focus the document.body to ensure we can use keyboard shortcuts\n\t\tif( document.hidden === false && document.activeElement !== document.body ) {\n\t\t\t// Not all elements support .blur() - SVGs among them.\n\t\t\tif( typeof document.activeElement.blur === 'function' ) {\n\t\t\t\tdocument.activeElement.blur();\n\t\t\t}\n\t\t\tdocument.body.focus();\n\t\t}\n\n\t}\n\n\t/**\n\t * Handles clicks on links that are set to preview in the\n\t * iframe overlay.\n\t *\n\t * @param {object} event\n\t */\n\tfunction onPreviewLinkClicked( event ) {\n\n\t\tif( event.currentTarget && event.currentTarget.hasAttribute( 'href' ) ) {\n\t\t\tlet url = event.currentTarget.getAttribute( 'href' );\n\t\t\tif( url ) {\n\t\t\t\tshowPreview( url );\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Handles click on the auto-sliding controls element.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onAutoSlidePlayerClick( event ) {\n\n\t\t// Replay\n\t\tif( isLastSlide() && config.loop === false ) {\n\t\t\tslide( 0, 0 );\n\t\t\tresumeAutoSlide();\n\t\t}\n\t\t// Resume\n\t\telse if( autoSlidePaused ) {\n\t\t\tresumeAutoSlide();\n\t\t}\n\t\t// Pause\n\t\telse {\n\t\t\tpauseAutoSlide();\n\t\t}\n\n\t}\n\n\n\t// --------------------------------------------------------------------//\n\t// ------------------------------- API --------------------------------//\n\t// --------------------------------------------------------------------//\n\n\t// The public reveal.js API\n\tconst API = {\n\t\tVERSION,\n\n\t\tinitialize,\n\t\tconfigure,\n\n\t\tsync,\n\t\tsyncSlide,\n\t\tsyncFragments: fragments.sync.bind( fragments ),\n\n\t\t// Navigation methods\n\t\tslide,\n\t\tleft: navigateLeft,\n\t\tright: navigateRight,\n\t\tup: navigateUp,\n\t\tdown: navigateDown,\n\t\tprev: navigatePrev,\n\t\tnext: navigateNext,\n\n\t\t// Navigation aliases\n\t\tnavigateLeft, navigateRight, navigateUp, navigateDown, navigatePrev, navigateNext,\n\n\t\t// Fragment methods\n\t\tnavigateFragment: fragments.goto.bind( fragments ),\n\t\tprevFragment: fragments.prev.bind( fragments ),\n\t\tnextFragment: fragments.next.bind( fragments ),\n\n\t\t// Event binding\n\t\ton,\n\t\toff,\n\n\t\t// Legacy event binding methods left in for backwards compatibility\n\t\taddEventListener: on,\n\t\tremoveEventListener: off,\n\n\t\t// Forces an update in slide layout\n\t\tlayout,\n\n\t\t// Randomizes the order of slides\n\t\tshuffle,\n\n\t\t// Returns an object with the available routes as booleans (left/right/top/bottom)\n\t\tavailableRoutes,\n\n\t\t// Returns an object with the available fragments as booleans (prev/next)\n\t\tavailableFragments: fragments.availableRoutes.bind( fragments ),\n\n\t\t// Toggles a help overlay with keyboard shortcuts\n\t\ttoggleHelp,\n\n\t\t// Toggles the overview mode on/off\n\t\ttoggleOverview: overview.toggle.bind( overview ),\n\n\t\t// Toggles the \"black screen\" mode on/off\n\t\ttogglePause,\n\n\t\t// Toggles the auto slide mode on/off\n\t\ttoggleAutoSlide,\n\n\t\t// Slide navigation checks\n\t\tisFirstSlide,\n\t\tisLastSlide,\n\t\tisLastVerticalSlide,\n\t\tisVerticalSlide,\n\n\t\t// State checks\n\t\tisPaused,\n\t\tisAutoSliding,\n\t\tisSpeakerNotes: notes.isSpeakerNotesWindow.bind( notes ),\n\t\tisOverview: overview.isActive.bind( overview ),\n\t\tisPrintingPDF: print.isPrintingPDF.bind( print ),\n\n\t\t// Checks if reveal.js has been loaded and is ready for use\n\t\tisReady: () => ready,\n\n\t\t// Slide preloading\n\t\tloadSlide: slideContent.load.bind( slideContent ),\n\t\tunloadSlide: slideContent.unload.bind( slideContent ),\n\n\t\t// Adds or removes all internal event listeners\n\t\taddEventListeners,\n\t\tremoveEventListeners,\n\t\tdispatchEvent,\n\n\t\t// Facility for persisting and restoring the presentation state\n\t\tgetState,\n\t\tsetState,\n\n\t\t// Presentation progress on range of 0-1\n\t\tgetProgress,\n\n\t\t// Returns the indices of the current, or specified, slide\n\t\tgetIndices,\n\n\t\t// Returns an Array of key:value maps of the attributes of each\n\t\t// slide in the deck\n\t\tgetSlidesAttributes,\n\n\t\t// Returns the number of slides that we have passed\n\t\tgetSlidePastCount,\n\n\t\t// Returns the total number of slides\n\t\tgetTotalSlides,\n\n\t\t// Returns the slide element at the specified index\n\t\tgetSlide,\n\n\t\t// Returns the previous slide element, may be null\n\t\tgetPreviousSlide: () => previousSlide,\n\n\t\t// Returns the current slide element\n\t\tgetCurrentSlide: () => currentSlide,\n\n\t\t// Returns the slide background element at the specified index\n\t\tgetSlideBackground,\n\n\t\t// Returns the speaker notes string for a slide, or null\n\t\tgetSlideNotes: notes.getSlideNotes.bind( notes ),\n\n\t\t// Returns an Array of all slides\n\t\tgetSlides,\n\n\t\t// Returns an array with all horizontal/vertical slides in the deck\n\t\tgetHorizontalSlides,\n\t\tgetVerticalSlides,\n\n\t\t// Checks if the presentation contains two or more horizontal\n\t\t// and vertical slides\n\t\thasHorizontalSlides,\n\t\thasVerticalSlides,\n\n\t\t// Checks if the deck has navigated on either axis at least once\n\t\thasNavigatedHorizontally: () => navigationHistory.hasNavigatedHorizontally,\n\t\thasNavigatedVertically: () => navigationHistory.hasNavigatedVertically,\n\n\t\t// Adds/removes a custom key binding\n\t\taddKeyBinding: keyboard.addKeyBinding.bind( keyboard ),\n\t\tremoveKeyBinding: keyboard.removeKeyBinding.bind( keyboard ),\n\n\t\t// Programmatically triggers a keyboard event\n\t\ttriggerKey: keyboard.triggerKey.bind( keyboard ),\n\n\t\t// Registers a new shortcut to include in the help overlay\n\t\tregisterKeyboardShortcut: keyboard.registerKeyboardShortcut.bind( keyboard ),\n\n\t\tgetComputedSlideSize,\n\n\t\t// Returns the current scale of the presentation content\n\t\tgetScale: () => scale,\n\n\t\t// Returns the current configuration object\n\t\tgetConfig: () => config,\n\n\t\t// Helper method, retrieves query string as a key:value map\n\t\tgetQueryHash: Util.getQueryHash,\n\n\t\t// Returns reveal.js DOM elements\n\t\tgetRevealElement: () => revealElement,\n\t\tgetSlidesElement: () => dom.slides,\n\t\tgetBackgroundsElement: () => backgrounds.element,\n\n\t\t// API for registering and retrieving plugins\n\t\tregisterPlugin: plugins.registerPlugin.bind( plugins ),\n\t\thasPlugin: plugins.hasPlugin.bind( plugins ),\n\t\tgetPlugin: plugins.getPlugin.bind( plugins ),\n\t\tgetPlugins: plugins.getRegisteredPlugins.bind( plugins )\n\n\t};\n\n\t// Our internal API which controllers have access to\n\tUtil.extend( Reveal, {\n\t\t...API,\n\n\t\t// Methods for announcing content to screen readers\n\t\tannounceStatus,\n\t\tgetStatusText,\n\n\t\t// Controllers\n\t\tprint,\n\t\tprogress,\n\t\tcontrols,\n\t\tlocation,\n\t\toverview,\n\t\tfragments,\n\t\tslideContent,\n\t\tslideNumber,\n\n\t\tonUserInput,\n\t\tcloseOverlay,\n\t\tupdateSlidesVisibility,\n\t\tlayoutSlideContents,\n\t\ttransformSlides,\n\t\tcueAutoSlide,\n\t\tcancelAutoSlide\n\t} );\n\n\treturn API;\n\n};\n","import Deck from './reveal.js'\n\n/**\n * Expose the Reveal class to the window. To create a\n * new instance:\n * let deck = new Reveal( document.querySelector( '.reveal' ), {\n * controls: false\n * } );\n * deck.initialize().then(() => {\n * // reveal.js is ready\n * });\n */\nvar Reveal = Deck;\n\n\n/**\n * The below is a thin shell that mimics the pre 4.0\n * reveal.js API and ensures backwards compatibility.\n * This API only allows for once Reveal instance per\n * page, whereas the new API above lets you run many\n * presentations on the same page.\n *\n * Reveal.initialize( { controls: false } ).then(() => {\n * // reveal.js is ready\n * });\n */\n\nlet enqueuedAPICalls = [];\n\nReveal.initialize = options => {\n\n\t// Create our singleton reveal.js instance\n\tObject.assign( Reveal, new Deck( document.querySelector( '.reveal' ), options ) );\n\n\t// Invoke any enqueued API calls\n\tenqueuedAPICalls.map( method => method( Reveal ) );\n\n\treturn Reveal.initialize();\n\n}\n\n/**\n * The pre 4.0 API let you add event listener before\n * initializing. We maintain the same behavior by\n * queuing up early API calls and invoking all of them\n * when Reveal.initialize is called.\n */\n[ 'on', 'off', 'addEventListener', 'removeEventListener', 'registerPlugin' ].forEach( method => {\n\tReveal[method] = ( ...args ) => {\n\t\tenqueuedAPICalls.push( deck => deck[method].call( null, ...args ) );\n\t}\n} );\n\nexport default Reveal;"],"names":["POST_MESSAGE_METHOD_BLACKLIST","FRAGMENT_STYLE_REGEX","extend","a","b","i","queryAll","el","selector","Array","from","querySelectorAll","deserialize","value","match","parseFloat","transformElement","element","transform","style","closestParent","target","parent","parentNode","matchesMethod","matches","matchesSelector","msMatchesSelector","call","createSingletonNode","container","tagname","classname","innerHTML","nodes","length","testNode","node","document","createElement","className","appendChild","createStyleSheet","tag","type","styleSheet","cssText","createTextNode","head","getQueryHash","query","location","search","replace","split","shift","pop","unescape","getRemainingHeight","height","newHeight","oldHeight","offsetHeight","removeProperty","UA","navigator","userAgent","testElement","isMobile","test","platform","maxTouchPoints","isChrome","isAndroid","supportsZoom","supportsHistoryAPI","window","history","replaceState","SlideContent","Reveal","startEmbeddedIframe","this","bind","preload","getConfig","preloadIframes","hasAttribute","slide","options","display","forEach","tagName","_this","shouldPreload","setAttribute","getAttribute","removeAttribute","media","sources","source","load","background","slideBackgroundElement","backgroundContent","slideBackgroundContentElement","backgroundIframe","backgroundImage","backgroundVideo","backgroundVideoLoop","backgroundVideoMuted","encodeURI","isSpeakerNotes","video","muted","autoplay","excludeIframes","iframe","width","maxHeight","maxWidth","backgroundIframeElement","querySelector","getSlideBackground","_appendParamToIframeSource","sourceAttribute","sourceURL","param","_this2","getSlidesElement","src","indexOf","_this3","autoPlayMedia","play","readyState","startEmbeddedMedia","promise","catch","controls","addEventListener","removeEventListener","event","isAttachedToDOM","isVisible","currentTime","contentWindow","postMessage","unloadIframes","pause","_this4","SlideNumber","getRevealElement","config","oldConfig","slideNumberDisplay","slideNumber","isPrintingPDF","showSlideNumber","getSlideNumber","getCurrentSlide","format","getHorizontalSlides","push","getSlidePastCount","getTotalSlides","indices","getIndices","h","sep","isVerticalSlide","v","url","getHash","formatNumber","delimiter","isNaN","colorToRgb","color","hex3","r","parseInt","charAt","g","hex6","substr","rgb","rgba","Backgrounds","classList","add","slideh","backgroundStack","createBackground","slidev","parallaxBackgroundImage","backgroundSize","parallaxBackgroundSize","backgroundRepeat","parallaxBackgroundRepeat","backgroundPosition","parallaxBackgroundPosition","setTimeout","remove","contentElement","sync","backgroundColor","opacity","data","backgroundTransition","backgroundOpacity","contrastColor","computedBackgroundStyle","getComputedStyle","includeAll","currentSlide","currentBackground","horizontalPast","rtl","horizontalFuture","childNodes","backgroundh","backgroundv","previousBackground","slideContent","stopEmbeddedContent","startEmbeddedContent","currentBackgroundContent","backgroundImageURL","previousBackgroundHash","currentBackgroundHash","classToBubble","contains","backgroundWidth","backgroundHeight","horizontalSlides","verticalSlides","getVerticalSlides","horizontalOffset","slideWidth","offsetWidth","horizontalSlideCount","parallaxBackgroundHorizontal","verticalOffsetMultiplier","verticalOffset","slideHeight","verticalSlideCount","parallaxBackgroundVertical","AutoAnimate","autoAnimateCounter","fromSlide","toSlide","reset","autoAnimateStyleSheet","animationOptions","getAutoAnimateOptions","dataset","autoAnimate","allSlides","getSlides","slideDirection","css","getAutoAnimatableElements","map","elements","autoAnimateElements","to","autoAnimateUnmatched","defaultUnmatchedDuration","duration","defaultUnmatchedDelay","getUnmatchedAutoAnimateElements","unmatchedElement","unmatchedOptions","id","delay","autoAnimateTarget","join","requestAnimationFrame","fontWeight","dispatchEvent","sheet","removeChild","elementOptions","easing","fromProps","getAutoAnimatableProperties","toProps","styles","translate","scale","presentationScale","getScale","delta","x","y","scaleX","scaleY","Math","round","propertyName","toValue","fromValue","explicitValue","toStyleProperties","Object","keys","inheritedOptions","autoAnimateEasing","autoAnimateDuration","closest","autoAnimatedParent","autoAnimateDelay","direction","bounds","properties","measure","getBoundingClientRect","computedStyles","autoAnimateStyles","property","pairs","autoAnimateMatcher","getAutoAnimatePairs","reserved","filter","pair","index","textNodes","findAutoAnimateMatches","nodeName","innerText","textContent","getLocalBoundingBox","offsetLeft","offsetTop","fromScope","toScope","serializer","fromMatches","toMatches","slice","key","fromElement","pimaryIndex","secondaryIndex","rootElement","children","reduce","result","containsAnimatedElements","concat","Fragments","fragments","disable","enable","hiddenFragments","prev","next","grouped","ordered","unordered","sorted","fragment","group","horizontalSlide","verticalSlide","sort","changedFragments","shown","hidden","maxIndex","currentFragment","max","wasVisible","announceStatus","getStatusText","bubbles","min","offset","lastVisibleFragment","update","progress","fragmentInURL","writeURL","goto","Overview","active","onSlideClicked","overview","isActive","cancelAutoSlide","getBackgroundsElement","slideSize","getComputedSlideSize","overviewSlideWidth","overviewSlideHeight","updateSlidesVisibility","layout","hslide","vslide","hbackground","vbackground","vmin","innerWidth","innerHeight","transformSlides","cueAutoSlide","override","activate","deactivate","preventDefault","Keyboard","shortcuts","bindings","onDocumentKeyDown","onDocumentKeyPress","navigationMode","binding","callback","_typeof","keyCode","description","shiftKey","charCode","toggleHelp","keyboardCondition","autoSlideWasPaused","isAutoSliding","onUserInput","activeElementIsCE","activeElement","contentEditable","activeElementIsInput","activeElementIsNotes","prevSlideShortcut","firstSlideShortcut","lastSlideShortcut","unusedModifier","altKey","ctrlKey","metaKey","resumeKeyCodes","keyboard","isPaused","requestMethod","useLinearMode","hasHorizontalSlides","hasVerticalSlides","triggered","apply","action","left","Number","MAX_VALUE","right","up","down","togglePause","documentElement","requestFullscreen","webkitRequestFullscreen","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen","autoSlideStoppable","toggleAutoSlide","closeOverlay","toggle","Location","writeURLTimeout","hash","bits","name","getElementById","decodeURIComponent","error","isSameNameAsCurrentSlide","elementIndex","f","hashIndexBase","hashOneBasedIndex","undefined","clearTimeout","pathname","s","encodeURIComponent","Controls","onNavigateLeftClicked","onNavigateRightClicked","onNavigateUpClicked","onNavigateDownClicked","onNavigatePrevClicked","onNavigateNextClicked","revealElement","controlsLeft","controlsRight","controlsUp","controlsDown","controlsPrev","controlsNext","controlsRightArrow","controlsLeftArrow","controlsDownArrow","controlsLayout","controlsBackArrows","pointerEvents","eventName","routes","availableRoutes","fragmentsRoutes","controlsTutorial","hasNavigatedVertically","hasNavigatedHorizontally","Progress","onProgressClicked","bar","getProgress","getMaxWidth","slidesTotal","slideIndex","floor","clientX","Pointer","lastMouseWheelStep","cursorHidden","cursorInactiveTimeout","onDocumentCursorActive","onDocumentMouseScroll","mouseWheel","hideInactiveCursor","showCursor","cursor","hideCursor","hideCursorTime","Date","now","detail","wheelDelta","loadScript","script","async","defer","onload","onreadystatechange","onerror","err","Error","insertBefore","lastChild","Plugins","reveal","state","registeredPlugins","asyncDependencies","plugins","dependencies","registerPlugin","Promise","resolve","scripts","scriptsToLoad","condition","scriptLoadedCallback","initPlugins","then","console","warn","pluginValues","values","pluginsToInitialize","loadAsync","initNextPlugin","afterPlugInitialized","plugin","init","arguments","Print","pageWidth","margin","pageHeight","body","layoutSlideContents","doingSlideNumbers","top","contentHeight","scrollHeight","numberOfPages","ceil","pdfMaxPagesPerSlide","center","page","pdfPageHeightOffset","showNotes","notes","getSlideNotes","notesLayout","notesElement","nextSibling","notesSpacing","bottom","numberElement","pdfSeparateFragments","previousFragmentStep","previousPage","fragmentGroups","clonedPage","cloneNode","Touch","touchStartX","touchStartY","touchStartCount","touchCaptured","onPointerDown","onPointerMove","onPointerUp","onTouchStart","onTouchMove","onTouchEnd","msPointerEnabled","isSwipePrevented","touches","clientY","currentX","currentY","deltaX","deltaY","abs","embedded","pointerType","MSPOINTER_TYPE_TOUCH","Notes","print","hasNotes","Playback","progressCheck","diameter","diameter2","thickness","playing","progressOffset","canvas","context","getContext","render","wasPlaying","animate","progressBefore","radius","endAngle","PI","startAngle","save","clearRect","beginPath","arc","fillStyle","fill","lineWidth","strokeStyle","stroke","iconSize","fillRect","moveTo","lineTo","restore","listener","minScale","maxScale","disableLayout","touch","loop","shuffle","help","autoSlide","autoSlideMethod","defaultTiming","previewLinks","postMessageEvents","focusBodyOnPageVisibilityChange","transition","transitionSpeed","POSITIVE_INFINITY","viewDistance","mobileViewDistance","indexh","indexv","previousSlide","autoSlidePlayer","VERSION","ready","navigationHistory","slidesTransform","dom","autoSlideTimeout","autoSlideStartTime","autoSlidePaused","backgrounds","pointer","initialize","initOptions","wrapper","slides","defaultConfig","Util","setViewport","start","on","setupDOM","setupPostMessage","setupScrollPrevention","resetVerticalSlides","configure","readURL","removeEventListeners","setupPDF","Device","pauseOverlay","statusElement","createStatusElement","position","overflow","clip","text","nodeType","isAriaHidden","isDisplayHidden","child","trim","setInterval","scrollTop","scrollLeft","JSON","parse","method","args","dispatchPostMessage","isReady","numberOfSlides","resume","enablePreviewLinks","disablePreviewLinks","destroy","onAutoSlidePlayerClick","addEventListeners","onWindowHashChange","onWindowResize","onTransitionEnd","onPageVisibilityChange","unbind","useCapture","off","transforms","createEvent","initEvent","self","message","namespace","getState","stringify","onPreviewLinkClicked","showPreview","overlay","showHelp","html","registeredKeyBindings","setProperty","size","oldScale","presentationWidth","presentationHeight","zoom","devicePixelRatio","len","updateParallax","remainingHeight","nw","naturalWidth","videoWidth","nh","naturalHeight","videoHeight","es","setPreviousVerticalIndex","stack","getPreviousVerticalIndex","attributeName","isLastVerticalSlide","nextElementSibling","isFirstSlide","isLastSlide","wasPaused","resumeAutoSlide","pauseAutoSlide","o","stateBefore","indexhBefore","indexvBefore","updateSlides","slideChanged","currentHorizontalSlide","currentVerticalSlides","autoAnimateTransition","getVerticalStacks","stateLoop","j","splice","origin","run","create","sortAll","updateVisibility","formatEmbeddedContent","syncSlide","random","slidesLength","printMode","reverse","wasPresent","slideState","distanceX","horizontalSlidesLength","verticalSlidesLength","unload","oy","pastCount","mainLoop","visibility","totalCount","allFragments","isVertical","SLIDES_SELECTOR","HORIZONTAL_SLIDES_SELECTOR","getSlidesAttributes","attributes","attribute","getSlide","indexf","paused","setState","pausedFlag","overviewFlag","fragmentAutoSlide","parentAutoSlide","slideAutoSlide","playbackRate","navigateNext","setPlaying","navigateLeft","navigateRight","navigateUp","navigateDown","navigatePrev","blur","focus","currentTarget","API","syncFragments","navigateFragment","prevFragment","nextFragment","availableFragments","toggleOverview","isSpeakerNotesWindow","isOverview","loadSlide","unloadSlide","getPreviousSlide","addKeyBinding","removeKeyBinding","triggerKey","registerKeyboardShortcut","hasPlugin","getPlugin","getPlugins","getRegisteredPlugins","Deck","enqueuedAPICalls","assign","deck"],"mappings":"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"} |