).';\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\tif( !dom.slides ) throw 'Unable to find slides container (
).';\n\n\t\t// Compose our config object in order of increasing precedence:\n\t\t// 1. Default reveal.js options\n\t\t// 2. Options provided via Reveal.configure() prior to\n\t\t// initialization\n\t\t// 3. Options passed to the Reveal constructor\n\t\t// 4. Options passed to Reveal.initialize\n\t\t// 5. Query params\n\t\tconfig = { ...defaultConfig, ...config, ...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\tdom.viewport = Util.closest( revealElement, '.reveal-viewport' ) || revealElement;\n\t\t}\n\t\t// Full-page decks use the body as their viewport\n\t\telse {\n\t\t\tdom.viewport = document.body;\n\t\t\tdocument.documentElement.classList.add( 'reveal-full-page' );\n\t\t}\n\n\t\tdom.viewport.classList.add( 'reveal-viewport' );\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// Remove slides hidden with data-visibility\n\t\tremoveHiddenSlides();\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// Adds bindings for fullscreen mode\n\t\tsetupFullscreen();\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', () => {\n\t\t\t\t\tprint.setupPDF();\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Removes all slides with data-visibility=\"hidden\". This\n\t * is done right before the rest of the presentation is\n\t * initialized.\n\t *\n\t * If you want to show all hidden slides, initialize\n\t * reveal.js with showHiddenSlides set to true.\n\t */\n\tfunction removeHiddenSlides() {\n\n\t\tif( !config.showHiddenSlides ) {\n\t\t\tUtil.queryAll( dom.wrapper, 'section[data-visibility=\"hidden\"]' ).forEach( slide => {\n\t\t\t\tslide.parentNode.removeChild( slide );\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\tjumpToSlide.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 ? '
Resume presentation ' : 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 * After entering fullscreen we need to force a layout to\n\t * get our presentations to scale correctly. This behavior\n\t * is inconsistent across browsers but a force layout seems\n\t * to normalize it.\n\t */\n\tfunction setupFullscreen() {\n\n\t\tdocument.addEventListener( 'fullscreenchange', onFullscreenChange );\n\t\tdocument.addEventListener( 'webkitfullscreenchange', onFullscreenChange );\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', onPostMessage, 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\t// Expose our configured slide dimensions as custom props\n\t\tdom.viewport.style.setProperty( '--slide-width', config.width + 'px' );\n\t\tdom.viewport.style.setProperty( '--slide-height', config.height + 'px' );\n\n\t\tif( config.shuffle ) {\n\t\t\tshuffle();\n\t\t}\n\n\t\tUtil.toggleClass( dom.wrapper, 'embedded', config.embedded );\n\t\tUtil.toggleClass( dom.wrapper, 'rtl', config.rtl );\n\t\tUtil.toggleClass( dom.wrapper, 'center', config.center );\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\tfocus.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( '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\tif( config.respondToHashChanges ) location.bind();\n\t\tcontrols.bind();\n\t\tfocus.bind();\n\n\t\tdom.slides.addEventListener( 'click', onSlidesClicked, false );\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\tfocus.unbind();\n\t\tkeyboard.unbind();\n\t\tcontrols.unbind();\n\t\tprogress.unbind();\n\t\tlocation.unbind();\n\n\t\twindow.removeEventListener( 'resize', onWindowResize, false );\n\n\t\tdom.slides.removeEventListener( 'click', onSlidesClicked, false );\n\t\tdom.slides.removeEventListener( 'transitionend', onTransitionEnd, false );\n\t\tdom.pauseOverlay.removeEventListener( 'click', resume, false );\n\n\t}\n\n\t/**\n\t * Uninitializes reveal.js by undoing changes made to the\n\t * DOM and removing all event listeners.\n\t */\n\tfunction destroy() {\n\n\t\tremoveEventListeners();\n\t\tcancelAutoSlide();\n\t\tdisablePreviewLinks();\n\n\t\t// Destroy controllers\n\t\tnotes.destroy();\n\t\tfocus.destroy();\n\t\tplugins.destroy();\n\t\tpointer.destroy();\n\t\tcontrols.destroy();\n\t\tprogress.destroy();\n\t\tbackgrounds.destroy();\n\t\tslideNumber.destroy();\n\t\tjumpToSlide.destroy();\n\n\t\t// Remove event listeners\n\t\tdocument.removeEventListener( 'fullscreenchange', onFullscreenChange );\n\t\tdocument.removeEventListener( 'webkitfullscreenchange', onFullscreenChange );\n\t\tdocument.removeEventListener( 'visibilitychange', onPageVisibilityChange, false );\n\t\twindow.removeEventListener( 'message', onPostMessage, false );\n\t\twindow.removeEventListener( 'load', layout, false );\n\n\t\t// Undo DOM changes\n\t\tif( dom.pauseOverlay ) dom.pauseOverlay.remove();\n\t\tif( dom.statusElement ) dom.statusElement.remove();\n\n\t\tdocument.documentElement.classList.remove( 'reveal-full-page' );\n\n\t\tdom.wrapper.classList.remove( 'ready', 'center', 'has-horizontal-slides', 'has-vertical-slides' );\n\t\tdom.wrapper.removeAttribute( 'data-transition-speed' );\n\t\tdom.wrapper.removeAttribute( 'data-background-transition' );\n\n\t\tdom.viewport.classList.remove( 'reveal-viewport' );\n\t\tdom.viewport.style.removeProperty( '--slide-width' );\n\t\tdom.viewport.style.removeProperty( '--slide-height' );\n\n\t\tdom.slides.style.removeProperty( 'width' );\n\t\tdom.slides.style.removeProperty( 'height' );\n\t\tdom.slides.style.removeProperty( 'zoom' );\n\t\tdom.slides.style.removeProperty( 'left' );\n\t\tdom.slides.style.removeProperty( 'top' );\n\t\tdom.slides.style.removeProperty( 'bottom' );\n\t\tdom.slides.style.removeProperty( 'right' );\n\t\tdom.slides.style.removeProperty( 'transform' );\n\n\t\tArray.from( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( slide => {\n\t\t\tslide.style.removeProperty( 'display' );\n\t\t\tslide.style.removeProperty( 'top' );\n\t\t\tslide.removeAttribute( 'hidden' );\n\t\t\tslide.removeAttribute( 'aria-hidden' );\n\t\t} );\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\treturn event;\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`
\n\t\t\t\t \n\t\t\t\t \n\t\t\t \n\t\t\t
\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\tUnable to load iframe. This is likely due to the site's policy (x-frame-options). \n\t\t\t\t \n\t\t\t
`;\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 = '
Keyboard Shortcuts
';\n\n\t\t\tlet shortcuts = keyboard.getShortcuts(),\n\t\t\t\tbindings = keyboard.getBindings();\n\n\t\t\thtml += '
KEY ACTION ';\n\t\t\tfor( let key in shortcuts ) {\n\t\t\t\thtml += `${key} ${shortcuts[ key ]} `;\n\t\t\t}\n\n\t\t\t// Add custom key bindings that have associated descriptions\n\t\t\tfor( let binding in bindings ) {\n\t\t\t\tif( bindings[binding].key && bindings[binding].description ) {\n\t\t\t\t\thtml += `${bindings[binding].key} ${bindings[binding].description} `;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\thtml += '
';\n\n\t\t\tdom.overlay.innerHTML = `\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
${html}
\n\t\t\t\t
\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 && !config.embedded ) {\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\tdom.slides.style.zoom = '';\n\t\t\t\t\tdom.slides.style.left = '50%';\n\t\t\t\t\tdom.slides.style.top = '50%';\n\t\t\t\t\tdom.slides.style.bottom = 'auto';\n\t\t\t\t\tdom.slides.style.right = 'auto';\n\t\t\t\t\ttransformSlides( { layout: 'translate(-50%, -50%) scale('+ scale +')' } );\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\tdom.viewport.style.setProperty( '--slide-scale', scale );\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 'r-stretch' class\n\t\tUtil.queryAll( dom.slides, 'section > .stretch, section > .r-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\t\tlet width = config.width;\n\t\tlet height = config.height;\n\n\t\tif( config.disableLayout ) {\n\t\t\twidth = dom.slides.offsetWidth;\n\t\t\theight = dom.slides.offsetHeight;\n\t\t}\n\n\t\tconst size = {\n\t\t\t// Slide size\n\t\t\twidth: width,\n\t\t\theight: 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 visibility of the jump-to-slide UI.\n\t */\n\tfunction toggleJumpToSlide( override ) {\n\n\t\tif( typeof override === 'boolean' ) {\n\t\t\toverride ? jumpToSlide.show() : jumpToSlide.hide();\n\t\t}\n\t\telse {\n\t\t\tjumpToSlide.isVisible() ? jumpToSlide.hide() : jumpToSlide.show();\n\t\t}\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} [origin] Origin for use in multimaster environments\n\t */\n\tfunction slide( h, v, f, origin ) {\n\n\t\t// Dispatch an event before the slide\n\t\tconst slidechange = dispatchEvent({\n\t\t\ttype: 'beforeslidechange',\n\t\t\tdata: {\n\t\t\t\tindexh: h === undefined ? indexh : h,\n\t\t\t\tindexv: v === undefined ? indexv : v,\n\t\t\t\torigin\n\t\t\t}\n\t\t});\n\n\t\t// Abort if this slide change was prevented by an event listener\n\t\tif( slidechange.defaultPrevented ) return;\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\t\t&& previousSlide.getAttribute( 'data-auto-animate-id' ) === currentSlide.getAttribute( 'data-auto-animate-id' )\n\t\t\t\t\t&& !( ( indexh > indexhBefore || indexv > indexvBefore ) ? currentSlide : previousSlide ).hasAttribute( 'data-auto-animate-restart' ) ) {\n\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\tdom.viewport.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\tdom.viewport.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\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\t// Use animation frame to prevent getComputedStyle in getStatusText\n\t\t// from triggering layout mid-frame\n\t\trequestAnimationFrame( () => {\n\t\t\tannounceStatus( getStatusText( currentSlide ) );\n\t\t});\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\tif( config.sortFragmentsOnSync === true ) {\n\t\t\tfragments.sortAll();\n\t\t}\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( slides = getHorizontalSlides() ) {\n\n\t\tslides.forEach( ( slide, i ) => {\n\n\t\t\t// Insert the slide next to a randomly picked sibling slide\n\t\t\t// slide. This may cause the slide to insert before itself,\n\t\t\t// but that's not an issue.\n\t\t\tlet beforeSlide = slides[ Math.floor( Math.random() * slides.length ) ];\n\t\t\tif( beforeSlide.parentNode === slide.parentNode ) {\n\t\t\t\tslide.parentNode.insertBefore( slide, beforeSlide );\n\t\t\t}\n\n\t\t\t// Randomize the order of vertical slides (if there are any)\n\t\t\tlet verticalSlides = slide.querySelectorAll( 'section' );\n\t\t\tif( verticalSlides.length ) {\n\t\t\t\tshuffle( verticalSlides );\n\t\t\t}\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\t\tlet loopedForwards = false;\n\t\tlet loopedBackwards = false;\n\n\t\tif( slidesLength ) {\n\n\t\t\t// Should the index loop?\n\t\t\tif( config.loop ) {\n\t\t\t\tif( index >= slidesLength ) loopedForwards = true;\n\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\tloopedBackwards = true;\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\t// Avoid .remove() with multiple args for IE11 support\n\t\t\t\telement.classList.remove( 'past' );\n\t\t\t\telement.classList.remove( 'present' );\n\t\t\t\telement.classList.remove( '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\tshowFragmentsIn( element );\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\thideFragmentsIn( element );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Update the visibility of fragments when a presentation loops\n\t\t\t\t// in either direction\n\t\t\t\telse if( i === index && config.fragments ) {\n\t\t\t\t\tif( loopedForwards ) {\n\t\t\t\t\t\thideFragmentsIn( element );\n\t\t\t\t\t}\n\t\t\t\t\telse if( loopedBackwards ) {\n\t\t\t\t\t\tshowFragmentsIn( element );\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 * Shows all fragment elements within the given contaienr.\n\t */\n\tfunction showFragmentsIn( container ) {\n\n\t\tUtil.queryAll( container, '.fragment' ).forEach( fragment => {\n\t\t\tfragment.classList.add( 'visible' );\n\t\t\tfragment.classList.remove( 'current-fragment' );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Hides all fragment elements within the given contaienr.\n\t */\n\tfunction hideFragmentsIn( container ) {\n\n\t\tUtil.queryAll( container, '.fragment.visible' ).forEach( fragment => {\n\t\t\tfragment.classList.remove( 'visible', 'current-fragment' );\n\t\t} );\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({ includeFragments = false } = {}) {\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// If includeFragments is set, a route will be considered\n\t\t// available if either a slid OR fragment is available in\n\t\t// the given direction\n\t\tif( includeFragments === true ) {\n\t\t\tlet fragmentRoutes = fragments.availableRoutes();\n\t\t\troutes.left = routes.left || fragmentRoutes.prev;\n\t\t\troutes.up = routes.up || fragmentRoutes.prev;\n\t\t\troutes.down = routes.down || fragmentRoutes.next;\n\t\t\troutes.right = routes.right || fragmentRoutes.next;\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\n\t\t\t\t// If there are media elements with data-autoplay,\n\t\t\t\t// automatically set the autoSlide duration to the\n\t\t\t\t// length of that media. Not applicable if the slide\n\t\t\t\t// is divided up into fragments.\n\t\t\t\t// playbackRate is accounted for in the duration.\n\t\t\t\tif( currentSlide.querySelectorAll( '.fragment' ).length === 0 ) {\n\t\t\t\t\tUtil.queryAll( currentSlide, 'video, audio' ).forEach( el => {\n\t\t\t\t\t\tif( el.hasAttribute( 'data-autoplay' ) ) {\n\t\t\t\t\t\t\tif( autoSlide && (el.duration * 1000 / el.playbackRate ) > autoSlide ) {\n\t\t\t\t\t\t\t\tautoSlide = ( el.duration * 1000 / el.playbackRate ) + 1000;\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}\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({skipFragments=false}={}) {\n\n\t\tnavigationHistory.hasNavigatedHorizontally = true;\n\n\t\t// Reverse for RTL\n\t\tif( config.rtl ) {\n\t\t\tif( ( overview.isActive() || skipFragments || 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() || skipFragments || 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({skipFragments=false}={}) {\n\n\t\tnavigationHistory.hasNavigatedHorizontally = true;\n\n\t\t// Reverse for RTL\n\t\tif( config.rtl ) {\n\t\t\tif( ( overview.isActive() || skipFragments || 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() || skipFragments || 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({skipFragments=false}={}) {\n\n\t\t// Prioritize hiding fragments\n\t\tif( ( overview.isActive() || skipFragments || fragments.prev() === false ) && availableRoutes().up ) {\n\t\t\tslide( indexh, indexv - 1 );\n\t\t}\n\n\t}\n\n\tfunction navigateDown({skipFragments=false}={}) {\n\n\t\tnavigationHistory.hasNavigatedVertically = true;\n\n\t\t// Prioritize revealing fragments\n\t\tif( ( overview.isActive() || skipFragments || 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({skipFragments=false}={}) {\n\n\t\t// Prioritize revealing fragments\n\t\tif( skipFragments || fragments.prev() === false ) {\n\t\t\tif( availableRoutes().up ) {\n\t\t\t\tnavigateUp({skipFragments});\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\t// When going backwards and arriving on a stack we start\n\t\t\t\t// at the bottom of the stack\n\t\t\t\tif( previousSlide && previousSlide.classList.contains( 'stack' ) ) {\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\telse {\n\t\t\t\t\tnavigateLeft({skipFragments});\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({skipFragments=false}={}) {\n\n\t\tnavigationHistory.hasNavigatedHorizontally = true;\n\t\tnavigationHistory.hasNavigatedVertically = true;\n\n\t\t// Prioritize revealing fragments\n\t\tif( skipFragments || 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() ) {\n\t\t\t\troutes.down = false;\n\t\t\t}\n\n\t\t\tif( routes.down ) {\n\t\t\t\tnavigateDown({skipFragments});\n\t\t\t}\n\t\t\telse if( config.rtl ) {\n\t\t\t\tnavigateLeft({skipFragments});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnavigateRight({skipFragments});\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* Listener for post message events posted to this window.\n\t*/\n\tfunction onPostMessage( event ) {\n\n\t\tlet data = event.data;\n\n\t\t// Make sure we're dealing with JSON\n\t\tif( typeof data === 'string' && data.charAt( 0 ) === '{' && data.charAt( data.length - 1 ) === '}' ) {\n\t\t\tdata = JSON.parse( data );\n\n\t\t\t// Check if the requested method can be found\n\t\t\tif( data.method && typeof Reveal[data.method] === 'function' ) {\n\n\t\t\t\tif( POST_MESSAGE_METHOD_BLACKLIST.test( data.method ) === false ) {\n\n\t\t\t\t\tconst result = Reveal[data.method].apply( Reveal, data.args );\n\n\t\t\t\t\t// Dispatch a postMessage event with the returned value from\n\t\t\t\t\t// our method invocation for getter functions\n\t\t\t\t\tdispatchPostMessage( 'callback', { method: data.method, result: result } );\n\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tconsole.warn( 'reveal.js: \"'+ data.method +'\" is is blacklisted from the postMessage API' );\n\t\t\t\t}\n\n\t\t\t}\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 * A global listener for all click events inside of the\n\t * .slides container.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onSlidesClicked( event ) {\n\n\t\tconst anchor = Util.closest( event.target, 'a[href^=\"#\"]' );\n\n\t\t// If a hash link is clicked, we find the target slide\n\t\t// and navigate to it. We previously relied on 'hashchange'\n\t\t// for links like these but that prevented media with\n\t\t// audio tracks from playing in mobile browsers since it\n\t\t// wasn't considered a direct interaction with the document.\n\t\tif( anchor ) {\n\t\t\tconst hash = anchor.getAttribute( 'href' );\n\t\t\tconst indices = location.getIndicesFromHash( hash );\n\n\t\t\tif( indices ) {\n\t\t\t\tReveal.slide( indices.h, indices.v, indices.f );\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t}\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 * Handler for the document level 'fullscreenchange' event.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onFullscreenChange( event ) {\n\n\t\tlet element = document.fullscreenElement || document.webkitFullscreenElement;\n\t\tif( element === dom.wrapper ) {\n\t\t\tevent.stopImmediatePropagation();\n\n\t\t\t// Timeout to avoid layout shift in Safari\n\t\t\tsetTimeout( () => {\n\t\t\t\tReveal.layout();\n\t\t\t\tReveal.focus.focus(); // focus.focus :'(\n\t\t\t}, 1 );\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\t\tdestroy,\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// Toggles visibility of the jump-to-slide UI\n\t\ttoggleJumpToSlide,\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\tisFocused: focus.isFocused.bind( focus ),\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// Preview management\n\t\tshowPreview,\n\t\thidePreview: closeOverlay,\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 the path to the current slide as represented in the URL\n\t\tgetSlidePath: location.getHash.bind( location ),\n\n\t\t// Returns reveal.js DOM elements\n\t\tgetRevealElement: () => revealElement,\n\t\tgetSlidesElement: () => dom.slides,\n\t\tgetViewportElement: () => dom.viewport,\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\tfocus,\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, { VERSION } 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 */\nlet 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 one 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 premature API calls and invoking all\n * of them when Reveal.initialize is called.\n */\n[ 'configure', '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\nReveal.isReady = () => false;\n\nReveal.VERSION = VERSION;\n\nexport default Reveal;"],"names":["extend","a","b","i","queryAll","el","selector","Array","from","querySelectorAll","toggleClass","className","value","classList","add","remove","deserialize","match","parseFloat","transformElement","element","transform","style","matches","target","matchesMethod","matchesSelector","msMatchesSelector","call","closest","parentNode","createSingletonNode","container","tagname","classname","innerHTML","nodes","length","testNode","node","document","createElement","appendChild","createStyleSheet","tag","type","styleSheet","cssText","createTextNode","head","getQueryHash","query","location","search","replace","split","shift","pop","unescape","getRemainingHeight","height","newHeight","oldHeight","offsetHeight","removeProperty","fileExtensionToMimeMap","UA","navigator","userAgent","isMobile","test","platform","maxTouchPoints","isAndroid","Object","defineProperty","fitty_module","_extends","assign","arguments","source","key","prototype","hasOwnProperty","w","toArray","nl","slice","DrawState","fitties","redrawFrame","requestRedraw","cancelAnimationFrame","requestAnimationFrame","redraw","filter","f","dirty","active","redrawAll","forEach","styleComputed","computeStyle","shouldPreStyle","applyStyle","fittiesToRedraw","shouldRedraw","calculateStyles","markAsClean","dispatchFitEvent","availableWidth","clientWidth","currentWidth","scrollWidth","previousFontSize","currentFontSize","Math","min","max","minSize","maxSize","whiteSpace","multiLine","getComputedStyle","getPropertyValue","display","preStyle","preStyleTestCompleted","fontSize","dispatchEvent","CustomEvent","detail","oldValue","newValue","scaleFactor","fit","destroy","_","observeMutations","observer","disconnect","originalStyle","subscribe","unsubscribe","MutationObserver","observe","defaultOptions","subtree","childList","characterData","resizeDebounce","onWindowResized","clearTimeout","setTimeout","fitty","observeWindowDelay","events","set","enabled","method","e","observeWindow","fitAll","fittyCreate","elements","options","fittyOptions","publicFitties","map","newbie","push","init","unfreeze","freeze","undefined","window","SlideContent","constructor","Reveal","startEmbeddedIframe","this","bind","shouldPreload","preload","getConfig","preloadIframes","hasAttribute","load","slide","tagName","setAttribute","getAttribute","removeAttribute","media","sources","background","slideBackgroundElement","backgroundContent","slideBackgroundContentElement","backgroundIframe","backgroundImage","backgroundVideo","backgroundVideoLoop","backgroundVideoMuted","trim","url","encodeURI","c","charCodeAt","toString","toUpperCase","encodeRFC3986URI","decodeURI","join","isSpeakerNotes","video","muted","filename","getMimeTypeFromFile","excludeIframes","iframe","width","maxHeight","maxWidth","backgroundIframeElement","querySelector","layout","scopeElement","unload","getSlideBackground","formatEmbeddedContent","_appendParamToIframeSource","sourceAttribute","sourceURL","param","getSlidesElement","src","indexOf","startEmbeddedContent","autoplay","autoPlayMedia","play","readyState","startEmbeddedMedia","promise","catch","controls","addEventListener","removeEventListener","event","isAttachedToDOM","isVisible","currentTime","contentWindow","postMessage","stopEmbeddedContent","unloadIframes","pause","SlideNumber","render","getRevealElement","configure","config","oldConfig","slideNumberDisplay","slideNumber","isPrintingPDF","showSlideNumber","update","getSlideNumber","getCurrentSlide","format","getHorizontalSlides","horizontalOffset","dataset","visibility","getSlidePastCount","getTotalSlides","indices","getIndices","h","sep","isVerticalSlide","v","getHash","formatNumber","delimiter","isNaN","JumpToSlide","onInput","onBlur","onKeyDown","jumpInput","placeholder","show","indicesOnShow","focus","hide","jumpTimeout","jump","getIndicesFromHash","oneBasedIndex","jumpAfter","delay","regex","RegExp","getSlides","find","innerText","cancel","confirm","keyCode","stopImmediatePropagation","colorToRgb","color","hex3","r","parseInt","charAt","g","hex6","rgb","rgba","Backgrounds","create","slideh","backgroundStack","createBackground","slidev","parallaxBackgroundImage","backgroundSize","parallaxBackgroundSize","backgroundRepeat","parallaxBackgroundRepeat","backgroundPosition","parallaxBackgroundPosition","contentElement","sync","data","backgroundColor","backgroundGradient","backgroundTransition","backgroundOpacity","dataPreload","opacity","contrastColor","computedBackgroundStyle","includeAll","currentSlide","currentBackground","horizontalPast","rtl","horizontalFuture","childNodes","backgroundh","backgroundv","previousBackground","slideContent","currentBackgroundContent","backgroundImageURL","previousBackgroundHash","currentBackgroundHash","classToBubble","contains","updateParallax","backgroundWidth","backgroundHeight","horizontalSlides","verticalSlides","getVerticalSlides","horizontalOffsetMultiplier","slideWidth","offsetWidth","horizontalSlideCount","parallaxBackgroundHorizontal","verticalOffsetMultiplier","verticalOffset","slideHeight","verticalSlideCount","parallaxBackgroundVertical","SLIDES_SELECTOR","HORIZONTAL_SLIDES_SELECTOR","VERTICAL_SLIDES_SELECTOR","POST_MESSAGE_METHOD_BLACKLIST","FRAGMENT_STYLE_REGEX","autoAnimateCounter","AutoAnimate","run","fromSlide","toSlide","reset","allSlides","toSlideIndex","fromSlideIndex","autoAnimateStyleSheet","animationOptions","getAutoAnimateOptions","autoAnimate","slideDirection","fromSlideIsHidden","css","getAutoAnimatableElements","autoAnimateElements","to","autoAnimateUnmatched","defaultUnmatchedDuration","duration","defaultUnmatchedDelay","getUnmatchedAutoAnimateElements","unmatchedElement","unmatchedOptions","id","autoAnimateTarget","fontWeight","sheet","removeChild","elementOptions","easing","fromProps","getAutoAnimatableProperties","toProps","styles","translate","scale","presentationScale","getScale","delta","x","y","scaleX","scaleY","round","propertyName","toValue","fromValue","explicitValue","toStyleProperties","keys","inheritedOptions","autoAnimateEasing","autoAnimateDuration","autoAnimatedParent","autoAnimateDelay","direction","properties","bounds","measure","center","getBoundingClientRect","offsetLeft","offsetTop","computedStyles","autoAnimateStyles","property","pairs","autoAnimateMatcher","getAutoAnimatePairs","reserved","pair","index","textNodes","findAutoAnimateMatches","nodeName","textContent","getLocalBoundingBox","fromScope","toScope","serializer","fromMatches","toMatches","fromElement","primaryIndex","secondaryIndex","rootElement","children","reduce","result","containsAnimatedElements","concat","Fragments","fragments","disable","enable","availableRoutes","hiddenFragments","prev","next","sort","grouped","ordered","unordered","sorted","fragment","group","sortAll","horizontalSlide","verticalSlide","changedFragments","shown","hidden","maxIndex","currentFragment","wasVisible","announceStatus","getStatusText","bubbles","goto","offset","lastVisibleFragment","progress","fragmentInURL","writeURL","Overview","onSlideClicked","activate","overview","isActive","cancelAutoSlide","getBackgroundsElement","margin","slideSize","getComputedSlideSize","overviewSlideWidth","overviewSlideHeight","updateSlidesVisibility","hslide","vslide","hbackground","vbackground","vmin","innerWidth","innerHeight","transformSlides","deactivate","cueAutoSlide","toggle","override","preventDefault","Keyboard","shortcuts","bindings","onDocumentKeyDown","onDocumentKeyPress","navigationMode","unbind","addKeyBinding","binding","callback","description","removeKeyBinding","triggerKey","registerKeyboardShortcut","getShortcuts","getBindings","shiftKey","charCode","toggleHelp","keyboardCondition","isFocused","autoSlideWasPaused","isAutoSliding","onUserInput","activeElementIsCE","activeElement","isContentEditable","activeElementIsInput","activeElementIsNotes","unusedModifier","altKey","ctrlKey","metaKey","resumeKeyCodes","keyboard","isPaused","useLinearMode","hasHorizontalSlides","hasVerticalSlides","triggered","apply","action","skipFragments","left","right","up","Number","MAX_VALUE","down","togglePause","requestMethod","documentElement","requestFullscreen","webkitRequestFullscreen","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen","enterFullscreen","embedded","getViewportElement","autoSlideStoppable","toggleAutoSlide","jumpToSlide","toggleJumpToSlide","closeOverlay","Location","writeURLTimeout","replaceStateTimestamp","onWindowHashChange","hash","name","bits","hashIndexBase","hashOneBasedIndex","getElementById","decodeURIComponent","error","readURL","currentIndices","newIndices","history","debouncedReplaceState","pathname","replaceState","Date","now","replaceStateTimeout","MAX_REPLACE_STATE_FREQUENCY","s","encodeURIComponent","Controls","onNavigateLeftClicked","onNavigateRightClicked","onNavigateUpClicked","onNavigateDownClicked","onNavigatePrevClicked","onNavigateNextClicked","revealElement","controlsLeft","controlsRight","controlsUp","controlsDown","controlsPrev","controlsNext","controlsRightArrow","controlsLeftArrow","controlsDownArrow","controlsLayout","controlsBackArrows","pointerEvents","eventName","routes","fragmentsRoutes","controlsTutorial","hasNavigatedVertically","hasNavigatedHorizontally","Progress","onProgressClicked","bar","getProgress","getMaxWidth","slides","slidesTotal","slideIndex","floor","clientX","targetIndices","Pointer","lastMouseWheelStep","cursorHidden","cursorInactiveTimeout","onDocumentCursorActive","onDocumentMouseScroll","mouseWheel","hideInactiveCursor","showCursor","cursor","hideCursor","hideCursorTime","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","hasPlugin","getPlugin","getRegisteredPlugins","Print","injectPageNumbers","pageWidth","pageHeight","body","viewportElement","presentationBackground","viewportStyles","layoutSlideContents","slideScrollHeights","scrollHeight","pages","pageContainer","top","contentHeight","numberOfPages","ceil","pdfMaxPagesPerSlide","page","pdfPageHeightOffset","showNotes","notes","getSlideNotes","notesSpacing","notesLayout","notesElement","bottom","numberElement","pdfSeparateFragments","fragmentGroups","previousFragmentStep","clonedPage","cloneNode","fragmentNumber","Touch","touchStartX","touchStartY","touchStartCount","touchCaptured","onPointerDown","onPointerMove","onPointerUp","onTouchStart","onTouchMove","onTouchEnd","msPointerEnabled","isSwipePrevented","touches","clientY","currentX","currentY","includeFragments","deltaX","deltaY","abs","pointerType","MSPOINTER_TYPE_TOUCH","STATE_FOCUS","STATE_BLUR","Focus","onRevealPointerDown","onDocumentPointerDown","blur","Notes","print","updateVisibility","hasNotes","isSpeakerNotesWindow","notesElements","Playback","progressCheck","diameter","diameter2","thickness","playing","progressOffset","canvas","context","getContext","setPlaying","wasPlaying","animate","progressBefore","radius","iconSize","endAngle","PI","startAngle","save","clearRect","beginPath","arc","fillStyle","fill","lineWidth","strokeStyle","stroke","fillRect","moveTo","lineTo","restore","on","listener","off","minScale","maxScale","respondToHashChanges","disableLayout","touch","loop","shuffle","help","showHiddenSlides","autoSlide","autoSlideMethod","defaultTiming","previewLinks","postMessageEvents","focusBodyOnPageVisibilityChange","transition","transitionSpeed","POSITIVE_INFINITY","viewDistance","mobileViewDistance","sortFragmentsOnSync","VERSION","indexh","indexv","previousSlide","autoSlidePlayer","ready","navigationHistory","slidesTransform","dom","autoSlideTimeout","autoSlideStartTime","autoSlidePaused","backgrounds","pointer","initialize","initOptions","wrapper","defaultConfig","Util","setViewport","start","viewport","removeHiddenSlides","setupDOM","setupPostMessage","setupScrollPrevention","setupFullscreen","resetVerticalSlides","removeEventListeners","setupPDF","Device","pauseOverlay","statusElement","createStatusElement","position","overflow","clip","text","nodeType","isAriaHidden","isDisplayHidden","child","setInterval","scrollTop","scrollLeft","onFullscreenChange","onPostMessage","isReady","numberOfSlides","setProperty","resume","enablePreviewLinks","disablePreviewLinks","onAutoSlidePlayerClick","addEventListeners","onWindowResize","onSlidesClicked","onTransitionEnd","onPageVisibilityChange","useCapture","transforms","createEvent","initEvent","dispatchPostMessage","parent","self","message","namespace","getState","JSON","stringify","onPreviewLinkClicked","showPreview","overlay","showHelp","html","size","oldScale","presentationWidth","presentationHeight","zoom","len","remainingHeight","nw","naturalWidth","videoWidth","nh","naturalHeight","videoHeight","es","setPreviousVerticalIndex","stack","getPreviousVerticalIndex","attributeName","isLastVerticalSlide","nextElementSibling","isFirstSlide","isLastSlide","wasPaused","resumeAutoSlide","pauseAutoSlide","origin","defaultPrevented","stateBefore","indexhBefore","indexvBefore","updateSlides","slideChanged","currentHorizontalSlide","currentVerticalSlides","autoAnimateTransition","getVerticalStacks","stateLoop","j","splice","syncSlide","beforeSlide","random","slidesLength","printMode","loopedForwards","loopedBackwards","reverse","showFragmentsIn","hideFragmentsIn","wasPresent","slideState","distanceX","distanceY","horizontalSlidesLength","verticalSlidesLength","oy","fragmentRoutes","pastCount","mainLoop","totalCount","allFragments","fragmentWeight","isVertical","getSlidesAttributes","attributes","attribute","getSlide","indexf","paused","setState","pausedFlag","overviewFlag","fragmentAutoSlide","parentAutoSlide","slideAutoSlide","playbackRate","navigateNext","navigateLeft","navigateRight","navigateUp","navigateDown","navigatePrev","parse","args","anchor","fullscreenElement","webkitFullscreenElement","currentTarget","API","syncFragments","navigateFragment","prevFragment","nextFragment","availableFragments","toggleOverview","isOverview","loadSlide","unloadSlide","hidePreview","getPreviousSlide","getSlidePath","getPlugins","Deck","enqueuedAPICalls","deck"],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/reveal.js b/dist/reveal.js
new file mode 100644
index 00000000000..dadb229f1a3
--- /dev/null
+++ b/dist/reveal.js
@@ -0,0 +1,9 @@
+/*!
+* reveal.js 4.5.0
+* https://revealjs.com
+* MIT licensed
+*
+* Copyright (C) 2011-2023 Hakim El Hattab, https://hakim.se
+*/
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Reveal=t()}(this,(function(){"use strict";const e=(e,t)=>{for(let i in t)e[i]=t[i];return e},t=(e,t)=>Array.from(e.querySelectorAll(t)),i=(e,t,i)=>{i?e.classList.add(t):e.classList.remove(t)},n=e=>{if("string"==typeof e){if("null"===e)return null;if("true"===e)return!0;if("false"===e)return!1;if(e.match(/^-?[\d\.]+$/))return parseFloat(e)}return e},s=(e,t)=>{e.style.transform=t},a=(e,t)=>{let i=e.matches||e.matchesSelector||e.msMatchesSelector;return!(!i||!i.call(e,t))},o=(e,t)=>{if("function"==typeof e.closest)return e.closest(t);for(;e;){if(a(e,t))return e;e=e.parentNode}return null},r=(e,t,i,n="")=>{let s=e.querySelectorAll("."+i);for(let t=0;t
{let t=document.createElement("style");return t.type="text/css",e&&e.length>0&&(t.styleSheet?t.styleSheet.cssText=e:t.appendChild(document.createTextNode(e))),document.head.appendChild(t),t},d=()=>{let e={};location.search.replace(/[A-Z0-9]+?=([\w\.%-]*)/gi,(t=>{e[t.split("=").shift()]=t.split("=").pop()}));for(let t in e){let i=e[t];e[t]=n(unescape(i))}return void 0!==e.dependencies&&delete e.dependencies,e},c=(e,t=0)=>{if(e){let i,n=e.style.height;return e.style.height="0px",e.parentNode.style.height="auto",i=t-e.parentNode.offsetHeight,e.style.height=n+"px",e.parentNode.style.removeProperty("height"),i}return t},h={mp4:"video/mp4",m4a:"video/mp4",ogv:"video/ogg",mpeg:"video/mpeg",webm:"video/webm"},u=navigator.userAgent,g=/(iphone|ipod|ipad|android)/gi.test(u)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1;/chrome/i.test(u)&&/edge/i.test(u);const v=/android/gi.test(u);var p={};Object.defineProperty(p,"__esModule",{value:!0});var m=Object.assign||function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:{};return"string"==typeof e?x(t(document.querySelectorAll(e)),i):x([e],i)[0]}}("undefined"==typeof window?null:window);class b{constructor(e){this.Reveal=e,this.startEmbeddedIframe=this.startEmbeddedIframe.bind(this)}shouldPreload(e){let t=this.Reveal.getConfig().preloadIframes;return"boolean"!=typeof t&&(t=e.hasAttribute("data-preload")),t}load(e,i={}){e.style.display=this.Reveal.getConfig().display,t(e,"img[data-src], video[data-src], audio[data-src], iframe[data-src]").forEach((e=>{("IFRAME"!==e.tagName||this.shouldPreload(e))&&(e.setAttribute("src",e.getAttribute("data-src")),e.setAttribute("data-lazy-loaded",""),e.removeAttribute("data-src"))})),t(e,"video, audio").forEach((e=>{let i=0;t(e,"source[data-src]").forEach((e=>{e.setAttribute("src",e.getAttribute("data-src")),e.removeAttribute("data-src"),e.setAttribute("data-lazy-loaded",""),i+=1})),g&&"VIDEO"===e.tagName&&e.setAttribute("playsinline",""),i>0&&e.load()}));let n=e.slideBackgroundElement;if(n){n.style.display="block";let t=e.slideBackgroundContentElement,s=e.getAttribute("data-background-iframe");if(!1===n.hasAttribute("data-loaded")){n.setAttribute("data-loaded","true");let a=e.getAttribute("data-background-image"),o=e.getAttribute("data-background-video"),r=e.hasAttribute("data-background-video-loop"),l=e.hasAttribute("data-background-video-muted");if(a)/^data:/.test(a.trim())?t.style.backgroundImage=`url(${a.trim()})`:t.style.backgroundImage=a.split(",").map((e=>`url(${((e="")=>encodeURI(e).replace(/%5B/g,"[").replace(/%5D/g,"]").replace(/[!'()*]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)))(decodeURI(e.trim()))})`)).join(",");else if(o&&!this.Reveal.isSpeakerNotes()){let e=document.createElement("video");r&&e.setAttribute("loop",""),l&&(e.muted=!0),g&&(e.muted=!0,e.setAttribute("playsinline","")),o.split(",").forEach((t=>{let i=((e="")=>h[e.split(".").pop()])(t);e.innerHTML+=i?``:``})),t.appendChild(e)}else if(s&&!0!==i.excludeIframes){let e=document.createElement("iframe");e.setAttribute("allowfullscreen",""),e.setAttribute("mozallowfullscreen",""),e.setAttribute("webkitallowfullscreen",""),e.setAttribute("allow","autoplay"),e.setAttribute("data-src",s),e.style.width="100%",e.style.height="100%",e.style.maxHeight="100%",e.style.maxWidth="100%",t.appendChild(e)}}let a=t.querySelector("iframe[data-src]");a&&this.shouldPreload(n)&&!/autoplay=(1|true|yes)/gi.test(s)&&a.getAttribute("src")!==s&&a.setAttribute("src",s)}this.layout(e)}layout(e){Array.from(e.querySelectorAll(".r-fit-text")).forEach((e=>{f(e,{minSize:24,maxSize:.8*this.Reveal.getConfig().height,observeMutations:!1,observeWindow:!1})}))}unload(e){e.style.display="none";let i=this.Reveal.getSlideBackground(e);i&&(i.style.display="none",t(i,"iframe[src]").forEach((e=>{e.removeAttribute("src")}))),t(e,"video[data-lazy-loaded][src], audio[data-lazy-loaded][src], iframe[data-lazy-loaded][src]").forEach((e=>{e.setAttribute("data-src",e.getAttribute("src")),e.removeAttribute("src")})),t(e,"video[data-lazy-loaded] source[src], audio source[src]").forEach((e=>{e.setAttribute("data-src",e.getAttribute("src")),e.removeAttribute("src")}))}formatEmbeddedContent(){let e=(e,i,n)=>{t(this.Reveal.getSlidesElement(),"iframe["+e+'*="'+i+'"]').forEach((t=>{let i=t.getAttribute(e);i&&-1===i.indexOf(n)&&t.setAttribute(e,i+(/\?/.test(i)?"&":"?")+n)}))};e("src","youtube.com/embed/","enablejsapi=1"),e("data-src","youtube.com/embed/","enablejsapi=1"),e("src","player.vimeo.com/","api=1"),e("data-src","player.vimeo.com/","api=1")}startEmbeddedContent(e){e&&!this.Reveal.isSpeakerNotes()&&(t(e,'img[src$=".gif"]').forEach((e=>{e.setAttribute("src",e.getAttribute("src"))})),t(e,"video, audio").forEach((e=>{if(o(e,".fragment")&&!o(e,".fragment.visible"))return;let t=this.Reveal.getConfig().autoPlayMedia;if("boolean"!=typeof t&&(t=e.hasAttribute("data-autoplay")||!!o(e,".slide-background")),t&&"function"==typeof e.play)if(e.readyState>1)this.startEmbeddedMedia({target:e});else if(g){let t=e.play();t&&"function"==typeof t.catch&&!1===e.controls&&t.catch((()=>{e.controls=!0,e.addEventListener("play",(()=>{e.controls=!1}))}))}else e.removeEventListener("loadeddata",this.startEmbeddedMedia),e.addEventListener("loadeddata",this.startEmbeddedMedia)})),t(e,"iframe[src]").forEach((e=>{o(e,".fragment")&&!o(e,".fragment.visible")||this.startEmbeddedIframe({target:e})})),t(e,"iframe[data-src]").forEach((e=>{o(e,".fragment")&&!o(e,".fragment.visible")||e.getAttribute("src")!==e.getAttribute("data-src")&&(e.removeEventListener("load",this.startEmbeddedIframe),e.addEventListener("load",this.startEmbeddedIframe),e.setAttribute("src",e.getAttribute("data-src")))})))}startEmbeddedMedia(e){let t=!!o(e.target,"html"),i=!!o(e.target,".present");t&&i&&(e.target.currentTime=0,e.target.play()),e.target.removeEventListener("loadeddata",this.startEmbeddedMedia)}startEmbeddedIframe(e){let t=e.target;if(t&&t.contentWindow){let i=!!o(e.target,"html"),n=!!o(e.target,".present");if(i&&n){let e=this.Reveal.getConfig().autoPlayMedia;"boolean"!=typeof e&&(e=t.hasAttribute("data-autoplay")||!!o(t,".slide-background")),/youtube\.com\/embed\//.test(t.getAttribute("src"))&&e?t.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}',"*"):/player\.vimeo\.com\//.test(t.getAttribute("src"))&&e?t.contentWindow.postMessage('{"method":"play"}',"*"):t.contentWindow.postMessage("slide:start","*")}}}stopEmbeddedContent(i,n={}){n=e({unloadIframes:!0},n),i&&i.parentNode&&(t(i,"video, audio").forEach((e=>{e.hasAttribute("data-ignore")||"function"!=typeof e.pause||(e.setAttribute("data-paused-by-reveal",""),e.pause())})),t(i,"iframe").forEach((e=>{e.contentWindow&&e.contentWindow.postMessage("slide:stop","*"),e.removeEventListener("load",this.startEmbeddedIframe)})),t(i,'iframe[src*="youtube.com/embed/"]').forEach((e=>{!e.hasAttribute("data-ignore")&&e.contentWindow&&"function"==typeof e.contentWindow.postMessage&&e.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}',"*")})),t(i,'iframe[src*="player.vimeo.com/"]').forEach((e=>{!e.hasAttribute("data-ignore")&&e.contentWindow&&"function"==typeof e.contentWindow.postMessage&&e.contentWindow.postMessage('{"method":"pause"}',"*")})),!0===n.unloadIframes&&t(i,"iframe[data-src]").forEach((e=>{e.setAttribute("src","about:blank"),e.removeAttribute("src")})))}}class y{constructor(e){this.Reveal=e}render(){this.element=document.createElement("div"),this.element.className="slide-number",this.Reveal.getRevealElement().appendChild(this.element)}configure(e,t){let i="none";e.slideNumber&&!this.Reveal.isPrintingPDF()&&("all"===e.showSlideNumber||"speaker"===e.showSlideNumber&&this.Reveal.isSpeakerNotes())&&(i="block"),this.element.style.display=i}update(){this.Reveal.getConfig().slideNumber&&this.element&&(this.element.innerHTML=this.getSlideNumber())}getSlideNumber(e=this.Reveal.getCurrentSlide()){let t,i=this.Reveal.getConfig(),n="h.v";if("function"==typeof i.slideNumber)t=i.slideNumber(e);else{"string"==typeof i.slideNumber&&(n=i.slideNumber),/c/.test(n)||1!==this.Reveal.getHorizontalSlides().length||(n="c");let s=e&&"uncounted"===e.dataset.visibility?0:1;switch(t=[],n){case"c":t.push(this.Reveal.getSlidePastCount(e)+s);break;case"c/t":t.push(this.Reveal.getSlidePastCount(e)+s,"/",this.Reveal.getTotalSlides());break;default:let i=this.Reveal.getIndices(e);t.push(i.h+s);let a="h/v"===n?"/":".";this.Reveal.isVerticalSlide(e)&&t.push(a,i.v+1)}}let s="#"+this.Reveal.location.getHash(e);return this.formatNumber(t[0],t[1],t[2],s)}formatNumber(e,t,i,n="#"+this.Reveal.location.getHash()){return"number"!=typeof i||isNaN(i)?`\n\t\t\t\t\t${e} \n\t\t\t\t\t `:`\n\t\t\t\t\t${e} \n\t\t\t\t\t${t} \n\t\t\t\t\t${i} \n\t\t\t\t\t `}destroy(){this.element.remove()}}class w{constructor(e){this.Reveal=e,this.onInput=this.onInput.bind(this),this.onBlur=this.onBlur.bind(this),this.onKeyDown=this.onKeyDown.bind(this)}render(){this.element=document.createElement("div"),this.element.className="jump-to-slide",this.jumpInput=document.createElement("input"),this.jumpInput.type="text",this.jumpInput.className="jump-to-slide-input",this.jumpInput.placeholder="Jump to slide",this.jumpInput.addEventListener("input",this.onInput),this.jumpInput.addEventListener("keydown",this.onKeyDown),this.jumpInput.addEventListener("blur",this.onBlur),this.element.appendChild(this.jumpInput)}show(){this.indicesOnShow=this.Reveal.getIndices(),this.Reveal.getRevealElement().appendChild(this.element),this.jumpInput.focus()}hide(){this.isVisible()&&(this.element.remove(),this.jumpInput.value="",clearTimeout(this.jumpTimeout),delete this.jumpTimeout)}isVisible(){return!!this.element.parentNode}jump(){clearTimeout(this.jumpTimeout),delete this.jumpTimeout;const e=this.jumpInput.value.trim("");let t=this.Reveal.location.getIndicesFromHash(e,{oneBasedIndex:!0});return!t&&/\S+/i.test(e)&&e.length>1&&(t=this.search(e)),t&&""!==e?(this.Reveal.slide(t.h,t.v,t.f),!0):(this.Reveal.slide(this.indicesOnShow.h,this.indicesOnShow.v,this.indicesOnShow.f),!1)}jumpAfter(e){clearTimeout(this.jumpTimeout),this.jumpTimeout=setTimeout((()=>this.jump()),e)}search(e){const t=new RegExp("\\b"+e.trim()+"\\b","i"),i=this.Reveal.getSlides().find((e=>t.test(e.innerText)));return i?this.Reveal.getIndices(i):null}cancel(){this.Reveal.slide(this.indicesOnShow.h,this.indicesOnShow.v,this.indicesOnShow.f),this.hide()}confirm(){this.jump(),this.hide()}destroy(){this.jumpInput.removeEventListener("input",this.onInput),this.jumpInput.removeEventListener("keydown",this.onKeyDown),this.jumpInput.removeEventListener("blur",this.onBlur),this.element.remove()}onKeyDown(e){13===e.keyCode?this.confirm():27===e.keyCode&&(this.cancel(),e.stopImmediatePropagation())}onInput(e){this.jumpAfter(200)}onBlur(){setTimeout((()=>this.hide()),1)}}const E=e=>{let t=e.match(/^#([0-9a-f]{3})$/i);if(t&&t[1])return t=t[1],{r:17*parseInt(t.charAt(0),16),g:17*parseInt(t.charAt(1),16),b:17*parseInt(t.charAt(2),16)};let i=e.match(/^#([0-9a-f]{6})$/i);if(i&&i[1])return i=i[1],{r:parseInt(i.slice(0,2),16),g:parseInt(i.slice(2,4),16),b:parseInt(i.slice(4,6),16)};let n=e.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);if(n)return{r:parseInt(n[1],10),g:parseInt(n[2],10),b:parseInt(n[3],10)};let s=e.match(/^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\,\s*([\d]+|[\d]*.[\d]+)\s*\)$/i);return s?{r:parseInt(s[1],10),g:parseInt(s[2],10),b:parseInt(s[3],10),a:parseFloat(s[4])}:null};class R{constructor(e){this.Reveal=e}render(){this.element=document.createElement("div"),this.element.className="backgrounds",this.Reveal.getRevealElement().appendChild(this.element)}create(){this.element.innerHTML="",this.element.classList.add("no-transition"),this.Reveal.getHorizontalSlides().forEach((e=>{let i=this.createBackground(e,this.element);t(e,"section").forEach((e=>{this.createBackground(e,i),i.classList.add("stack")}))})),this.Reveal.getConfig().parallaxBackgroundImage?(this.element.style.backgroundImage='url("'+this.Reveal.getConfig().parallaxBackgroundImage+'")',this.element.style.backgroundSize=this.Reveal.getConfig().parallaxBackgroundSize,this.element.style.backgroundRepeat=this.Reveal.getConfig().parallaxBackgroundRepeat,this.element.style.backgroundPosition=this.Reveal.getConfig().parallaxBackgroundPosition,setTimeout((()=>{this.Reveal.getRevealElement().classList.add("has-parallax-background")}),1)):(this.element.style.backgroundImage="",this.Reveal.getRevealElement().classList.remove("has-parallax-background"))}createBackground(e,t){let i=document.createElement("div");i.className="slide-background "+e.className.replace(/present|past|future/,"");let n=document.createElement("div");return n.className="slide-background-content",i.appendChild(n),t.appendChild(i),e.slideBackgroundElement=i,e.slideBackgroundContentElement=n,this.sync(e),i}sync(e){const t=e.slideBackgroundElement,i=e.slideBackgroundContentElement,n={background:e.getAttribute("data-background"),backgroundSize:e.getAttribute("data-background-size"),backgroundImage:e.getAttribute("data-background-image"),backgroundVideo:e.getAttribute("data-background-video"),backgroundIframe:e.getAttribute("data-background-iframe"),backgroundColor:e.getAttribute("data-background-color"),backgroundGradient:e.getAttribute("data-background-gradient"),backgroundRepeat:e.getAttribute("data-background-repeat"),backgroundPosition:e.getAttribute("data-background-position"),backgroundTransition:e.getAttribute("data-background-transition"),backgroundOpacity:e.getAttribute("data-background-opacity")},s=e.hasAttribute("data-preload");e.classList.remove("has-dark-background"),e.classList.remove("has-light-background"),t.removeAttribute("data-loaded"),t.removeAttribute("data-background-hash"),t.removeAttribute("data-background-size"),t.removeAttribute("data-background-transition"),t.style.backgroundColor="",i.style.backgroundSize="",i.style.backgroundRepeat="",i.style.backgroundPosition="",i.style.backgroundImage="",i.style.opacity="",i.innerHTML="",n.background&&(/^(http|file|\/\/)/gi.test(n.background)||/\.(svg|png|jpg|jpeg|gif|bmp|webp)([?#\s]|$)/gi.test(n.background)?e.setAttribute("data-background-image",n.background):t.style.background=n.background),(n.background||n.backgroundColor||n.backgroundGradient||n.backgroundImage||n.backgroundVideo||n.backgroundIframe)&&t.setAttribute("data-background-hash",n.background+n.backgroundSize+n.backgroundImage+n.backgroundVideo+n.backgroundIframe+n.backgroundColor+n.backgroundGradient+n.backgroundRepeat+n.backgroundPosition+n.backgroundTransition+n.backgroundOpacity),n.backgroundSize&&t.setAttribute("data-background-size",n.backgroundSize),n.backgroundColor&&(t.style.backgroundColor=n.backgroundColor),n.backgroundGradient&&(t.style.backgroundImage=n.backgroundGradient),n.backgroundTransition&&t.setAttribute("data-background-transition",n.backgroundTransition),s&&t.setAttribute("data-preload",""),n.backgroundSize&&(i.style.backgroundSize=n.backgroundSize),n.backgroundRepeat&&(i.style.backgroundRepeat=n.backgroundRepeat),n.backgroundPosition&&(i.style.backgroundPosition=n.backgroundPosition),n.backgroundOpacity&&(i.style.opacity=n.backgroundOpacity);let a=n.backgroundColor;if(!a||!E(a)){let e=window.getComputedStyle(t);e&&e.backgroundColor&&(a=e.backgroundColor)}if(a){const t=E(a);t&&0!==t.a&&("string"==typeof(o=a)&&(o=E(o)),(o?(299*o.r+587*o.g+114*o.b)/1e3:null)<128?e.classList.add("has-dark-background"):e.classList.add("has-light-background"))}var o}update(e=!1){let i=this.Reveal.getCurrentSlide(),n=this.Reveal.getIndices(),s=null,a=this.Reveal.getConfig().rtl?"future":"past",o=this.Reveal.getConfig().rtl?"past":"future";if(Array.from(this.element.childNodes).forEach(((i,r)=>{i.classList.remove("past","present","future"),rn.h?i.classList.add(o):(i.classList.add("present"),s=i),(e||r===n.h)&&t(i,".slide-background").forEach(((e,t)=>{e.classList.remove("past","present","future"),tn.v?e.classList.add("future"):(e.classList.add("present"),r===n.h&&(s=e))}))})),this.previousBackground&&this.Reveal.slideContent.stopEmbeddedContent(this.previousBackground,{unloadIframes:!this.Reveal.slideContent.shouldPreload(this.previousBackground)}),s){this.Reveal.slideContent.startEmbeddedContent(s);let e=s.querySelector(".slide-background-content");if(e){let t=e.style.backgroundImage||"";/\.gif/i.test(t)&&(e.style.backgroundImage="",window.getComputedStyle(e).opacity,e.style.backgroundImage=t)}let t=this.previousBackground?this.previousBackground.getAttribute("data-background-hash"):null,i=s.getAttribute("data-background-hash");i&&i===t&&s!==this.previousBackground&&this.element.classList.add("no-transition"),this.previousBackground=s}i&&["has-light-background","has-dark-background"].forEach((e=>{i.classList.contains(e)?this.Reveal.getRevealElement().classList.add(e):this.Reveal.getRevealElement().classList.remove(e)}),this),setTimeout((()=>{this.element.classList.remove("no-transition")}),1)}updateParallax(){let e=this.Reveal.getIndices();if(this.Reveal.getConfig().parallaxBackgroundImage){let t,i,n=this.Reveal.getHorizontalSlides(),s=this.Reveal.getVerticalSlides(),a=this.element.style.backgroundSize.split(" ");1===a.length?t=i=parseInt(a[0],10):(t=parseInt(a[0],10),i=parseInt(a[1],10));let o,r,l=this.element.offsetWidth,d=n.length;o="number"==typeof this.Reveal.getConfig().parallaxBackgroundHorizontal?this.Reveal.getConfig().parallaxBackgroundHorizontal:d>1?(t-l)/(d-1):0,r=o*e.h*-1;let c,h,u=this.element.offsetHeight,g=s.length;c="number"==typeof this.Reveal.getConfig().parallaxBackgroundVertical?this.Reveal.getConfig().parallaxBackgroundVertical:(i-u)/(g-1),h=g>0?c*e.v:0,this.element.style.backgroundPosition=r+"px "+-h+"px"}}destroy(){this.element.remove()}}const S=".slides section",A=".slides>section",k=".slides>section.present>section",L=/registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener|showPreview/,C=/fade-(down|up|right|left|out|in-then-out|in-then-semi-out)|semi-fade-out|current-visible|shrink|grow/;let x=0;class P{constructor(e){this.Reveal=e}run(e,t){this.reset();let i=this.Reveal.getSlides(),n=i.indexOf(t),s=i.indexOf(e);if(e.hasAttribute("data-auto-animate")&&t.hasAttribute("data-auto-animate")&&e.getAttribute("data-auto-animate-id")===t.getAttribute("data-auto-animate-id")&&!(n>s?t:e).hasAttribute("data-auto-animate-restart")){this.autoAnimateStyleSheet=this.autoAnimateStyleSheet||l();let i=this.getAutoAnimateOptions(t);e.dataset.autoAnimate="pending",t.dataset.autoAnimate="pending",i.slideDirection=n>s?"forward":"backward";let a="none"===e.style.display;a&&(e.style.display=this.Reveal.getConfig().display);let o=this.getAutoAnimatableElements(e,t).map((e=>this.autoAnimateElements(e.from,e.to,e.options||{},i,x++)));if(a&&(e.style.display="none"),"false"!==t.dataset.autoAnimateUnmatched&&!0===this.Reveal.getConfig().autoAnimateUnmatched){let e=.8*i.duration,n=.2*i.duration;this.getUnmatchedAutoAnimateElements(t).forEach((e=>{let t=this.getAutoAnimateOptions(e,i),n="unmatched";t.duration===i.duration&&t.delay===i.delay||(n="unmatched-"+x++,o.push(`[data-auto-animate="running"] [data-auto-animate-target="${n}"] { transition: opacity ${t.duration}s ease ${t.delay}s; }`)),e.dataset.autoAnimateTarget=n}),this),o.push(`[data-auto-animate="running"] [data-auto-animate-target="unmatched"] { transition: opacity ${e}s ease ${n}s; }`)}this.autoAnimateStyleSheet.innerHTML=o.join(""),requestAnimationFrame((()=>{this.autoAnimateStyleSheet&&(getComputedStyle(this.autoAnimateStyleSheet).fontWeight,t.dataset.autoAnimate="running")})),this.Reveal.dispatchEvent({type:"autoanimate",data:{fromSlide:e,toSlide:t,sheet:this.autoAnimateStyleSheet}})}}reset(){t(this.Reveal.getRevealElement(),'[data-auto-animate]:not([data-auto-animate=""])').forEach((e=>{e.dataset.autoAnimate=""})),t(this.Reveal.getRevealElement(),"[data-auto-animate-target]").forEach((e=>{delete e.dataset.autoAnimateTarget})),this.autoAnimateStyleSheet&&this.autoAnimateStyleSheet.parentNode&&(this.autoAnimateStyleSheet.parentNode.removeChild(this.autoAnimateStyleSheet),this.autoAnimateStyleSheet=null)}autoAnimateElements(e,t,i,n,s){e.dataset.autoAnimateTarget="",t.dataset.autoAnimateTarget=s;let a=this.getAutoAnimateOptions(t,n);void 0!==i.delay&&(a.delay=i.delay),void 0!==i.duration&&(a.duration=i.duration),void 0!==i.easing&&(a.easing=i.easing);let o=this.getAutoAnimatableProperties("from",e,i),r=this.getAutoAnimatableProperties("to",t,i);if(t.classList.contains("fragment")&&(delete r.styles.opacity,e.classList.contains("fragment"))){(e.className.match(C)||[""])[0]===(t.className.match(C)||[""])[0]&&"forward"===n.slideDirection&&t.classList.add("visible","disabled")}if(!1!==i.translate||!1!==i.scale){let e=this.Reveal.getScale(),t={x:(o.x-r.x)/e,y:(o.y-r.y)/e,scaleX:o.width/r.width,scaleY:o.height/r.height};t.x=Math.round(1e3*t.x)/1e3,t.y=Math.round(1e3*t.y)/1e3,t.scaleX=Math.round(1e3*t.scaleX)/1e3,t.scaleX=Math.round(1e3*t.scaleX)/1e3;let n=!1!==i.translate&&(0!==t.x||0!==t.y),s=!1!==i.scale&&(0!==t.scaleX||0!==t.scaleY);if(n||s){let e=[];n&&e.push(`translate(${t.x}px, ${t.y}px)`),s&&e.push(`scale(${t.scaleX}, ${t.scaleY})`),o.styles.transform=e.join(" "),o.styles["transform-origin"]="top left",r.styles.transform="none"}}for(let e in r.styles){const t=r.styles[e],i=o.styles[e];t===i?delete r.styles[e]:(!0===t.explicitValue&&(r.styles[e]=t.value),!0===i.explicitValue&&(o.styles[e]=i.value))}let l="",d=Object.keys(r.styles);if(d.length>0){o.styles.transition="none",r.styles.transition=`all ${a.duration}s ${a.easing} ${a.delay}s`,r.styles["transition-property"]=d.join(", "),r.styles["will-change"]=d.join(", "),l='[data-auto-animate-target="'+s+'"] {'+Object.keys(o.styles).map((e=>e+": "+o.styles[e]+" !important;")).join("")+'}[data-auto-animate="running"] [data-auto-animate-target="'+s+'"] {'+Object.keys(r.styles).map((e=>e+": "+r.styles[e]+" !important;")).join("")+"}"}return l}getAutoAnimateOptions(t,i){let n={easing:this.Reveal.getConfig().autoAnimateEasing,duration:this.Reveal.getConfig().autoAnimateDuration,delay:0};if(n=e(n,i),t.parentNode){let e=o(t.parentNode,"[data-auto-animate-target]");e&&(n=this.getAutoAnimateOptions(e,n))}return t.dataset.autoAnimateEasing&&(n.easing=t.dataset.autoAnimateEasing),t.dataset.autoAnimateDuration&&(n.duration=parseFloat(t.dataset.autoAnimateDuration)),t.dataset.autoAnimateDelay&&(n.delay=parseFloat(t.dataset.autoAnimateDelay)),n}getAutoAnimatableProperties(e,t,i){let n=this.Reveal.getConfig(),s={styles:[]};if(!1!==i.translate||!1!==i.scale){let e;if("function"==typeof i.measure)e=i.measure(t);else if(n.center)e=t.getBoundingClientRect();else{let i=this.Reveal.getScale();e={x:t.offsetLeft*i,y:t.offsetTop*i,width:t.offsetWidth*i,height:t.offsetHeight*i}}s.x=e.x,s.y=e.y,s.width=e.width,s.height=e.height}const a=getComputedStyle(t);return(i.styles||n.autoAnimateStyles).forEach((t=>{let i;"string"==typeof t&&(t={property:t}),void 0!==t.from&&"from"===e?i={value:t.from,explicitValue:!0}:void 0!==t.to&&"to"===e?i={value:t.to,explicitValue:!0}:("line-height"===t.property&&(i=parseFloat(a["line-height"])/parseFloat(a["font-size"])),isNaN(i)&&(i=a[t.property])),""!==i&&(s.styles[t.property]=i)})),s}getAutoAnimatableElements(e,t){let i=("function"==typeof this.Reveal.getConfig().autoAnimateMatcher?this.Reveal.getConfig().autoAnimateMatcher:this.getAutoAnimatePairs).call(this,e,t),n=[];return i.filter(((e,t)=>{if(-1===n.indexOf(e.to))return n.push(e.to),!0}))}getAutoAnimatePairs(e,t){let i=[];const n="h1, h2, h3, h4, h5, h6, p, li";return this.findAutoAnimateMatches(i,e,t,"[data-id]",(e=>e.nodeName+":::"+e.getAttribute("data-id"))),this.findAutoAnimateMatches(i,e,t,n,(e=>e.nodeName+":::"+e.innerText)),this.findAutoAnimateMatches(i,e,t,"img, video, iframe",(e=>e.nodeName+":::"+(e.getAttribute("src")||e.getAttribute("data-src")))),this.findAutoAnimateMatches(i,e,t,"pre",(e=>e.nodeName+":::"+e.innerText)),i.forEach((e=>{a(e.from,n)?e.options={scale:!1}:a(e.from,"pre")&&(e.options={scale:!1,styles:["width","height"]},this.findAutoAnimateMatches(i,e.from,e.to,".hljs .hljs-ln-code",(e=>e.textContent),{scale:!1,styles:[],measure:this.getLocalBoundingBox.bind(this)}),this.findAutoAnimateMatches(i,e.from,e.to,".hljs .hljs-ln-line[data-line-number]",(e=>e.getAttribute("data-line-number")),{scale:!1,styles:["width"],measure:this.getLocalBoundingBox.bind(this)}))}),this),i}getLocalBoundingBox(e){const t=this.Reveal.getScale();return{x:Math.round(e.offsetLeft*t*100)/100,y:Math.round(e.offsetTop*t*100)/100,width:Math.round(e.offsetWidth*t*100)/100,height:Math.round(e.offsetHeight*t*100)/100}}findAutoAnimateMatches(e,t,i,n,s,a){let o={},r={};[].slice.call(t.querySelectorAll(n)).forEach(((e,t)=>{const i=s(e);"string"==typeof i&&i.length&&(o[i]=o[i]||[],o[i].push(e))})),[].slice.call(i.querySelectorAll(n)).forEach(((t,i)=>{const n=s(t);let l;if(r[n]=r[n]||[],r[n].push(t),o[n]){const e=r[n].length-1,t=o[n].length-1;o[n][e]?(l=o[n][e],o[n][e]=null):o[n][t]&&(l=o[n][t],o[n][t]=null)}l&&e.push({from:l,to:t,options:a})}))}getUnmatchedAutoAnimateElements(e){return[].slice.call(e.children).reduce(((e,t)=>{const i=t.querySelector("[data-auto-animate-target]");return t.hasAttribute("data-auto-animate-target")||i||e.push(t),t.querySelector("[data-auto-animate-target]")&&(e=e.concat(this.getUnmatchedAutoAnimateElements(t))),e}),[])}}class N{constructor(e){this.Reveal=e}configure(e,t){!1===e.fragments?this.disable():!1===t.fragments&&this.enable()}disable(){t(this.Reveal.getSlidesElement(),".fragment").forEach((e=>{e.classList.add("visible"),e.classList.remove("current-fragment")}))}enable(){t(this.Reveal.getSlidesElement(),".fragment").forEach((e=>{e.classList.remove("visible"),e.classList.remove("current-fragment")}))}availableRoutes(){let e=this.Reveal.getCurrentSlide();if(e&&this.Reveal.getConfig().fragments){let t=e.querySelectorAll(".fragment:not(.disabled)"),i=e.querySelectorAll(".fragment:not(.disabled):not(.visible)");return{prev:t.length-i.length>0,next:!!i.length}}return{prev:!1,next:!1}}sort(e,t=!1){e=Array.from(e);let i=[],n=[],s=[];e.forEach((e=>{if(e.hasAttribute("data-fragment-index")){let t=parseInt(e.getAttribute("data-fragment-index"),10);i[t]||(i[t]=[]),i[t].push(e)}else n.push([e])})),i=i.concat(n);let a=0;return i.forEach((e=>{e.forEach((e=>{s.push(e),e.setAttribute("data-fragment-index",a)})),a++})),!0===t?i:s}sortAll(){this.Reveal.getHorizontalSlides().forEach((e=>{let i=t(e,"section");i.forEach(((e,t)=>{this.sort(e.querySelectorAll(".fragment"))}),this),0===i.length&&this.sort(e.querySelectorAll(".fragment"))}))}update(e,t){let i={shown:[],hidden:[]},n=this.Reveal.getCurrentSlide();if(n&&this.Reveal.getConfig().fragments&&(t=t||this.sort(n.querySelectorAll(".fragment"))).length){let s=0;if("number"!=typeof e){let t=this.sort(n.querySelectorAll(".fragment.visible")).pop();t&&(e=parseInt(t.getAttribute("data-fragment-index")||0,10))}Array.from(t).forEach(((t,n)=>{if(t.hasAttribute("data-fragment-index")&&(n=parseInt(t.getAttribute("data-fragment-index"),10)),s=Math.max(s,n),n<=e){let s=t.classList.contains("visible");t.classList.add("visible"),t.classList.remove("current-fragment"),n===e&&(this.Reveal.announceStatus(this.Reveal.getStatusText(t)),t.classList.add("current-fragment"),this.Reveal.slideContent.startEmbeddedContent(t)),s||(i.shown.push(t),this.Reveal.dispatchEvent({target:t,type:"visible",bubbles:!1}))}else{let e=t.classList.contains("visible");t.classList.remove("visible"),t.classList.remove("current-fragment"),e&&(this.Reveal.slideContent.stopEmbeddedContent(t),i.hidden.push(t),this.Reveal.dispatchEvent({target:t,type:"hidden",bubbles:!1}))}})),e="number"==typeof e?e:-1,e=Math.max(Math.min(e,s),-1),n.setAttribute("data-fragment",e)}return i}sync(e=this.Reveal.getCurrentSlide()){return this.sort(e.querySelectorAll(".fragment"))}goto(e,t=0){let i=this.Reveal.getCurrentSlide();if(i&&this.Reveal.getConfig().fragments){let n=this.sort(i.querySelectorAll(".fragment:not(.disabled)"));if(n.length){if("number"!=typeof e){let t=this.sort(i.querySelectorAll(".fragment:not(.disabled).visible")).pop();e=t?parseInt(t.getAttribute("data-fragment-index")||0,10):-1}e+=t;let s=this.update(e,n);return s.hidden.length&&this.Reveal.dispatchEvent({type:"fragmenthidden",data:{fragment:s.hidden[0],fragments:s.hidden}}),s.shown.length&&this.Reveal.dispatchEvent({type:"fragmentshown",data:{fragment:s.shown[0],fragments:s.shown}}),this.Reveal.controls.update(),this.Reveal.progress.update(),this.Reveal.getConfig().fragmentInURL&&this.Reveal.location.writeURL(),!(!s.shown.length&&!s.hidden.length)}}return!1}next(){return this.goto(null,1)}prev(){return this.goto(null,-1)}}class M{constructor(e){this.Reveal=e,this.active=!1,this.onSlideClicked=this.onSlideClicked.bind(this)}activate(){if(this.Reveal.getConfig().overview&&!this.isActive()){this.active=!0,this.Reveal.getRevealElement().classList.add("overview"),this.Reveal.cancelAutoSlide(),this.Reveal.getSlidesElement().appendChild(this.Reveal.getBackgroundsElement()),t(this.Reveal.getRevealElement(),S).forEach((e=>{e.classList.contains("stack")||e.addEventListener("click",this.onSlideClicked,!0)}));const e=70,i=this.Reveal.getComputedSlideSize();this.overviewSlideWidth=i.width+e,this.overviewSlideHeight=i.height+e,this.Reveal.getConfig().rtl&&(this.overviewSlideWidth=-this.overviewSlideWidth),this.Reveal.updateSlidesVisibility(),this.layout(),this.update(),this.Reveal.layout();const n=this.Reveal.getIndices();this.Reveal.dispatchEvent({type:"overviewshown",data:{indexh:n.h,indexv:n.v,currentSlide:this.Reveal.getCurrentSlide()}})}}layout(){this.Reveal.getHorizontalSlides().forEach(((e,i)=>{e.setAttribute("data-index-h",i),s(e,"translate3d("+i*this.overviewSlideWidth+"px, 0, 0)"),e.classList.contains("stack")&&t(e,"section").forEach(((e,t)=>{e.setAttribute("data-index-h",i),e.setAttribute("data-index-v",t),s(e,"translate3d(0, "+t*this.overviewSlideHeight+"px, 0)")}))})),Array.from(this.Reveal.getBackgroundsElement().childNodes).forEach(((e,i)=>{s(e,"translate3d("+i*this.overviewSlideWidth+"px, 0, 0)"),t(e,".slide-background").forEach(((e,t)=>{s(e,"translate3d(0, "+t*this.overviewSlideHeight+"px, 0)")}))}))}update(){const e=Math.min(window.innerWidth,window.innerHeight),t=Math.max(e/5,150)/e,i=this.Reveal.getIndices();this.Reveal.transformSlides({overview:["scale("+t+")","translateX("+-i.h*this.overviewSlideWidth+"px)","translateY("+-i.v*this.overviewSlideHeight+"px)"].join(" ")})}deactivate(){if(this.Reveal.getConfig().overview){this.active=!1,this.Reveal.getRevealElement().classList.remove("overview"),this.Reveal.getRevealElement().classList.add("overview-deactivating"),setTimeout((()=>{this.Reveal.getRevealElement().classList.remove("overview-deactivating")}),1),this.Reveal.getRevealElement().appendChild(this.Reveal.getBackgroundsElement()),t(this.Reveal.getRevealElement(),S).forEach((e=>{s(e,""),e.removeEventListener("click",this.onSlideClicked,!0)})),t(this.Reveal.getBackgroundsElement(),".slide-background").forEach((e=>{s(e,"")})),this.Reveal.transformSlides({overview:""});const e=this.Reveal.getIndices();this.Reveal.slide(e.h,e.v),this.Reveal.layout(),this.Reveal.cueAutoSlide(),this.Reveal.dispatchEvent({type:"overviewhidden",data:{indexh:e.h,indexv:e.v,currentSlide:this.Reveal.getCurrentSlide()}})}}toggle(e){"boolean"==typeof e?e?this.activate():this.deactivate():this.isActive()?this.deactivate():this.activate()}isActive(){return this.active}onSlideClicked(e){if(this.isActive()){e.preventDefault();let t=e.target;for(;t&&!t.nodeName.match(/section/gi);)t=t.parentNode;if(t&&!t.classList.contains("disabled")&&(this.deactivate(),t.nodeName.match(/section/gi))){let e=parseInt(t.getAttribute("data-index-h"),10),i=parseInt(t.getAttribute("data-index-v"),10);this.Reveal.slide(e,i)}}}}class I{constructor(e){this.Reveal=e,this.shortcuts={},this.bindings={},this.onDocumentKeyDown=this.onDocumentKeyDown.bind(this),this.onDocumentKeyPress=this.onDocumentKeyPress.bind(this)}configure(e,t){"linear"===e.navigationMode?(this.shortcuts["→ , ↓ , SPACE , N , L , J"]="Next slide",this.shortcuts["← , ↑ , P , H , K"]="Previous slide"):(this.shortcuts["N , SPACE"]="Next slide",this.shortcuts["P , Shift SPACE"]="Previous slide",this.shortcuts["← , H"]="Navigate left",this.shortcuts["→ , L"]="Navigate right",this.shortcuts["↑ , K"]="Navigate up",this.shortcuts["↓ , J"]="Navigate down"),this.shortcuts["Alt + ←/↑/→/↓"]="Navigate without fragments",this.shortcuts["Shift + ←/↑/→/↓"]="Jump to first/last slide",this.shortcuts["B , ."]="Pause",this.shortcuts.F="Fullscreen",this.shortcuts.G="Jump to slide",this.shortcuts["ESC, O"]="Slide overview"}bind(){document.addEventListener("keydown",this.onDocumentKeyDown,!1),document.addEventListener("keypress",this.onDocumentKeyPress,!1)}unbind(){document.removeEventListener("keydown",this.onDocumentKeyDown,!1),document.removeEventListener("keypress",this.onDocumentKeyPress,!1)}addKeyBinding(e,t){"object"==typeof e&&e.keyCode?this.bindings[e.keyCode]={callback:t,key:e.key,description:e.description}:this.bindings[e]={callback:t,key:null,description:null}}removeKeyBinding(e){delete this.bindings[e]}triggerKey(e){this.onDocumentKeyDown({keyCode:e})}registerKeyboardShortcut(e,t){this.shortcuts[e]=t}getShortcuts(){return this.shortcuts}getBindings(){return this.bindings}onDocumentKeyPress(e){e.shiftKey&&63===e.charCode&&this.Reveal.toggleHelp()}onDocumentKeyDown(e){let t=this.Reveal.getConfig();if("function"==typeof t.keyboardCondition&&!1===t.keyboardCondition(e))return!0;if("focused"===t.keyboardCondition&&!this.Reveal.isFocused())return!0;let i=e.keyCode,n=!this.Reveal.isAutoSliding();this.Reveal.onUserInput(e);let s=document.activeElement&&!0===document.activeElement.isContentEditable,a=document.activeElement&&document.activeElement.tagName&&/input|textarea/i.test(document.activeElement.tagName),o=document.activeElement&&document.activeElement.className&&/speaker-notes/i.test(document.activeElement.className),r=!(-1!==[32,37,38,39,40,78,80].indexOf(e.keyCode)&&e.shiftKey||e.altKey)&&(e.shiftKey||e.altKey||e.ctrlKey||e.metaKey);if(s||a||o||r)return;let l,d=[66,86,190,191];if("object"==typeof t.keyboard)for(l in t.keyboard)"togglePause"===t.keyboard[l]&&d.push(parseInt(l,10));if(this.Reveal.isPaused()&&-1===d.indexOf(i))return!1;let c="linear"===t.navigationMode||!this.Reveal.hasHorizontalSlides()||!this.Reveal.hasVerticalSlides(),h=!1;if("object"==typeof t.keyboard)for(l in t.keyboard)if(parseInt(l,10)===i){let i=t.keyboard[l];"function"==typeof i?i.apply(null,[e]):"string"==typeof i&&"function"==typeof this.Reveal[i]&&this.Reveal[i].call(),h=!0}if(!1===h)for(l in this.bindings)if(parseInt(l,10)===i){let t=this.bindings[l].callback;"function"==typeof t?t.apply(null,[e]):"string"==typeof t&&"function"==typeof this.Reveal[t]&&this.Reveal[t].call(),h=!0}!1===h&&(h=!0,80===i||33===i?this.Reveal.prev({skipFragments:e.altKey}):78===i||34===i?this.Reveal.next({skipFragments:e.altKey}):72===i||37===i?e.shiftKey?this.Reveal.slide(0):!this.Reveal.overview.isActive()&&c?this.Reveal.prev({skipFragments:e.altKey}):this.Reveal.left({skipFragments:e.altKey}):76===i||39===i?e.shiftKey?this.Reveal.slide(this.Reveal.getHorizontalSlides().length-1):!this.Reveal.overview.isActive()&&c?this.Reveal.next({skipFragments:e.altKey}):this.Reveal.right({skipFragments:e.altKey}):75===i||38===i?e.shiftKey?this.Reveal.slide(void 0,0):!this.Reveal.overview.isActive()&&c?this.Reveal.prev({skipFragments:e.altKey}):this.Reveal.up({skipFragments:e.altKey}):74===i||40===i?e.shiftKey?this.Reveal.slide(void 0,Number.MAX_VALUE):!this.Reveal.overview.isActive()&&c?this.Reveal.next({skipFragments:e.altKey}):this.Reveal.down({skipFragments:e.altKey}):36===i?this.Reveal.slide(0):35===i?this.Reveal.slide(this.Reveal.getHorizontalSlides().length-1):32===i?(this.Reveal.overview.isActive()&&this.Reveal.overview.deactivate(),e.shiftKey?this.Reveal.prev({skipFragments:e.altKey}):this.Reveal.next({skipFragments:e.altKey})):58===i||59===i||66===i||86===i||190===i||191===i?this.Reveal.togglePause():70===i?(e=>{let t=(e=e||document.documentElement).requestFullscreen||e.webkitRequestFullscreen||e.webkitRequestFullScreen||e.mozRequestFullScreen||e.msRequestFullscreen;t&&t.apply(e)})(t.embedded?this.Reveal.getViewportElement():document.documentElement):65===i?t.autoSlideStoppable&&this.Reveal.toggleAutoSlide(n):71===i?t.jumpToSlide&&this.Reveal.toggleJumpToSlide():h=!1),h?e.preventDefault&&e.preventDefault():27!==i&&79!==i||(!1===this.Reveal.closeOverlay()&&this.Reveal.overview.toggle(),e.preventDefault&&e.preventDefault()),this.Reveal.cueAutoSlide()}}class T{constructor(e){var t,i,n;n=1e3,(i="MAX_REPLACE_STATE_FREQUENCY")in(t=this)?Object.defineProperty(t,i,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[i]=n,this.Reveal=e,this.writeURLTimeout=0,this.replaceStateTimestamp=0,this.onWindowHashChange=this.onWindowHashChange.bind(this)}bind(){window.addEventListener("hashchange",this.onWindowHashChange,!1)}unbind(){window.removeEventListener("hashchange",this.onWindowHashChange,!1)}getIndicesFromHash(e=window.location.hash,t={}){let i=e.replace(/^#\/?/,""),n=i.split("/");if(/^[0-9]*$/.test(n[0])||!i.length){const e=this.Reveal.getConfig();let i,s=e.hashOneBasedIndex||t.oneBasedIndex?1:0,a=parseInt(n[0],10)-s||0,o=parseInt(n[1],10)-s||0;return e.fragmentInURL&&(i=parseInt(n[2],10),isNaN(i)&&(i=void 0)),{h:a,v:o,f:i}}{let e,t;/\/[-\d]+$/g.test(i)&&(t=parseInt(i.split("/").pop(),10),t=isNaN(t)?void 0:t,i=i.split("/").shift());try{e=document.getElementById(decodeURIComponent(i))}catch(e){}if(e)return{...this.Reveal.getIndices(e),f:t}}return null}readURL(){const e=this.Reveal.getIndices(),t=this.getIndicesFromHash();t?t.h===e.h&&t.v===e.v&&void 0===t.f||this.Reveal.slide(t.h,t.v,t.f):this.Reveal.slide(e.h||0,e.v||0)}writeURL(e){let t=this.Reveal.getConfig(),i=this.Reveal.getCurrentSlide();if(clearTimeout(this.writeURLTimeout),"number"==typeof e)this.writeURLTimeout=setTimeout(this.writeURL,e);else if(i){let e=this.getHash();t.history?window.location.hash=e:t.hash&&("/"===e?this.debouncedReplaceState(window.location.pathname+window.location.search):this.debouncedReplaceState("#"+e))}}replaceState(e){window.history.replaceState(null,null,e),this.replaceStateTimestamp=Date.now()}debouncedReplaceState(e){clearTimeout(this.replaceStateTimeout),Date.now()-this.replaceStateTimestamp>this.MAX_REPLACE_STATE_FREQUENCY?this.replaceState(e):this.replaceStateTimeout=setTimeout((()=>this.replaceState(e)),this.MAX_REPLACE_STATE_FREQUENCY)}getHash(e){let t="/",i=e||this.Reveal.getCurrentSlide(),n=i?i.getAttribute("id"):null;n&&(n=encodeURIComponent(n));let s=this.Reveal.getIndices(e);if(this.Reveal.getConfig().fragmentInURL||(s.f=void 0),"string"==typeof n&&n.length)t="/"+n,s.f>=0&&(t+="/"+s.f);else{let e=this.Reveal.getConfig().hashOneBasedIndex?1:0;(s.h>0||s.v>0||s.f>=0)&&(t+=s.h+e),(s.v>0||s.f>=0)&&(t+="/"+(s.v+e)),s.f>=0&&(t+="/"+s.f)}return t}onWindowHashChange(e){this.readURL()}}class D{constructor(e){this.Reveal=e,this.onNavigateLeftClicked=this.onNavigateLeftClicked.bind(this),this.onNavigateRightClicked=this.onNavigateRightClicked.bind(this),this.onNavigateUpClicked=this.onNavigateUpClicked.bind(this),this.onNavigateDownClicked=this.onNavigateDownClicked.bind(this),this.onNavigatePrevClicked=this.onNavigatePrevClicked.bind(this),this.onNavigateNextClicked=this.onNavigateNextClicked.bind(this)}render(){const e=this.Reveal.getConfig().rtl,i=this.Reveal.getRevealElement();this.element=document.createElement("aside"),this.element.className="controls",this.element.innerHTML=`
\n\t\t\t
\n\t\t\t
\n\t\t\t
`,this.Reveal.getRevealElement().appendChild(this.element),this.controlsLeft=t(i,".navigate-left"),this.controlsRight=t(i,".navigate-right"),this.controlsUp=t(i,".navigate-up"),this.controlsDown=t(i,".navigate-down"),this.controlsPrev=t(i,".navigate-prev"),this.controlsNext=t(i,".navigate-next"),this.controlsRightArrow=this.element.querySelector(".navigate-right"),this.controlsLeftArrow=this.element.querySelector(".navigate-left"),this.controlsDownArrow=this.element.querySelector(".navigate-down")}configure(e,t){this.element.style.display=e.controls?"block":"none",this.element.setAttribute("data-controls-layout",e.controlsLayout),this.element.setAttribute("data-controls-back-arrows",e.controlsBackArrows)}bind(){let e=["touchstart","click"];v&&(e=["touchstart"]),e.forEach((e=>{this.controlsLeft.forEach((t=>t.addEventListener(e,this.onNavigateLeftClicked,!1))),this.controlsRight.forEach((t=>t.addEventListener(e,this.onNavigateRightClicked,!1))),this.controlsUp.forEach((t=>t.addEventListener(e,this.onNavigateUpClicked,!1))),this.controlsDown.forEach((t=>t.addEventListener(e,this.onNavigateDownClicked,!1))),this.controlsPrev.forEach((t=>t.addEventListener(e,this.onNavigatePrevClicked,!1))),this.controlsNext.forEach((t=>t.addEventListener(e,this.onNavigateNextClicked,!1)))}))}unbind(){["touchstart","click"].forEach((e=>{this.controlsLeft.forEach((t=>t.removeEventListener(e,this.onNavigateLeftClicked,!1))),this.controlsRight.forEach((t=>t.removeEventListener(e,this.onNavigateRightClicked,!1))),this.controlsUp.forEach((t=>t.removeEventListener(e,this.onNavigateUpClicked,!1))),this.controlsDown.forEach((t=>t.removeEventListener(e,this.onNavigateDownClicked,!1))),this.controlsPrev.forEach((t=>t.removeEventListener(e,this.onNavigatePrevClicked,!1))),this.controlsNext.forEach((t=>t.removeEventListener(e,this.onNavigateNextClicked,!1)))}))}update(){let e=this.Reveal.availableRoutes();[...this.controlsLeft,...this.controlsRight,...this.controlsUp,...this.controlsDown,...this.controlsPrev,...this.controlsNext].forEach((e=>{e.classList.remove("enabled","fragmented"),e.setAttribute("disabled","disabled")})),e.left&&this.controlsLeft.forEach((e=>{e.classList.add("enabled"),e.removeAttribute("disabled")})),e.right&&this.controlsRight.forEach((e=>{e.classList.add("enabled"),e.removeAttribute("disabled")})),e.up&&this.controlsUp.forEach((e=>{e.classList.add("enabled"),e.removeAttribute("disabled")})),e.down&&this.controlsDown.forEach((e=>{e.classList.add("enabled"),e.removeAttribute("disabled")})),(e.left||e.up)&&this.controlsPrev.forEach((e=>{e.classList.add("enabled"),e.removeAttribute("disabled")})),(e.right||e.down)&&this.controlsNext.forEach((e=>{e.classList.add("enabled"),e.removeAttribute("disabled")}));let t=this.Reveal.getCurrentSlide();if(t){let e=this.Reveal.fragments.availableRoutes();e.prev&&this.controlsPrev.forEach((e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")})),e.next&&this.controlsNext.forEach((e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")})),this.Reveal.isVerticalSlide(t)?(e.prev&&this.controlsUp.forEach((e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")})),e.next&&this.controlsDown.forEach((e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")}))):(e.prev&&this.controlsLeft.forEach((e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")})),e.next&&this.controlsRight.forEach((e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")})))}if(this.Reveal.getConfig().controlsTutorial){let t=this.Reveal.getIndices();!this.Reveal.hasNavigatedVertically()&&e.down?this.controlsDownArrow.classList.add("highlight"):(this.controlsDownArrow.classList.remove("highlight"),this.Reveal.getConfig().rtl?!this.Reveal.hasNavigatedHorizontally()&&e.left&&0===t.v?this.controlsLeftArrow.classList.add("highlight"):this.controlsLeftArrow.classList.remove("highlight"):!this.Reveal.hasNavigatedHorizontally()&&e.right&&0===t.v?this.controlsRightArrow.classList.add("highlight"):this.controlsRightArrow.classList.remove("highlight"))}}destroy(){this.unbind(),this.element.remove()}onNavigateLeftClicked(e){e.preventDefault(),this.Reveal.onUserInput(),"linear"===this.Reveal.getConfig().navigationMode?this.Reveal.prev():this.Reveal.left()}onNavigateRightClicked(e){e.preventDefault(),this.Reveal.onUserInput(),"linear"===this.Reveal.getConfig().navigationMode?this.Reveal.next():this.Reveal.right()}onNavigateUpClicked(e){e.preventDefault(),this.Reveal.onUserInput(),this.Reveal.up()}onNavigateDownClicked(e){e.preventDefault(),this.Reveal.onUserInput(),this.Reveal.down()}onNavigatePrevClicked(e){e.preventDefault(),this.Reveal.onUserInput(),this.Reveal.prev()}onNavigateNextClicked(e){e.preventDefault(),this.Reveal.onUserInput(),this.Reveal.next()}}class F{constructor(e){this.Reveal=e,this.onProgressClicked=this.onProgressClicked.bind(this)}render(){this.element=document.createElement("div"),this.element.className="progress",this.Reveal.getRevealElement().appendChild(this.element),this.bar=document.createElement("span"),this.element.appendChild(this.bar)}configure(e,t){this.element.style.display=e.progress?"block":"none"}bind(){this.Reveal.getConfig().progress&&this.element&&this.element.addEventListener("click",this.onProgressClicked,!1)}unbind(){this.Reveal.getConfig().progress&&this.element&&this.element.removeEventListener("click",this.onProgressClicked,!1)}update(){if(this.Reveal.getConfig().progress&&this.bar){let e=this.Reveal.getProgress();this.Reveal.getTotalSlides()<2&&(e=0),this.bar.style.transform="scaleX("+e+")"}}getMaxWidth(){return this.Reveal.getRevealElement().offsetWidth}onProgressClicked(e){this.Reveal.onUserInput(e),e.preventDefault();let t=this.Reveal.getSlides(),i=t.length,n=Math.floor(e.clientX/this.getMaxWidth()*i);this.Reveal.getConfig().rtl&&(n=i-n);let s=this.Reveal.getIndices(t[n]);this.Reveal.slide(s.h,s.v)}destroy(){this.element.remove()}}class z{constructor(e){this.Reveal=e,this.lastMouseWheelStep=0,this.cursorHidden=!1,this.cursorInactiveTimeout=0,this.onDocumentCursorActive=this.onDocumentCursorActive.bind(this),this.onDocumentMouseScroll=this.onDocumentMouseScroll.bind(this)}configure(e,t){e.mouseWheel?(document.addEventListener("DOMMouseScroll",this.onDocumentMouseScroll,!1),document.addEventListener("mousewheel",this.onDocumentMouseScroll,!1)):(document.removeEventListener("DOMMouseScroll",this.onDocumentMouseScroll,!1),document.removeEventListener("mousewheel",this.onDocumentMouseScroll,!1)),e.hideInactiveCursor?(document.addEventListener("mousemove",this.onDocumentCursorActive,!1),document.addEventListener("mousedown",this.onDocumentCursorActive,!1)):(this.showCursor(),document.removeEventListener("mousemove",this.onDocumentCursorActive,!1),document.removeEventListener("mousedown",this.onDocumentCursorActive,!1))}showCursor(){this.cursorHidden&&(this.cursorHidden=!1,this.Reveal.getRevealElement().style.cursor="")}hideCursor(){!1===this.cursorHidden&&(this.cursorHidden=!0,this.Reveal.getRevealElement().style.cursor="none")}destroy(){this.showCursor(),document.removeEventListener("DOMMouseScroll",this.onDocumentMouseScroll,!1),document.removeEventListener("mousewheel",this.onDocumentMouseScroll,!1),document.removeEventListener("mousemove",this.onDocumentCursorActive,!1),document.removeEventListener("mousedown",this.onDocumentCursorActive,!1)}onDocumentCursorActive(e){this.showCursor(),clearTimeout(this.cursorInactiveTimeout),this.cursorInactiveTimeout=setTimeout(this.hideCursor.bind(this),this.Reveal.getConfig().hideCursorTime)}onDocumentMouseScroll(e){if(Date.now()-this.lastMouseWheelStep>1e3){this.lastMouseWheelStep=Date.now();let t=e.detail||-e.wheelDelta;t>0?this.Reveal.next():t<0&&this.Reveal.prev()}}}const H=(e,t)=>{const i=document.createElement("script");i.type="text/javascript",i.async=!1,i.defer=!1,i.src=e,"function"==typeof t&&(i.onload=i.onreadystatechange=e=>{("load"===e.type||/loaded|complete/.test(i.readyState))&&(i.onload=i.onreadystatechange=i.onerror=null,t())},i.onerror=e=>{i.onload=i.onreadystatechange=i.onerror=null,t(new Error("Failed loading script: "+i.src+"\n"+e))});const n=document.querySelector("head");n.insertBefore(i,n.lastChild)};class B{constructor(e){this.Reveal=e,this.state="idle",this.registeredPlugins={},this.asyncDependencies=[]}load(e,t){return this.state="loading",e.forEach(this.registerPlugin.bind(this)),new Promise((e=>{let i=[],n=0;if(t.forEach((e=>{e.condition&&!e.condition()||(e.async?this.asyncDependencies.push(e):i.push(e))})),i.length){n=i.length;const t=t=>{t&&"function"==typeof t.callback&&t.callback(),0==--n&&this.initPlugins().then(e)};i.forEach((e=>{"string"==typeof e.id?(this.registerPlugin(e),t(e)):"string"==typeof e.src?H(e.src,(()=>t(e))):(console.warn("Unrecognized plugin format",e),t())}))}else this.initPlugins().then(e)}))}initPlugins(){return new Promise((e=>{let t=Object.values(this.registeredPlugins),i=t.length;if(0===i)this.loadAsync().then(e);else{let n,s=()=>{0==--i?this.loadAsync().then(e):n()},a=0;n=()=>{let e=t[a++];if("function"==typeof e.init){let t=e.init(this.Reveal);t&&"function"==typeof t.then?t.then(s):s()}else s()},n()}}))}loadAsync(){return this.state="loaded",this.asyncDependencies.length&&this.asyncDependencies.forEach((e=>{H(e.src,e.callback)})),Promise.resolve()}registerPlugin(e){2===arguments.length&&"string"==typeof arguments[0]?(e=arguments[1]).id=arguments[0]:"function"==typeof e&&(e=e());let t=e.id;"string"!=typeof t?console.warn("Unrecognized plugin format; can't find plugin.id",e):void 0===this.registeredPlugins[t]?(this.registeredPlugins[t]=e,"loaded"===this.state&&"function"==typeof e.init&&e.init(this.Reveal)):console.warn('reveal.js: "'+t+'" plugin has already been registered')}hasPlugin(e){return!!this.registeredPlugins[e]}getPlugin(e){return this.registeredPlugins[e]}getRegisteredPlugins(){return this.registeredPlugins}destroy(){Object.values(this.registeredPlugins).forEach((e=>{"function"==typeof e.destroy&&e.destroy()})),this.registeredPlugins={},this.asyncDependencies=[]}}class O{constructor(e){this.Reveal=e}async setupPDF(){const e=this.Reveal.getConfig(),i=t(this.Reveal.getRevealElement(),S),n=e.slideNumber&&/all|print/i.test(e.showSlideNumber),s=this.Reveal.getComputedSlideSize(window.innerWidth,window.innerHeight),a=Math.floor(s.width*(1+e.margin)),o=Math.floor(s.height*(1+e.margin)),r=s.width,d=s.height;await new Promise(requestAnimationFrame),l("@page{size:"+a+"px "+o+"px; margin: 0px;}"),l(".reveal section>img, .reveal section>video, .reveal section>iframe{max-width: "+r+"px; max-height:"+d+"px}"),document.documentElement.classList.add("print-pdf"),document.body.style.width=a+"px",document.body.style.height=o+"px";const c=document.querySelector(".reveal-viewport");let h;if(c){const e=window.getComputedStyle(c);e&&e.background&&(h=e.background)}await new Promise(requestAnimationFrame),this.Reveal.layoutSlideContents(r,d),await new Promise(requestAnimationFrame);const u=i.map((e=>e.scrollHeight)),g=[],v=i[0].parentNode;let p=1;i.forEach((function(i,s){if(!1===i.classList.contains("stack")){let l=(a-r)/2,c=(o-d)/2;const v=u[s];let m=Math.max(Math.ceil(v/o),1);m=Math.min(m,e.pdfMaxPagesPerSlide),(1===m&&e.center||i.classList.contains("center"))&&(c=Math.max((o-v)/2,0));const f=document.createElement("div");if(g.push(f),f.className="pdf-page",f.style.height=(o+e.pdfPageHeightOffset)*m+"px",h&&(f.style.background=h),f.appendChild(i),i.style.left=l+"px",i.style.top=c+"px",i.style.width=r+"px",this.Reveal.slideContent.layout(i),i.slideBackgroundElement&&f.insertBefore(i.slideBackgroundElement,i),e.showNotes){const t=this.Reveal.getSlideNotes(i);if(t){const i=8,n="string"==typeof e.showNotes?e.showNotes:"inline",s=document.createElement("div");s.classList.add("speaker-notes"),s.classList.add("speaker-notes-pdf"),s.setAttribute("data-layout",n),s.innerHTML=t,"separate-page"===n?g.push(s):(s.style.left=i+"px",s.style.bottom=i+"px",s.style.width=a-2*i+"px",f.appendChild(s))}}if(n){const e=document.createElement("div");e.classList.add("slide-number"),e.classList.add("slide-number-pdf"),e.innerHTML=p++,f.appendChild(e)}if(e.pdfSeparateFragments){const e=this.Reveal.fragments.sort(f.querySelectorAll(".fragment"),!0);let t;e.forEach((function(e,i){t&&t.forEach((function(e){e.classList.remove("current-fragment")})),e.forEach((function(e){e.classList.add("visible","current-fragment")}),this);const s=f.cloneNode(!0);if(n){const e=i+1;s.querySelector(".slide-number-pdf").innerHTML+="."+e}g.push(s),t=e}),this),e.forEach((function(e){e.forEach((function(e){e.classList.remove("visible","current-fragment")}))}))}else t(f,".fragment:not(.fade-out)").forEach((function(e){e.classList.add("visible")}))}}),this),await new Promise(requestAnimationFrame),g.forEach((e=>v.appendChild(e))),this.Reveal.slideContent.layout(this.Reveal.getSlidesElement()),this.Reveal.dispatchEvent({type:"pdf-ready"})}isPrintingPDF(){return/print-pdf/gi.test(window.location.search)}}class q{constructor(e){this.Reveal=e,this.touchStartX=0,this.touchStartY=0,this.touchStartCount=0,this.touchCaptured=!1,this.onPointerDown=this.onPointerDown.bind(this),this.onPointerMove=this.onPointerMove.bind(this),this.onPointerUp=this.onPointerUp.bind(this),this.onTouchStart=this.onTouchStart.bind(this),this.onTouchMove=this.onTouchMove.bind(this),this.onTouchEnd=this.onTouchEnd.bind(this)}bind(){let e=this.Reveal.getRevealElement();"onpointerdown"in window?(e.addEventListener("pointerdown",this.onPointerDown,!1),e.addEventListener("pointermove",this.onPointerMove,!1),e.addEventListener("pointerup",this.onPointerUp,!1)):window.navigator.msPointerEnabled?(e.addEventListener("MSPointerDown",this.onPointerDown,!1),e.addEventListener("MSPointerMove",this.onPointerMove,!1),e.addEventListener("MSPointerUp",this.onPointerUp,!1)):(e.addEventListener("touchstart",this.onTouchStart,!1),e.addEventListener("touchmove",this.onTouchMove,!1),e.addEventListener("touchend",this.onTouchEnd,!1))}unbind(){let e=this.Reveal.getRevealElement();e.removeEventListener("pointerdown",this.onPointerDown,!1),e.removeEventListener("pointermove",this.onPointerMove,!1),e.removeEventListener("pointerup",this.onPointerUp,!1),e.removeEventListener("MSPointerDown",this.onPointerDown,!1),e.removeEventListener("MSPointerMove",this.onPointerMove,!1),e.removeEventListener("MSPointerUp",this.onPointerUp,!1),e.removeEventListener("touchstart",this.onTouchStart,!1),e.removeEventListener("touchmove",this.onTouchMove,!1),e.removeEventListener("touchend",this.onTouchEnd,!1)}isSwipePrevented(e){if(a(e,"video, audio"))return!0;for(;e&&"function"==typeof e.hasAttribute;){if(e.hasAttribute("data-prevent-swipe"))return!0;e=e.parentNode}return!1}onTouchStart(e){if(this.isSwipePrevented(e.target))return!0;this.touchStartX=e.touches[0].clientX,this.touchStartY=e.touches[0].clientY,this.touchStartCount=e.touches.length}onTouchMove(e){if(this.isSwipePrevented(e.target))return!0;let t=this.Reveal.getConfig();if(this.touchCaptured)v&&e.preventDefault();else{this.Reveal.onUserInput(e);let i=e.touches[0].clientX,n=e.touches[0].clientY;if(1===e.touches.length&&2!==this.touchStartCount){let s=this.Reveal.availableRoutes({includeFragments:!0}),a=i-this.touchStartX,o=n-this.touchStartY;a>40&&Math.abs(a)>Math.abs(o)?(this.touchCaptured=!0,"linear"===t.navigationMode?t.rtl?this.Reveal.next():this.Reveal.prev():this.Reveal.left()):a<-40&&Math.abs(a)>Math.abs(o)?(this.touchCaptured=!0,"linear"===t.navigationMode?t.rtl?this.Reveal.prev():this.Reveal.next():this.Reveal.right()):o>40&&s.up?(this.touchCaptured=!0,"linear"===t.navigationMode?this.Reveal.prev():this.Reveal.up()):o<-40&&s.down&&(this.touchCaptured=!0,"linear"===t.navigationMode?this.Reveal.next():this.Reveal.down()),t.embedded?(this.touchCaptured||this.Reveal.isVerticalSlide())&&e.preventDefault():e.preventDefault()}}}onTouchEnd(e){this.touchCaptured=!1}onPointerDown(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],this.onTouchStart(e))}onPointerMove(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],this.onTouchMove(e))}onPointerUp(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],this.onTouchEnd(e))}}const U="focus",j="blur";class W{constructor(e){this.Reveal=e,this.onRevealPointerDown=this.onRevealPointerDown.bind(this),this.onDocumentPointerDown=this.onDocumentPointerDown.bind(this)}configure(e,t){e.embedded?this.blur():(this.focus(),this.unbind())}bind(){this.Reveal.getConfig().embedded&&this.Reveal.getRevealElement().addEventListener("pointerdown",this.onRevealPointerDown,!1)}unbind(){this.Reveal.getRevealElement().removeEventListener("pointerdown",this.onRevealPointerDown,!1),document.removeEventListener("pointerdown",this.onDocumentPointerDown,!1)}focus(){this.state!==U&&(this.Reveal.getRevealElement().classList.add("focused"),document.addEventListener("pointerdown",this.onDocumentPointerDown,!1)),this.state=U}blur(){this.state!==j&&(this.Reveal.getRevealElement().classList.remove("focused"),document.removeEventListener("pointerdown",this.onDocumentPointerDown,!1)),this.state=j}isFocused(){return this.state===U}destroy(){this.Reveal.getRevealElement().classList.remove("focused")}onRevealPointerDown(e){this.focus()}onDocumentPointerDown(e){let t=o(e.target,".reveal");t&&t===this.Reveal.getRevealElement()||this.blur()}}class K{constructor(e){this.Reveal=e}render(){this.element=document.createElement("div"),this.element.className="speaker-notes",this.element.setAttribute("data-prevent-swipe",""),this.element.setAttribute("tabindex","0"),this.Reveal.getRevealElement().appendChild(this.element)}configure(e,t){e.showNotes&&this.element.setAttribute("data-layout","string"==typeof e.showNotes?e.showNotes:"inline")}update(){this.Reveal.getConfig().showNotes&&this.element&&this.Reveal.getCurrentSlide()&&!this.Reveal.print.isPrintingPDF()&&(this.element.innerHTML=this.getSlideNotes()||'No notes on this slide. ')}updateVisibility(){this.Reveal.getConfig().showNotes&&this.hasNotes()&&!this.Reveal.print.isPrintingPDF()?this.Reveal.getRevealElement().classList.add("show-notes"):this.Reveal.getRevealElement().classList.remove("show-notes")}hasNotes(){return this.Reveal.getSlidesElement().querySelectorAll("[data-notes], aside.notes").length>0}isSpeakerNotesWindow(){return!!window.location.search.match(/receiver/gi)}getSlideNotes(e=this.Reveal.getCurrentSlide()){if(e.hasAttribute("data-notes"))return e.getAttribute("data-notes");let t=e.querySelectorAll("aside.notes");return t?Array.from(t).map((e=>e.innerHTML)).join("\n"):null}destroy(){this.element.remove()}}class V{constructor(e,t){this.diameter=100,this.diameter2=this.diameter/2,this.thickness=6,this.playing=!1,this.progress=0,this.progressOffset=1,this.container=e,this.progressCheck=t,this.canvas=document.createElement("canvas"),this.canvas.className="playback",this.canvas.width=this.diameter,this.canvas.height=this.diameter,this.canvas.style.width=this.diameter2+"px",this.canvas.style.height=this.diameter2+"px",this.context=this.canvas.getContext("2d"),this.container.appendChild(this.canvas),this.render()}setPlaying(e){const t=this.playing;this.playing=e,!t&&this.playing?this.animate():this.render()}animate(){const e=this.progress;this.progress=this.progressCheck(),e>.8&&this.progress<.2&&(this.progressOffset=this.progress),this.render(),this.playing&&requestAnimationFrame(this.animate.bind(this))}render(){let e=this.playing?this.progress:0,t=this.diameter2-this.thickness,i=this.diameter2,n=this.diameter2,s=28;this.progressOffset+=.1*(1-this.progressOffset);const a=-Math.PI/2+e*(2*Math.PI),o=-Math.PI/2+this.progressOffset*(2*Math.PI);this.context.save(),this.context.clearRect(0,0,this.diameter,this.diameter),this.context.beginPath(),this.context.arc(i,n,t+4,0,2*Math.PI,!1),this.context.fillStyle="rgba( 0, 0, 0, 0.4 )",this.context.fill(),this.context.beginPath(),this.context.arc(i,n,t,0,2*Math.PI,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="rgba( 255, 255, 255, 0.2 )",this.context.stroke(),this.playing&&(this.context.beginPath(),this.context.arc(i,n,t,o,a,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="#fff",this.context.stroke()),this.context.translate(i-14,n-14),this.playing?(this.context.fillStyle="#fff",this.context.fillRect(0,0,10,s),this.context.fillRect(18,0,10,s)):(this.context.beginPath(),this.context.translate(4,0),this.context.moveTo(0,0),this.context.lineTo(24,14),this.context.lineTo(0,s),this.context.fillStyle="#fff",this.context.fill()),this.context.restore()}on(e,t){this.canvas.addEventListener(e,t,!1)}off(e,t){this.canvas.removeEventListener(e,t,!1)}destroy(){this.playing=!1,this.canvas.parentNode&&this.container.removeChild(this.canvas)}}var $={width:960,height:700,margin:.04,minScale:.2,maxScale:2,controls:!0,controlsTutorial:!0,controlsLayout:"bottom-right",controlsBackArrows:"faded",progress:!0,slideNumber:!1,showSlideNumber:"all",hashOneBasedIndex:!1,hash:!1,respondToHashChanges:!0,jumpToSlide:!0,history:!1,keyboard:!0,keyboardCondition:null,disableLayout:!1,overview:!0,center:!0,touch:!0,loop:!1,rtl:!1,navigationMode:"default",shuffle:!1,fragments:!0,fragmentInURL:!0,embedded:!1,help:!0,pause:!0,showNotes:!1,showHiddenSlides:!1,autoPlayMedia:null,preloadIframes:null,autoAnimate:!0,autoAnimateMatcher:null,autoAnimateEasing:"ease",autoAnimateDuration:1,autoAnimateUnmatched:!0,autoAnimateStyles:["opacity","color","background-color","padding","font-size","line-height","letter-spacing","border-width","border-color","border-radius","outline","outline-offset"],autoSlide:0,autoSlideStoppable:!0,autoSlideMethod:null,defaultTiming:null,mouseWheel:!1,previewLinks:!1,postMessage:!0,postMessageEvents:!1,focusBodyOnPageVisibilityChange:!0,transition:"slide",transitionSpeed:"default",backgroundTransition:"fade",parallaxBackgroundImage:"",parallaxBackgroundSize:"",parallaxBackgroundRepeat:"",parallaxBackgroundPosition:"",parallaxBackgroundHorizontal:null,parallaxBackgroundVertical:null,pdfMaxPagesPerSlide:Number.POSITIVE_INFINITY,pdfSeparateFragments:!0,pdfPageHeightOffset:-1,viewDistance:3,mobileViewDistance:2,display:"block",hideInactiveCursor:!0,hideCursorTime:5e3,sortFragmentsOnSync:!0,dependencies:[],plugins:[]};const X="4.5.0";function Y(a,l){arguments.length<2&&(l=arguments[0],a=document.querySelector(".reveal"));const h={};let u,v,p,m,f,E={},C=!1,x={hasNavigatedHorizontally:!1,hasNavigatedVertically:!1},H=[],U=1,j={layout:"",overview:""},Y={},_="idle",J=0,G=0,Q=-1,Z=!1,ee=new b(h),te=new y(h),ie=new w(h),ne=new P(h),se=new R(h),ae=new N(h),oe=new M(h),re=new I(h),le=new T(h),de=new D(h),ce=new F(h),he=new z(h),ue=new B(h),ge=new O(h),ve=new W(h),pe=new q(h),me=new K(h);function fe(e){if(!a)throw'Unable to find presentation root ().';if(Y.wrapper=a,Y.slides=a.querySelector(".slides"),!Y.slides)throw'Unable to find slides container (
).';return E={...$,...E,...l,...e,...d()},be(),window.addEventListener("load",We,!1),ue.load(E.plugins,E.dependencies).then(ye),new Promise((e=>h.on("ready",e)))}function be(){!0===E.embedded?Y.viewport=o(a,".reveal-viewport")||a:(Y.viewport=document.body,document.documentElement.classList.add("reveal-full-page")),Y.viewport.classList.add("reveal-viewport")}function ye(){C=!0,we(),Ee(),Ce(),ke(),Le(),lt(),xe(),le.readURL(),se.update(!0),setTimeout((()=>{Y.slides.classList.remove("no-transition"),Y.wrapper.classList.add("ready"),Fe({type:"ready",data:{indexh:u,indexv:v,currentSlide:m}})}),1),ge.isPrintingPDF()&&(Ne(),"complete"===document.readyState?ge.setupPDF():window.addEventListener("load",(()=>{ge.setupPDF()})))}function we(){E.showHiddenSlides||t(Y.wrapper,'section[data-visibility="hidden"]').forEach((e=>{e.parentNode.removeChild(e)}))}function Ee(){Y.slides.classList.add("no-transition"),g?Y.wrapper.classList.add("no-hover"):Y.wrapper.classList.remove("no-hover"),se.render(),te.render(),ie.render(),de.render(),ce.render(),me.render(),Y.pauseOverlay=r(Y.wrapper,"div","pause-overlay",E.controls?'
Resume presentation ':null),Y.statusElement=Re(),Y.wrapper.setAttribute("role","application")}function Re(){let e=Y.wrapper.querySelector(".aria-status");return e||(e=document.createElement("div"),e.style.position="absolute",e.style.height="1px",e.style.width="1px",e.style.overflow="hidden",e.style.clip="rect( 1px, 1px, 1px, 1px )",e.classList.add("aria-status"),e.setAttribute("aria-live","polite"),e.setAttribute("aria-atomic","true"),Y.wrapper.appendChild(e)),e}function Se(e){Y.statusElement.textContent=e}function Ae(e){let t="";if(3===e.nodeType)t+=e.textContent;else if(1===e.nodeType){let i=e.getAttribute("aria-hidden"),n="none"===window.getComputedStyle(e).display;"true"===i||n||Array.from(e.childNodes).forEach((e=>{t+=Ae(e)}))}return t=t.trim(),""===t?"":t+" "}function ke(){setInterval((()=>{0===Y.wrapper.scrollTop&&0===Y.wrapper.scrollLeft||(Y.wrapper.scrollTop=0,Y.wrapper.scrollLeft=0)}),1e3)}function Le(){document.addEventListener("fullscreenchange",$t),document.addEventListener("webkitfullscreenchange",$t)}function Ce(){E.postMessage&&window.addEventListener("message",Ut,!1)}function xe(t){const n={...E};if("object"==typeof t&&e(E,t),!1===h.isReady())return;const s=Y.wrapper.querySelectorAll(S).length;Y.wrapper.classList.remove(n.transition),Y.wrapper.classList.add(E.transition),Y.wrapper.setAttribute("data-transition-speed",E.transitionSpeed),Y.wrapper.setAttribute("data-background-transition",E.backgroundTransition),Y.viewport.style.setProperty("--slide-width",E.width+"px"),Y.viewport.style.setProperty("--slide-height",E.height+"px"),E.shuffle&&dt(),i(Y.wrapper,"embedded",E.embedded),i(Y.wrapper,"rtl",E.rtl),i(Y.wrapper,"center",E.center),!1===E.pause&&Ze(),E.previewLinks?(He(),Be("[data-preview-link=false]")):(Be(),He("[data-preview-link]:not([data-preview-link=false])")),ne.reset(),f&&(f.destroy(),f=null),s>1&&E.autoSlide&&E.autoSlideStoppable&&(f=new V(Y.wrapper,(()=>Math.min(Math.max((Date.now()-Q)/J,0),1))),f.on("click",Yt),Z=!1),"default"!==E.navigationMode?Y.wrapper.setAttribute("data-navigation-mode",E.navigationMode):Y.wrapper.removeAttribute("data-navigation-mode"),me.configure(E,n),ve.configure(E,n),he.configure(E,n),de.configure(E,n),ce.configure(E,n),re.configure(E,n),ae.configure(E,n),te.configure(E,n),ot()}function Pe(){window.addEventListener("resize",Kt,!1),E.touch&&pe.bind(),E.keyboard&&re.bind(),E.progress&&ce.bind(),E.respondToHashChanges&&le.bind(),de.bind(),ve.bind(),Y.slides.addEventListener("click",Wt,!1),Y.slides.addEventListener("transitionend",jt,!1),Y.pauseOverlay.addEventListener("click",Ze,!1),E.focusBodyOnPageVisibilityChange&&document.addEventListener("visibilitychange",Vt,!1)}function Ne(){pe.unbind(),ve.unbind(),re.unbind(),de.unbind(),ce.unbind(),le.unbind(),window.removeEventListener("resize",Kt,!1),Y.slides.removeEventListener("click",Wt,!1),Y.slides.removeEventListener("transitionend",jt,!1),Y.pauseOverlay.removeEventListener("click",Ze,!1)}function Me(){Ne(),Mt(),Be(),me.destroy(),ve.destroy(),ue.destroy(),he.destroy(),de.destroy(),ce.destroy(),se.destroy(),te.destroy(),ie.destroy(),document.removeEventListener("fullscreenchange",$t),document.removeEventListener("webkitfullscreenchange",$t),document.removeEventListener("visibilitychange",Vt,!1),window.removeEventListener("message",Ut,!1),window.removeEventListener("load",We,!1),Y.pauseOverlay&&Y.pauseOverlay.remove(),Y.statusElement&&Y.statusElement.remove(),document.documentElement.classList.remove("reveal-full-page"),Y.wrapper.classList.remove("ready","center","has-horizontal-slides","has-vertical-slides"),Y.wrapper.removeAttribute("data-transition-speed"),Y.wrapper.removeAttribute("data-background-transition"),Y.viewport.classList.remove("reveal-viewport"),Y.viewport.style.removeProperty("--slide-width"),Y.viewport.style.removeProperty("--slide-height"),Y.slides.style.removeProperty("width"),Y.slides.style.removeProperty("height"),Y.slides.style.removeProperty("zoom"),Y.slides.style.removeProperty("left"),Y.slides.style.removeProperty("top"),Y.slides.style.removeProperty("bottom"),Y.slides.style.removeProperty("right"),Y.slides.style.removeProperty("transform"),Array.from(Y.wrapper.querySelectorAll(S)).forEach((e=>{e.style.removeProperty("display"),e.style.removeProperty("top"),e.removeAttribute("hidden"),e.removeAttribute("aria-hidden")}))}function Ie(e,t,i){a.addEventListener(e,t,i)}function Te(e,t,i){a.removeEventListener(e,t,i)}function De(e){"string"==typeof e.layout&&(j.layout=e.layout),"string"==typeof e.overview&&(j.overview=e.overview),j.layout?s(Y.slides,j.layout+" "+j.overview):s(Y.slides,j.overview)}function Fe({target:t=Y.wrapper,type:i,data:n,bubbles:s=!0}){let a=document.createEvent("HTMLEvents",1,2);return a.initEvent(i,s,!0),e(a,n),t.dispatchEvent(a),t===Y.wrapper&&ze(i),a}function ze(t,i){if(E.postMessageEvents&&window.parent!==window.self){let n={namespace:"reveal",eventName:t,state:xt()};e(n,i),window.parent.postMessage(JSON.stringify(n),"*")}}function He(e="a"){Array.from(Y.wrapper.querySelectorAll(e)).forEach((e=>{/^(http|www)/gi.test(e.getAttribute("href"))&&e.addEventListener("click",Xt,!1)}))}function Be(e="a"){Array.from(Y.wrapper.querySelectorAll(e)).forEach((e=>{/^(http|www)/gi.test(e.getAttribute("href"))&&e.removeEventListener("click",Xt,!1)}))}function Oe(e){je(),Y.overlay=document.createElement("div"),Y.overlay.classList.add("overlay"),Y.overlay.classList.add("overlay-preview"),Y.wrapper.appendChild(Y.overlay),Y.overlay.innerHTML=`
\n\t\t\t\t \n\t\t\t\t \n\t\t\t \n\t\t\t
\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\tUnable to load iframe. This is likely due to the site's policy (x-frame-options). \n\t\t\t\t \n\t\t\t
`,Y.overlay.querySelector("iframe").addEventListener("load",(e=>{Y.overlay.classList.add("loaded")}),!1),Y.overlay.querySelector(".close").addEventListener("click",(e=>{je(),e.preventDefault()}),!1),Y.overlay.querySelector(".external").addEventListener("click",(e=>{je()}),!1)}function qe(e){"boolean"==typeof e?e?Ue():je():Y.overlay?je():Ue()}function Ue(){if(E.help){je(),Y.overlay=document.createElement("div"),Y.overlay.classList.add("overlay"),Y.overlay.classList.add("overlay-help"),Y.wrapper.appendChild(Y.overlay);let e='
Keyboard Shortcuts
',t=re.getShortcuts(),i=re.getBindings();e+="
KEY ACTION ";for(let i in t)e+=`${i} ${t[i]} `;for(let t in i)i[t].key&&i[t].description&&(e+=`${i[t].key} ${i[t].description} `);e+="
",Y.overlay.innerHTML=`\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
${e}
\n\t\t\t\t
\n\t\t\t`,Y.overlay.querySelector(".close").addEventListener("click",(e=>{je(),e.preventDefault()}),!1)}}function je(){return!!Y.overlay&&(Y.overlay.parentNode.removeChild(Y.overlay),Y.overlay=null,!0)}function We(){if(Y.wrapper&&!ge.isPrintingPDF()){if(!E.disableLayout){g&&!E.embedded&&document.documentElement.style.setProperty("--vh",.01*window.innerHeight+"px");const e=Ve(),t=U;Ke(E.width,E.height),Y.slides.style.width=e.width+"px",Y.slides.style.height=e.height+"px",U=Math.min(e.presentationWidth/e.width,e.presentationHeight/e.height),U=Math.max(U,E.minScale),U=Math.min(U,E.maxScale),1===U?(Y.slides.style.zoom="",Y.slides.style.left="",Y.slides.style.top="",Y.slides.style.bottom="",Y.slides.style.right="",De({layout:""})):(Y.slides.style.zoom="",Y.slides.style.left="50%",Y.slides.style.top="50%",Y.slides.style.bottom="auto",Y.slides.style.right="auto",De({layout:"translate(-50%, -50%) scale("+U+")"}));const i=Array.from(Y.wrapper.querySelectorAll(S));for(let t=0,n=i.length;t
.stretch, section > .r-stretch").forEach((t=>{let n=c(t,i);if(/(img|video)/gi.test(t.nodeName)){const i=t.naturalWidth||t.videoWidth,s=t.naturalHeight||t.videoHeight,a=Math.min(e/i,n/s);t.style.width=i*a+"px",t.style.height=s*a+"px"}else t.style.width=e+"px",t.style.height=n+"px"}))}function Ve(e,t){let i=E.width,n=E.height;E.disableLayout&&(i=Y.slides.offsetWidth,n=Y.slides.offsetHeight);const s={width:i,height:n,presentationWidth:e||Y.wrapper.offsetWidth,presentationHeight:t||Y.wrapper.offsetHeight};return s.presentationWidth-=s.presentationWidth*E.margin,s.presentationHeight-=s.presentationHeight*E.margin,"string"==typeof s.width&&/%$/.test(s.width)&&(s.width=parseInt(s.width,10)/100*s.presentationWidth),"string"==typeof s.height&&/%$/.test(s.height)&&(s.height=parseInt(s.height,10)/100*s.presentationHeight),s}function $e(e,t){"object"==typeof e&&"function"==typeof e.setAttribute&&e.setAttribute("data-previous-indexv",t||0)}function Xe(e){if("object"==typeof e&&"function"==typeof e.setAttribute&&e.classList.contains("stack")){const t=e.hasAttribute("data-start-indexv")?"data-start-indexv":"data-previous-indexv";return parseInt(e.getAttribute(t)||0,10)}return 0}function Ye(e=m){return e&&e.parentNode&&!!e.parentNode.nodeName.match(/section/i)}function _e(){return!(!m||!Ye(m))&&!m.nextElementSibling}function Je(){return 0===u&&0===v}function Ge(){return!!m&&(!m.nextElementSibling&&(!Ye(m)||!m.parentNode.nextElementSibling))}function Qe(){if(E.pause){const e=Y.wrapper.classList.contains("paused");Mt(),Y.wrapper.classList.add("paused"),!1===e&&Fe({type:"paused"})}}function Ze(){const e=Y.wrapper.classList.contains("paused");Y.wrapper.classList.remove("paused"),Nt(),e&&Fe({type:"resumed"})}function et(e){"boolean"==typeof e?e?Qe():Ze():tt()?Ze():Qe()}function tt(){return Y.wrapper.classList.contains("paused")}function it(e){"boolean"==typeof e?e?ie.show():ie.hide():ie.isVisible()?ie.hide():ie.show()}function nt(e){"boolean"==typeof e?e?Tt():It():Z?Tt():It()}function st(){return!(!J||Z)}function at(e,t,i,n){if(Fe({type:"beforeslidechange",data:{indexh:void 0===e?u:e,indexv:void 0===t?v:t,origin:n}}).defaultPrevented)return;p=m;const s=Y.wrapper.querySelectorAll(A);if(0===s.length)return;void 0!==t||oe.isActive()||(t=Xe(s[e])),p&&p.parentNode&&p.parentNode.classList.contains("stack")&&$e(p.parentNode,v);const a=H.concat();H.length=0;let o=u||0,r=v||0;u=ct(A,void 0===e?u:e),v=ct(k,void 0===t?v:t);let l=u!==o||v!==r;l||(p=null);let d=s[u],c=d.querySelectorAll("section");m=c[v]||d;let h=!1;l&&p&&m&&!oe.isActive()&&(p.hasAttribute("data-auto-animate")&&m.hasAttribute("data-auto-animate")&&p.getAttribute("data-auto-animate-id")===m.getAttribute("data-auto-animate-id")&&!(u>o||v>r?m:p).hasAttribute("data-auto-animate-restart")&&(h=!0,Y.slides.classList.add("disable-slide-transitions")),_="running"),gt(),We(),oe.isActive()&&oe.update(),void 0!==i&&ae.goto(i),p&&p!==m&&(p.classList.remove("present"),p.setAttribute("aria-hidden","true"),Je()&&setTimeout((()=>{Et().forEach((e=>{$e(e,0)}))}),0));e:for(let e=0,t=H.length;e{Se(Ae(m))})),ce.update(),de.update(),me.update(),se.update(),se.updateParallax(),te.update(),ae.update(),le.writeURL(),Nt(),h&&(setTimeout((()=>{Y.slides.classList.remove("disable-slide-transitions")}),0),E.autoAnimate&&ne.run(p,m))}function ot(){Ne(),Pe(),We(),J=E.autoSlide,Nt(),se.create(),le.writeURL(),!0===E.sortFragmentsOnSync&&ae.sortAll(),de.update(),ce.update(),gt(),me.update(),me.updateVisibility(),se.update(!0),te.update(),ee.formatEmbeddedContent(),!1===E.autoPlayMedia?ee.stopEmbeddedContent(m,{unloadIframes:!1}):ee.startEmbeddedContent(m),oe.isActive()&&oe.layout()}function rt(e=m){se.sync(e),ae.sync(e),ee.load(e),se.update(),me.update()}function lt(){yt().forEach((e=>{t(e,"section").forEach(((e,t)=>{t>0&&(e.classList.remove("present"),e.classList.remove("past"),e.classList.add("future"),e.setAttribute("aria-hidden","true"))}))}))}function dt(e=yt()){e.forEach(((t,i)=>{let n=e[Math.floor(Math.random()*e.length)];n.parentNode===t.parentNode&&t.parentNode.insertBefore(t,n);let s=t.querySelectorAll("section");s.length&&dt(s)}))}function ct(e,i){let n=t(Y.wrapper,e),s=n.length,a=ge.isPrintingPDF(),o=!1,r=!1;if(s){E.loop&&(i>=s&&(o=!0),(i%=s)<0&&(i=s+i,r=!0)),i=Math.max(Math.min(i,s-1),0);for(let e=0;ei?(t.classList.add(s?"past":"future"),E.fragments&&ut(t)):e===i&&E.fragments&&(o?ut(t):r&&ht(t))}let e=n[i],t=e.classList.contains("present");e.classList.add("present"),e.removeAttribute("hidden"),e.removeAttribute("aria-hidden"),t||Fe({target:e,type:"visible",bubbles:!1});let l=e.getAttribute("data-state");l&&(H=H.concat(l.split(" ")))}else i=0;return i}function ht(e){t(e,".fragment").forEach((e=>{e.classList.add("visible"),e.classList.remove("current-fragment")}))}function ut(e){t(e,".fragment.visible").forEach((e=>{e.classList.remove("visible","current-fragment")}))}function gt(){let e,i,n=yt(),s=n.length;if(s&&void 0!==u){let a=oe.isActive()?10:E.viewDistance;g&&(a=oe.isActive()?6:E.mobileViewDistance),ge.isPrintingPDF()&&(a=Number.MAX_VALUE);for(let o=0;o0,right:u0,down:v1&&(n.left=!0,n.right=!0),i.length>1&&(n.up=!0,n.down=!0)),t.length>1&&"linear"===E.navigationMode&&(n.right=n.right||n.down,n.left=n.left||n.up),!0===e){let e=ae.availableRoutes();n.left=n.left||e.prev,n.up=n.up||e.prev,n.down=n.down||e.next,n.right=n.right||e.next}if(E.rtl){let e=n.left;n.left=n.right,n.right=e}return n}function pt(e=m){let t=yt(),i=0;e:for(let n=0;n0){let i=.9;t+=m.querySelectorAll(".fragment.visible").length/e.length*i}}return Math.min(t/(e-1),1)}function ft(e){let i,n=u,s=v;if(e){let i=Ye(e),a=i?e.parentNode:e,o=yt();n=Math.max(o.indexOf(a),0),s=void 0,i&&(s=Math.max(t(e.parentNode,"section").indexOf(e),0))}if(!e&&m){if(m.querySelectorAll(".fragment").length>0){let e=m.querySelector(".current-fragment");i=e&&e.hasAttribute("data-fragment-index")?parseInt(e.getAttribute("data-fragment-index"),10):m.querySelectorAll(".fragment.visible").length-1}}return{h:n,v:s,f:i}}function bt(){return t(Y.wrapper,S+':not(.stack):not([data-visibility="uncounted"])')}function yt(){return t(Y.wrapper,A)}function wt(){return t(Y.wrapper,".slides>section>section")}function Et(){return t(Y.wrapper,A+".stack")}function Rt(){return yt().length>1}function St(){return wt().length>1}function At(){return bt().map((e=>{let t={};for(let i=0;i{e.hasAttribute("data-autoplay")&&J&&1e3*e.duration/e.playbackRate>J&&(J=1e3*e.duration/e.playbackRate+1e3)}))),!J||Z||tt()||oe.isActive()||Ge()&&!ae.availableRoutes().next&&!0!==E.loop||(G=setTimeout((()=>{"function"==typeof E.autoSlideMethod?E.autoSlideMethod():Ot(),Nt()}),J),Q=Date.now()),f&&f.setPlaying(-1!==G)}}function Mt(){clearTimeout(G),G=-1}function It(){J&&!Z&&(Z=!0,Fe({type:"autoslidepaused"}),clearTimeout(G),f&&f.setPlaying(!1))}function Tt(){J&&Z&&(Z=!1,Fe({type:"autoslideresumed"}),Nt())}function Dt({skipFragments:e=!1}={}){x.hasNavigatedHorizontally=!0,E.rtl?(oe.isActive()||e||!1===ae.next())&&vt().left&&at(u+1,"grid"===E.navigationMode?v:void 0):(oe.isActive()||e||!1===ae.prev())&&vt().left&&at(u-1,"grid"===E.navigationMode?v:void 0)}function Ft({skipFragments:e=!1}={}){x.hasNavigatedHorizontally=!0,E.rtl?(oe.isActive()||e||!1===ae.prev())&&vt().right&&at(u-1,"grid"===E.navigationMode?v:void 0):(oe.isActive()||e||!1===ae.next())&&vt().right&&at(u+1,"grid"===E.navigationMode?v:void 0)}function zt({skipFragments:e=!1}={}){(oe.isActive()||e||!1===ae.prev())&&vt().up&&at(u,v-1)}function Ht({skipFragments:e=!1}={}){x.hasNavigatedVertically=!0,(oe.isActive()||e||!1===ae.next())&&vt().down&&at(u,v+1)}function Bt({skipFragments:e=!1}={}){if(e||!1===ae.prev())if(vt().up)zt({skipFragments:e});else{let i;if(i=E.rtl?t(Y.wrapper,A+".future").pop():t(Y.wrapper,A+".past").pop(),i&&i.classList.contains("stack")){let e=i.querySelectorAll("section").length-1||void 0;at(u-1,e)}else Dt({skipFragments:e})}}function Ot({skipFragments:e=!1}={}){if(x.hasNavigatedHorizontally=!0,x.hasNavigatedVertically=!0,e||!1===ae.next()){let t=vt();t.down&&t.right&&E.loop&&_e()&&(t.down=!1),t.down?Ht({skipFragments:e}):E.rtl?Dt({skipFragments:e}):Ft({skipFragments:e})}}function qt(e){E.autoSlideStoppable&&It()}function Ut(e){let t=e.data;if("string"==typeof t&&"{"===t.charAt(0)&&"}"===t.charAt(t.length-1)&&(t=JSON.parse(t),t.method&&"function"==typeof h[t.method]))if(!1===L.test(t.method)){const e=h[t.method].apply(h,t.args);ze("callback",{method:t.method,result:e})}else console.warn('reveal.js: "'+t.method+'" is is blacklisted from the postMessage API')}function jt(e){"running"===_&&/section/gi.test(e.target.nodeName)&&(_="idle",Fe({type:"slidetransitionend",data:{indexh:u,indexv:v,previousSlide:p,currentSlide:m}}))}function Wt(e){const t=o(e.target,'a[href^="#"]');if(t){const i=t.getAttribute("href"),n=le.getIndicesFromHash(i);n&&(h.slide(n.h,n.v,n.f),e.preventDefault())}}function Kt(e){We()}function Vt(e){!1===document.hidden&&document.activeElement!==document.body&&("function"==typeof document.activeElement.blur&&document.activeElement.blur(),document.body.focus())}function $t(e){(document.fullscreenElement||document.webkitFullscreenElement)===Y.wrapper&&(e.stopImmediatePropagation(),setTimeout((()=>{h.layout(),h.focus.focus()}),1))}function Xt(e){if(e.currentTarget&&e.currentTarget.hasAttribute("href")){let t=e.currentTarget.getAttribute("href");t&&(Oe(t),e.preventDefault())}}function Yt(e){Ge()&&!1===E.loop?(at(0,0),Tt()):Z?Tt():It()}const _t={VERSION:X,initialize:fe,configure:xe,destroy:Me,sync:ot,syncSlide:rt,syncFragments:ae.sync.bind(ae),slide:at,left:Dt,right:Ft,up:zt,down:Ht,prev:Bt,next:Ot,navigateLeft:Dt,navigateRight:Ft,navigateUp:zt,navigateDown:Ht,navigatePrev:Bt,navigateNext:Ot,navigateFragment:ae.goto.bind(ae),prevFragment:ae.prev.bind(ae),nextFragment:ae.next.bind(ae),on:Ie,off:Te,addEventListener:Ie,removeEventListener:Te,layout:We,shuffle:dt,availableRoutes:vt,availableFragments:ae.availableRoutes.bind(ae),toggleHelp:qe,toggleOverview:oe.toggle.bind(oe),togglePause:et,toggleAutoSlide:nt,toggleJumpToSlide:it,isFirstSlide:Je,isLastSlide:Ge,isLastVerticalSlide:_e,isVerticalSlide:Ye,isPaused:tt,isAutoSliding:st,isSpeakerNotes:me.isSpeakerNotesWindow.bind(me),isOverview:oe.isActive.bind(oe),isFocused:ve.isFocused.bind(ve),isPrintingPDF:ge.isPrintingPDF.bind(ge),isReady:()=>C,loadSlide:ee.load.bind(ee),unloadSlide:ee.unload.bind(ee),showPreview:Oe,hidePreview:je,addEventListeners:Pe,removeEventListeners:Ne,dispatchEvent:Fe,getState:xt,setState:Pt,getProgress:mt,getIndices:ft,getSlidesAttributes:At,getSlidePastCount:pt,getTotalSlides:kt,getSlide:Lt,getPreviousSlide:()=>p,getCurrentSlide:()=>m,getSlideBackground:Ct,getSlideNotes:me.getSlideNotes.bind(me),getSlides:bt,getHorizontalSlides:yt,getVerticalSlides:wt,hasHorizontalSlides:Rt,hasVerticalSlides:St,hasNavigatedHorizontally:()=>x.hasNavigatedHorizontally,hasNavigatedVertically:()=>x.hasNavigatedVertically,addKeyBinding:re.addKeyBinding.bind(re),removeKeyBinding:re.removeKeyBinding.bind(re),triggerKey:re.triggerKey.bind(re),registerKeyboardShortcut:re.registerKeyboardShortcut.bind(re),getComputedSlideSize:Ve,getScale:()=>U,getConfig:()=>E,getQueryHash:d,getSlidePath:le.getHash.bind(le),getRevealElement:()=>a,getSlidesElement:()=>Y.slides,getViewportElement:()=>Y.viewport,getBackgroundsElement:()=>se.element,registerPlugin:ue.registerPlugin.bind(ue),hasPlugin:ue.hasPlugin.bind(ue),getPlugin:ue.getPlugin.bind(ue),getPlugins:ue.getRegisteredPlugins.bind(ue)};return e(h,{..._t,announceStatus:Se,getStatusText:Ae,print:ge,focus:ve,progress:ce,controls:de,location:le,overview:oe,fragments:ae,slideContent:ee,slideNumber:te,onUserInput:qt,closeOverlay:je,updateSlidesVisibility:gt,layoutSlideContents:Ke,transformSlides:De,cueAutoSlide:Nt,cancelAutoSlide:Mt}),_t}let _=Y,J=[];return _.initialize=e=>(Object.assign(_,new Y(document.querySelector(".reveal"),e)),J.map((e=>e(_))),_.initialize()),["configure","on","off","addEventListener","removeEventListener","registerPlugin"].forEach((e=>{_[e]=(...t)=>{J.push((i=>i[e].call(null,...t)))}})),_.isReady=()=>!1,_.VERSION=X,_}));
+//# sourceMappingURL=reveal.js.map
diff --git a/dist/reveal.js.map b/dist/reveal.js.map
new file mode 100644
index 00000000000..cfde6ede0fc
--- /dev/null
+++ b/dist/reveal.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"reveal.js","sources":["../js/utils/util.js","../js/utils/device.js","../node_modules/fitty/dist/fitty.module.js","../js/controllers/slidecontent.js","../js/controllers/slidenumber.js","../js/controllers/jumptoslide.js","../js/utils/color.js","../js/controllers/backgrounds.js","../js/utils/constants.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/focus.js","../js/controllers/notes.js","../js/components/playback.js","../js/config.js","../js/reveal.js","../js/index.js"],"sourcesContent":["/**\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 * classList.toggle() with cross browser support\n */\nexport const toggleClass = ( el, className, value ) => {\n\tif( value ) {\n\t\tel.classList.add( className );\n\t}\n\telse {\n\t\tel.classList.remove( className );\n\t}\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 * Element.matches with IE support.\n *\n * @param {HTMLElement} target The element to match\n * @param {String} selector The CSS selector to match\n * the element against\n *\n * @return {Boolean}\n */\nexport const matches = ( target, selector ) => {\n\n\tlet matchesMethod = target.matches || target.matchesSelector || target.msMatchesSelector;\n\n\treturn !!( matchesMethod && matchesMethod.call( target, selector ) );\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 closest = ( target, selector ) => {\n\n\t// Native Element.closest\n\tif( typeof target.closest === 'function' ) {\n\t\treturn target.closest( selector );\n\t}\n\n\t// Polyfill\n\twhile( target ) {\n\t\tif( matches( target, selector ) ) {\n\t\t\treturn target;\n\t\t}\n\n\t\t// Keep searching\n\t\ttarget = target.parentNode;\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 = element => {\n\n\telement = 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}\n\nconst fileExtensionToMimeMap = {\n\t'mp4': 'video/mp4',\n\t'm4a': 'video/mp4',\n\t'ogv': 'video/ogg',\n\t'mpeg': 'video/mpeg',\n\t'webm': 'video/webm'\n}\n\n/**\n * Guess the MIME type for common file formats.\n */\nexport const getMimeTypeFromFile = ( filename='' ) => {\n\treturn fileExtensionToMimeMap[filename.split('.').pop()]\n}\n\n/**\n * Encodes a string for RFC3986-compliant URL format.\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI#encoding_for_rfc3986\n *\n * @param {string} url\n */\nexport const encodeRFC3986URI = ( url='' ) => {\n\treturn encodeURI(url)\n\t .replace(/%5B/g, \"[\")\n\t .replace(/%5D/g, \"]\")\n\t .replace(\n\t\t/[!'()*]/g,\n\t\t(c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`\n\t );\n}","const UA = navigator.userAgent;\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 * fitty v2.3.3 - Snugly resizes text to fit its parent container\n * Copyright (c) 2020 Rik Schennink (https://pqina.nl/)\n */\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nexports.default = function (w) {\n\n // no window, early exit\n if (!w) return;\n\n // node list to array helper method\n var toArray = function toArray(nl) {\n return [].slice.call(nl);\n };\n\n // states\n var DrawState = {\n IDLE: 0,\n DIRTY_CONTENT: 1,\n DIRTY_LAYOUT: 2,\n DIRTY: 3\n };\n\n // all active fitty elements\n var fitties = [];\n\n // group all redraw calls till next frame, we cancel each frame request when a new one comes in. If no support for request animation frame, this is an empty function and supports for fitty stops.\n var redrawFrame = null;\n var requestRedraw = 'requestAnimationFrame' in w ? function () {\n w.cancelAnimationFrame(redrawFrame);\n redrawFrame = w.requestAnimationFrame(function () {\n return redraw(fitties.filter(function (f) {\n return f.dirty && f.active;\n }));\n });\n } : function () {};\n\n // sets all fitties to dirty so they are redrawn on the next redraw loop, then calls redraw\n var redrawAll = function redrawAll(type) {\n return function () {\n fitties.forEach(function (f) {\n return f.dirty = type;\n });\n requestRedraw();\n };\n };\n\n // redraws fitties so they nicely fit their parent container\n var redraw = function redraw(fitties) {\n\n // getting info from the DOM at this point should not trigger a reflow, let's gather as much intel as possible before triggering a reflow\n\n // check if styles of all fitties have been computed\n fitties.filter(function (f) {\n return !f.styleComputed;\n }).forEach(function (f) {\n f.styleComputed = computeStyle(f);\n });\n\n // restyle elements that require pre-styling, this triggers a reflow, please try to prevent by adding CSS rules (see docs)\n fitties.filter(shouldPreStyle).forEach(applyStyle);\n\n // we now determine which fitties should be redrawn\n var fittiesToRedraw = fitties.filter(shouldRedraw);\n\n // we calculate final styles for these fitties\n fittiesToRedraw.forEach(calculateStyles);\n\n // now we apply the calculated styles from our previous loop\n fittiesToRedraw.forEach(function (f) {\n applyStyle(f);\n markAsClean(f);\n });\n\n // now we dispatch events for all restyled fitties\n fittiesToRedraw.forEach(dispatchFitEvent);\n };\n\n var markAsClean = function markAsClean(f) {\n return f.dirty = DrawState.IDLE;\n };\n\n var calculateStyles = function calculateStyles(f) {\n\n // get available width from parent node\n f.availableWidth = f.element.parentNode.clientWidth;\n\n // the space our target element uses\n f.currentWidth = f.element.scrollWidth;\n\n // remember current font size\n f.previousFontSize = f.currentFontSize;\n\n // let's calculate the new font size\n f.currentFontSize = Math.min(Math.max(f.minSize, f.availableWidth / f.currentWidth * f.previousFontSize), f.maxSize);\n\n // if allows wrapping, only wrap when at minimum font size (otherwise would break container)\n f.whiteSpace = f.multiLine && f.currentFontSize === f.minSize ? 'normal' : 'nowrap';\n };\n\n // should always redraw if is not dirty layout, if is dirty layout, only redraw if size has changed\n var shouldRedraw = function shouldRedraw(f) {\n return f.dirty !== DrawState.DIRTY_LAYOUT || f.dirty === DrawState.DIRTY_LAYOUT && f.element.parentNode.clientWidth !== f.availableWidth;\n };\n\n // every fitty element is tested for invalid styles\n var computeStyle = function computeStyle(f) {\n\n // get style properties\n var style = w.getComputedStyle(f.element, null);\n\n // get current font size in pixels (if we already calculated it, use the calculated version)\n f.currentFontSize = parseFloat(style.getPropertyValue('font-size'));\n\n // get display type and wrap mode\n f.display = style.getPropertyValue('display');\n f.whiteSpace = style.getPropertyValue('white-space');\n };\n\n // determines if this fitty requires initial styling, can be prevented by applying correct styles through CSS\n var shouldPreStyle = function shouldPreStyle(f) {\n\n var preStyle = false;\n\n // if we already tested for prestyling we don't have to do it again\n if (f.preStyleTestCompleted) return false;\n\n // should have an inline style, if not, apply\n if (!/inline-/.test(f.display)) {\n preStyle = true;\n f.display = 'inline-block';\n }\n\n // to correctly calculate dimensions the element should have whiteSpace set to nowrap\n if (f.whiteSpace !== 'nowrap') {\n preStyle = true;\n f.whiteSpace = 'nowrap';\n }\n\n // we don't have to do this twice\n f.preStyleTestCompleted = true;\n\n return preStyle;\n };\n\n // apply styles to single fitty\n var applyStyle = function applyStyle(f) {\n f.element.style.whiteSpace = f.whiteSpace;\n f.element.style.display = f.display;\n f.element.style.fontSize = f.currentFontSize + 'px';\n };\n\n // dispatch a fit event on a fitty\n var dispatchFitEvent = function dispatchFitEvent(f) {\n f.element.dispatchEvent(new CustomEvent('fit', {\n detail: {\n oldValue: f.previousFontSize,\n newValue: f.currentFontSize,\n scaleFactor: f.currentFontSize / f.previousFontSize\n }\n }));\n };\n\n // fit method, marks the fitty as dirty and requests a redraw (this will also redraw any other fitty marked as dirty)\n var fit = function fit(f, type) {\n return function () {\n f.dirty = type;\n if (!f.active) return;\n requestRedraw();\n };\n };\n\n var init = function init(f) {\n\n // save some of the original CSS properties before we change them\n f.originalStyle = {\n whiteSpace: f.element.style.whiteSpace,\n display: f.element.style.display,\n fontSize: f.element.style.fontSize\n };\n\n // should we observe DOM mutations\n observeMutations(f);\n\n // this is a new fitty so we need to validate if it's styles are in order\n f.newbie = true;\n\n // because it's a new fitty it should also be dirty, we want it to redraw on the first loop\n f.dirty = true;\n\n // we want to be able to update this fitty\n fitties.push(f);\n };\n\n var destroy = function destroy(f) {\n return function () {\n\n // remove from fitties array\n fitties = fitties.filter(function (_) {\n return _.element !== f.element;\n });\n\n // stop observing DOM\n if (f.observeMutations) f.observer.disconnect();\n\n // reset the CSS properties we changes\n f.element.style.whiteSpace = f.originalStyle.whiteSpace;\n f.element.style.display = f.originalStyle.display;\n f.element.style.fontSize = f.originalStyle.fontSize;\n };\n };\n\n // add a new fitty, does not redraw said fitty\n var subscribe = function subscribe(f) {\n return function () {\n if (f.active) return;\n f.active = true;\n requestRedraw();\n };\n };\n\n // remove an existing fitty\n var unsubscribe = function unsubscribe(f) {\n return function () {\n return f.active = false;\n };\n };\n\n var observeMutations = function observeMutations(f) {\n\n // no observing?\n if (!f.observeMutations) return;\n\n // start observing mutations\n f.observer = new MutationObserver(fit(f, DrawState.DIRTY_CONTENT));\n\n // start observing\n f.observer.observe(f.element, f.observeMutations);\n };\n\n // default mutation observer settings\n var mutationObserverDefaultSetting = {\n subtree: true,\n childList: true,\n characterData: true\n };\n\n // default fitty options\n var defaultOptions = {\n minSize: 16,\n maxSize: 512,\n multiLine: true,\n observeMutations: 'MutationObserver' in w ? mutationObserverDefaultSetting : false\n };\n\n // array of elements in, fitty instances out\n function fittyCreate(elements, options) {\n\n // set options object\n var fittyOptions = _extends({}, defaultOptions, options);\n\n // create fitties\n var publicFitties = elements.map(function (element) {\n\n // create fitty instance\n var f = _extends({}, fittyOptions, {\n\n // internal options for this fitty\n element: element,\n active: true\n });\n\n // initialise this fitty\n init(f);\n\n // expose API\n return {\n element: element,\n fit: fit(f, DrawState.DIRTY),\n unfreeze: subscribe(f),\n freeze: unsubscribe(f),\n unsubscribe: destroy(f)\n };\n });\n\n // call redraw on newly initiated fitties\n requestRedraw();\n\n // expose fitties\n return publicFitties;\n }\n\n // fitty creation function\n function fitty(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n\n // if target is a string\n return typeof target === 'string' ?\n\n // treat it as a querySelector\n fittyCreate(toArray(document.querySelectorAll(target)), options) :\n\n // create single fitty\n fittyCreate([target], options)[0];\n }\n\n // handles viewport changes, redraws all fitties, but only does so after a timeout\n var resizeDebounce = null;\n var onWindowResized = function onWindowResized() {\n w.clearTimeout(resizeDebounce);\n resizeDebounce = w.setTimeout(redrawAll(DrawState.DIRTY_LAYOUT), fitty.observeWindowDelay);\n };\n\n // define observe window property, so when we set it to true or false events are automatically added and removed\n var events = ['resize', 'orientationchange'];\n Object.defineProperty(fitty, 'observeWindow', {\n set: function set(enabled) {\n var method = (enabled ? 'add' : 'remove') + 'EventListener';\n events.forEach(function (e) {\n w[method](e, onWindowResized);\n });\n }\n });\n\n // fitty global properties (by setting observeWindow to true the events above get added)\n fitty.observeWindow = true;\n fitty.observeWindowDelay = 100;\n\n // public fit all method, will force redraw no matter what\n fitty.fitAll = redrawAll(DrawState.DIRTY);\n\n // export our fitty function, we don't want to keep it to our selves\n return fitty;\n}(typeof window === 'undefined' ? null : window);","import { extend, queryAll, closest, getMimeTypeFromFile, encodeRFC3986URI } from '../utils/util.js'\nimport { isMobile } from '../utils/device.js'\n\nimport fitty from 'fitty';\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 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// Enable inline video playback in mobile Safari\n\t\t\tif( isMobile && media.tagName === 'VIDEO' ) {\n\t\t\t\tmedia.setAttribute( 'playsinline', '' );\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\t// base64\n\t\t\t\t\tif( /^data:/.test( backgroundImage.trim() ) ) {\n\t\t\t\t\t\tbackgroundContent.style.backgroundImage = `url(${backgroundImage.trim()})`;\n\t\t\t\t\t}\n\t\t\t\t\t// URL(s)\n\t\t\t\t\telse {\n\t\t\t\t\t\tbackgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => {\n\t\t\t\t\t\t\t// Decode URL(s) that are already encoded first\n\t\t\t\t\t\t\tlet decoded = decodeURI(background.trim());\n\t\t\t\t\t\t\treturn `url(${encodeRFC3986URI(decoded)})`;\n\t\t\t\t\t\t}).join( ',' );\n\t\t\t\t\t}\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// Enable inline playback in mobile Safari\n\t\t\t\t\t//\n\t\t\t\t\t// Mute is required for video to play when using\n\t\t\t\t\t// swipe gestures to navigate since they don't\n\t\t\t\t\t// count as direct user actions :'(\n\t\t\t\t\tif( isMobile ) {\n\t\t\t\t\t\tvideo.muted = 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\tlet type = getMimeTypeFromFile( source );\n\t\t\t\t\t\tif( type ) {\n\t\t\t\t\t\t\tvideo.innerHTML += ``;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tvideo.innerHTML += ``;\n\t\t\t\t\t\t}\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\tthis.layout( slide );\n\n\t}\n\n\t/**\n\t * Applies JS-dependent layout helpers for the scope.\n\t */\n\tlayout( scopeElement ) {\n\n\t\t// Autosize text with the r-fit-text class based on the\n\t\t// size of its container. This needs to happen after the\n\t\t// slide is visible in order to measure the text.\n\t\tArray.from( scopeElement.querySelectorAll( '.r-fit-text' ) ).forEach( element => {\n\t\t\tfitty( element, {\n\t\t\t\tminSize: 24,\n\t\t\t\tmaxSize: this.Reveal.getConfig().height * 0.8,\n\t\t\t\tobserveMutations: false,\n\t\t\t\tobserveWindow: false\n\t\t\t} );\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 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( closest( el, '.fragment' ) && !closest( 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' ) || !!closest( 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( closest( el, '.fragment' ) && !closest( 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( closest( el, '.fragment' ) && !closest( 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 = !!closest( event.target, 'html' ),\n\t\t\tisVisible \t\t= !!closest( 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 = !!closest( event.target, 'html' ),\n\t\t\t\tisVisible \t\t= !!closest( 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' ) || !!closest( 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","/**\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\t// Offset the current slide number by 1 to make it 1-indexed\n\t\t\tlet horizontalOffset = slide && slide.dataset.visibility === 'uncounted' ? 0 : 1;\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 ) + horizontalOffset );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'c/t':\n\t\t\t\t\tvalue.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset, '/', 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 + horizontalOffset );\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 `\n\t\t\t\t\t${a} \n\t\t\t\t\t${delimiter} \n\t\t\t\t\t${b} \n\t\t\t\t\t `;\n\t\t}\n\t\telse {\n\t\t\treturn `\n\t\t\t\t\t${a} \n\t\t\t\t\t `;\n\t\t}\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.element.remove();\n\n\t}\n\n}","/**\n * Makes it possible to jump to a slide by entering its\n * slide number or id.\n */\nexport default class JumpToSlide {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.onInput = this.onInput.bind( this );\n\t\tthis.onBlur = this.onBlur.bind( this );\n\t\tthis.onKeyDown = this.onKeyDown.bind( this );\n\n\t}\n\n\trender() {\n\n\t\tthis.element = document.createElement( 'div' );\n\t\tthis.element.className = 'jump-to-slide';\n\n this.jumpInput = document.createElement( 'input' );\n this.jumpInput.type = 'text';\n this.jumpInput.className = 'jump-to-slide-input';\n this.jumpInput.placeholder = 'Jump to slide';\n\t\tthis.jumpInput.addEventListener( 'input', this.onInput );\n\t\tthis.jumpInput.addEventListener( 'keydown', this.onKeyDown );\n\t\tthis.jumpInput.addEventListener( 'blur', this.onBlur );\n\n this.element.appendChild( this.jumpInput );\n\n\t}\n\n\tshow() {\n\n\t\tthis.indicesOnShow = this.Reveal.getIndices();\n\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\t\tthis.jumpInput.focus();\n\n\t}\n\n\thide() {\n\n\t\tif( this.isVisible() ) {\n\t\t\tthis.element.remove();\n\t\t\tthis.jumpInput.value = '';\n\n\t\t\tclearTimeout( this.jumpTimeout );\n\t\t\tdelete this.jumpTimeout;\n\t\t}\n\n\t}\n\n\tisVisible() {\n\n\t\treturn !!this.element.parentNode;\n\n\t}\n\n\t/**\n\t * Parses the current input and jumps to the given slide.\n\t */\n\tjump() {\n\n\t\tclearTimeout( this.jumpTimeout );\n\t\tdelete this.jumpTimeout;\n\n\t\tconst query = this.jumpInput.value.trim( '' );\n\t\tlet indices = this.Reveal.location.getIndicesFromHash( query, { oneBasedIndex: true } );\n\n\t\t// If no valid index was found and the input query is a\n\t\t// string, fall back on a simple search\n\t\tif( !indices && /\\S+/i.test( query ) && query.length > 1 ) {\n\t\t\tindices = this.search( query );\n\t\t}\n\n\t\tif( indices && query !== '' ) {\n\t\t\tthis.Reveal.slide( indices.h, indices.v, indices.f );\n\t\t\treturn true;\n\t\t}\n\t\telse {\n\t\t\tthis.Reveal.slide( this.indicesOnShow.h, this.indicesOnShow.v, this.indicesOnShow.f );\n\t\t\treturn false;\n\t\t}\n\n\t}\n\n\tjumpAfter( delay ) {\n\n\t\tclearTimeout( this.jumpTimeout );\n\t\tthis.jumpTimeout = setTimeout( () => this.jump(), delay );\n\n\t}\n\n\t/**\n\t * A lofi search that looks for the given query in all\n\t * of our slides and returns the first match.\n\t */\n\tsearch( query ) {\n\n\t\tconst regex = new RegExp( '\\\\b' + query.trim() + '\\\\b', 'i' );\n\n\t\tconst slide = this.Reveal.getSlides().find( ( slide ) => {\n\t\t\treturn regex.test( slide.innerText );\n\t\t} );\n\n\t\tif( slide ) {\n\t\t\treturn this.Reveal.getIndices( slide );\n\t\t}\n\t\telse {\n\t\t\treturn null;\n\t\t}\n\n\t}\n\n\t/**\n\t * Reverts back to the slide we were on when jump to slide was\n\t * invoked.\n\t */\n\tcancel() {\n\n\t\tthis.Reveal.slide( this.indicesOnShow.h, this.indicesOnShow.v, this.indicesOnShow.f );\n\t\tthis.hide();\n\n\t}\n\n\tconfirm() {\n\n\t\tthis.jump();\n\t\tthis.hide();\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.jumpInput.removeEventListener( 'input', this.onInput );\n\t\tthis.jumpInput.removeEventListener( 'keydown', this.onKeyDown );\n\t\tthis.jumpInput.removeEventListener( 'blur', this.onBlur );\n\n\t\tthis.element.remove();\n\n\t}\n\n\tonKeyDown( event ) {\n\n\t\tif( event.keyCode === 13 ) {\n\t\t\tthis.confirm();\n\t\t}\n\t\telse if( event.keyCode === 27 ) {\n\t\t\tthis.cancel();\n\n\t\t\tevent.stopImmediatePropagation();\n\t\t}\n\n\t}\n\n\tonInput( event ) {\n\n\t\tthis.jumpAfter( 200 );\n\n\t}\n\n\tonBlur() {\n\n\t\tsetTimeout( () => this.hide(), 1 );\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.slice( 0, 2 ), 16 ),\n\t\t\tg: parseInt( hex6.slice( 2, 4 ), 16 ),\n\t\t\tb: parseInt( hex6.slice( 4, 6 ), 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\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\tconst element = slide.slideBackgroundElement,\n\t\t\tcontentElement = slide.slideBackgroundContentElement;\n\n\t\tconst 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\tbackgroundGradient: slide.getAttribute( 'data-background-gradient' ),\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\tconst dataPreload = slide.hasAttribute( 'data-preload' );\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\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|webp)([?#\\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.backgroundGradient || 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.backgroundGradient +\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.backgroundGradient ) element.style.backgroundImage = data.backgroundGradient;\n\t\tif( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );\n\n\t\tif( dataPreload ) 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, or it cannot be converted by colorToRgb, check the computed background\n\t\tif( !contrastColor || !colorToRgb( 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\tconst 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\tdestroy() {\n\n\t\tthis.element.remove();\n\n\t}\n\n}\n","\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|showPreview/;\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/;","import { queryAll, extend, createStyleSheet, matches, closest } from '../utils/util.js'\nimport { FRAGMENT_STYLE_REGEX } from '../utils/constants.js'\n\n// Counter used to generate unique IDs for auto-animated elements\nlet autoAnimateCounter = 0;\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}\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\tlet allSlides = this.Reveal.getSlides();\n\t\tlet toSlideIndex = allSlides.indexOf( toSlide );\n\t\tlet fromSlideIndex = allSlides.indexOf( fromSlide );\n\n\t\t// Ensure that both slides are auto-animate targets with the same data-auto-animate-id value\n\t\t// (including null if absent on both) and that data-auto-animate-restart isn't set on the\n\t\t// physically latter slide (independent of slide direction)\n\t\tif( fromSlide.hasAttribute( 'data-auto-animate' ) && toSlide.hasAttribute( 'data-auto-animate' )\n\t\t\t\t&& fromSlide.getAttribute( 'data-auto-animate-id' ) === toSlide.getAttribute( 'data-auto-animate-id' ) \n\t\t\t\t&& !( toSlideIndex > fromSlideIndex ? toSlide : fromSlide ).hasAttribute( 'data-auto-animate-restart' ) ) {\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\tanimationOptions.slideDirection = toSlideIndex > fromSlideIndex ? 'forward' : 'backward';\n\n\t\t\t// If the from-slide is hidden because it has moved outside\n\t\t\t// the view distance, we need to temporarily show it while\n\t\t\t// measuring\n\t\t\tlet fromSlideIsHidden = fromSlide.style.display === 'none';\n\t\t\tif( fromSlideIsHidden ) fromSlide.style.display = this.Reveal.getConfig().display;\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, autoAnimateCounter++ );\n\t\t\t} );\n\n\t\t\tif( fromSlideIsHidden ) fromSlide.style.display = 'none';\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-' + 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.parentNode ) {\n\t\t\tlet autoAnimatedParent = closest( element.parentNode, '[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 config = this.Reveal.getConfig();\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\tif( config.center ) {\n\t\t\t\t\t// More precise, but breaks when used in combination\n\t\t\t\t\t// with zoom for scaling the deck ¯\\_(ツ)_/¯\n\t\t\t\t\tbounds = element.getBoundingClientRect();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tlet scale = this.Reveal.getScale();\n\t\t\t\t\tbounds = {\n\t\t\t\t\t\tx: element.offsetLeft * scale,\n\t\t\t\t\t\ty: element.offsetTop * scale,\n\t\t\t\t\t\twidth: element.offsetWidth * scale,\n\t\t\t\t\t\theight: element.offsetHeight * scale\n\t\t\t\t\t};\n\t\t\t\t}\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 || config.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\t// Use a unitless value for line-height so that it inherits properly\n\t\t\t\tif( style.property === 'line-height' ) {\n\t\t\t\t\tvalue = parseFloat( computedStyles['line-height'] ) / parseFloat( computedStyles['font-size'] );\n\t\t\t\t}\n\n\t\t\t\tif( isNaN(value) ) {\n\t\t\t\t\tvalue = computedStyles[style.property];\n\t\t\t\t}\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// Explicit 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\t\t\t// Disable scale transformations on text nodes, we transition\n\t\t\t// each individual text property instead\n\t\t\tif( matches( pair.from, 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( matches( pair.from, 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 primaryIndex = 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][ primaryIndex ] ) {\n\t\t\t\t\tfromElement = fromMatches[key][ primaryIndex ];\n\t\t\t\t\tfromMatches[key][ primaryIndex ] = 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 considered\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}\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\tthis.Reveal.slideContent.stopEmbeddedContent( el );\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 .\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 , Shift SPACE'] = '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['Alt + ←/↑/→/↓'] = 'Navigate without fragments';\n\t\tthis.shortcuts['Shift + ←/↑/→/↓'] = 'Jump to first/last slide';\n\t\tthis.shortcuts['B , .'] = 'Pause';\n\t\tthis.shortcuts['F'] = 'Fullscreen';\n\t\tthis.shortcuts['G'] = 'Jump to slide';\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\tgetShortcuts() {\n\n\t\treturn this.shortcuts;\n\n\t}\n\n\tgetBindings() {\n\n\t\treturn this.bindings;\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// If keyboardCondition is set, only capture keyboard events\n\t\t// for embedded decks when they are focused\n\t\tif( config.keyboardCondition === 'focused' && !this.Reveal.isFocused() ) {\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.isContentEditable === true;\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 certain modifiers for slide navigation shortcuts\n\t\tlet isNavigationKey = [32, 37, 38, 39, 40, 78, 80].indexOf( event.keyCode ) !== -1;\n\n\t\t// Prevent all other events when a modifier is pressed\n\t\tlet unusedModifier = \t!( isNavigationKey && event.shiftKey || event.altKey ) &&\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({skipFragments: event.altKey});\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({skipFragments: event.altKey});\n\t\t\t}\n\t\t\t// H, LEFT\n\t\t\telse if( keyCode === 72 || keyCode === 37 ) {\n\t\t\t\tif( event.shiftKey ) {\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({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.left({skipFragments: event.altKey});\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( event.shiftKey ) {\n\t\t\t\t\tthis.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 );\n\t\t\t\t}\n\t\t\t\telse if( !this.Reveal.overview.isActive() && useLinearMode ) {\n\t\t\t\t\tthis.Reveal.next({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.right({skipFragments: event.altKey});\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( event.shiftKey ) {\n\t\t\t\t\tthis.Reveal.slide( undefined, 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({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.up({skipFragments: event.altKey});\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( event.shiftKey ) {\n\t\t\t\t\tthis.Reveal.slide( undefined, 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({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.down({skipFragments: event.altKey});\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( this.Reveal.getHorizontalSlides().length - 1 );\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({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.next({skipFragments: event.altKey});\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( config.embedded ? this.Reveal.getViewportElement() : document.documentElement );\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\t// G\n\t\t\telse if( keyCode === 71 ) {\n\t\t\t\tif ( config.jumpToSlide ) {\n\t\t\t\t\tthis.Reveal.toggleJumpToSlide();\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}","/**\n * Reads and writes the URL based on reveal.js' current state.\n */\nexport default class Location {\n\n\t// The minimum number of milliseconds that must pass between\n\t// calls to history.replaceState\n\tMAX_REPLACE_STATE_FREQUENCY = 1000\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\tthis.replaceStateTimestamp = 0;\n\n\t\tthis.onWindowHashChange = this.onWindowHashChange.bind( this );\n\n\t}\n\n\tbind() {\n\n\t\twindow.addEventListener( 'hashchange', this.onWindowHashChange, false );\n\n\t}\n\n\tunbind() {\n\n\t\twindow.removeEventListener( 'hashchange', this.onWindowHashChange, false );\n\n\t}\n\n\t/**\n\t * Returns the slide indices for the given hash link.\n\t *\n\t * @param {string} [hash] the hash string that we want to\n\t * find the indices for\n\t *\n\t * @returns slide indices or null\n\t */\n\tgetIndicesFromHash( hash=window.location.hash, options={} ) {\n\n\t\t// Attempt to parse the hash as either an index or name\n\t\tlet name = hash.replace( /^#\\/?/, '' );\n\t\tlet bits = name.split( '/' );\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\tlet f;\n\n\t\t\t// Parse named links with fragments (#/named-link/2)\n\t\t\tif( /\\/[-\\d]+$/g.test( name ) ) {\n\t\t\t\tf = parseInt( name.split( '/' ).pop(), 10 );\n\t\t\t\tf = isNaN(f) ? undefined : f;\n\t\t\t\tname = name.split( '/' ).shift();\n\t\t\t}\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\tif( element ) {\n\t\t\t\treturn { ...this.Reveal.getIndices( element ), f };\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tconst config = this.Reveal.getConfig();\n\t\t\tlet hashIndexBase = config.hashOneBasedIndex || options.oneBasedIndex ? 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\treturn { h, v, f };\n\t\t}\n\n\t\t// The hash couldn't be parsed or no matching named link was found\n\t\treturn null\n\n\t}\n\n\t/**\n\t * Reads the current URL (hash) and navigates accordingly.\n\t */\n\treadURL() {\n\n\t\tconst currentIndices = this.Reveal.getIndices();\n\t\tconst newIndices = this.getIndicesFromHash();\n\n\t\tif( newIndices ) {\n\t\t\tif( ( newIndices.h !== currentIndices.h || newIndices.v !== currentIndices.v || newIndices.f !== undefined ) ) {\n\t\t\t\t\tthis.Reveal.slide( newIndices.h, newIndices.v, newIndices.f );\n\t\t\t}\n\t\t}\n\t\t// If no new indices are available, we're trying to navigate to\n\t\t// a slide hash that does not exist\n\t\telse {\n\t\t\tthis.Reveal.slide( currentIndices.h || 0, currentIndices.v || 0 );\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\n\t\t\tlet hash = this.getHash();\n\n\t\t\t// If we're configured to push to history OR the history\n\t\t\t// API is not available.\n\t\t\tif( config.history ) {\n\t\t\t\twindow.location.hash = hash;\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\t// If the hash is empty, don't add it to the URL\n\t\t\t\tif( hash === '/' ) {\n\t\t\t\t\tthis.debouncedReplaceState( window.location.pathname + window.location.search );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.debouncedReplaceState( '#' + hash );\n\t\t\t\t}\n\t\t\t}\n\t\t\t// UPDATE: The below nuking of all hash changes breaks\n\t\t\t// anchors on pages where reveal.js is running. Removed\n\t\t\t// in 4.0. Why was it here in the first place? ¯\\_(ツ)_/¯\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\t// else {\n\t\t\t// \twindow.history.replaceState( null, null, window.location.pathname + window.location.search );\n\t\t\t// }\n\n\t\t}\n\n\t}\n\n\treplaceState( url ) {\n\n\t\twindow.history.replaceState( null, null, url );\n\t\tthis.replaceStateTimestamp = Date.now();\n\n\t}\n\n\tdebouncedReplaceState( url ) {\n\n\t\tclearTimeout( this.replaceStateTimeout );\n\n\t\tif( Date.now() - this.replaceStateTimestamp > this.MAX_REPLACE_STATE_FREQUENCY ) {\n\t\t\tthis.replaceState( url );\n\t\t}\n\t\telse {\n\t\t\tthis.replaceStateTimeout = setTimeout( () => this.replaceState( url ), this.MAX_REPLACE_STATE_FREQUENCY );\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 ) {\n\t\t\turl = '/' + id;\n\n\t\t\t// If there is also a fragment, append that at the end\n\t\t\t// of the named link, like: #/named-link/2\n\t\t\tif( index.f >= 0 ) url += '/' + index.f;\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 >= 0 ) url += index.h + hashIndexBase;\n\t\t\tif( index.v > 0 || index.f >= 0 ) url += '/' + (index.v + hashIndexBase );\n\t\t\tif( index.f >= 0 ) url += '/' + index.f;\n\t\t}\n\n\t\treturn url;\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\tonWindowHashChange( event ) {\n\n\t\tthis.readURL();\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`
\n\t\t\t
\n\t\t\t
\n\t\t\t
`;\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\tdestroy() {\n\n\t\tthis.unbind();\n\t\tthis.element.remove();\n\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\tlet scale = this.Reveal.getProgress();\n\n\t\t\t// Don't fill the progress bar if there's only one slide\n\t\t\tif( this.Reveal.getTotalSlides() < 2 ) {\n\t\t\t\tscale = 0;\n\t\t\t}\n\n\t\t\tthis.bar.style.transform = 'scaleX('+ scale +')';\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 slides = this.Reveal.getSlides();\n\t\tlet slidesTotal = slides.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\tlet targetIndices = this.Reveal.getIndices(slides[slideIndex]);\n\t\tthis.Reveal.slide( targetIndices.h, targetIndices.v );\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.element.remove();\n\n\t}\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\tdestroy() {\n\n\t\tthis.showCursor();\n\n\t\tdocument.removeEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false );\n\t\tdocument.removeEventListener( 'mousewheel', this.onDocumentMouseScroll, false );\n\t\tdocument.removeEventListener( 'mousemove', this.onDocumentCursorActive, false );\n\t\tdocument.removeEventListener( 'mousedown', this.onDocumentCursorActive, false );\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 \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 registered 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 registered 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\t\t// Plugin can optionally be a function which we call\n\t\t// to create an instance of the plugin\n\t\telse if( typeof plugin === 'function' ) {\n\t\t\tplugin = plugin();\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\tdestroy() {\n\n\t\tObject.values( this.registeredPlugins ).forEach( plugin => {\n\t\t\tif( typeof plugin.destroy === 'function' ) {\n\t\t\t\tplugin.destroy();\n\t\t\t}\n\t\t} );\n\n\t\tthis.registeredPlugins = {};\n\t\tthis.asyncDependencies = [];\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\tasync setupPDF() {\n\n\t\tconst config = this.Reveal.getConfig();\n\t\tconst slides = queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR )\n\n\t\t// Compute slide numbers now, before we start duplicating slides\n\t\tconst injectPageNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber );\n\n\t\tconst slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );\n\n\t\t// Dimensions of the PDF pages\n\t\tconst 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\tconst slideWidth = slideSize.width,\n\t\t\tslideHeight = slideSize.height;\n\n\t\tawait new Promise( requestAnimationFrame );\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\tconst viewportElement = document.querySelector( '.reveal-viewport' );\n\t\tlet presentationBackground;\n\t\tif( viewportElement ) {\n\t\t\tconst viewportStyles = window.getComputedStyle( viewportElement );\n\t\t\tif( viewportStyles && viewportStyles.background ) {\n\t\t\t\tpresentationBackground = viewportStyles.background;\n\t\t\t}\n\t\t}\n\n\t\t// Make sure stretch elements fit on slide\n\t\tawait new Promise( requestAnimationFrame );\n\t\tthis.Reveal.layoutSlideContents( slideWidth, slideHeight );\n\n\t\t// Batch scrollHeight access to prevent layout thrashing\n\t\tawait new Promise( requestAnimationFrame );\n\n\t\tconst slideScrollHeights = slides.map( slide => slide.scrollHeight );\n\n\t\tconst pages = [];\n\t\tconst pageContainer = slides[0].parentNode;\n\t\tlet slideNumber = 1;\n\n\t\t// Slide and slide background layout\n\t\tslides.forEach( function( slide, index ) {\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\tlet top = ( pageHeight - slideHeight ) / 2;\n\n\t\t\t\tconst contentHeight = slideScrollHeights[ index ];\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\tconst page = document.createElement( 'div' );\n\t\t\t\tpages.push( page );\n\n\t\t\t\tpage.className = 'pdf-page';\n\t\t\t\tpage.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px';\n\n\t\t\t\t// Copy the presentation-wide background to each individual\n\t\t\t\t// page when printing\n\t\t\t\tif( presentationBackground ) {\n\t\t\t\t\tpage.style.background = presentationBackground;\n\t\t\t\t}\n\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\tthis.Reveal.slideContent.layout( slide );\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\tconst notes = this.Reveal.getSlideNotes( slide );\n\t\t\t\t\tif( notes ) {\n\n\t\t\t\t\t\tconst notesSpacing = 8;\n\t\t\t\t\t\tconst notesLayout = typeof config.showNotes === 'string' ? config.showNotes : 'inline';\n\t\t\t\t\t\tconst 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\tpages.push( notesElement );\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 page numbers if `slideNumbers` are enabled\n\t\t\t\tif( injectPageNumbers ) {\n\t\t\t\t\tconst 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 = slideNumber++;\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\tconst fragmentGroups = this.Reveal.fragments.sort( page.querySelectorAll( '.fragment' ), true );\n\n\t\t\t\t\tlet previousFragmentStep;\n\n\t\t\t\t\tfragmentGroups.forEach( function( fragments, index ) {\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\tconst clonedPage = page.cloneNode( true );\n\n\t\t\t\t\t\t// Inject unique page numbers for fragments\n\t\t\t\t\t\tif( injectPageNumbers ) {\n\t\t\t\t\t\t\tconst numberElement = clonedPage.querySelector( '.slide-number-pdf' );\n\t\t\t\t\t\t\tconst fragmentNumber = index + 1;\n\t\t\t\t\t\t\tnumberElement.innerHTML += '.' + fragmentNumber;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tpages.push( clonedPage );\n\n\t\t\t\t\t\tpreviousFragmentStep = fragments;\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\tawait new Promise( requestAnimationFrame );\n\n\t\tpages.forEach( page => pageContainer.appendChild( page ) );\n\n\t\t// Re-run JS-based content layout after the slide is added to page DOM\n\t\tthis.Reveal.slideContent.layout( this.Reveal.getSlidesElement() );\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}\n","import { isAndroid } from '../utils/device.js'\nimport { matches } from '../utils/util.js'\n\nconst 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\tlet 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\tlet 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\t// Prevent accidental swipes when scrubbing timelines\n\t\tif( matches( target, 'video, audio' ) ) return true;\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 availableRoutes = this.Reveal.availableRoutes({ includeFragments: true });\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 && availableRoutes.up ) {\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 && availableRoutes.down ) {\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() ) {\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}","import { closest } from '../utils/util.js'\n\n/**\n * Manages focus when a presentation is embedded. This\n * helps us only capture keyboard from the presentation\n * a user is currently interacting with in a page where\n * multiple presentations are embedded.\n */\n\nconst STATE_FOCUS = 'focus';\nconst STATE_BLUR = 'blur';\n\nexport default class Focus {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.onRevealPointerDown = this.onRevealPointerDown.bind( this );\n\t\tthis.onDocumentPointerDown = this.onDocumentPointerDown.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.embedded ) {\n\t\t\tthis.blur();\n\t\t}\n\t\telse {\n\t\t\tthis.focus();\n\t\t\tthis.unbind();\n\t\t}\n\n\t}\n\n\tbind() {\n\n\t\tif( this.Reveal.getConfig().embedded ) {\n\t\t\tthis.Reveal.getRevealElement().addEventListener( 'pointerdown', this.onRevealPointerDown, false );\n\t\t}\n\n\t}\n\n\tunbind() {\n\n\t\tthis.Reveal.getRevealElement().removeEventListener( 'pointerdown', this.onRevealPointerDown, false );\n\t\tdocument.removeEventListener( 'pointerdown', this.onDocumentPointerDown, false );\n\n\t}\n\n\tfocus() {\n\n\t\tif( this.state !== STATE_FOCUS ) {\n\t\t\tthis.Reveal.getRevealElement().classList.add( 'focused' );\n\t\t\tdocument.addEventListener( 'pointerdown', this.onDocumentPointerDown, false );\n\t\t}\n\n\t\tthis.state = STATE_FOCUS;\n\n\t}\n\n\tblur() {\n\n\t\tif( this.state !== STATE_BLUR ) {\n\t\t\tthis.Reveal.getRevealElement().classList.remove( 'focused' );\n\t\t\tdocument.removeEventListener( 'pointerdown', this.onDocumentPointerDown, false );\n\t\t}\n\n\t\tthis.state = STATE_BLUR;\n\n\t}\n\n\tisFocused() {\n\n\t\treturn this.state === STATE_FOCUS;\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.Reveal.getRevealElement().classList.remove( 'focused' );\n\n\t}\n\n\tonRevealPointerDown( event ) {\n\n\t\tthis.focus();\n\n\t}\n\n\tonDocumentPointerDown( event ) {\n\n\t\tlet revealElement = closest( event.target, '.reveal' );\n\t\tif( !revealElement || revealElement !== this.Reveal.getRevealElement() ) {\n\t\t\tthis.blur();\n\t\t}\n\n\t}\n\n}","/**\n * Handles the showing of speaker notes\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() || 'No notes on this slide. ';\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() && !this.Reveal.print.isPrintingPDF() ) {\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 \n\t * 2. With elements inside 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 elements\n\t\tlet notesElements = slide.querySelectorAll( 'aside.notes' );\n\t\tif( notesElements ) {\n\t\t\treturn Array.from(notesElements).map( notesElement => notesElement.innerHTML ).join( '\\n' );\n\t\t}\n\n\t\treturn null;\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.element.remove();\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// Flags if we should monitor the hash and change slides accordingly\n\trespondToHashChanges: true,\n\n\t// Enable support for jump-to-slide navigation shortcuts\n\tjumpToSlide: true,\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\t//\n\t// If you set this to 'focused', we will only capture keyboard events\n\t// for embedded decks when they are in focus\n\tkeyboardCondition: null,\n\n\t// Disables the default reveal.js slide layout (scaling and centering)\n\t// so that you can use custom CSS layout\n\tdisableLayout: false,\n\n\t// Enable the slide overview mode\n\toverview: true,\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: true,\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// Flags if slides with data-visibility=\"hidden\" should be kep visible\n\tshowHiddenSlides: false,\n\n\t// Global override for autoplaying 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// Should we automatmically sort and set indices for fragments\n\t// at each sync? (See Reveal.sync)\n\tsortFragmentsOnSync: true,\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 JumpToSlide from './controllers/jumptoslide.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 Focus from './controllers/focus.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// The reveal.js version\nexport const VERSION = '4.5.0';\n\n/**\n * reveal.js\n * https://revealjs.com\n * MIT licensed\n *\n * Copyright (C) 2011-2022 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// 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\tjumpToSlide = new JumpToSlide( 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\tfocus = new Focus( 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\tif( !revealElement ) throw 'Unable to find presentation root ().';\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\tif( !dom.slides ) throw 'Unable to find slides container (
).';\n\n\t\t// Compose our config object in order of increasing precedence:\n\t\t// 1. Default reveal.js options\n\t\t// 2. Options provided via Reveal.configure() prior to\n\t\t// initialization\n\t\t// 3. Options passed to the Reveal constructor\n\t\t// 4. Options passed to Reveal.initialize\n\t\t// 5. Query params\n\t\tconfig = { ...defaultConfig, ...config, ...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\tdom.viewport = Util.closest( revealElement, '.reveal-viewport' ) || revealElement;\n\t\t}\n\t\t// Full-page decks use the body as their viewport\n\t\telse {\n\t\t\tdom.viewport = document.body;\n\t\t\tdocument.documentElement.classList.add( 'reveal-full-page' );\n\t\t}\n\n\t\tdom.viewport.classList.add( 'reveal-viewport' );\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// Remove slides hidden with data-visibility\n\t\tremoveHiddenSlides();\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// Adds bindings for fullscreen mode\n\t\tsetupFullscreen();\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', () => {\n\t\t\t\t\tprint.setupPDF();\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Removes all slides with data-visibility=\"hidden\". This\n\t * is done right before the rest of the presentation is\n\t * initialized.\n\t *\n\t * If you want to show all hidden slides, initialize\n\t * reveal.js with showHiddenSlides set to true.\n\t */\n\tfunction removeHiddenSlides() {\n\n\t\tif( !config.showHiddenSlides ) {\n\t\t\tUtil.queryAll( dom.wrapper, 'section[data-visibility=\"hidden\"]' ).forEach( slide => {\n\t\t\t\tslide.parentNode.removeChild( slide );\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\tjumpToSlide.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 ? '
Resume presentation ' : 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 * After entering fullscreen we need to force a layout to\n\t * get our presentations to scale correctly. This behavior\n\t * is inconsistent across browsers but a force layout seems\n\t * to normalize it.\n\t */\n\tfunction setupFullscreen() {\n\n\t\tdocument.addEventListener( 'fullscreenchange', onFullscreenChange );\n\t\tdocument.addEventListener( 'webkitfullscreenchange', onFullscreenChange );\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', onPostMessage, 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\t// Expose our configured slide dimensions as custom props\n\t\tdom.viewport.style.setProperty( '--slide-width', config.width + 'px' );\n\t\tdom.viewport.style.setProperty( '--slide-height', config.height + 'px' );\n\n\t\tif( config.shuffle ) {\n\t\t\tshuffle();\n\t\t}\n\n\t\tUtil.toggleClass( dom.wrapper, 'embedded', config.embedded );\n\t\tUtil.toggleClass( dom.wrapper, 'rtl', config.rtl );\n\t\tUtil.toggleClass( dom.wrapper, 'center', config.center );\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\tfocus.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( '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\tif( config.respondToHashChanges ) location.bind();\n\t\tcontrols.bind();\n\t\tfocus.bind();\n\n\t\tdom.slides.addEventListener( 'click', onSlidesClicked, false );\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\tfocus.unbind();\n\t\tkeyboard.unbind();\n\t\tcontrols.unbind();\n\t\tprogress.unbind();\n\t\tlocation.unbind();\n\n\t\twindow.removeEventListener( 'resize', onWindowResize, false );\n\n\t\tdom.slides.removeEventListener( 'click', onSlidesClicked, false );\n\t\tdom.slides.removeEventListener( 'transitionend', onTransitionEnd, false );\n\t\tdom.pauseOverlay.removeEventListener( 'click', resume, false );\n\n\t}\n\n\t/**\n\t * Uninitializes reveal.js by undoing changes made to the\n\t * DOM and removing all event listeners.\n\t */\n\tfunction destroy() {\n\n\t\tremoveEventListeners();\n\t\tcancelAutoSlide();\n\t\tdisablePreviewLinks();\n\n\t\t// Destroy controllers\n\t\tnotes.destroy();\n\t\tfocus.destroy();\n\t\tplugins.destroy();\n\t\tpointer.destroy();\n\t\tcontrols.destroy();\n\t\tprogress.destroy();\n\t\tbackgrounds.destroy();\n\t\tslideNumber.destroy();\n\t\tjumpToSlide.destroy();\n\n\t\t// Remove event listeners\n\t\tdocument.removeEventListener( 'fullscreenchange', onFullscreenChange );\n\t\tdocument.removeEventListener( 'webkitfullscreenchange', onFullscreenChange );\n\t\tdocument.removeEventListener( 'visibilitychange', onPageVisibilityChange, false );\n\t\twindow.removeEventListener( 'message', onPostMessage, false );\n\t\twindow.removeEventListener( 'load', layout, false );\n\n\t\t// Undo DOM changes\n\t\tif( dom.pauseOverlay ) dom.pauseOverlay.remove();\n\t\tif( dom.statusElement ) dom.statusElement.remove();\n\n\t\tdocument.documentElement.classList.remove( 'reveal-full-page' );\n\n\t\tdom.wrapper.classList.remove( 'ready', 'center', 'has-horizontal-slides', 'has-vertical-slides' );\n\t\tdom.wrapper.removeAttribute( 'data-transition-speed' );\n\t\tdom.wrapper.removeAttribute( 'data-background-transition' );\n\n\t\tdom.viewport.classList.remove( 'reveal-viewport' );\n\t\tdom.viewport.style.removeProperty( '--slide-width' );\n\t\tdom.viewport.style.removeProperty( '--slide-height' );\n\n\t\tdom.slides.style.removeProperty( 'width' );\n\t\tdom.slides.style.removeProperty( 'height' );\n\t\tdom.slides.style.removeProperty( 'zoom' );\n\t\tdom.slides.style.removeProperty( 'left' );\n\t\tdom.slides.style.removeProperty( 'top' );\n\t\tdom.slides.style.removeProperty( 'bottom' );\n\t\tdom.slides.style.removeProperty( 'right' );\n\t\tdom.slides.style.removeProperty( 'transform' );\n\n\t\tArray.from( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( slide => {\n\t\t\tslide.style.removeProperty( 'display' );\n\t\t\tslide.style.removeProperty( 'top' );\n\t\t\tslide.removeAttribute( 'hidden' );\n\t\t\tslide.removeAttribute( 'aria-hidden' );\n\t\t} );\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\treturn event;\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`
\n\t\t\t\t \n\t\t\t\t \n\t\t\t \n\t\t\t
\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\tUnable to load iframe. This is likely due to the site's policy (x-frame-options). \n\t\t\t\t \n\t\t\t
`;\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 = '
Keyboard Shortcuts
';\n\n\t\t\tlet shortcuts = keyboard.getShortcuts(),\n\t\t\t\tbindings = keyboard.getBindings();\n\n\t\t\thtml += '
KEY ACTION ';\n\t\t\tfor( let key in shortcuts ) {\n\t\t\t\thtml += `${key} ${shortcuts[ key ]} `;\n\t\t\t}\n\n\t\t\t// Add custom key bindings that have associated descriptions\n\t\t\tfor( let binding in bindings ) {\n\t\t\t\tif( bindings[binding].key && bindings[binding].description ) {\n\t\t\t\t\thtml += `${bindings[binding].key} ${bindings[binding].description} `;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\thtml += '
';\n\n\t\t\tdom.overlay.innerHTML = `\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
${html}
\n\t\t\t\t
\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 && !config.embedded ) {\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\tdom.slides.style.zoom = '';\n\t\t\t\t\tdom.slides.style.left = '50%';\n\t\t\t\t\tdom.slides.style.top = '50%';\n\t\t\t\t\tdom.slides.style.bottom = 'auto';\n\t\t\t\t\tdom.slides.style.right = 'auto';\n\t\t\t\t\ttransformSlides( { layout: 'translate(-50%, -50%) scale('+ scale +')' } );\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\tdom.viewport.style.setProperty( '--slide-scale', scale );\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 'r-stretch' class\n\t\tUtil.queryAll( dom.slides, 'section > .stretch, section > .r-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\t\tlet width = config.width;\n\t\tlet height = config.height;\n\n\t\tif( config.disableLayout ) {\n\t\t\twidth = dom.slides.offsetWidth;\n\t\t\theight = dom.slides.offsetHeight;\n\t\t}\n\n\t\tconst size = {\n\t\t\t// Slide size\n\t\t\twidth: width,\n\t\t\theight: 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 visibility of the jump-to-slide UI.\n\t */\n\tfunction toggleJumpToSlide( override ) {\n\n\t\tif( typeof override === 'boolean' ) {\n\t\t\toverride ? jumpToSlide.show() : jumpToSlide.hide();\n\t\t}\n\t\telse {\n\t\t\tjumpToSlide.isVisible() ? jumpToSlide.hide() : jumpToSlide.show();\n\t\t}\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} [origin] Origin for use in multimaster environments\n\t */\n\tfunction slide( h, v, f, origin ) {\n\n\t\t// Dispatch an event before the slide\n\t\tconst slidechange = dispatchEvent({\n\t\t\ttype: 'beforeslidechange',\n\t\t\tdata: {\n\t\t\t\tindexh: h === undefined ? indexh : h,\n\t\t\t\tindexv: v === undefined ? indexv : v,\n\t\t\t\torigin\n\t\t\t}\n\t\t});\n\n\t\t// Abort if this slide change was prevented by an event listener\n\t\tif( slidechange.defaultPrevented ) return;\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\t\t&& previousSlide.getAttribute( 'data-auto-animate-id' ) === currentSlide.getAttribute( 'data-auto-animate-id' )\n\t\t\t\t\t&& !( ( indexh > indexhBefore || indexv > indexvBefore ) ? currentSlide : previousSlide ).hasAttribute( 'data-auto-animate-restart' ) ) {\n\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\tdom.viewport.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\tdom.viewport.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\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\t// Use animation frame to prevent getComputedStyle in getStatusText\n\t\t// from triggering layout mid-frame\n\t\trequestAnimationFrame( () => {\n\t\t\tannounceStatus( getStatusText( currentSlide ) );\n\t\t});\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\tif( config.sortFragmentsOnSync === true ) {\n\t\t\tfragments.sortAll();\n\t\t}\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( slides = getHorizontalSlides() ) {\n\n\t\tslides.forEach( ( slide, i ) => {\n\n\t\t\t// Insert the slide next to a randomly picked sibling slide\n\t\t\t// slide. This may cause the slide to insert before itself,\n\t\t\t// but that's not an issue.\n\t\t\tlet beforeSlide = slides[ Math.floor( Math.random() * slides.length ) ];\n\t\t\tif( beforeSlide.parentNode === slide.parentNode ) {\n\t\t\t\tslide.parentNode.insertBefore( slide, beforeSlide );\n\t\t\t}\n\n\t\t\t// Randomize the order of vertical slides (if there are any)\n\t\t\tlet verticalSlides = slide.querySelectorAll( 'section' );\n\t\t\tif( verticalSlides.length ) {\n\t\t\t\tshuffle( verticalSlides );\n\t\t\t}\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\t\tlet loopedForwards = false;\n\t\tlet loopedBackwards = false;\n\n\t\tif( slidesLength ) {\n\n\t\t\t// Should the index loop?\n\t\t\tif( config.loop ) {\n\t\t\t\tif( index >= slidesLength ) loopedForwards = true;\n\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\tloopedBackwards = true;\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\t// Avoid .remove() with multiple args for IE11 support\n\t\t\t\telement.classList.remove( 'past' );\n\t\t\t\telement.classList.remove( 'present' );\n\t\t\t\telement.classList.remove( '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\tshowFragmentsIn( element );\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\thideFragmentsIn( element );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Update the visibility of fragments when a presentation loops\n\t\t\t\t// in either direction\n\t\t\t\telse if( i === index && config.fragments ) {\n\t\t\t\t\tif( loopedForwards ) {\n\t\t\t\t\t\thideFragmentsIn( element );\n\t\t\t\t\t}\n\t\t\t\t\telse if( loopedBackwards ) {\n\t\t\t\t\t\tshowFragmentsIn( element );\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 * Shows all fragment elements within the given contaienr.\n\t */\n\tfunction showFragmentsIn( container ) {\n\n\t\tUtil.queryAll( container, '.fragment' ).forEach( fragment => {\n\t\t\tfragment.classList.add( 'visible' );\n\t\t\tfragment.classList.remove( 'current-fragment' );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Hides all fragment elements within the given contaienr.\n\t */\n\tfunction hideFragmentsIn( container ) {\n\n\t\tUtil.queryAll( container, '.fragment.visible' ).forEach( fragment => {\n\t\t\tfragment.classList.remove( 'visible', 'current-fragment' );\n\t\t} );\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({ includeFragments = false } = {}) {\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// If includeFragments is set, a route will be considered\n\t\t// available if either a slid OR fragment is available in\n\t\t// the given direction\n\t\tif( includeFragments === true ) {\n\t\t\tlet fragmentRoutes = fragments.availableRoutes();\n\t\t\troutes.left = routes.left || fragmentRoutes.prev;\n\t\t\troutes.up = routes.up || fragmentRoutes.prev;\n\t\t\troutes.down = routes.down || fragmentRoutes.next;\n\t\t\troutes.right = routes.right || fragmentRoutes.next;\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\n\t\t\t\t// If there are media elements with data-autoplay,\n\t\t\t\t// automatically set the autoSlide duration to the\n\t\t\t\t// length of that media. Not applicable if the slide\n\t\t\t\t// is divided up into fragments.\n\t\t\t\t// playbackRate is accounted for in the duration.\n\t\t\t\tif( currentSlide.querySelectorAll( '.fragment' ).length === 0 ) {\n\t\t\t\t\tUtil.queryAll( currentSlide, 'video, audio' ).forEach( el => {\n\t\t\t\t\t\tif( el.hasAttribute( 'data-autoplay' ) ) {\n\t\t\t\t\t\t\tif( autoSlide && (el.duration * 1000 / el.playbackRate ) > autoSlide ) {\n\t\t\t\t\t\t\t\tautoSlide = ( el.duration * 1000 / el.playbackRate ) + 1000;\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}\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({skipFragments=false}={}) {\n\n\t\tnavigationHistory.hasNavigatedHorizontally = true;\n\n\t\t// Reverse for RTL\n\t\tif( config.rtl ) {\n\t\t\tif( ( overview.isActive() || skipFragments || 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() || skipFragments || 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({skipFragments=false}={}) {\n\n\t\tnavigationHistory.hasNavigatedHorizontally = true;\n\n\t\t// Reverse for RTL\n\t\tif( config.rtl ) {\n\t\t\tif( ( overview.isActive() || skipFragments || 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() || skipFragments || 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({skipFragments=false}={}) {\n\n\t\t// Prioritize hiding fragments\n\t\tif( ( overview.isActive() || skipFragments || fragments.prev() === false ) && availableRoutes().up ) {\n\t\t\tslide( indexh, indexv - 1 );\n\t\t}\n\n\t}\n\n\tfunction navigateDown({skipFragments=false}={}) {\n\n\t\tnavigationHistory.hasNavigatedVertically = true;\n\n\t\t// Prioritize revealing fragments\n\t\tif( ( overview.isActive() || skipFragments || 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({skipFragments=false}={}) {\n\n\t\t// Prioritize revealing fragments\n\t\tif( skipFragments || fragments.prev() === false ) {\n\t\t\tif( availableRoutes().up ) {\n\t\t\t\tnavigateUp({skipFragments});\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\t// When going backwards and arriving on a stack we start\n\t\t\t\t// at the bottom of the stack\n\t\t\t\tif( previousSlide && previousSlide.classList.contains( 'stack' ) ) {\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\telse {\n\t\t\t\t\tnavigateLeft({skipFragments});\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({skipFragments=false}={}) {\n\n\t\tnavigationHistory.hasNavigatedHorizontally = true;\n\t\tnavigationHistory.hasNavigatedVertically = true;\n\n\t\t// Prioritize revealing fragments\n\t\tif( skipFragments || 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() ) {\n\t\t\t\troutes.down = false;\n\t\t\t}\n\n\t\t\tif( routes.down ) {\n\t\t\t\tnavigateDown({skipFragments});\n\t\t\t}\n\t\t\telse if( config.rtl ) {\n\t\t\t\tnavigateLeft({skipFragments});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnavigateRight({skipFragments});\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* Listener for post message events posted to this window.\n\t*/\n\tfunction onPostMessage( event ) {\n\n\t\tlet data = event.data;\n\n\t\t// Make sure we're dealing with JSON\n\t\tif( typeof data === 'string' && data.charAt( 0 ) === '{' && data.charAt( data.length - 1 ) === '}' ) {\n\t\t\tdata = JSON.parse( data );\n\n\t\t\t// Check if the requested method can be found\n\t\t\tif( data.method && typeof Reveal[data.method] === 'function' ) {\n\n\t\t\t\tif( POST_MESSAGE_METHOD_BLACKLIST.test( data.method ) === false ) {\n\n\t\t\t\t\tconst result = Reveal[data.method].apply( Reveal, data.args );\n\n\t\t\t\t\t// Dispatch a postMessage event with the returned value from\n\t\t\t\t\t// our method invocation for getter functions\n\t\t\t\t\tdispatchPostMessage( 'callback', { method: data.method, result: result } );\n\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tconsole.warn( 'reveal.js: \"'+ data.method +'\" is is blacklisted from the postMessage API' );\n\t\t\t\t}\n\n\t\t\t}\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 * A global listener for all click events inside of the\n\t * .slides container.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onSlidesClicked( event ) {\n\n\t\tconst anchor = Util.closest( event.target, 'a[href^=\"#\"]' );\n\n\t\t// If a hash link is clicked, we find the target slide\n\t\t// and navigate to it. We previously relied on 'hashchange'\n\t\t// for links like these but that prevented media with\n\t\t// audio tracks from playing in mobile browsers since it\n\t\t// wasn't considered a direct interaction with the document.\n\t\tif( anchor ) {\n\t\t\tconst hash = anchor.getAttribute( 'href' );\n\t\t\tconst indices = location.getIndicesFromHash( hash );\n\n\t\t\tif( indices ) {\n\t\t\t\tReveal.slide( indices.h, indices.v, indices.f );\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t}\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 * Handler for the document level 'fullscreenchange' event.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onFullscreenChange( event ) {\n\n\t\tlet element = document.fullscreenElement || document.webkitFullscreenElement;\n\t\tif( element === dom.wrapper ) {\n\t\t\tevent.stopImmediatePropagation();\n\n\t\t\t// Timeout to avoid layout shift in Safari\n\t\t\tsetTimeout( () => {\n\t\t\t\tReveal.layout();\n\t\t\t\tReveal.focus.focus(); // focus.focus :'(\n\t\t\t}, 1 );\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\t\tdestroy,\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// Toggles visibility of the jump-to-slide UI\n\t\ttoggleJumpToSlide,\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\tisFocused: focus.isFocused.bind( focus ),\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// Preview management\n\t\tshowPreview,\n\t\thidePreview: closeOverlay,\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 the path to the current slide as represented in the URL\n\t\tgetSlidePath: location.getHash.bind( location ),\n\n\t\t// Returns reveal.js DOM elements\n\t\tgetRevealElement: () => revealElement,\n\t\tgetSlidesElement: () => dom.slides,\n\t\tgetViewportElement: () => dom.viewport,\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\tfocus,\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, { VERSION } 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 */\nlet 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 one 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 premature API calls and invoking all\n * of them when Reveal.initialize is called.\n */\n[ 'configure', '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\nReveal.isReady = () => false;\n\nReveal.VERSION = VERSION;\n\nexport default Reveal;"],"names":["extend","a","b","i","queryAll","el","selector","Array","from","querySelectorAll","toggleClass","className","value","classList","add","remove","deserialize","match","parseFloat","transformElement","element","transform","style","matches","target","matchesMethod","matchesSelector","msMatchesSelector","call","closest","parentNode","createSingletonNode","container","tagname","classname","innerHTML","nodes","length","testNode","node","document","createElement","appendChild","createStyleSheet","tag","type","styleSheet","cssText","createTextNode","head","getQueryHash","query","location","search","replace","split","shift","pop","unescape","getRemainingHeight","height","newHeight","oldHeight","offsetHeight","removeProperty","fileExtensionToMimeMap","UA","navigator","userAgent","isMobile","test","platform","maxTouchPoints","isAndroid","Object","defineProperty","fitty_module","_extends","assign","arguments","source","key","prototype","hasOwnProperty","w","toArray","nl","slice","DrawState","fitties","redrawFrame","requestRedraw","cancelAnimationFrame","requestAnimationFrame","redraw","filter","f","dirty","active","redrawAll","forEach","styleComputed","computeStyle","shouldPreStyle","applyStyle","fittiesToRedraw","shouldRedraw","calculateStyles","markAsClean","dispatchFitEvent","availableWidth","clientWidth","currentWidth","scrollWidth","previousFontSize","currentFontSize","Math","min","max","minSize","maxSize","whiteSpace","multiLine","getComputedStyle","getPropertyValue","display","preStyle","preStyleTestCompleted","fontSize","dispatchEvent","CustomEvent","detail","oldValue","newValue","scaleFactor","fit","destroy","_","observeMutations","observer","disconnect","originalStyle","subscribe","unsubscribe","MutationObserver","observe","defaultOptions","subtree","childList","characterData","resizeDebounce","onWindowResized","clearTimeout","setTimeout","fitty","observeWindowDelay","events","set","enabled","method","e","observeWindow","fitAll","fittyCreate","elements","options","fittyOptions","publicFitties","map","newbie","push","init","unfreeze","freeze","undefined","window","SlideContent","constructor","Reveal","startEmbeddedIframe","this","bind","shouldPreload","preload","getConfig","preloadIframes","hasAttribute","load","slide","tagName","setAttribute","getAttribute","removeAttribute","media","sources","background","slideBackgroundElement","backgroundContent","slideBackgroundContentElement","backgroundIframe","backgroundImage","backgroundVideo","backgroundVideoLoop","backgroundVideoMuted","trim","url","encodeURI","c","charCodeAt","toString","toUpperCase","encodeRFC3986URI","decodeURI","join","isSpeakerNotes","video","muted","filename","getMimeTypeFromFile","excludeIframes","iframe","width","maxHeight","maxWidth","backgroundIframeElement","querySelector","layout","scopeElement","unload","getSlideBackground","formatEmbeddedContent","_appendParamToIframeSource","sourceAttribute","sourceURL","param","getSlidesElement","src","indexOf","startEmbeddedContent","autoplay","autoPlayMedia","play","readyState","startEmbeddedMedia","promise","catch","controls","addEventListener","removeEventListener","event","isAttachedToDOM","isVisible","currentTime","contentWindow","postMessage","stopEmbeddedContent","unloadIframes","pause","SlideNumber","render","getRevealElement","configure","config","oldConfig","slideNumberDisplay","slideNumber","isPrintingPDF","showSlideNumber","update","getSlideNumber","getCurrentSlide","format","getHorizontalSlides","horizontalOffset","dataset","visibility","getSlidePastCount","getTotalSlides","indices","getIndices","h","sep","isVerticalSlide","v","getHash","formatNumber","delimiter","isNaN","JumpToSlide","onInput","onBlur","onKeyDown","jumpInput","placeholder","show","indicesOnShow","focus","hide","jumpTimeout","jump","getIndicesFromHash","oneBasedIndex","jumpAfter","delay","regex","RegExp","getSlides","find","innerText","cancel","confirm","keyCode","stopImmediatePropagation","colorToRgb","color","hex3","r","parseInt","charAt","g","hex6","rgb","rgba","Backgrounds","create","slideh","backgroundStack","createBackground","slidev","parallaxBackgroundImage","backgroundSize","parallaxBackgroundSize","backgroundRepeat","parallaxBackgroundRepeat","backgroundPosition","parallaxBackgroundPosition","contentElement","sync","data","backgroundColor","backgroundGradient","backgroundTransition","backgroundOpacity","dataPreload","opacity","contrastColor","computedBackgroundStyle","includeAll","currentSlide","currentBackground","horizontalPast","rtl","horizontalFuture","childNodes","backgroundh","backgroundv","previousBackground","slideContent","currentBackgroundContent","backgroundImageURL","previousBackgroundHash","currentBackgroundHash","classToBubble","contains","updateParallax","backgroundWidth","backgroundHeight","horizontalSlides","verticalSlides","getVerticalSlides","horizontalOffsetMultiplier","slideWidth","offsetWidth","horizontalSlideCount","parallaxBackgroundHorizontal","verticalOffsetMultiplier","verticalOffset","slideHeight","verticalSlideCount","parallaxBackgroundVertical","SLIDES_SELECTOR","HORIZONTAL_SLIDES_SELECTOR","VERTICAL_SLIDES_SELECTOR","POST_MESSAGE_METHOD_BLACKLIST","FRAGMENT_STYLE_REGEX","autoAnimateCounter","AutoAnimate","run","fromSlide","toSlide","reset","allSlides","toSlideIndex","fromSlideIndex","autoAnimateStyleSheet","animationOptions","getAutoAnimateOptions","autoAnimate","slideDirection","fromSlideIsHidden","css","getAutoAnimatableElements","autoAnimateElements","to","autoAnimateUnmatched","defaultUnmatchedDuration","duration","defaultUnmatchedDelay","getUnmatchedAutoAnimateElements","unmatchedElement","unmatchedOptions","id","autoAnimateTarget","fontWeight","sheet","removeChild","elementOptions","easing","fromProps","getAutoAnimatableProperties","toProps","styles","translate","scale","presentationScale","getScale","delta","x","y","scaleX","scaleY","round","propertyName","toValue","fromValue","explicitValue","toStyleProperties","keys","inheritedOptions","autoAnimateEasing","autoAnimateDuration","autoAnimatedParent","autoAnimateDelay","direction","properties","bounds","measure","center","getBoundingClientRect","offsetLeft","offsetTop","computedStyles","autoAnimateStyles","property","pairs","autoAnimateMatcher","getAutoAnimatePairs","reserved","pair","index","textNodes","findAutoAnimateMatches","nodeName","textContent","getLocalBoundingBox","fromScope","toScope","serializer","fromMatches","toMatches","fromElement","primaryIndex","secondaryIndex","rootElement","children","reduce","result","containsAnimatedElements","concat","Fragments","fragments","disable","enable","availableRoutes","hiddenFragments","prev","next","sort","grouped","ordered","unordered","sorted","fragment","group","sortAll","horizontalSlide","verticalSlide","changedFragments","shown","hidden","maxIndex","currentFragment","wasVisible","announceStatus","getStatusText","bubbles","goto","offset","lastVisibleFragment","progress","fragmentInURL","writeURL","Overview","onSlideClicked","activate","overview","isActive","cancelAutoSlide","getBackgroundsElement","margin","slideSize","getComputedSlideSize","overviewSlideWidth","overviewSlideHeight","updateSlidesVisibility","hslide","vslide","hbackground","vbackground","vmin","innerWidth","innerHeight","transformSlides","deactivate","cueAutoSlide","toggle","override","preventDefault","Keyboard","shortcuts","bindings","onDocumentKeyDown","onDocumentKeyPress","navigationMode","unbind","addKeyBinding","binding","callback","description","removeKeyBinding","triggerKey","registerKeyboardShortcut","getShortcuts","getBindings","shiftKey","charCode","toggleHelp","keyboardCondition","isFocused","autoSlideWasPaused","isAutoSliding","onUserInput","activeElementIsCE","activeElement","isContentEditable","activeElementIsInput","activeElementIsNotes","unusedModifier","altKey","ctrlKey","metaKey","resumeKeyCodes","keyboard","isPaused","useLinearMode","hasHorizontalSlides","hasVerticalSlides","triggered","apply","action","skipFragments","left","right","up","Number","MAX_VALUE","down","togglePause","requestMethod","documentElement","requestFullscreen","webkitRequestFullscreen","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen","enterFullscreen","embedded","getViewportElement","autoSlideStoppable","toggleAutoSlide","jumpToSlide","toggleJumpToSlide","closeOverlay","Location","writeURLTimeout","replaceStateTimestamp","onWindowHashChange","hash","name","bits","hashIndexBase","hashOneBasedIndex","getElementById","decodeURIComponent","error","readURL","currentIndices","newIndices","history","debouncedReplaceState","pathname","replaceState","Date","now","replaceStateTimeout","MAX_REPLACE_STATE_FREQUENCY","s","encodeURIComponent","Controls","onNavigateLeftClicked","onNavigateRightClicked","onNavigateUpClicked","onNavigateDownClicked","onNavigatePrevClicked","onNavigateNextClicked","revealElement","controlsLeft","controlsRight","controlsUp","controlsDown","controlsPrev","controlsNext","controlsRightArrow","controlsLeftArrow","controlsDownArrow","controlsLayout","controlsBackArrows","pointerEvents","eventName","routes","fragmentsRoutes","controlsTutorial","hasNavigatedVertically","hasNavigatedHorizontally","Progress","onProgressClicked","bar","getProgress","getMaxWidth","slides","slidesTotal","slideIndex","floor","clientX","targetIndices","Pointer","lastMouseWheelStep","cursorHidden","cursorInactiveTimeout","onDocumentCursorActive","onDocumentMouseScroll","mouseWheel","hideInactiveCursor","showCursor","cursor","hideCursor","hideCursorTime","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","hasPlugin","getPlugin","getRegisteredPlugins","Print","injectPageNumbers","pageWidth","pageHeight","body","viewportElement","presentationBackground","viewportStyles","layoutSlideContents","slideScrollHeights","scrollHeight","pages","pageContainer","top","contentHeight","numberOfPages","ceil","pdfMaxPagesPerSlide","page","pdfPageHeightOffset","showNotes","notes","getSlideNotes","notesSpacing","notesLayout","notesElement","bottom","numberElement","pdfSeparateFragments","fragmentGroups","previousFragmentStep","clonedPage","cloneNode","fragmentNumber","Touch","touchStartX","touchStartY","touchStartCount","touchCaptured","onPointerDown","onPointerMove","onPointerUp","onTouchStart","onTouchMove","onTouchEnd","msPointerEnabled","isSwipePrevented","touches","clientY","currentX","currentY","includeFragments","deltaX","deltaY","abs","pointerType","MSPOINTER_TYPE_TOUCH","STATE_FOCUS","STATE_BLUR","Focus","onRevealPointerDown","onDocumentPointerDown","blur","Notes","print","updateVisibility","hasNotes","isSpeakerNotesWindow","notesElements","Playback","progressCheck","diameter","diameter2","thickness","playing","progressOffset","canvas","context","getContext","setPlaying","wasPlaying","animate","progressBefore","radius","iconSize","endAngle","PI","startAngle","save","clearRect","beginPath","arc","fillStyle","fill","lineWidth","strokeStyle","stroke","fillRect","moveTo","lineTo","restore","on","listener","off","minScale","maxScale","respondToHashChanges","disableLayout","touch","loop","shuffle","help","showHiddenSlides","autoSlide","autoSlideMethod","defaultTiming","previewLinks","postMessageEvents","focusBodyOnPageVisibilityChange","transition","transitionSpeed","POSITIVE_INFINITY","viewDistance","mobileViewDistance","sortFragmentsOnSync","VERSION","indexh","indexv","previousSlide","autoSlidePlayer","ready","navigationHistory","slidesTransform","dom","autoSlideTimeout","autoSlideStartTime","autoSlidePaused","backgrounds","pointer","initialize","initOptions","wrapper","defaultConfig","Util","setViewport","start","viewport","removeHiddenSlides","setupDOM","setupPostMessage","setupScrollPrevention","setupFullscreen","resetVerticalSlides","removeEventListeners","setupPDF","Device","pauseOverlay","statusElement","createStatusElement","position","overflow","clip","text","nodeType","isAriaHidden","isDisplayHidden","child","setInterval","scrollTop","scrollLeft","onFullscreenChange","onPostMessage","isReady","numberOfSlides","setProperty","resume","enablePreviewLinks","disablePreviewLinks","onAutoSlidePlayerClick","addEventListeners","onWindowResize","onSlidesClicked","onTransitionEnd","onPageVisibilityChange","useCapture","transforms","createEvent","initEvent","dispatchPostMessage","parent","self","message","namespace","getState","JSON","stringify","onPreviewLinkClicked","showPreview","overlay","showHelp","html","size","oldScale","presentationWidth","presentationHeight","zoom","len","remainingHeight","nw","naturalWidth","videoWidth","nh","naturalHeight","videoHeight","es","setPreviousVerticalIndex","stack","getPreviousVerticalIndex","attributeName","isLastVerticalSlide","nextElementSibling","isFirstSlide","isLastSlide","wasPaused","resumeAutoSlide","pauseAutoSlide","origin","defaultPrevented","stateBefore","indexhBefore","indexvBefore","updateSlides","slideChanged","currentHorizontalSlide","currentVerticalSlides","autoAnimateTransition","getVerticalStacks","stateLoop","j","splice","syncSlide","beforeSlide","random","slidesLength","printMode","loopedForwards","loopedBackwards","reverse","showFragmentsIn","hideFragmentsIn","wasPresent","slideState","distanceX","distanceY","horizontalSlidesLength","verticalSlidesLength","oy","fragmentRoutes","pastCount","mainLoop","totalCount","allFragments","fragmentWeight","isVertical","getSlidesAttributes","attributes","attribute","getSlide","indexf","paused","setState","pausedFlag","overviewFlag","fragmentAutoSlide","parentAutoSlide","slideAutoSlide","playbackRate","navigateNext","navigateLeft","navigateRight","navigateUp","navigateDown","navigatePrev","parse","args","anchor","fullscreenElement","webkitFullscreenElement","currentTarget","API","syncFragments","navigateFragment","prevFragment","nextFragment","availableFragments","toggleOverview","isOverview","loadSlide","unloadSlide","hidePreview","getPreviousSlide","getSlidePath","getPlugins","Deck","enqueuedAPICalls","deck"],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/theme/beige.css b/dist/theme/beige.css
new file mode 100644
index 00000000000..16eb9134465
--- /dev/null
+++ b/dist/theme/beige.css
@@ -0,0 +1,364 @@
+/**
+ * Beige theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+@import url(./fonts/league-gothic/league-gothic.css);
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
+ color: #fff;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #f7f3de;
+ --r-main-font: Lato, sans-serif;
+ --r-main-font-size: 40px;
+ --r-main-color: #333;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: League Gothic, Impact, sans-serif;
+ --r-heading-color: #333;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: normal;
+ --r-heading-text-transform: uppercase;
+ --r-heading-text-shadow: none;
+ --r-heading-font-weight: normal;
+ --r-heading1-text-shadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15);
+ --r-heading1-size: 3.77em;
+ --r-heading2-size: 2.11em;
+ --r-heading3-size: 1.55em;
+ --r-heading4-size: 1em;
+ --r-code-font: monospace;
+ --r-link-color: #8b743d;
+ --r-link-color-dark: #564826;
+ --r-link-color-hover: #c0a86e;
+ --r-selection-background-color: rgba(79, 64, 28, 0.99);
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #f7f2d3;
+ background: -moz-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+ background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, white), color-stop(100%, #f7f2d3));
+ background: -webkit-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+ background: -o-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+ background: -ms-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+ background: radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
\ No newline at end of file
diff --git a/dist/theme/black-contrast.css b/dist/theme/black-contrast.css
new file mode 100644
index 00000000000..e69eb69e580
--- /dev/null
+++ b/dist/theme/black-contrast.css
@@ -0,0 +1,360 @@
+/**
+ * Black compact & high contrast reveal.js theme, with headers not in capitals.
+ *
+ * By Peter Kehl. Based on black.(s)css by Hakim El Hattab, http://hakim.se
+ *
+ * - Keep the source similar to black.css - for easy comparison.
+ * - $mainFontSize controls code blocks, too (although under some ratio).
+ */
+@import url(./fonts/source-sans-pro/source-sans-pro.css);
+section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
+ color: #000;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #000000;
+ --r-main-font: Source Sans Pro, Helvetica, sans-serif;
+ --r-main-font-size: 42px;
+ --r-main-color: #fff;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: Source Sans Pro, Helvetica, sans-serif;
+ --r-heading-color: #fff;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: normal;
+ --r-heading-text-transform: uppercase;
+ --r-heading-text-shadow: none;
+ --r-heading-font-weight: 600;
+ --r-heading1-text-shadow: none;
+ --r-heading1-size: 2.5em;
+ --r-heading2-size: 1.6em;
+ --r-heading3-size: 1.3em;
+ --r-heading4-size: 1em;
+ --r-code-font: monospace;
+ --r-link-color: #42affa;
+ --r-link-color-dark: #068de9;
+ --r-link-color-hover: #8dcffc;
+ --r-selection-background-color: #bee4fd;
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #000000;
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
\ No newline at end of file
diff --git a/dist/theme/black.css b/dist/theme/black.css
new file mode 100644
index 00000000000..511772728b2
--- /dev/null
+++ b/dist/theme/black.css
@@ -0,0 +1,357 @@
+/**
+ * Black theme for reveal.js. This is the opposite of the 'white' theme.
+ *
+ * By Hakim El Hattab, http://hakim.se
+ */
+@import url(./fonts/source-sans-pro/source-sans-pro.css);
+section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
+ color: #222;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #191919;
+ --r-main-font: Source Sans Pro, Helvetica, sans-serif;
+ --r-main-font-size: 42px;
+ --r-main-color: #fff;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: Source Sans Pro, Helvetica, sans-serif;
+ --r-heading-color: #fff;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: normal;
+ --r-heading-text-transform: uppercase;
+ --r-heading-text-shadow: none;
+ --r-heading-font-weight: 600;
+ --r-heading1-text-shadow: none;
+ --r-heading1-size: 2.5em;
+ --r-heading2-size: 1.6em;
+ --r-heading3-size: 1.3em;
+ --r-heading4-size: 1em;
+ --r-code-font: monospace;
+ --r-link-color: #42affa;
+ --r-link-color-dark: #068de9;
+ --r-link-color-hover: #8dcffc;
+ --r-selection-background-color: rgba(66, 175, 250, 0.75);
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #191919;
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
\ No newline at end of file
diff --git a/dist/theme/blood.css b/dist/theme/blood.css
new file mode 100644
index 00000000000..c48714fa616
--- /dev/null
+++ b/dist/theme/blood.css
@@ -0,0 +1,390 @@
+/**
+ * Blood theme for reveal.js
+ * Author: Walther http://github.com/Walther
+ *
+ * Designed to be used with highlight.js theme
+ * "monokai_sublime.css" available from
+ * https://github.com/isagalaev/highlight.js/
+ *
+ * For other themes, change $codeBackground accordingly.
+ *
+ */
+@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic);
+section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
+ color: #222;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #222;
+ --r-main-font: Ubuntu, sans-serif;
+ --r-main-font-size: 40px;
+ --r-main-color: #eee;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: Ubuntu, sans-serif;
+ --r-heading-color: #eee;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: normal;
+ --r-heading-text-transform: uppercase;
+ --r-heading-text-shadow: 2px 2px 2px #222;
+ --r-heading-font-weight: normal;
+ --r-heading1-text-shadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15);
+ --r-heading1-size: 3.77em;
+ --r-heading2-size: 2.11em;
+ --r-heading3-size: 1.55em;
+ --r-heading4-size: 1em;
+ --r-code-font: monospace;
+ --r-link-color: #a23;
+ --r-link-color-dark: #6a1520;
+ --r-link-color-hover: #dd5566;
+ --r-selection-background-color: #a23;
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #222;
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
+.reveal p {
+ font-weight: 300;
+ text-shadow: 1px 1px #222;
+}
+
+section.has-light-background p, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4 {
+ text-shadow: none;
+}
+
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ font-weight: 700;
+}
+
+.reveal p code {
+ background-color: #23241f;
+ display: inline-block;
+ border-radius: 7px;
+}
+
+.reveal small code {
+ vertical-align: baseline;
+}
\ No newline at end of file
diff --git a/dist/theme/dracula.css b/dist/theme/dracula.css
new file mode 100644
index 00000000000..3eb33069672
--- /dev/null
+++ b/dist/theme/dracula.css
@@ -0,0 +1,414 @@
+@charset "UTF-8";
+/**
+ * Dracula Dark theme for reveal.js.
+ * Based on https://draculatheme.com
+ */
+/**
+ * Dracula colors by Zeno Rocha
+ * https://draculatheme.com/contribute
+ */
+html * {
+ color-profile: sRGB;
+ rendering-intent: auto;
+}
+
+section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
+ color: #282A36;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #282A36;
+ --r-main-font: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;
+ --r-main-font-size: 40px;
+ --r-main-color: #F8F8F2;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: League Gothic, Impact, sans-serif;
+ --r-heading-color: #BD93F9;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: normal;
+ --r-heading-text-transform: none;
+ --r-heading-text-shadow: none;
+ --r-heading-font-weight: normal;
+ --r-heading1-text-shadow: none;
+ --r-heading1-size: 3.77em;
+ --r-heading2-size: 2.11em;
+ --r-heading3-size: 1.55em;
+ --r-heading4-size: 1em;
+ --r-code-font: Fira Code, Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;
+ --r-link-color: #FF79C6;
+ --r-link-color-dark: #ff2da5;
+ --r-link-color-hover: #8BE9FD;
+ --r-selection-background-color: #44475A;
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #282A36;
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
+:root {
+ --r-bold-color: #FFB86C;
+ --r-italic-color: #F1FA8C;
+ --r-inline-code-color: #50FA7B;
+ --r-list-bullet-color: #8BE9FD;
+}
+
+.reveal strong, .reveal b {
+ color: var(--r-bold-color);
+}
+
+.reveal em, .reveal i, .reveal blockquote {
+ color: var(--r-italic-color);
+}
+
+.reveal code {
+ color: var(--r-inline-code-color);
+}
+
+.reveal ul {
+ list-style: none;
+}
+
+.reveal ul li::before {
+ content: "•";
+ color: var(--r-list-bullet-color);
+ display: inline-block;
+ width: 1em;
+ margin-left: -1em;
+}
+
+.reveal ol {
+ list-style: none;
+ counter-reset: li;
+}
+
+.reveal ol li::before {
+ content: counter(li) ".";
+ color: var(--r-list-bullet-color);
+ display: inline-block;
+ width: 2em;
+ margin-left: -2.5em;
+ margin-right: 0.5em;
+ text-align: right;
+}
+
+.reveal ol li {
+ counter-increment: li;
+}
\ No newline at end of file
diff --git a/lib/font/league-gothic/LICENSE b/dist/theme/fonts/league-gothic/LICENSE
similarity index 100%
rename from lib/font/league-gothic/LICENSE
rename to dist/theme/fonts/league-gothic/LICENSE
diff --git a/dist/theme/fonts/league-gothic/league-gothic.css b/dist/theme/fonts/league-gothic/league-gothic.css
new file mode 100644
index 00000000000..32862f8f51a
--- /dev/null
+++ b/dist/theme/fonts/league-gothic/league-gothic.css
@@ -0,0 +1,10 @@
+@font-face {
+ font-family: 'League Gothic';
+ src: url('./league-gothic.eot');
+ src: url('./league-gothic.eot?#iefix') format('embedded-opentype'),
+ url('./league-gothic.woff') format('woff'),
+ url('./league-gothic.ttf') format('truetype');
+
+ font-weight: normal;
+ font-style: normal;
+}
diff --git a/lib/font/league-gothic/league-gothic.eot b/dist/theme/fonts/league-gothic/league-gothic.eot
similarity index 100%
rename from lib/font/league-gothic/league-gothic.eot
rename to dist/theme/fonts/league-gothic/league-gothic.eot
diff --git a/lib/font/league-gothic/league-gothic.ttf b/dist/theme/fonts/league-gothic/league-gothic.ttf
similarity index 100%
rename from lib/font/league-gothic/league-gothic.ttf
rename to dist/theme/fonts/league-gothic/league-gothic.ttf
diff --git a/lib/font/league-gothic/league-gothic.woff b/dist/theme/fonts/league-gothic/league-gothic.woff
similarity index 100%
rename from lib/font/league-gothic/league-gothic.woff
rename to dist/theme/fonts/league-gothic/league-gothic.woff
diff --git a/lib/font/source-sans-pro/LICENSE b/dist/theme/fonts/source-sans-pro/LICENSE
similarity index 100%
rename from lib/font/source-sans-pro/LICENSE
rename to dist/theme/fonts/source-sans-pro/LICENSE
diff --git a/lib/font/source-sans-pro/source-sans-pro-italic.eot b/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.eot
similarity index 100%
rename from lib/font/source-sans-pro/source-sans-pro-italic.eot
rename to dist/theme/fonts/source-sans-pro/source-sans-pro-italic.eot
diff --git a/lib/font/source-sans-pro/source-sans-pro-italic.ttf b/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.ttf
similarity index 100%
rename from lib/font/source-sans-pro/source-sans-pro-italic.ttf
rename to dist/theme/fonts/source-sans-pro/source-sans-pro-italic.ttf
diff --git a/lib/font/source-sans-pro/source-sans-pro-italic.woff b/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.woff
similarity index 100%
rename from lib/font/source-sans-pro/source-sans-pro-italic.woff
rename to dist/theme/fonts/source-sans-pro/source-sans-pro-italic.woff
diff --git a/lib/font/source-sans-pro/source-sans-pro-regular.eot b/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.eot
similarity index 100%
rename from lib/font/source-sans-pro/source-sans-pro-regular.eot
rename to dist/theme/fonts/source-sans-pro/source-sans-pro-regular.eot
diff --git a/lib/font/source-sans-pro/source-sans-pro-regular.ttf b/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.ttf
similarity index 100%
rename from lib/font/source-sans-pro/source-sans-pro-regular.ttf
rename to dist/theme/fonts/source-sans-pro/source-sans-pro-regular.ttf
diff --git a/lib/font/source-sans-pro/source-sans-pro-regular.woff b/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.woff
similarity index 100%
rename from lib/font/source-sans-pro/source-sans-pro-regular.woff
rename to dist/theme/fonts/source-sans-pro/source-sans-pro-regular.woff
diff --git a/lib/font/source-sans-pro/source-sans-pro-semibold.eot b/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.eot
similarity index 100%
rename from lib/font/source-sans-pro/source-sans-pro-semibold.eot
rename to dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.eot
diff --git a/lib/font/source-sans-pro/source-sans-pro-semibold.ttf b/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.ttf
similarity index 100%
rename from lib/font/source-sans-pro/source-sans-pro-semibold.ttf
rename to dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.ttf
diff --git a/lib/font/source-sans-pro/source-sans-pro-semibold.woff b/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.woff
similarity index 100%
rename from lib/font/source-sans-pro/source-sans-pro-semibold.woff
rename to dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.woff
diff --git a/lib/font/source-sans-pro/source-sans-pro-semibolditalic.eot b/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.eot
similarity index 100%
rename from lib/font/source-sans-pro/source-sans-pro-semibolditalic.eot
rename to dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.eot
diff --git a/lib/font/source-sans-pro/source-sans-pro-semibolditalic.ttf b/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.ttf
similarity index 100%
rename from lib/font/source-sans-pro/source-sans-pro-semibolditalic.ttf
rename to dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.ttf
diff --git a/lib/font/source-sans-pro/source-sans-pro-semibolditalic.woff b/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.woff
similarity index 100%
rename from lib/font/source-sans-pro/source-sans-pro-semibolditalic.woff
rename to dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.woff
diff --git a/dist/theme/fonts/source-sans-pro/source-sans-pro.css b/dist/theme/fonts/source-sans-pro/source-sans-pro.css
new file mode 100644
index 00000000000..99e4fb71a71
--- /dev/null
+++ b/dist/theme/fonts/source-sans-pro/source-sans-pro.css
@@ -0,0 +1,39 @@
+@font-face {
+ font-family: 'Source Sans Pro';
+ src: url('./source-sans-pro-regular.eot');
+ src: url('./source-sans-pro-regular.eot?#iefix') format('embedded-opentype'),
+ url('./source-sans-pro-regular.woff') format('woff'),
+ url('./source-sans-pro-regular.ttf') format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'Source Sans Pro';
+ src: url('./source-sans-pro-italic.eot');
+ src: url('./source-sans-pro-italic.eot?#iefix') format('embedded-opentype'),
+ url('./source-sans-pro-italic.woff') format('woff'),
+ url('./source-sans-pro-italic.ttf') format('truetype');
+ font-weight: normal;
+ font-style: italic;
+}
+
+@font-face {
+ font-family: 'Source Sans Pro';
+ src: url('./source-sans-pro-semibold.eot');
+ src: url('./source-sans-pro-semibold.eot?#iefix') format('embedded-opentype'),
+ url('./source-sans-pro-semibold.woff') format('woff'),
+ url('./source-sans-pro-semibold.ttf') format('truetype');
+ font-weight: 600;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'Source Sans Pro';
+ src: url('./source-sans-pro-semibolditalic.eot');
+ src: url('./source-sans-pro-semibolditalic.eot?#iefix') format('embedded-opentype'),
+ url('./source-sans-pro-semibolditalic.woff') format('woff'),
+ url('./source-sans-pro-semibolditalic.ttf') format('truetype');
+ font-weight: 600;
+ font-style: italic;
+}
diff --git a/dist/theme/league.css b/dist/theme/league.css
new file mode 100644
index 00000000000..ec1197608b3
--- /dev/null
+++ b/dist/theme/league.css
@@ -0,0 +1,366 @@
+/**
+ * League theme for reveal.js.
+ *
+ * This was the default theme pre-3.0.0.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+@import url(./fonts/league-gothic/league-gothic.css);
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
+ color: #222;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #2b2b2b;
+ --r-main-font: Lato, sans-serif;
+ --r-main-font-size: 40px;
+ --r-main-color: #eee;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: League Gothic, Impact, sans-serif;
+ --r-heading-color: #eee;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: normal;
+ --r-heading-text-transform: uppercase;
+ --r-heading-text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2);
+ --r-heading-font-weight: normal;
+ --r-heading1-text-shadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15);
+ --r-heading1-size: 3.77em;
+ --r-heading2-size: 2.11em;
+ --r-heading3-size: 1.55em;
+ --r-heading4-size: 1em;
+ --r-code-font: monospace;
+ --r-link-color: #13DAEC;
+ --r-link-color-dark: #0d99a5;
+ --r-link-color-hover: #71e9f4;
+ --r-selection-background-color: #FF5E99;
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #1c1e20;
+ background: -moz-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+ background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #555a5f), color-stop(100%, #1c1e20));
+ background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+ background: -o-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+ background: -ms-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+ background: radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
\ No newline at end of file
diff --git a/dist/theme/moon.css b/dist/theme/moon.css
new file mode 100644
index 00000000000..de6f7cb5511
--- /dev/null
+++ b/dist/theme/moon.css
@@ -0,0 +1,365 @@
+/**
+ * Solarized Dark theme for reveal.js.
+ * Author: Achim Staebler
+ */
+@import url(./fonts/league-gothic/league-gothic.css);
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * Solarized colors by Ethan Schoonover
+ */
+html * {
+ color-profile: sRGB;
+ rendering-intent: auto;
+}
+
+section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
+ color: #222;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #002b36;
+ --r-main-font: Lato, sans-serif;
+ --r-main-font-size: 40px;
+ --r-main-color: #93a1a1;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: League Gothic, Impact, sans-serif;
+ --r-heading-color: #eee8d5;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: normal;
+ --r-heading-text-transform: uppercase;
+ --r-heading-text-shadow: none;
+ --r-heading-font-weight: normal;
+ --r-heading1-text-shadow: none;
+ --r-heading1-size: 3.77em;
+ --r-heading2-size: 2.11em;
+ --r-heading3-size: 1.55em;
+ --r-heading4-size: 1em;
+ --r-code-font: monospace;
+ --r-link-color: #268bd2;
+ --r-link-color-dark: #1a6091;
+ --r-link-color-hover: #78b9e6;
+ --r-selection-background-color: #d33682;
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #002b36;
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
\ No newline at end of file
diff --git a/dist/theme/night.css b/dist/theme/night.css
new file mode 100644
index 00000000000..8ab9735099d
--- /dev/null
+++ b/dist/theme/night.css
@@ -0,0 +1,358 @@
+/**
+ * Black theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+@import url(https://fonts.googleapis.com/css?family=Montserrat:700);
+@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic);
+section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
+ color: #222;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #111;
+ --r-main-font: Open Sans, sans-serif;
+ --r-main-font-size: 40px;
+ --r-main-color: #eee;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: Montserrat, Impact, sans-serif;
+ --r-heading-color: #eee;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: -0.03em;
+ --r-heading-text-transform: none;
+ --r-heading-text-shadow: none;
+ --r-heading-font-weight: normal;
+ --r-heading1-text-shadow: none;
+ --r-heading1-size: 3.77em;
+ --r-heading2-size: 2.11em;
+ --r-heading3-size: 1.55em;
+ --r-heading4-size: 1em;
+ --r-code-font: monospace;
+ --r-link-color: #e7ad52;
+ --r-link-color-dark: #d08a1d;
+ --r-link-color-hover: #f3d7ac;
+ --r-selection-background-color: #e7ad52;
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #111;
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
\ No newline at end of file
diff --git a/dist/theme/serif.css b/dist/theme/serif.css
new file mode 100644
index 00000000000..738ffe84404
--- /dev/null
+++ b/dist/theme/serif.css
@@ -0,0 +1,361 @@
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is brown.
+ *
+ * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
+ */
+.reveal a {
+ line-height: 1.3em;
+}
+
+section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
+ color: #fff;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #F0F1EB;
+ --r-main-font: Palatino Linotype, Book Antiqua, Palatino, FreeSerif, serif;
+ --r-main-font-size: 40px;
+ --r-main-color: #000;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: Palatino Linotype, Book Antiqua, Palatino, FreeSerif, serif;
+ --r-heading-color: #383D3D;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: normal;
+ --r-heading-text-transform: none;
+ --r-heading-text-shadow: none;
+ --r-heading-font-weight: normal;
+ --r-heading1-text-shadow: none;
+ --r-heading1-size: 3.77em;
+ --r-heading2-size: 2.11em;
+ --r-heading3-size: 1.55em;
+ --r-heading4-size: 1em;
+ --r-code-font: monospace;
+ --r-link-color: #51483D;
+ --r-link-color-dark: #25211c;
+ --r-link-color-hover: #8b7c69;
+ --r-selection-background-color: #26351C;
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #F0F1EB;
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
\ No newline at end of file
diff --git a/dist/theme/simple.css b/dist/theme/simple.css
new file mode 100644
index 00000000000..ffc16c96c62
--- /dev/null
+++ b/dist/theme/simple.css
@@ -0,0 +1,360 @@
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is darkblue.
+ *
+ * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
+ * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+@import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700);
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
+ color: #fff;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #fff;
+ --r-main-font: Lato, sans-serif;
+ --r-main-font-size: 40px;
+ --r-main-color: #000;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: News Cycle, Impact, sans-serif;
+ --r-heading-color: #000;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: normal;
+ --r-heading-text-transform: none;
+ --r-heading-text-shadow: none;
+ --r-heading-font-weight: normal;
+ --r-heading1-text-shadow: none;
+ --r-heading1-size: 3.77em;
+ --r-heading2-size: 2.11em;
+ --r-heading3-size: 1.55em;
+ --r-heading4-size: 1em;
+ --r-code-font: monospace;
+ --r-link-color: #00008B;
+ --r-link-color-dark: #00003f;
+ --r-link-color-hover: #0000f1;
+ --r-selection-background-color: rgba(0, 0, 0, 0.99);
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #fff;
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
\ No newline at end of file
diff --git a/dist/theme/sky.css b/dist/theme/sky.css
new file mode 100644
index 00000000000..1720dfe6a9b
--- /dev/null
+++ b/dist/theme/sky.css
@@ -0,0 +1,368 @@
+/**
+ * Sky theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+@import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
+@import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
+.reveal a {
+ line-height: 1.3em;
+}
+
+section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
+ color: #fff;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #f7fbfc;
+ --r-main-font: Open Sans, sans-serif;
+ --r-main-font-size: 40px;
+ --r-main-color: #333;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: Quicksand, sans-serif;
+ --r-heading-color: #333;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: -0.08em;
+ --r-heading-text-transform: uppercase;
+ --r-heading-text-shadow: none;
+ --r-heading-font-weight: normal;
+ --r-heading1-text-shadow: none;
+ --r-heading1-size: 3.77em;
+ --r-heading2-size: 2.11em;
+ --r-heading3-size: 1.55em;
+ --r-heading4-size: 1em;
+ --r-code-font: monospace;
+ --r-link-color: #3b759e;
+ --r-link-color-dark: #264c66;
+ --r-link-color-hover: #74a7cb;
+ --r-selection-background-color: #134674;
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #add9e4;
+ background: -moz-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+ background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #f7fbfc), color-stop(100%, #add9e4));
+ background: -webkit-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+ background: -o-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+ background: -ms-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+ background: radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
\ No newline at end of file
diff --git a/dist/theme/solarized.css b/dist/theme/solarized.css
new file mode 100644
index 00000000000..978f48e197a
--- /dev/null
+++ b/dist/theme/solarized.css
@@ -0,0 +1,361 @@
+/**
+ * Solarized Light theme for reveal.js.
+ * Author: Achim Staebler
+ */
+@import url(./fonts/league-gothic/league-gothic.css);
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * Solarized colors by Ethan Schoonover
+ */
+html * {
+ color-profile: sRGB;
+ rendering-intent: auto;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #fdf6e3;
+ --r-main-font: Lato, sans-serif;
+ --r-main-font-size: 40px;
+ --r-main-color: #657b83;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: League Gothic, Impact, sans-serif;
+ --r-heading-color: #586e75;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: normal;
+ --r-heading-text-transform: uppercase;
+ --r-heading-text-shadow: none;
+ --r-heading-font-weight: normal;
+ --r-heading1-text-shadow: none;
+ --r-heading1-size: 3.77em;
+ --r-heading2-size: 2.11em;
+ --r-heading3-size: 1.55em;
+ --r-heading4-size: 1em;
+ --r-code-font: monospace;
+ --r-link-color: #268bd2;
+ --r-link-color-dark: #1a6091;
+ --r-link-color-hover: #78b9e6;
+ --r-selection-background-color: #d33682;
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #fdf6e3;
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
\ No newline at end of file
diff --git a/dist/theme/white-contrast.css b/dist/theme/white-contrast.css
new file mode 100644
index 00000000000..186c4531a68
--- /dev/null
+++ b/dist/theme/white-contrast.css
@@ -0,0 +1,360 @@
+/**
+ * White compact & high contrast reveal.js theme, with headers not in capitals.
+ *
+ * By Peter Kehl. Based on white.(s)css by Hakim El Hattab, http://hakim.se
+ *
+ * - Keep the source similar to black.css - for easy comparison.
+ * - $mainFontSize controls code blocks, too (although under some ratio).
+ */
+@import url(./fonts/source-sans-pro/source-sans-pro.css);
+section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
+ color: #fff;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #fff;
+ --r-main-font: Source Sans Pro, Helvetica, sans-serif;
+ --r-main-font-size: 42px;
+ --r-main-color: #000;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: Source Sans Pro, Helvetica, sans-serif;
+ --r-heading-color: #000;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: normal;
+ --r-heading-text-transform: uppercase;
+ --r-heading-text-shadow: none;
+ --r-heading-font-weight: 600;
+ --r-heading1-text-shadow: none;
+ --r-heading1-size: 2.5em;
+ --r-heading2-size: 1.6em;
+ --r-heading3-size: 1.3em;
+ --r-heading4-size: 1em;
+ --r-code-font: monospace;
+ --r-link-color: #2a76dd;
+ --r-link-color-dark: #1a53a1;
+ --r-link-color-hover: #6ca0e8;
+ --r-selection-background-color: #98bdef;
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #fff;
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
\ No newline at end of file
diff --git a/dist/theme/white.css b/dist/theme/white.css
new file mode 100644
index 00000000000..2218f392ee0
--- /dev/null
+++ b/dist/theme/white.css
@@ -0,0 +1,357 @@
+/**
+ * White theme for reveal.js. This is the opposite of the 'black' theme.
+ *
+ * By Hakim El Hattab, http://hakim.se
+ */
+@import url(./fonts/source-sans-pro/source-sans-pro.css);
+section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
+ color: #fff;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #fff;
+ --r-main-font: Source Sans Pro, Helvetica, sans-serif;
+ --r-main-font-size: 42px;
+ --r-main-color: #222;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: Source Sans Pro, Helvetica, sans-serif;
+ --r-heading-color: #222;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: normal;
+ --r-heading-text-transform: uppercase;
+ --r-heading-text-shadow: none;
+ --r-heading-font-weight: 600;
+ --r-heading1-text-shadow: none;
+ --r-heading1-size: 2.5em;
+ --r-heading2-size: 1.6em;
+ --r-heading3-size: 1.3em;
+ --r-heading4-size: 1em;
+ --r-code-font: monospace;
+ --r-link-color: #2a76dd;
+ --r-link-color-dark: #1a53a1;
+ --r-link-color-hover: #6ca0e8;
+ --r-selection-background-color: #98bdef;
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #fff;
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
\ No newline at end of file
diff --git a/dist/theme/white_contrast_compact_verbatim_headers.css b/dist/theme/white_contrast_compact_verbatim_headers.css
new file mode 100644
index 00000000000..55e8838edb6
--- /dev/null
+++ b/dist/theme/white_contrast_compact_verbatim_headers.css
@@ -0,0 +1,360 @@
+/**
+ * White compact & high contrast reveal.js theme, with headers not in capitals.
+ *
+ * By Peter Kehl. Based on white.(s)css by Hakim El Hattab, http://hakim.se
+ *
+ * - Keep the source similar to black.css - for easy comparison.
+ * - $mainFontSize controls code blocks, too (although under some ratio).
+ */
+@import url(./fonts/source-sans-pro/source-sans-pro.css);
+section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
+ color: #fff;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+:root {
+ --r-background-color: #fff;
+ --r-main-font: Source Sans Pro, Helvetica, sans-serif;
+ --r-main-font-size: 25px;
+ --r-main-color: #000;
+ --r-block-margin: 20px;
+ --r-heading-margin: 0 0 20px 0;
+ --r-heading-font: Source Sans Pro, Helvetica, sans-serif;
+ --r-heading-color: #000;
+ --r-heading-line-height: 1.2;
+ --r-heading-letter-spacing: normal;
+ --r-heading-text-transform: none;
+ --r-heading-text-shadow: none;
+ --r-heading-font-weight: 450;
+ --r-heading1-text-shadow: none;
+ --r-heading1-size: 2.5em;
+ --r-heading2-size: 1.6em;
+ --r-heading3-size: 1.3em;
+ --r-heading4-size: 1em;
+ --r-code-font: monospace;
+ --r-link-color: #2a76dd;
+ --r-link-color-dark: #1a53a1;
+ --r-link-color-hover: #6ca0e8;
+ --r-selection-background-color: #98bdef;
+ --r-selection-color: #fff;
+}
+
+.reveal-viewport {
+ background: #fff;
+ background-color: var(--r-background-color);
+}
+
+.reveal {
+ font-family: var(--r-main-font);
+ font-size: var(--r-main-font-size);
+ font-weight: normal;
+ color: var(--r-main-color);
+}
+
+.reveal ::selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal ::-moz-selection {
+ color: var(--r-selection-color);
+ background: var(--r-selection-background-color);
+ text-shadow: none;
+}
+
+.reveal .slides section,
+.reveal .slides section > section {
+ line-height: 1.3;
+ font-weight: inherit;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+ margin: var(--r-heading-margin);
+ color: var(--r-heading-color);
+ font-family: var(--r-heading-font);
+ font-weight: var(--r-heading-font-weight);
+ line-height: var(--r-heading-line-height);
+ letter-spacing: var(--r-heading-letter-spacing);
+ text-transform: var(--r-heading-text-transform);
+ text-shadow: var(--r-heading-text-shadow);
+ word-wrap: break-word;
+}
+
+.reveal h1 {
+ font-size: var(--r-heading1-size);
+}
+
+.reveal h2 {
+ font-size: var(--r-heading2-size);
+}
+
+.reveal h3 {
+ font-size: var(--r-heading3-size);
+}
+
+.reveal h4 {
+ font-size: var(--r-heading4-size);
+}
+
+.reveal h1 {
+ text-shadow: var(--r-heading1-text-shadow);
+}
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: var(--r-block-margin) 0;
+ line-height: 1.3;
+}
+
+/* Remove trailing margins after titles */
+.reveal h1:last-child,
+.reveal h2:last-child,
+.reveal h3:last-child,
+.reveal h4:last-child,
+.reveal h5:last-child,
+.reveal h6:last-child {
+ margin-bottom: 0;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+ max-width: 95%;
+ max-height: 95%;
+}
+
+.reveal strong,
+.reveal b {
+ font-weight: bold;
+}
+
+.reveal em {
+ font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em;
+}
+
+.reveal ol {
+ list-style-type: decimal;
+}
+
+.reveal ul {
+ list-style-type: disc;
+}
+
+.reveal ul ul {
+ list-style-type: square;
+}
+
+.reveal ul ul ul {
+ list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+ display: block;
+ margin-left: 40px;
+}
+
+.reveal dt {
+ font-weight: bold;
+}
+
+.reveal dd {
+ margin-left: 40px;
+}
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: var(--r-block-margin) auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
+}
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+ display: inline-block;
+}
+
+.reveal q {
+ font-style: italic;
+}
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: var(--r-block-margin) auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: var(--r-code-font);
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
+}
+
+.reveal code {
+ font-family: var(--r-code-font);
+ text-transform: none;
+ tab-size: 2;
+}
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+}
+
+.reveal .code-wrapper {
+ white-space: normal;
+}
+
+.reveal .code-wrapper code {
+ white-space: pre;
+}
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.reveal table th {
+ font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid;
+}
+
+.reveal table th[align=center],
+.reveal table td[align=center] {
+ text-align: center;
+}
+
+.reveal table th[align=right],
+.reveal table td[align=right] {
+ text-align: right;
+}
+
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.reveal sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+.reveal sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top;
+}
+
+.reveal small * {
+ vertical-align: top;
+}
+
+.reveal img {
+ margin: var(--r-block-margin) 0;
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: var(--r-link-color);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.reveal a:hover {
+ color: var(--r-link-color-hover);
+ text-shadow: none;
+ border: none;
+}
+
+.reveal .roll span:after {
+ color: #fff;
+ background: var(--r-link-color-dark);
+}
+
+/*********************************************
+ * Frame helper
+ *********************************************/
+.reveal .r-frame {
+ border: 4px solid var(--r-main-color);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+}
+
+.reveal a .r-frame {
+ transition: all 0.15s linear;
+}
+
+.reveal a:hover .r-frame {
+ border-color: var(--r-link-color);
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls {
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2);
+ color: var(--r-link-color);
+}
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+ .backgrounds {
+ background-color: var(--r-background-color);
+ }
+}
\ No newline at end of file
diff --git a/test/examples/assets/beeping.txt b/examples/assets/beeping.txt
similarity index 100%
rename from test/examples/assets/beeping.txt
rename to examples/assets/beeping.txt
diff --git a/test/examples/assets/beeping.wav b/examples/assets/beeping.wav
similarity index 100%
rename from test/examples/assets/beeping.wav
rename to examples/assets/beeping.wav
diff --git a/test/examples/assets/image1.png b/examples/assets/image1.png
similarity index 100%
rename from test/examples/assets/image1.png
rename to examples/assets/image1.png
diff --git a/test/examples/assets/image2.png b/examples/assets/image2.png
similarity index 100%
rename from test/examples/assets/image2.png
rename to examples/assets/image2.png
diff --git a/examples/auto-animate.html b/examples/auto-animate.html
new file mode 100644
index 00000000000..199810e409a
--- /dev/null
+++ b/examples/auto-animate.html
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+
reveal.js - Auto Animate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto-Animate Example
+ This will fade out
+
+
+ function Example() {
+ const [count, setCount] = useState(0);
+ }
+
+
+
+ Auto-Animate Example
+ This will fade out
+ This element is unmatched
+
+
+ function Example() {
+ New line!
+ const [count, setCount] = useState(0);
+ }
+
+
+
+
+ Line Height & Letter Spacing
+
+
+ Line Height & Letter Spacing
+
+
+
+
+
+ import React, { useState } from 'react';
+
+ function Example() {
+ const [count, setCount] = useState(0);
+
+ return (
+ ...
+ );
+ }
+
+
+
+
+ function Example() {
+ const [count, setCount] = useState(0);
+
+ return (
+ <div>
+ <p>You clicked {count} times</p>
+ <button onClick={() => setCount(count + 1)}>
+ Click me
+ </button>
+ </div>
+ );
+ }
+
+
+
+
+ function Example() {
+ // A comment!
+ const [count, setCount] = useState(0);
+
+ return (
+ <div>
+ <p>You clicked {count} times</p>
+ <button onClick={() => setCount(count + 1)}>
+ Click me
+ </button>
+ </div>
+ );
+ }
+
+
+
+
+
+
+ Swapping list items
+
+
+
+ Swapping list items
+
+
+
+ Swapping list items
+
+
+
+
+
+ SLIDE 1
+ Animate Anything
+
+
+
+
+
+
+ SLIDE 2
+ With Auto Animate
+
+
+
+
+
+
+ SLIDE 3
+ With Auto Animate
+
+
+
+
+
+
+ SLIDE 3
+ With Auto Animate
+
+
+
+
+
+
+
+ data-auto-animate-id="a"
+ A1
+
+
+ data-auto-animate-id="a"
+ A1
+ A2
+
+
+ data-auto-animate-id="b"
+ B1
+
+
+ data-auto-animate-id="b"
+ B1
+ B2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/examples/slide-backgrounds.html b/examples/backgrounds.html
similarity index 92%
rename from test/examples/slide-backgrounds.html
rename to examples/backgrounds.html
index e08d260c0dc..19d40c3463e 100644
--- a/test/examples/slide-backgrounds.html
+++ b/examples/backgrounds.html
@@ -8,8 +8,8 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/examples/slide-transitions.html b/examples/transitions.html
similarity index 91%
rename from test/examples/slide-transitions.html
rename to examples/transitions.html
index b7520ab0910..adbfd150e72 100644
--- a/test/examples/slide-transitions.html
+++ b/examples/transitions.html
@@ -6,8 +6,8 @@
reveal.js - Slide Transitions
-
-
+
+
",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"' );
-
- var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
- leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
-
- if( leadingTabs > 0 ) {
- text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
- }
- else if( leadingWs > 1 ) {
- text = text.replace( new RegExp('\\n? {' + leadingWs + '}', 'g'), '\n' );
- }
-
- return text;
-
- }
-
- /**
- * Given a markdown slide section element, this will
- * return all arguments that aren't related to markdown
- * parsing. Used to forward any other user-defined arguments
- * to the output markdown slide.
- */
- function getForwardedAttributes( section ) {
-
- var attributes = section.attributes;
- var result = [];
-
- for( var i = 0, len = attributes.length; i < len; i++ ) {
- var name = attributes[i].name,
- value = attributes[i].value;
-
- // disregard attributes that are used for markdown loading/parsing
- if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
-
- if( value ) {
- result.push( name + '="' + value + '"' );
- }
- else {
- result.push( name );
- }
- }
-
- return result.join( ' ' );
-
- }
-
- /**
- * Inspects the given options and fills out default
- * values for what's not defined.
- */
- function getSlidifyOptions( options ) {
-
- options = options || {};
- options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
- options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
- options.attributes = options.attributes || '';
-
- return options;
-
- }
-
- /**
- * Helper function for constructing a markdown slide.
- */
- function createMarkdownSlide( content, options ) {
-
- options = getSlidifyOptions( options );
-
- var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
-
- if( notesMatch.length === 2 ) {
- content = notesMatch[0] + '
' + marked(notesMatch[1].trim()) + ' ';
- }
-
- // prevent script end tags in the content from interfering
- // with parsing
- content = content.replace( /<\/script>/g, SCRIPT_END_PLACEHOLDER );
-
- return '';
-
- }
-
- /**
- * Parses a data string into multiple slides based
- * on the passed in separator arguments.
- */
- function slidify( markdown, options ) {
-
- options = getSlidifyOptions( options );
-
- var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
- horizontalSeparatorRegex = new RegExp( options.separator );
-
- var matches,
- lastIndex = 0,
- isHorizontal,
- wasHorizontal = true,
- content,
- sectionStack = [];
-
- // iterate until all blocks between separators are stacked up
- while( matches = separatorRegex.exec( markdown ) ) {
- notes = null;
-
- // determine direction (horizontal by default)
- isHorizontal = horizontalSeparatorRegex.test( matches[0] );
-
- if( !isHorizontal && wasHorizontal ) {
- // create vertical stack
- sectionStack.push( [] );
- }
-
- // pluck slide content from markdown input
- content = markdown.substring( lastIndex, matches.index );
-
- if( isHorizontal && wasHorizontal ) {
- // add to horizontal stack
- sectionStack.push( content );
- }
- else {
- // add to vertical stack
- sectionStack[sectionStack.length-1].push( content );
- }
-
- lastIndex = separatorRegex.lastIndex;
- wasHorizontal = isHorizontal;
- }
-
- // add the remaining slide
- ( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
-
- var markdownSections = '';
-
- // flatten the hierarchical stack, and insert
tags
- for( var i = 0, len = sectionStack.length; i < len; i++ ) {
- // vertical
- if( sectionStack[i] instanceof Array ) {
- markdownSections += '';
-
- sectionStack[i].forEach( function( child ) {
- markdownSections += '' + createMarkdownSlide( child, options ) + ' ';
- } );
-
- markdownSections += ' ';
- }
- else {
- markdownSections += '' + createMarkdownSlide( sectionStack[i], options ) + ' ';
- }
- }
-
- return markdownSections;
-
- }
-
- /**
- * Parses any current data-markdown slides, splits
- * multi-slide markdown into separate sections and
- * handles loading of external markdown.
- */
- function processSlides() {
-
- return new Promise( function( resolve ) {
-
- var externalPromises = [];
-
- [].slice.call( document.querySelectorAll( '[data-markdown]') ).forEach( function( section, i ) {
-
- if( section.getAttribute( 'data-markdown' ).length ) {
-
- externalPromises.push( loadExternalMarkdown( section ).then(
-
- // Finished loading external file
- function( xhr, url ) {
- section.outerHTML = slidify( xhr.responseText, {
- separator: section.getAttribute( 'data-separator' ),
- verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
- notesSeparator: section.getAttribute( 'data-separator-notes' ),
- attributes: getForwardedAttributes( section )
- });
- },
-
- // Failed to load markdown
- function( xhr, url ) {
- section.outerHTML = '' +
- 'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' +
- 'Check your browser\'s JavaScript console for more details.' +
- 'Remember that you need to serve the presentation HTML from a HTTP server.
' +
- ' ';
- }
-
- ) );
-
- }
- else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) {
-
- section.outerHTML = slidify( getMarkdownFromSlide( section ), {
- separator: section.getAttribute( 'data-separator' ),
- verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
- notesSeparator: section.getAttribute( 'data-separator-notes' ),
- attributes: getForwardedAttributes( section )
- });
-
- }
- else {
- section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
- }
-
- });
-
- Promise.all( externalPromises ).then( resolve );
-
- } );
-
- }
-
- function loadExternalMarkdown( section ) {
-
- return new Promise( function( resolve, reject ) {
-
- var xhr = new XMLHttpRequest(),
- url = section.getAttribute( 'data-markdown' );
-
- datacharset = section.getAttribute( 'data-charset' );
-
- // see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
- if( datacharset != null && datacharset != '' ) {
- xhr.overrideMimeType( 'text/html; charset=' + datacharset );
- }
-
- xhr.onreadystatechange = function( section, xhr ) {
- if( xhr.readyState === 4 ) {
- // file protocol yields status code 0 (useful for local debug, mobile applications etc.)
- if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) {
-
- resolve( xhr, url );
-
- }
- else {
-
- reject( xhr, url );
-
- }
- }
- }.bind( this, section, xhr );
-
- xhr.open( 'GET', url, true );
-
- try {
- xhr.send();
- }
- catch ( e ) {
- alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
- resolve( xhr, url );
- }
-
- } );
-
- }
-
- /**
- * Check if a node value has the attributes pattern.
- * If yes, extract it and add that value as one or several attributes
- * to the target element.
- *
- * You need Cache Killer on Chrome to see the effect on any FOM transformation
- * directly on refresh (F5)
- * http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277
- */
- function addAttributeInElement( node, elementTarget, separator ) {
-
- var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
- var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"=]+?)\"", 'mg' );
- var nodeValue = node.nodeValue;
- if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
-
- var classes = matches[1];
- nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
- node.nodeValue = nodeValue;
- while( matchesClass = mardownClassRegex.exec( classes ) ) {
- elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
- }
- return true;
- }
- return false;
- }
-
- /**
- * Add attributes to the parent element of a text node,
- * or the element of an attribute node.
- */
- function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
-
- if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
- previousParentElement = element;
- for( var i = 0; i < element.childNodes.length; i++ ) {
- childElement = element.childNodes[i];
- if ( i > 0 ) {
- j = i - 1;
- while ( j >= 0 ) {
- aPreviousChildElement = element.childNodes[j];
- if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
- previousParentElement = aPreviousChildElement;
- break;
- }
- j = j - 1;
- }
- }
- parentSection = section;
- if( childElement.nodeName == "section" ) {
- parentSection = childElement ;
- previousParentElement = childElement ;
- }
- if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
- addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
- }
- }
- }
-
- if ( element.nodeType == Node.COMMENT_NODE ) {
- if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
- addAttributeInElement( element, section, separatorSectionAttributes );
- }
- }
- }
-
- /**
- * Converts any current data-markdown slides in the
- * DOM to HTML.
- */
- function convertSlides() {
-
- var sections = document.querySelectorAll( '[data-markdown]:not([data-markdown-parsed])');
-
- [].slice.call( sections ).forEach( function( section ) {
-
- section.setAttribute( 'data-markdown-parsed', true )
-
- var notes = section.querySelector( 'aside.notes' );
- var markdown = getMarkdownFromSlide( section );
-
- section.innerHTML = marked( markdown );
- addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) ||
- section.parentNode.getAttribute( 'data-element-attributes' ) ||
- DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
- section.getAttribute( 'data-attributes' ) ||
- section.parentNode.getAttribute( 'data-attributes' ) ||
- DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
-
- // If there were notes, we need to re-add them after
- // having overwritten the section's HTML
- if( notes ) {
- section.appendChild( notes );
- }
-
- } );
-
- return Promise.resolve();
-
- }
-
- // API
- var RevealMarkdown = {
-
- /**
- * Starts processing and converting Markdown within the
- * current reveal.js deck.
- *
- * @param {function} callback function to invoke once
- * we've finished loading and parsing Markdown
- */
- init: function( callback ) {
-
- if( typeof marked === 'undefined' ) {
- throw 'The reveal.js Markdown plugin requires marked to be loaded';
- }
-
- if( typeof hljs !== 'undefined' ) {
- marked.setOptions({
- highlight: function( code, lang ) {
- return hljs.highlightAuto( code, [lang] ).value;
- }
- });
- }
-
- // marked can be configured via reveal.js config options
- var options = Reveal.getConfig().markdown;
- if( options ) {
- marked.setOptions( options );
- }
-
- return processSlides().then( convertSlides );
-
- },
-
- // TODO: Do these belong in the API?
- processSlides: processSlides,
- convertSlides: convertSlides,
- slidify: slidify
-
- };
-
- // Register our plugin so that reveal.js will call our
- // plugin 'init' method as part of the initialization
- Reveal.registerPlugin( 'markdown', RevealMarkdown );
-
- return RevealMarkdown;
-
-}));
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).RevealMarkdown=t()}(this,(function(){"use strict";function e(){return{baseUrl:null,breaks:!1,extensions:null,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}}let t={baseUrl:null,breaks:!1,extensions:null,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1};const n=/[&<>"']/,r=/[&<>"']/g,s=/[<>"']|&(?!#?\w+;)/,i=/[<>"']|&(?!#?\w+;)/g,l={"&":"&","<":"<",">":">",'"':""","'":"'"},a=e=>l[e];function o(e,t){if(t){if(n.test(e))return e.replace(r,a)}else if(s.test(e))return e.replace(i,a);return e}const c=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;function h(e){return e.replace(c,((e,t)=>"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""))}const p=/(^|[^\[])\^/g;function u(e,t){e=e.source||e,t=t||"";const n={replace:(t,r)=>(r=(r=r.source||r).replace(p,"$1"),e=e.replace(t,r),n),getRegex:()=>new RegExp(e,t)};return n}const g=/[^\w:]/g,d=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;function f(e,t,n){if(e){let e;try{e=decodeURIComponent(h(n)).replace(g,"").toLowerCase()}catch(e){return null}if(0===e.indexOf("javascript:")||0===e.indexOf("vbscript:")||0===e.indexOf("data:"))return null}t&&!d.test(n)&&(n=function(e,t){k[" "+e]||(x.test(e)?k[" "+e]=e+"/":k[" "+e]=z(e,"/",!0));e=k[" "+e];const n=-1===e.indexOf(":");return"//"===t.substring(0,2)?n?t:e.replace(m,"$1")+t:"/"===t.charAt(0)?n?t:e.replace(b,"$1")+t:e+t}(t,n));try{n=encodeURI(n).replace(/%25/g,"%")}catch(e){return null}return n}const k={},x=/^[^:]+:\/*[^/]*$/,m=/^([^:]+:)[\s\S]*$/,b=/^([^:]+:\/*[^/]*)[\s\S]*$/;const w={exec:function(){}};function y(e){let t,n,r=1;for(;r{let r=!1,s=t;for(;--s>=0&&"\\"===n[s];)r=!r;return r?"|":" |"})).split(/ \|/);let r=0;if(n[0].trim()||n.shift(),n.length>0&&!n[n.length-1].trim()&&n.pop(),n.length>t)n.splice(t);else for(;n.length1;)1&t&&(n+=e),t>>=1,e+=e;return n+e}function T(e,t,n,r){const s=t.href,i=t.title?o(t.title):null,l=e[1].replace(/\\([\[\]])/g,"$1");if("!"!==e[0].charAt(0)){r.state.inLink=!0;const e={type:"link",raw:n,href:s,title:i,text:l,tokens:r.inlineTokens(l,[])};return r.state.inLink=!1,e}return{type:"image",raw:n,href:s,title:i,text:o(l)}}class A{constructor(e){this.options=e||t}space(e){const t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)return{type:"space",raw:t[0]}}code(e){const t=this.rules.block.code.exec(e);if(t){const e=t[0].replace(/^ {1,4}/gm,"");return{type:"code",raw:t[0],codeBlockStyle:"indented",text:this.options.pedantic?e:z(e,"\n")}}}fences(e){const t=this.rules.block.fences.exec(e);if(t){const e=t[0],n=function(e,t){const n=e.match(/^(\s+)(?:```)/);if(null===n)return t;const r=n[1];return t.split("\n").map((e=>{const t=e.match(/^\s+/);if(null===t)return e;const[n]=t;return n.length>=r.length?e.slice(r.length):e})).join("\n")}(e,t[3]||"");return{type:"code",raw:e,lang:t[2]?t[2].trim():t[2],text:n}}}heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].trim();if(/#$/.test(e)){const t=z(e,"#");this.options.pedantic?e=t.trim():t&&!/ $/.test(t)||(e=t.trim())}const n={type:"heading",raw:t[0],depth:t[1].length,text:e,tokens:[]};return this.lexer.inline(n.text,n.tokens),n}}hr(e){const t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:t[0]}}blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){const e=t[0].replace(/^ *> ?/gm,"");return{type:"blockquote",raw:t[0],tokens:this.lexer.blockTokens(e,[]),text:e}}}list(e){let t=this.rules.block.list.exec(e);if(t){let n,r,s,i,l,a,o,c,h,p,u,g,d=t[1].trim();const f=d.length>1,k={type:"list",raw:"",ordered:f,start:f?+d.slice(0,-1):"",loose:!1,items:[]};d=f?`\\d{1,9}\\${d.slice(-1)}`:`\\${d}`,this.options.pedantic&&(d=f?d:"[*+-]");const x=new RegExp(`^( {0,3}${d})((?: [^\\n]*)?(?:\\n|$))`);for(;e&&(g=!1,t=x.exec(e))&&!this.rules.block.hr.test(e);){if(n=t[0],e=e.substring(n.length),c=t[2].split("\n",1)[0],h=e.split("\n",1)[0],this.options.pedantic?(i=2,u=c.trimLeft()):(i=t[2].search(/[^ ]/),i=i>4?1:i,u=c.slice(i),i+=t[1].length),a=!1,!c&&/^ *$/.test(h)&&(n+=h+"\n",e=e.substring(h.length+1),g=!0),!g){const t=new RegExp(`^ {0,${Math.min(3,i-1)}}(?:[*+-]|\\d{1,9}[.)])`);for(;e&&(p=e.split("\n",1)[0],c=p,this.options.pedantic&&(c=c.replace(/^ {1,4}(?=( {4})*[^ ])/g," ")),!t.test(c));){if(c.search(/[^ ]/)>=i||!c.trim())u+="\n"+c.slice(i);else{if(a)break;u+="\n"+c}a||c.trim()||(a=!0),n+=p+"\n",e=e.substring(p.length+1)}}k.loose||(o?k.loose=!0:/\n *\n *$/.test(n)&&(o=!0)),this.options.gfm&&(r=/^\[[ xX]\] /.exec(u),r&&(s="[ ] "!==r[0],u=u.replace(/^\[[ xX]\] +/,""))),k.items.push({type:"list_item",raw:n,task:!!r,checked:s,loose:!1,text:u}),k.raw+=n}k.items[k.items.length-1].raw=n.trimRight(),k.items[k.items.length-1].text=u.trimRight(),k.raw=k.raw.trimRight();const m=k.items.length;for(l=0;l"space"===e.type)),t=e.every((e=>{const t=e.raw.split("");let n=0;for(const e of t)if("\n"===e&&(n+=1),n>1)return!0;return!1}));!k.loose&&e.length&&t&&(k.loose=!0,k.items[l].loose=!0)}return k}}html(e){const t=this.rules.block.html.exec(e);if(t){const e={type:"html",raw:t[0],pre:!this.options.sanitizer&&("pre"===t[1]||"script"===t[1]||"style"===t[1]),text:t[0]};return this.options.sanitize&&(e.type="paragraph",e.text=this.options.sanitizer?this.options.sanitizer(t[0]):o(t[0]),e.tokens=[],this.lexer.inline(e.text,e.tokens)),e}}def(e){const t=this.rules.block.def.exec(e);if(t){t[3]&&(t[3]=t[3].substring(1,t[3].length-1));return{type:"def",tag:t[1].toLowerCase().replace(/\s+/g," "),raw:t[0],href:t[2],title:t[3]}}}table(e){const t=this.rules.block.table.exec(e);if(t){const e={type:"table",header:_(t[1]).map((e=>({text:e}))),align:t[2].replace(/^ *|\| *$/g,"").split(/ *\| */),rows:t[3]&&t[3].trim()?t[3].replace(/\n[ \t]*$/,"").split("\n"):[]};if(e.header.length===e.align.length){e.raw=t[0];let n,r,s,i,l=e.align.length;for(n=0;n({text:e})));for(l=e.header.length,r=0;r/i.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&/^<(pre|code|kbd|script)(\s|>)/i.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:this.options.sanitize?"text":"html",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(t[0]):o(t[0]):t[0]}}link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim();if(!this.options.pedantic&&/^$/.test(e))return;const t=z(e.slice(0,-1),"\\");if((e.length-t.length)%2==0)return}else{const e=function(e,t){if(-1===e.indexOf(t[1]))return-1;const n=e.length;let r=0,s=0;for(;s-1){const n=(0===t[0].indexOf("!")?5:4)+t[1].length+e;t[2]=t[2].substring(0,e),t[0]=t[0].substring(0,n).trim(),t[3]=""}}let n=t[2],r="";if(this.options.pedantic){const e=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(n);e&&(n=e[1],r=e[3])}else r=t[3]?t[3].slice(1,-1):"";return n=n.trim(),/^$/.test(e)?n.slice(1):n.slice(1,-1)),T(t,{href:n?n.replace(this.rules.inline._escapes,"$1"):n,title:r?r.replace(this.rules.inline._escapes,"$1"):r},t[0],this.lexer)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){let e=(n[2]||n[1]).replace(/\s+/g," ");if(e=t[e.toLowerCase()],!e||!e.href){const e=n[0].charAt(0);return{type:"text",raw:e,text:e}}return T(n,e,n[0],this.lexer)}}emStrong(e,t,n=""){let r=this.rules.inline.emStrong.lDelim.exec(e);if(!r)return;if(r[3]&&n.match(/[\p{L}\p{N}]/u))return;const s=r[1]||r[2]||"";if(!s||s&&(""===n||this.rules.inline.punctuation.exec(n))){const n=r[0].length-1;let s,i,l=n,a=0;const o="*"===r[0][0]?this.rules.inline.emStrong.rDelimAst:this.rules.inline.emStrong.rDelimUnd;for(o.lastIndex=0,t=t.slice(-1*e.length+n);null!=(r=o.exec(t));){if(s=r[1]||r[2]||r[3]||r[4]||r[5]||r[6],!s)continue;if(i=s.length,r[3]||r[4]){l+=i;continue}if((r[5]||r[6])&&n%3&&!((n+i)%3)){a+=i;continue}if(l-=i,l>0)continue;if(i=Math.min(i,i+l+a),Math.min(n,i)%2){const t=e.slice(1,n+r.index+i);return{type:"em",raw:e.slice(0,n+r.index+i+1),text:t,tokens:this.lexer.inlineTokens(t,[])}}const t=e.slice(2,n+r.index+i-1);return{type:"strong",raw:e.slice(0,n+r.index+i+1),text:t,tokens:this.lexer.inlineTokens(t,[])}}}}codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].replace(/\n/g," ");const n=/[^ ]/.test(e),r=/^ /.test(e)&&/ $/.test(e);return n&&r&&(e=e.substring(1,e.length-1)),e=o(e,!0),{type:"codespan",raw:t[0],text:e}}}br(e){const t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t[0]}}del(e){const t=this.rules.inline.del.exec(e);if(t)return{type:"del",raw:t[0],text:t[2],tokens:this.lexer.inlineTokens(t[2],[])}}autolink(e,t){const n=this.rules.inline.autolink.exec(e);if(n){let e,r;return"@"===n[2]?(e=o(this.options.mangle?t(n[1]):n[1]),r="mailto:"+e):(e=o(n[1]),r=e),{type:"link",raw:n[0],text:e,href:r,tokens:[{type:"text",raw:e,text:e}]}}}url(e,t){let n;if(n=this.rules.inline.url.exec(e)){let e,r;if("@"===n[2])e=o(this.options.mangle?t(n[0]):n[0]),r="mailto:"+e;else{let t;do{t=n[0],n[0]=this.rules.inline._backpedal.exec(n[0])[0]}while(t!==n[0]);e=o(n[0]),r="www."===n[1]?"http://"+e:e}return{type:"link",raw:n[0],text:e,href:r,tokens:[{type:"text",raw:e,text:e}]}}}inlineText(e,t){const n=this.rules.inline.text.exec(e);if(n){let e;return e=this.lexer.state.inRawBlock?this.options.sanitize?this.options.sanitizer?this.options.sanitizer(n[0]):o(n[0]):n[0]:o(this.options.smartypants?t(n[0]):n[0]),{type:"text",raw:n[0],text:e}}}}const R={newline:/^(?: *(?:\n|$))+/,code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,fences:/^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( {0,3}bull)( [^\n]+?)?(?:\n|$)/,html:"^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))",def:/^ {0,3}\[(label)\]: *(?:\n *)?([^\s>]+)>?(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,table:w,lheading:/^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,_paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,text:/^[^\n]+/,_label:/(?!\s*\])(?:\\.|[^\[\]\\])+/,_title:/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/};R.def=u(R.def).replace("label",R._label).replace("title",R._title).getRegex(),R.bullet=/(?:[*+-]|\d{1,9}[.)])/,R.listItemStart=u(/^( *)(bull) */).replace("bull",R.bullet).getRegex(),R.list=u(R.list).replace(/bull/g,R.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+R.def.source+")").getRegex(),R._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",R._comment=/|$)/,R.html=u(R.html,"i").replace("comment",R._comment).replace("tag",R._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),R.paragraph=u(R._paragraph).replace("hr",R.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",R._tag).getRegex(),R.blockquote=u(R.blockquote).replace("paragraph",R.paragraph).getRegex(),R.normal=y({},R),R.gfm=y({},R.normal,{table:"^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"}),R.gfm.table=u(R.gfm.table).replace("hr",R.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",R._tag).getRegex(),R.gfm.paragraph=u(R._paragraph).replace("hr",R.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("table",R.gfm.table).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",R._tag).getRegex(),R.pedantic=y({},R.normal,{html:u("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?\\1> *(?:\\n{2,}|\\s*$)| \\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",R._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:w,paragraph:u(R.normal._paragraph).replace("hr",R.hr).replace("heading"," *#{1,6} *[^\n]").replace("lheading",R.lheading).replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").getRegex()});const v={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:w,tag:"^comment|^[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^",link:/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(ref)\]/,nolink:/^!?\[(ref)\](?:\[\])?/,reflinkSearch:"reflink|nolink(?!\\()",emStrong:{lDelim:/^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,rDelimAst:/^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,rDelimUnd:/^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/},code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,br:/^( {2,}|\\)\n(?!\s*$)/,del:w,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\.5&&(n="x"+n.toString(16)),r+=""+n+";";return r}v._punctuation="!\"#$%&'()+\\-.,/:;<=>?@\\[\\]`^{|}~",v.punctuation=u(v.punctuation).replace(/punctuation/g,v._punctuation).getRegex(),v.blockSkip=/\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g,v.escapedEmSt=/\\\*|\\_/g,v._comment=u(R._comment).replace("(?:--\x3e|$)","--\x3e").getRegex(),v.emStrong.lDelim=u(v.emStrong.lDelim).replace(/punct/g,v._punctuation).getRegex(),v.emStrong.rDelimAst=u(v.emStrong.rDelimAst,"g").replace(/punct/g,v._punctuation).getRegex(),v.emStrong.rDelimUnd=u(v.emStrong.rDelimUnd,"g").replace(/punct/g,v._punctuation).getRegex(),v._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,v._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,v._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,v.autolink=u(v.autolink).replace("scheme",v._scheme).replace("email",v._email).getRegex(),v._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,v.tag=u(v.tag).replace("comment",v._comment).replace("attribute",v._attribute).getRegex(),v._label=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,v._href=/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/,v._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,v.link=u(v.link).replace("label",v._label).replace("href",v._href).replace("title",v._title).getRegex(),v.reflink=u(v.reflink).replace("label",v._label).replace("ref",R._label).getRegex(),v.nolink=u(v.nolink).replace("ref",R._label).getRegex(),v.reflinkSearch=u(v.reflinkSearch,"g").replace("reflink",v.reflink).replace("nolink",v.nolink).getRegex(),v.normal=y({},v),v.pedantic=y({},v.normal,{strong:{start:/^__|\*\*/,middle:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,endAst:/\*\*(?!\*)/g,endUnd:/__(?!_)/g},em:{start:/^_|\*/,middle:/^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,endAst:/\*(?!\*)/g,endUnd:/_(?!_)/g},link:u(/^!?\[(label)\]\((.*?)\)/).replace("label",v._label).getRegex(),reflink:u(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",v._label).getRegex()}),v.gfm=y({},v.normal,{escape:u(v.escape).replace("])","~|])").getRegex(),_extended_email:/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,url:/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\!!(n=r.call({lexer:this},e,t))&&(e=e.substring(n.raw.length),t.push(n),!0)))))if(n=this.tokenizer.space(e))e=e.substring(n.raw.length),1===n.raw.length&&t.length>0?t[t.length-1].raw+="\n":t.push(n);else if(n=this.tokenizer.code(e))e=e.substring(n.raw.length),r=t[t.length-1],!r||"paragraph"!==r.type&&"text"!==r.type?t.push(n):(r.raw+="\n"+n.raw,r.text+="\n"+n.text,this.inlineQueue[this.inlineQueue.length-1].src=r.text);else if(n=this.tokenizer.fences(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.heading(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.hr(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.blockquote(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.list(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.html(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.def(e))e=e.substring(n.raw.length),r=t[t.length-1],!r||"paragraph"!==r.type&&"text"!==r.type?this.tokens.links[n.tag]||(this.tokens.links[n.tag]={href:n.href,title:n.title}):(r.raw+="\n"+n.raw,r.text+="\n"+n.raw,this.inlineQueue[this.inlineQueue.length-1].src=r.text);else if(n=this.tokenizer.table(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.lheading(e))e=e.substring(n.raw.length),t.push(n);else{if(s=e,this.options.extensions&&this.options.extensions.startBlock){let t=1/0;const n=e.slice(1);let r;this.options.extensions.startBlock.forEach((function(e){r=e.call({lexer:this},n),"number"==typeof r&&r>=0&&(t=Math.min(t,r))})),t<1/0&&t>=0&&(s=e.substring(0,t+1))}if(this.state.top&&(n=this.tokenizer.paragraph(s)))r=t[t.length-1],i&&"paragraph"===r.type?(r.raw+="\n"+n.raw,r.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=r.text):t.push(n),i=s.length!==e.length,e=e.substring(n.raw.length);else if(n=this.tokenizer.text(e))e=e.substring(n.raw.length),r=t[t.length-1],r&&"text"===r.type?(r.raw+="\n"+n.raw,r.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=r.text):t.push(n);else if(e){const t="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(t);break}throw new Error(t)}}return this.state.top=!0,t}inline(e,t){this.inlineQueue.push({src:e,tokens:t})}inlineTokens(e,t=[]){let n,r,s,i,l,a,o=e;if(this.tokens.links){const e=Object.keys(this.tokens.links);if(e.length>0)for(;null!=(i=this.tokenizer.rules.inline.reflinkSearch.exec(o));)e.includes(i[0].slice(i[0].lastIndexOf("[")+1,-1))&&(o=o.slice(0,i.index)+"["+$("a",i[0].length-2)+"]"+o.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;null!=(i=this.tokenizer.rules.inline.blockSkip.exec(o));)o=o.slice(0,i.index)+"["+$("a",i[0].length-2)+"]"+o.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;null!=(i=this.tokenizer.rules.inline.escapedEmSt.exec(o));)o=o.slice(0,i.index)+"++"+o.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);for(;e;)if(l||(a=""),l=!1,!(this.options.extensions&&this.options.extensions.inline&&this.options.extensions.inline.some((r=>!!(n=r.call({lexer:this},e,t))&&(e=e.substring(n.raw.length),t.push(n),!0)))))if(n=this.tokenizer.escape(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.tag(e))e=e.substring(n.raw.length),r=t[t.length-1],r&&"text"===n.type&&"text"===r.type?(r.raw+=n.raw,r.text+=n.text):t.push(n);else if(n=this.tokenizer.link(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.reflink(e,this.tokens.links))e=e.substring(n.raw.length),r=t[t.length-1],r&&"text"===n.type&&"text"===r.type?(r.raw+=n.raw,r.text+=n.text):t.push(n);else if(n=this.tokenizer.emStrong(e,o,a))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.codespan(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.br(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.del(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.autolink(e,I))e=e.substring(n.raw.length),t.push(n);else if(this.state.inLink||!(n=this.tokenizer.url(e,I))){if(s=e,this.options.extensions&&this.options.extensions.startInline){let t=1/0;const n=e.slice(1);let r;this.options.extensions.startInline.forEach((function(e){r=e.call({lexer:this},n),"number"==typeof r&&r>=0&&(t=Math.min(t,r))})),t<1/0&&t>=0&&(s=e.substring(0,t+1))}if(n=this.tokenizer.inlineText(s,E))e=e.substring(n.raw.length),"_"!==n.raw.slice(-1)&&(a=n.raw.slice(-1)),l=!0,r=t[t.length-1],r&&"text"===r.type?(r.raw+=n.raw,r.text+=n.text):t.push(n);else if(e){const t="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(t);break}throw new Error(t)}}else e=e.substring(n.raw.length),t.push(n);return t}}class L{constructor(e){this.options=e||t}code(e,t,n){const r=(t||"").match(/\S*/)[0];if(this.options.highlight){const t=this.options.highlight(e,r);null!=t&&t!==e&&(n=!0,e=t)}return e=e.replace(/\n$/,"")+"\n",r?''+(n?e:o(e,!0))+"
\n":""+(n?e:o(e,!0))+"
\n"}blockquote(e){return"\n"+e+" \n"}html(e){return e}heading(e,t,n,r){return this.options.headerIds?"\n":""+e+" \n"}hr(){return this.options.xhtml?" \n":" \n"}list(e,t,n){const r=t?"ol":"ul";return"<"+r+(t&&1!==n?' start="'+n+'"':"")+">\n"+e+""+r+">\n"}listitem(e){return""+e+" \n"}checkbox(e){return" "}paragraph(e){return""+e+"
\n"}table(e,t){return t&&(t=""+t+" "),"\n"}tablerow(e){return"\n"+e+" \n"}tablecell(e,t){const n=t.header?"th":"td";return(t.align?"<"+n+' align="'+t.align+'">':"<"+n+">")+e+""+n+">\n"}strong(e){return""+e+" "}em(e){return""+e+" "}codespan(e){return""+e+"
"}br(){return this.options.xhtml?" ":" "}del(e){return""+e+""}link(e,t,n){if(null===(e=f(this.options.sanitize,this.options.baseUrl,e)))return n;let r='"+n+" ",r}image(e,t,n){if(null===(e=f(this.options.sanitize,this.options.baseUrl,e)))return n;let r=' ":">",r}text(e){return e}}class Z{strong(e){return e}em(e){return e}codespan(e){return e}del(e){return e}html(e){return e}text(e){return e}link(e,t,n){return""+n}image(e,t,n){return""+n}br(){return""}}class C{constructor(){this.seen={}}serialize(e){return e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-")}getNextSafeSlug(e,t){let n=e,r=0;if(this.seen.hasOwnProperty(n)){r=this.seen[e];do{r++,n=e+"-"+r}while(this.seen.hasOwnProperty(n))}return t||(this.seen[e]=r,this.seen[n]=0),n}slug(e,t={}){const n=this.serialize(e);return this.getNextSafeSlug(n,t.dryrun)}}class O{constructor(e){this.options=e||t,this.options.renderer=this.options.renderer||new L,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new Z,this.slugger=new C}static parse(e,t){return new O(t).parse(e)}static parseInline(e,t){return new O(t).parseInline(e)}parse(e,t=!0){let n,r,s,i,l,a,o,c,p,u,g,d,f,k,x,m,b,w,y,_="";const z=e.length;for(n=0;n0&&"paragraph"===x.tokens[0].type?(x.tokens[0].text=w+" "+x.tokens[0].text,x.tokens[0].tokens&&x.tokens[0].tokens.length>0&&"text"===x.tokens[0].tokens[0].type&&(x.tokens[0].tokens[0].text=w+" "+x.tokens[0].tokens[0].text)):x.tokens.unshift({type:"text",text:w}):k+=w),k+=this.parse(x.tokens,f),p+=this.renderer.listitem(k,b,m);_+=this.renderer.list(p,g,d);continue;case"html":_+=this.renderer.html(u.text);continue;case"paragraph":_+=this.renderer.paragraph(this.parseInline(u.tokens));continue;case"text":for(p=u.tokens?this.parseInline(u.tokens):u.text;n+1{r(e.text,e.lang,(function(t,n){if(t)return i(t);null!=n&&n!==e.text&&(e.text=n,e.escaped=!0),l--,0===l&&i()}))}),0))})),void(0===l&&i())}try{const n=q.lex(e,t);return t.walkTokens&&N.walkTokens(n,t.walkTokens),O.parse(n,t)}catch(e){if(e.message+="\nPlease report this to https://github.com/markedjs/marked.",t.silent)return"An error occurred:
"+o(e.message+"",!0)+" ";throw e}}N.options=N.setOptions=function(e){var n;return y(N.defaults,e),n=N.defaults,t=n,N},N.getDefaults=e,N.defaults=t,N.use=function(...e){const t=y({},...e),n=N.defaults.extensions||{renderers:{},childTokens:{}};let r;e.forEach((e=>{if(e.extensions&&(r=!0,e.extensions.forEach((e=>{if(!e.name)throw new Error("extension name required");if(e.renderer){const t=n.renderers?n.renderers[e.name]:null;n.renderers[e.name]=t?function(...n){let r=e.renderer.apply(this,n);return!1===r&&(r=t.apply(this,n)),r}:e.renderer}if(e.tokenizer){if(!e.level||"block"!==e.level&&"inline"!==e.level)throw new Error("extension level must be 'block' or 'inline'");n[e.level]?n[e.level].unshift(e.tokenizer):n[e.level]=[e.tokenizer],e.start&&("block"===e.level?n.startBlock?n.startBlock.push(e.start):n.startBlock=[e.start]:"inline"===e.level&&(n.startInline?n.startInline.push(e.start):n.startInline=[e.start]))}e.childTokens&&(n.childTokens[e.name]=e.childTokens)}))),e.renderer){const n=N.defaults.renderer||new L;for(const t in e.renderer){const r=n[t];n[t]=(...s)=>{let i=e.renderer[t].apply(n,s);return!1===i&&(i=r.apply(n,s)),i}}t.renderer=n}if(e.tokenizer){const n=N.defaults.tokenizer||new A;for(const t in e.tokenizer){const r=n[t];n[t]=(...s)=>{let i=e.tokenizer[t].apply(n,s);return!1===i&&(i=r.apply(n,s)),i}}t.tokenizer=n}if(e.walkTokens){const n=N.defaults.walkTokens;t.walkTokens=function(t){e.walkTokens.call(this,t),n&&n.call(this,t)}}r&&(t.extensions=n),N.setOptions(t)}))},N.walkTokens=function(e,t){for(const n of e)switch(t.call(N,n),n.type){case"table":for(const e of n.header)N.walkTokens(e.tokens,t);for(const e of n.rows)for(const n of e)N.walkTokens(n.tokens,t);break;case"list":N.walkTokens(n.items,t);break;default:N.defaults.extensions&&N.defaults.extensions.childTokens&&N.defaults.extensions.childTokens[n.type]?N.defaults.extensions.childTokens[n.type].forEach((function(e){N.walkTokens(n[e],t)})):n.tokens&&N.walkTokens(n.tokens,t)}},N.parseInline=function(e,t){if(null==e)throw new Error("marked.parseInline(): input parameter is undefined or null");if("string"!=typeof e)throw new Error("marked.parseInline(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected");S(t=y({},N.defaults,t||{}));try{const n=q.lexInline(e,t);return t.walkTokens&&N.walkTokens(n,t.walkTokens),O.parseInline(n,t)}catch(e){if(e.message+="\nPlease report this to https://github.com/markedjs/marked.",t.silent)return"An error occurred:
"+o(e.message+"",!0)+" ";throw e}},N.Parser=O,N.parser=O.parse,N.Renderer=L,N.TextRenderer=Z,N.Lexer=q,N.lexer=q.lex,N.Tokenizer=A,N.Slugger=C,N.parse=N;
+/*!
+ * The reveal.js markdown plugin. Handles parsing of
+ * markdown inside of presentations as well as loading
+ * of external markdown documents.
+ */
+const D="__SCRIPT_END__",M=/\[([\s\d,|-]*)\]/,P={"&":"&","<":"<",">":">",'"':""","'":"'"};return()=>{let e;function t(e){var t=(e.querySelector("[data-template]")||e.querySelector("script")||e).textContent,n=(t=t.replace(new RegExp(D,"g"),"<\/script>")).match(/^\n?(\s*)/)[1].length,r=t.match(/^\n?(\t*)/)[1].length;return r>0?t=t.replace(new RegExp("\\n?\\t{"+r+"}(.*)","g"),(function(e,t){return"\n"+t})):n>1&&(t=t.replace(new RegExp("\\n? {"+n+"}(.*)","g"),(function(e,t){return"\n"+t}))),t}function n(e){for(var t=e.attributes,n=[],r=0,s=t.length;r'+N(n[1].trim())+""),'' );
+
+ var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
+ leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
+
+ if( leadingTabs > 0 ) {
+ text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}(.*)','g'), function(m, p1) { return '\n' + p1 ; } );
+ }
+ else if( leadingWs > 1 ) {
+ text = text.replace( new RegExp('\\n? {' + leadingWs + '}(.*)', 'g'), function(m, p1) { return '\n' + p1 ; } );
+ }
+
+ return text;
+
+ }
+
+ /**
+ * Given a markdown slide section element, this will
+ * return all arguments that aren't related to markdown
+ * parsing. Used to forward any other user-defined arguments
+ * to the output markdown slide.
+ */
+ function getForwardedAttributes( section ) {
+
+ var attributes = section.attributes;
+ var result = [];
+
+ for( var i = 0, len = attributes.length; i < len; i++ ) {
+ var name = attributes[i].name,
+ value = attributes[i].value;
+
+ // disregard attributes that are used for markdown loading/parsing
+ if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
+
+ if( value ) {
+ result.push( name + '="' + value + '"' );
+ }
+ else {
+ result.push( name );
+ }
+ }
+
+ return result.join( ' ' );
+
+ }
+
+ /**
+ * Inspects the given options and fills out default
+ * values for what's not defined.
+ */
+ function getSlidifyOptions( options ) {
+
+ options = options || {};
+ options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
+ options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
+ options.attributes = options.attributes || '';
+
+ return options;
+
+ }
+
+ /**
+ * Helper function for constructing a markdown slide.
+ */
+ function createMarkdownSlide( content, options ) {
+
+ options = getSlidifyOptions( options );
+
+ var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
+
+ if( notesMatch.length === 2 ) {
+ content = notesMatch[0] + '' + marked(notesMatch[1].trim()) + ' ';
+ }
+
+ // prevent script end tags in the content from interfering
+ // with parsing
+ content = content.replace( /<\/script>/g, SCRIPT_END_PLACEHOLDER );
+
+ return '';
+
+ }
+
+ /**
+ * Parses a data string into multiple slides based
+ * on the passed in separator arguments.
+ */
+ function slidify( markdown, options ) {
+
+ options = getSlidifyOptions( options );
+
+ var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
+ horizontalSeparatorRegex = new RegExp( options.separator );
+
+ var matches,
+ lastIndex = 0,
+ isHorizontal,
+ wasHorizontal = true,
+ content,
+ sectionStack = [];
+
+ // iterate until all blocks between separators are stacked up
+ while( matches = separatorRegex.exec( markdown ) ) {
+ var notes = null;
+
+ // determine direction (horizontal by default)
+ isHorizontal = horizontalSeparatorRegex.test( matches[0] );
+
+ if( !isHorizontal && wasHorizontal ) {
+ // create vertical stack
+ sectionStack.push( [] );
+ }
+
+ // pluck slide content from markdown input
+ content = markdown.substring( lastIndex, matches.index );
+
+ if( isHorizontal && wasHorizontal ) {
+ // add to horizontal stack
+ sectionStack.push( content );
+ }
+ else {
+ // add to vertical stack
+ sectionStack[sectionStack.length-1].push( content );
+ }
+
+ lastIndex = separatorRegex.lastIndex;
+ wasHorizontal = isHorizontal;
+ }
+
+ // add the remaining slide
+ ( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
+
+ var markdownSections = '';
+
+ // flatten the hierarchical stack, and insert tags
+ for( var i = 0, len = sectionStack.length; i < len; i++ ) {
+ // vertical
+ if( sectionStack[i] instanceof Array ) {
+ markdownSections += '';
+
+ sectionStack[i].forEach( function( child ) {
+ markdownSections += '' + createMarkdownSlide( child, options ) + ' ';
+ } );
+
+ markdownSections += ' ';
+ }
+ else {
+ markdownSections += '' + createMarkdownSlide( sectionStack[i], options ) + ' ';
+ }
+ }
+
+ return markdownSections;
+
+ }
+
+ /**
+ * Parses any current data-markdown slides, splits
+ * multi-slide markdown into separate sections and
+ * handles loading of external markdown.
+ */
+ function processSlides( scope ) {
+
+ return new Promise( function( resolve ) {
+
+ var externalPromises = [];
+
+ [].slice.call( scope.querySelectorAll( 'section[data-markdown]:not([data-markdown-parsed])') ).forEach( function( section, i ) {
+
+ if( section.getAttribute( 'data-markdown' ).length ) {
+
+ externalPromises.push( loadExternalMarkdown( section ).then(
+
+ // Finished loading external file
+ function( xhr, url ) {
+ section.outerHTML = slidify( xhr.responseText, {
+ separator: section.getAttribute( 'data-separator' ),
+ verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
+ notesSeparator: section.getAttribute( 'data-separator-notes' ),
+ attributes: getForwardedAttributes( section )
+ });
+ },
+
+ // Failed to load markdown
+ function( xhr, url ) {
+ section.outerHTML = '' +
+ 'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' +
+ 'Check your browser\'s JavaScript console for more details.' +
+ 'Remember that you need to serve the presentation HTML from a HTTP server.
' +
+ ' ';
+ }
+
+ ) );
+
+ }
+ else {
+
+ section.outerHTML = slidify( getMarkdownFromSlide( section ), {
+ separator: section.getAttribute( 'data-separator' ),
+ verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
+ notesSeparator: section.getAttribute( 'data-separator-notes' ),
+ attributes: getForwardedAttributes( section )
+ });
+
+ }
+
+ });
+
+ Promise.all( externalPromises ).then( resolve );
+
+ } );
+
+ }
+
+ function loadExternalMarkdown( section ) {
+
+ return new Promise( function( resolve, reject ) {
+
+ var xhr = new XMLHttpRequest(),
+ url = section.getAttribute( 'data-markdown' );
+
+ var datacharset = section.getAttribute( 'data-charset' );
+
+ // see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
+ if( datacharset != null && datacharset != '' ) {
+ xhr.overrideMimeType( 'text/html; charset=' + datacharset );
+ }
+
+ xhr.onreadystatechange = function( section, xhr ) {
+ if( xhr.readyState === 4 ) {
+ // file protocol yields status code 0 (useful for local debug, mobile applications etc.)
+ if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) {
+
+ resolve( xhr, url );
+
+ }
+ else {
+
+ reject( xhr, url );
+
+ }
+ }
+ }.bind( this, section, xhr );
+
+ xhr.open( 'GET', url, true );
+
+ try {
+ xhr.send();
+ }
+ catch ( e ) {
+ console.warn( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
+ resolve( xhr, url );
+ }
+
+ } );
+
+ }
+
+ /**
+ * Check if a node value has the attributes pattern.
+ * If yes, extract it and add that value as one or several attributes
+ * to the target element.
+ *
+ * You need Cache Killer on Chrome to see the effect on any FOM transformation
+ * directly on refresh (F5)
+ * http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277
+ */
+ function addAttributeInElement( node, elementTarget, separator ) {
+
+ var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
+ var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"]+?)\"|(data-[^\"= ]+?)(?=[\" ])", 'mg' );
+ var nodeValue = node.nodeValue;
+ var matches,
+ matchesClass;
+ if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
+
+ var classes = matches[1];
+ nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
+ node.nodeValue = nodeValue;
+ while( matchesClass = mardownClassRegex.exec( classes ) ) {
+ if( matchesClass[2] ) {
+ elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
+ } else {
+ elementTarget.setAttribute( matchesClass[3], "" );
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Add attributes to the parent element of a text node,
+ * or the element of an attribute node.
+ */
+ function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
+
+ if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
+ var previousParentElement = element;
+ for( var i = 0; i < element.childNodes.length; i++ ) {
+ var childElement = element.childNodes[i];
+ if ( i > 0 ) {
+ var j = i - 1;
+ while ( j >= 0 ) {
+ var aPreviousChildElement = element.childNodes[j];
+ if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
+ previousParentElement = aPreviousChildElement;
+ break;
+ }
+ j = j - 1;
+ }
+ }
+ var parentSection = section;
+ if( childElement.nodeName == "section" ) {
+ parentSection = childElement ;
+ previousParentElement = childElement ;
+ }
+ if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
+ addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
+ }
+ }
+ }
+
+ if ( element.nodeType == Node.COMMENT_NODE ) {
+ if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
+ addAttributeInElement( element, section, separatorSectionAttributes );
+ }
+ }
+ }
+
+ /**
+ * Converts any current data-markdown slides in the
+ * DOM to HTML.
+ */
+ function convertSlides() {
+
+ var sections = deck.getRevealElement().querySelectorAll( '[data-markdown]:not([data-markdown-parsed])');
+
+ [].slice.call( sections ).forEach( function( section ) {
+
+ section.setAttribute( 'data-markdown-parsed', true )
+
+ var notes = section.querySelector( 'aside.notes' );
+ var markdown = getMarkdownFromSlide( section );
+
+ section.innerHTML = marked( markdown );
+ addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) ||
+ section.parentNode.getAttribute( 'data-element-attributes' ) ||
+ DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
+ section.getAttribute( 'data-attributes' ) ||
+ section.parentNode.getAttribute( 'data-attributes' ) ||
+ DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
+
+ // If there were notes, we need to re-add them after
+ // having overwritten the section's HTML
+ if( notes ) {
+ section.appendChild( notes );
+ }
+
+ } );
+
+ return Promise.resolve();
+
+ }
+
+ function escapeForHTML( input ) {
+
+ return input.replace( /([&<>'"])/g, char => HTML_ESCAPE_MAP[char] );
+
+ }
+
+ return {
+ id: 'markdown',
+
+ /**
+ * Starts processing and converting Markdown within the
+ * current reveal.js deck.
+ */
+ init: function( reveal ) {
+
+ deck = reveal;
+
+ let { renderer, animateLists, ...markedOptions } = deck.getConfig().markdown || {};
+
+ if( !renderer ) {
+ renderer = new marked.Renderer();
+
+ renderer.code = ( code, language ) => {
+
+ // Off by default
+ let lineNumbers = '';
+
+ // Users can opt in to show line numbers and highlight
+ // specific lines.
+ // ```javascript [] show line numbers
+ // ```javascript [1,4-8] highlights lines 1 and 4-8
+ if( CODE_LINE_NUMBER_REGEX.test( language ) ) {
+ lineNumbers = language.match( CODE_LINE_NUMBER_REGEX )[1].trim();
+ lineNumbers = `data-line-numbers="${lineNumbers}"`;
+ language = language.replace( CODE_LINE_NUMBER_REGEX, '' ).trim();
+ }
+
+ // Escape before this gets injected into the DOM to
+ // avoid having the HTML parser alter our code before
+ // highlight.js is able to read it
+ code = escapeForHTML( code );
+
+ return `${code}
`;
+ };
+ }
+
+ if( animateLists === true ) {
+ renderer.listitem = text => `${text} `;
+ }
+
+ marked.setOptions( {
+ renderer,
+ ...markedOptions
+ } );
+
+ return processSlides( deck.getRevealElement() ).then( convertSlides );
+
+ },
+
+ // TODO: Do these belong in the API?
+ processSlides: processSlides,
+ convertSlides: convertSlides,
+ slidify: slidify,
+ marked: marked
+ }
+
+};
+
+export default Plugin;
diff --git a/plugin/math/katex.js b/plugin/math/katex.js
new file mode 100755
index 00000000000..a8b47c4a519
--- /dev/null
+++ b/plugin/math/katex.js
@@ -0,0 +1,96 @@
+/**
+ * A plugin which enables rendering of math equations inside
+ * of reveal.js slides. Essentially a thin wrapper for KaTeX.
+ *
+ * @author Hakim El Hattab
+ * @author Gerhard Burger
+ */
+export const KaTeX = () => {
+ let deck;
+
+ let defaultOptions = {
+ version: 'latest',
+ delimiters: [
+ {left: '$$', right: '$$', display: true}, // Note: $$ has to come before $
+ {left: '$', right: '$', display: false},
+ {left: '\\(', right: '\\)', display: false},
+ {left: '\\[', right: '\\]', display: true}
+ ],
+ ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre']
+ }
+
+ const loadCss = src => {
+ let link = document.createElement('link');
+ link.rel = 'stylesheet';
+ link.href = src;
+ document.head.appendChild(link);
+ };
+
+ /**
+ * Loads a JavaScript file and returns a Promise for when it is loaded
+ * Credits: https://aaronsmith.online/easily-load-an-external-script-using-javascript/
+ */
+ const loadScript = src => {
+ return new Promise((resolve, reject) => {
+ const script = document.createElement('script')
+ script.type = 'text/javascript'
+ script.onload = resolve
+ script.onerror = reject
+ script.src = src
+ document.head.append(script)
+ })
+ };
+
+ async function loadScripts(urls) {
+ for(const url of urls) {
+ await loadScript(url);
+ }
+ }
+
+ return {
+ id: 'katex',
+
+ init: function (reveal) {
+
+ deck = reveal;
+
+ let revealOptions = deck.getConfig().katex || {};
+
+ let options = {...defaultOptions, ...revealOptions};
+ const {local, version, extensions, ...katexOptions} = options;
+
+ let baseUrl = options.local || 'https://cdn.jsdelivr.net/npm/katex';
+ let versionString = options.local ? '' : '@' + options.version;
+
+ let cssUrl = baseUrl + versionString + '/dist/katex.min.css';
+ let katexUrl = baseUrl + versionString + '/dist/katex.min.js';
+ let mhchemUrl = baseUrl + versionString + '/dist/contrib/mhchem.min.js'
+ let karUrl = baseUrl + versionString + '/dist/contrib/auto-render.min.js';
+
+ let katexScripts = [katexUrl];
+ if(options.extensions && options.extensions.includes("mhchem")) {
+ katexScripts.push(mhchemUrl);
+ }
+ katexScripts.push(karUrl);
+
+ const renderMath = () => {
+ renderMathInElement(reveal.getSlidesElement(), katexOptions);
+ deck.layout();
+ }
+
+ loadCss(cssUrl);
+
+ // For some reason dynamically loading with defer attribute doesn't result in the expected behavior, the below code does
+ loadScripts(katexScripts).then(() => {
+ if( deck.isReady() ) {
+ renderMath();
+ }
+ else {
+ deck.on( 'ready', renderMath.bind( this ) );
+ }
+ });
+
+ }
+ }
+
+};
diff --git a/plugin/math/math.esm.js b/plugin/math/math.esm.js
new file mode 100644
index 00000000000..f25ff60a7f5
--- /dev/null
+++ b/plugin/math/math.esm.js
@@ -0,0 +1,6 @@
+const t=()=>{let t,e={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre"]},skipStartupTypeset:!0};return{id:"mathjax2",init:function(a){t=a;let n=t.getConfig().mathjax2||t.getConfig().math||{},i={...e,...n},s=(i.mathjax||"https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js")+"?config="+(i.config||"TeX-AMS_HTML-full");i.tex2jax={...e.tex2jax,...n.tex2jax},i.mathjax=i.config=null,function(t,e){let a=document.querySelector("head"),n=document.createElement("script");n.type="text/javascript",n.src=t;let i=()=>{"function"==typeof e&&(e.call(),e=null)};n.onload=i,n.onreadystatechange=()=>{"loaded"===this.readyState&&i()},a.appendChild(n)}(s,(function(){MathJax.Hub.Config(i),MathJax.Hub.Queue(["Typeset",MathJax.Hub,t.getRevealElement()]),MathJax.Hub.Queue(t.layout),t.on("slidechanged",(function(t){MathJax.Hub.Queue(["Typeset",MathJax.Hub,t.currentSlide])}))}))}}},e=t;
+/*!
+ * This plugin is a wrapper for the MathJax2,
+ * MathJax3 and KaTeX typesetter plugins.
+ */
+var a=Plugin=Object.assign(e(),{KaTeX:()=>{let t,e={version:"latest",delimiters:[{left:"$$",right:"$$",display:!0},{left:"$",right:"$",display:!1},{left:"\\(",right:"\\)",display:!1},{left:"\\[",right:"\\]",display:!0}],ignoredTags:["script","noscript","style","textarea","pre"]};const a=t=>new Promise(((e,a)=>{const n=document.createElement("script");n.type="text/javascript",n.onload=e,n.onerror=a,n.src=t,document.head.append(n)}));return{id:"katex",init:function(n){t=n;let i=t.getConfig().katex||{},s={...e,...i};const{local:l,version:o,extensions:r,...c}=s;let d=s.local||"https://cdn.jsdelivr.net/npm/katex",p=s.local?"":"@"+s.version,u=d+p+"/dist/katex.min.css",h=d+p+"/dist/contrib/mhchem.min.js",x=d+p+"/dist/contrib/auto-render.min.js",m=[d+p+"/dist/katex.min.js"];s.extensions&&s.extensions.includes("mhchem")&&m.push(h),m.push(x);const f=()=>{renderMathInElement(n.getSlidesElement(),c),t.layout()};(t=>{let e=document.createElement("link");e.rel="stylesheet",e.href=t,document.head.appendChild(e)})(u),async function(t){for(const e of t)await a(e)}(m).then((()=>{t.isReady()?f():t.on("ready",f.bind(this))}))}}},MathJax2:t,MathJax3:()=>{let t,e={tex:{inlineMath:[["$","$"],["\\(","\\)"]]},options:{skipHtmlTags:["script","noscript","style","textarea","pre"]},startup:{ready:()=>{MathJax.startup.defaultReady(),MathJax.startup.promise.then((()=>{Reveal.layout()}))}}};return{id:"mathjax3",init:function(a){t=a;let n=t.getConfig().mathjax3||{},i={...e,...n};i.tex={...e.tex,...n.tex},i.options={...e.options,...n.options},i.startup={...e.startup,...n.startup};let s=i.mathjax||"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js";i.mathjax=null,window.MathJax=i,function(t,e){let a=document.createElement("script");a.type="text/javascript",a.id="MathJax-script",a.src=t,a.async=!0,a.onload=()=>{"function"==typeof e&&(e.call(),e=null)},document.head.appendChild(a)}(s,(function(){Reveal.addEventListener("slidechanged",(function(t){MathJax.typeset()}))}))}}}});export default a;
diff --git a/plugin/math/math.js b/plugin/math/math.js
old mode 100755
new mode 100644
index d76c9dda198..05643171812
--- a/plugin/math/math.js
+++ b/plugin/math/math.js
@@ -1,92 +1 @@
-/**
- * A plugin which enables rendering of math equations inside
- * of reveal.js slides. Essentially a thin wrapper for MathJax.
- *
- * @author Hakim El Hattab
- */
-var RevealMath = window.RevealMath || (function(){
-
- var options = Reveal.getConfig().math || {};
- var mathjax = options.mathjax || 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js';
- var config = options.config || 'TeX-AMS_HTML-full';
- var url = mathjax + '?config=' + config;
-
- var defaultOptions = {
- messageStyle: 'none',
- tex2jax: {
- inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ],
- skipTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ]
- },
- skipStartupTypeset: true
- };
-
- function defaults( options, defaultOptions ) {
-
- for ( var i in defaultOptions ) {
- if ( !options.hasOwnProperty( i ) ) {
- options[i] = defaultOptions[i];
- }
- }
-
- }
-
- function loadScript( url, callback ) {
-
- var head = document.querySelector( 'head' );
- var script = document.createElement( 'script' );
- script.type = 'text/javascript';
- script.src = url;
-
- // Wrapper for callback to make sure it only fires once
- var finish = function() {
- if( typeof callback === 'function' ) {
- callback.call();
- callback = null;
- }
- }
-
- script.onload = finish;
-
- // IE
- script.onreadystatechange = function() {
- if ( this.readyState === 'loaded' ) {
- finish();
- }
- }
-
- // Normal browsers
- head.appendChild( script );
-
- }
-
- return {
- init: function() {
-
- defaults( options, defaultOptions );
- defaults( options.tex2jax, defaultOptions.tex2jax );
- options.mathjax = options.config = null;
-
- loadScript( url, function() {
-
- MathJax.Hub.Config( options );
-
- // Typeset followed by an immediate reveal.js layout since
- // the typesetting process could affect slide height
- MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] );
- MathJax.Hub.Queue( Reveal.layout );
-
- // Reprocess equations in slides when they turn visible
- Reveal.addEventListener( 'slidechanged', function( event ) {
-
- MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
-
- } );
-
- } );
-
- }
- }
-
-})();
-
-Reveal.registerPlugin( 'math', RevealMath );
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).RevealMath=e()}(this,(function(){"use strict";const t=()=>{let t,e={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre"]},skipStartupTypeset:!0};return{id:"mathjax2",init:function(n){t=n;let a=t.getConfig().mathjax2||t.getConfig().math||{},i={...e,...a},s=(i.mathjax||"https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js")+"?config="+(i.config||"TeX-AMS_HTML-full");i.tex2jax={...e.tex2jax,...a.tex2jax},i.mathjax=i.config=null,function(t,e){let n=document.querySelector("head"),a=document.createElement("script");a.type="text/javascript",a.src=t;let i=()=>{"function"==typeof e&&(e.call(),e=null)};a.onload=i,a.onreadystatechange=()=>{"loaded"===this.readyState&&i()},n.appendChild(a)}(s,(function(){MathJax.Hub.Config(i),MathJax.Hub.Queue(["Typeset",MathJax.Hub,t.getRevealElement()]),MathJax.Hub.Queue(t.layout),t.on("slidechanged",(function(t){MathJax.Hub.Queue(["Typeset",MathJax.Hub,t.currentSlide])}))}))}}},e=t;return Plugin=Object.assign(e(),{KaTeX:()=>{let t,e={version:"latest",delimiters:[{left:"$$",right:"$$",display:!0},{left:"$",right:"$",display:!1},{left:"\\(",right:"\\)",display:!1},{left:"\\[",right:"\\]",display:!0}],ignoredTags:["script","noscript","style","textarea","pre"]};const n=t=>new Promise(((e,n)=>{const a=document.createElement("script");a.type="text/javascript",a.onload=e,a.onerror=n,a.src=t,document.head.append(a)}));return{id:"katex",init:function(a){t=a;let i=t.getConfig().katex||{},s={...e,...i};const{local:o,version:l,extensions:r,...c}=s;let d=s.local||"https://cdn.jsdelivr.net/npm/katex",u=s.local?"":"@"+s.version,p=d+u+"/dist/katex.min.css",h=d+u+"/dist/contrib/mhchem.min.js",x=d+u+"/dist/contrib/auto-render.min.js",m=[d+u+"/dist/katex.min.js"];s.extensions&&s.extensions.includes("mhchem")&&m.push(h),m.push(x);const f=()=>{renderMathInElement(a.getSlidesElement(),c),t.layout()};(t=>{let e=document.createElement("link");e.rel="stylesheet",e.href=t,document.head.appendChild(e)})(p),async function(t){for(const e of t)await n(e)}(m).then((()=>{t.isReady()?f():t.on("ready",f.bind(this))}))}}},MathJax2:t,MathJax3:()=>{let t,e={tex:{inlineMath:[["$","$"],["\\(","\\)"]]},options:{skipHtmlTags:["script","noscript","style","textarea","pre"]},startup:{ready:()=>{MathJax.startup.defaultReady(),MathJax.startup.promise.then((()=>{Reveal.layout()}))}}};return{id:"mathjax3",init:function(n){t=n;let a=t.getConfig().mathjax3||{},i={...e,...a};i.tex={...e.tex,...a.tex},i.options={...e.options,...a.options},i.startup={...e.startup,...a.startup};let s=i.mathjax||"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js";i.mathjax=null,window.MathJax=i,function(t,e){let n=document.createElement("script");n.type="text/javascript",n.id="MathJax-script",n.src=t,n.async=!0,n.onload=()=>{"function"==typeof e&&(e.call(),e=null)},document.head.appendChild(n)}(s,(function(){Reveal.addEventListener("slidechanged",(function(t){MathJax.typeset()}))}))}}}})}));
diff --git a/plugin/math/mathjax2.js b/plugin/math/mathjax2.js
new file mode 100644
index 00000000000..daebe7e86b3
--- /dev/null
+++ b/plugin/math/mathjax2.js
@@ -0,0 +1,89 @@
+/**
+ * A plugin which enables rendering of math equations inside
+ * of reveal.js slides. Essentially a thin wrapper for MathJax.
+ *
+ * @author Hakim El Hattab
+ */
+export const MathJax2 = () => {
+
+ // The reveal.js instance this plugin is attached to
+ let deck;
+
+ let defaultOptions = {
+ messageStyle: 'none',
+ tex2jax: {
+ inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ],
+ skipTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ]
+ },
+ skipStartupTypeset: true
+ };
+
+ function loadScript( url, callback ) {
+
+ let head = document.querySelector( 'head' );
+ let script = document.createElement( 'script' );
+ script.type = 'text/javascript';
+ script.src = url;
+
+ // Wrapper for callback to make sure it only fires once
+ let finish = () => {
+ if( typeof callback === 'function' ) {
+ callback.call();
+ callback = null;
+ }
+ }
+
+ script.onload = finish;
+
+ // IE
+ script.onreadystatechange = () => {
+ if ( this.readyState === 'loaded' ) {
+ finish();
+ }
+ }
+
+ // Normal browsers
+ head.appendChild( script );
+
+ }
+
+ return {
+ id: 'mathjax2',
+
+ init: function( reveal ) {
+
+ deck = reveal;
+
+ let revealOptions = deck.getConfig().mathjax2 || deck.getConfig().math || {};
+
+ let options = { ...defaultOptions, ...revealOptions };
+ let mathjax = options.mathjax || 'https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js';
+ let config = options.config || 'TeX-AMS_HTML-full';
+ let url = mathjax + '?config=' + config;
+
+ options.tex2jax = { ...defaultOptions.tex2jax, ...revealOptions.tex2jax };
+
+ options.mathjax = options.config = null;
+
+ loadScript( url, function() {
+
+ MathJax.Hub.Config( options );
+
+ // Typeset followed by an immediate reveal.js layout since
+ // the typesetting process could affect slide height
+ MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, deck.getRevealElement() ] );
+ MathJax.Hub.Queue( deck.layout );
+
+ // Reprocess equations in slides when they turn visible
+ deck.on( 'slidechanged', function( event ) {
+
+ MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
+
+ } );
+
+ } );
+
+ }
+ }
+
+};
diff --git a/plugin/math/mathjax3.js b/plugin/math/mathjax3.js
new file mode 100644
index 00000000000..9e62d0d1486
--- /dev/null
+++ b/plugin/math/mathjax3.js
@@ -0,0 +1,77 @@
+/**
+ * A plugin which enables rendering of math equations inside
+ * of reveal.js slides. Essentially a thin wrapper for MathJax 3
+ *
+ * @author Hakim El Hattab
+ * @author Gerhard Burger
+ */
+export const MathJax3 = () => {
+
+ // The reveal.js instance this plugin is attached to
+ let deck;
+
+ let defaultOptions = {
+ tex: {
+ inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ]
+ },
+ options: {
+ skipHtmlTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ]
+ },
+ startup: {
+ ready: () => {
+ MathJax.startup.defaultReady();
+ MathJax.startup.promise.then(() => {
+ Reveal.layout();
+ });
+ }
+ }
+ };
+
+ function loadScript( url, callback ) {
+
+ let script = document.createElement( 'script' );
+ script.type = "text/javascript"
+ script.id = "MathJax-script"
+ script.src = url;
+ script.async = true
+
+ // Wrapper for callback to make sure it only fires once
+ script.onload = () => {
+ if (typeof callback === 'function') {
+ callback.call();
+ callback = null;
+ }
+ };
+
+ document.head.appendChild( script );
+
+ }
+
+ return {
+ id: 'mathjax3',
+ init: function(reveal) {
+
+ deck = reveal;
+
+ let revealOptions = deck.getConfig().mathjax3 || {};
+ let options = {...defaultOptions, ...revealOptions};
+ options.tex = {...defaultOptions.tex, ...revealOptions.tex}
+ options.options = {...defaultOptions.options, ...revealOptions.options}
+ options.startup = {...defaultOptions.startup, ...revealOptions.startup}
+
+ let url = options.mathjax || 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js';
+ options.mathjax = null;
+
+ window.MathJax = options;
+
+ loadScript( url, function() {
+ // Reprocess equations in slides when they turn visible
+ Reveal.addEventListener( 'slidechanged', function( event ) {
+ MathJax.typeset();
+ } );
+ } );
+
+ }
+ }
+
+};
diff --git a/plugin/math/plugin.js b/plugin/math/plugin.js
new file mode 100644
index 00000000000..a92ccfb7cdc
--- /dev/null
+++ b/plugin/math/plugin.js
@@ -0,0 +1,15 @@
+import {KaTeX} from "./katex";
+import {MathJax2} from "./mathjax2";
+import {MathJax3} from "./mathjax3";
+
+const defaultTypesetter = MathJax2;
+
+/*!
+ * This plugin is a wrapper for the MathJax2,
+ * MathJax3 and KaTeX typesetter plugins.
+ */
+export default Plugin = Object.assign( defaultTypesetter(), {
+ KaTeX,
+ MathJax2,
+ MathJax3
+} );
\ No newline at end of file
diff --git a/plugin/multiplex/client.js b/plugin/multiplex/client.js
deleted file mode 100644
index 3ffd1e033c2..00000000000
--- a/plugin/multiplex/client.js
+++ /dev/null
@@ -1,13 +0,0 @@
-(function() {
- var multiplex = Reveal.getConfig().multiplex;
- var socketId = multiplex.id;
- var socket = io.connect(multiplex.url);
-
- socket.on(multiplex.id, function(data) {
- // ignore data from sockets that aren't ours
- if (data.socketId !== socketId) { return; }
- if( window.location.host === 'localhost:1947' ) return;
-
- Reveal.setState(data.state);
- });
-}());
diff --git a/plugin/multiplex/index.js b/plugin/multiplex/index.js
deleted file mode 100644
index 8195f046d95..00000000000
--- a/plugin/multiplex/index.js
+++ /dev/null
@@ -1,64 +0,0 @@
-var http = require('http');
-var express = require('express');
-var fs = require('fs');
-var io = require('socket.io');
-var crypto = require('crypto');
-
-var app = express();
-var staticDir = express.static;
-var server = http.createServer(app);
-
-io = io(server);
-
-var opts = {
- port: process.env.PORT || 1948,
- baseDir : __dirname + '/../../'
-};
-
-io.on( 'connection', function( socket ) {
- socket.on('multiplex-statechanged', function(data) {
- if (typeof data.secret == 'undefined' || data.secret == null || data.secret === '') return;
- if (createHash(data.secret) === data.socketId) {
- data.secret = null;
- socket.broadcast.emit(data.socketId, data);
- };
- });
-});
-
-[ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) {
- app.use('/' + dir, staticDir(opts.baseDir + dir));
-});
-
-app.get("/", function(req, res) {
- res.writeHead(200, {'Content-Type': 'text/html'});
-
- var stream = fs.createReadStream(opts.baseDir + '/index.html');
- stream.on('error', function( error ) {
- res.write('reveal.js multiplex server. Generate token ');
- res.end();
- });
- stream.on('readable', function() {
- stream.pipe(res);
- });
-});
-
-app.get("/token", function(req,res) {
- var ts = new Date().getTime();
- var rand = Math.floor(Math.random()*9999999);
- var secret = ts.toString() + rand.toString();
- res.send({secret: secret, socketId: createHash(secret)});
-});
-
-var createHash = function(secret) {
- var cipher = crypto.createCipher('blowfish', secret);
- return(cipher.final('hex'));
-};
-
-// Actually listen
-server.listen( opts.port || null );
-
-var brown = '\033[33m',
- green = '\033[32m',
- reset = '\033[0m';
-
-console.log( brown + "reveal.js:" + reset + " Multiplex running on port " + green + opts.port + reset );
\ No newline at end of file
diff --git a/plugin/multiplex/master.js b/plugin/multiplex/master.js
deleted file mode 100644
index 7f4bf45110a..00000000000
--- a/plugin/multiplex/master.js
+++ /dev/null
@@ -1,34 +0,0 @@
-(function() {
-
- // Don't emit events from inside of notes windows
- if ( window.location.search.match( /receiver/gi ) ) { return; }
-
- var multiplex = Reveal.getConfig().multiplex;
-
- var socket = io.connect( multiplex.url );
-
- function post() {
-
- var messageData = {
- state: Reveal.getState(),
- secret: multiplex.secret,
- socketId: multiplex.id
- };
-
- socket.emit( 'multiplex-statechanged', messageData );
-
- };
-
- // post once the page is loaded, so the client follows also on "open URL".
- window.addEventListener( 'load', post );
-
- // Monitor events that trigger a change in state
- Reveal.addEventListener( 'slidechanged', post );
- Reveal.addEventListener( 'fragmentshown', post );
- Reveal.addEventListener( 'fragmenthidden', post );
- Reveal.addEventListener( 'overviewhidden', post );
- Reveal.addEventListener( 'overviewshown', post );
- Reveal.addEventListener( 'paused', post );
- Reveal.addEventListener( 'resumed', post );
-
-}());
diff --git a/plugin/multiplex/package.json b/plugin/multiplex/package.json
deleted file mode 100644
index bbed77a6763..00000000000
--- a/plugin/multiplex/package.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "reveal-js-multiplex",
- "version": "1.0.0",
- "description": "reveal.js multiplex server",
- "homepage": "http://revealjs.com",
- "scripts": {
- "start": "node index.js"
- },
- "engines": {
- "node": "~4.1.1"
- },
- "dependencies": {
- "express": "~4.13.3",
- "grunt-cli": "~0.1.13",
- "mustache": "~2.2.1",
- "socket.io": "~1.3.7"
- },
- "license": "MIT"
-}
diff --git a/plugin/notes-server/client.js b/plugin/notes-server/client.js
deleted file mode 100644
index 00b277bafa3..00000000000
--- a/plugin/notes-server/client.js
+++ /dev/null
@@ -1,65 +0,0 @@
-(function() {
-
- // don't emit events from inside the previews themselves
- if( window.location.search.match( /receiver/gi ) ) { return; }
-
- var socket = io.connect( window.location.origin ),
- socketId = Math.random().toString().slice( 2 );
-
- console.log( 'View slide notes at ' + window.location.origin + '/notes/' + socketId );
-
- window.open( window.location.origin + '/notes/' + socketId, 'notes-' + socketId );
-
- /**
- * Posts the current slide data to the notes window
- */
- function post() {
-
- var slideElement = Reveal.getCurrentSlide(),
- notesElement = slideElement.querySelector( 'aside.notes' );
-
- var messageData = {
- notes: '',
- markdown: false,
- socketId: socketId,
- state: Reveal.getState()
- };
-
- // Look for notes defined in a slide attribute
- if( slideElement.hasAttribute( 'data-notes' ) ) {
- messageData.notes = slideElement.getAttribute( 'data-notes' );
- }
-
- // Look for notes defined in an aside element
- if( notesElement ) {
- messageData.notes = notesElement.innerHTML;
- messageData.markdown = typeof notesElement.getAttribute( 'data-markdown' ) === 'string';
- }
-
- socket.emit( 'statechanged', messageData );
-
- }
-
- // When a new notes window connects, post our current state
- socket.on( 'new-subscriber', function( data ) {
- post();
- } );
-
- // When the state changes from inside of the speaker view
- socket.on( 'statechanged-speaker', function( data ) {
- Reveal.setState( data.state );
- } );
-
- // Monitor events that trigger a change in state
- Reveal.addEventListener( 'slidechanged', post );
- Reveal.addEventListener( 'fragmentshown', post );
- Reveal.addEventListener( 'fragmenthidden', post );
- Reveal.addEventListener( 'overviewhidden', post );
- Reveal.addEventListener( 'overviewshown', post );
- Reveal.addEventListener( 'paused', post );
- Reveal.addEventListener( 'resumed', post );
-
- // Post the initial state
- post();
-
-}());
diff --git a/plugin/notes-server/index.js b/plugin/notes-server/index.js
deleted file mode 100644
index b95f07188c8..00000000000
--- a/plugin/notes-server/index.js
+++ /dev/null
@@ -1,69 +0,0 @@
-var http = require('http');
-var express = require('express');
-var fs = require('fs');
-var io = require('socket.io');
-var Mustache = require('mustache');
-
-var app = express();
-var staticDir = express.static;
-var server = http.createServer(app);
-
-io = io(server);
-
-var opts = {
- port : 1947,
- baseDir : __dirname + '/../../'
-};
-
-io.on( 'connection', function( socket ) {
-
- socket.on( 'new-subscriber', function( data ) {
- socket.broadcast.emit( 'new-subscriber', data );
- });
-
- socket.on( 'statechanged', function( data ) {
- delete data.state.overview;
- socket.broadcast.emit( 'statechanged', data );
- });
-
- socket.on( 'statechanged-speaker', function( data ) {
- delete data.state.overview;
- socket.broadcast.emit( 'statechanged-speaker', data );
- });
-
-});
-
-[ 'css', 'js', 'images', 'plugin', 'lib' ].forEach( function( dir ) {
- app.use( '/' + dir, staticDir( opts.baseDir + dir ) );
-});
-
-app.get('/', function( req, res ) {
-
- res.writeHead( 200, { 'Content-Type': 'text/html' } );
- fs.createReadStream( opts.baseDir + '/index.html' ).pipe( res );
-
-});
-
-app.get( '/notes/:socketId', function( req, res ) {
-
- fs.readFile( opts.baseDir + 'plugin/notes-server/notes.html', function( err, data ) {
- res.send( Mustache.to_html( data.toString(), {
- socketId : req.params.socketId
- }));
- });
-
-});
-
-// Actually listen
-server.listen( opts.port || null );
-
-var brown = '\033[33m',
- green = '\033[32m',
- reset = '\033[0m';
-
-var slidesLocation = 'http://localhost' + ( opts.port ? ( ':' + opts.port ) : '' );
-
-console.log( brown + 'reveal.js - Speaker Notes' + reset );
-console.log( '1. Open the slides at ' + green + slidesLocation + reset );
-console.log( '2. Click on the link in your JS console to go to the notes page' );
-console.log( '3. Advance through your slides and your notes will advance automatically' );
diff --git a/plugin/notes-server/notes.html b/plugin/notes-server/notes.html
deleted file mode 100644
index ab8c5b17aea..00000000000
--- a/plugin/notes-server/notes.html
+++ /dev/null
@@ -1,585 +0,0 @@
-
-
-
-
-
- reveal.js - Slide Notes
-
-
-
-
-
-
-
- Upcoming
-
-
-
Time Click to Reset
-
- 0:00 AM
-
-
- 00 :00 :00
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/plugin/notes/notes.esm.js b/plugin/notes/notes.esm.js
new file mode 100644
index 00000000000..f5692e87010
--- /dev/null
+++ b/plugin/notes/notes.esm.js
@@ -0,0 +1 @@
+function t(){return{baseUrl:null,breaks:!1,extensions:null,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}}let e={baseUrl:null,breaks:!1,extensions:null,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1};const n=/[&<>"']/,i=/[&<>"']/g,s=/[<>"']|&(?!#?\w+;)/,r=/[<>"']|&(?!#?\w+;)/g,a={"&":"&","<":"<",">":">",'"':""","'":"'"},l=t=>a[t];function o(t,e){if(e){if(n.test(t))return t.replace(i,l)}else if(s.test(t))return t.replace(r,l);return t}const c=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;function p(t){return t.replace(c,((t,e)=>"colon"===(e=e.toLowerCase())?":":"#"===e.charAt(0)?"x"===e.charAt(1)?String.fromCharCode(parseInt(e.substring(2),16)):String.fromCharCode(+e.substring(1)):""))}const u=/(^|[^\[])\^/g;function d(t,e){t=t.source||t,e=e||"";const n={replace:(e,i)=>(i=(i=i.source||i).replace(u,"$1"),t=t.replace(e,i),n),getRegex:()=>new RegExp(t,e)};return n}const h=/[^\w:]/g,g=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;function m(t,e,n){if(t){let t;try{t=decodeURIComponent(p(n)).replace(h,"").toLowerCase()}catch(t){return null}if(0===t.indexOf("javascript:")||0===t.indexOf("vbscript:")||0===t.indexOf("data:"))return null}e&&!g.test(n)&&(n=function(t,e){f[" "+t]||(k.test(t)?f[" "+t]=t+"/":f[" "+t]=S(t,"/",!0));t=f[" "+t];const n=-1===t.indexOf(":");return"//"===e.substring(0,2)?n?e:t.replace(w,"$1")+e:"/"===e.charAt(0)?n?e:t.replace(x,"$1")+e:t+e}(e,n));try{n=encodeURI(n).replace(/%25/g,"%")}catch(t){return null}return n}const f={},k=/^[^:]+:\/*[^/]*$/,w=/^([^:]+:)[\s\S]*$/,x=/^([^:]+:\/*[^/]*)[\s\S]*$/;const b={exec:function(){}};function y(t){let e,n,i=1;for(;i{let i=!1,s=e;for(;--s>=0&&"\\"===n[s];)i=!i;return i?"|":" |"})).split(/ \|/);let i=0;if(n[0].trim()||n.shift(),n.length>0&&!n[n.length-1].trim()&&n.pop(),n.length>e)n.splice(e);else for(;n.length1;)1&e&&(n+=t),e>>=1,t+=t;return n+t}function z(t,e,n,i){const s=e.href,r=e.title?o(e.title):null,a=t[1].replace(/\\([\[\]])/g,"$1");if("!"!==t[0].charAt(0)){i.state.inLink=!0;const t={type:"link",raw:n,href:s,title:r,text:a,tokens:i.inlineTokens(a,[])};return i.state.inLink=!1,t}return{type:"image",raw:n,href:s,title:r,text:o(a)}}class A{constructor(t){this.options=t||e}space(t){const e=this.rules.block.newline.exec(t);if(e&&e[0].length>0)return{type:"space",raw:e[0]}}code(t){const e=this.rules.block.code.exec(t);if(e){const t=e[0].replace(/^ {1,4}/gm,"");return{type:"code",raw:e[0],codeBlockStyle:"indented",text:this.options.pedantic?t:S(t,"\n")}}}fences(t){const e=this.rules.block.fences.exec(t);if(e){const t=e[0],n=function(t,e){const n=t.match(/^(\s+)(?:```)/);if(null===n)return e;const i=n[1];return e.split("\n").map((t=>{const e=t.match(/^\s+/);if(null===e)return t;const[n]=e;return n.length>=i.length?t.slice(i.length):t})).join("\n")}(t,e[3]||"");return{type:"code",raw:t,lang:e[2]?e[2].trim():e[2],text:n}}}heading(t){const e=this.rules.block.heading.exec(t);if(e){let t=e[2].trim();if(/#$/.test(t)){const e=S(t,"#");this.options.pedantic?t=e.trim():e&&!/ $/.test(e)||(t=e.trim())}const n={type:"heading",raw:e[0],depth:e[1].length,text:t,tokens:[]};return this.lexer.inline(n.text,n.tokens),n}}hr(t){const e=this.rules.block.hr.exec(t);if(e)return{type:"hr",raw:e[0]}}blockquote(t){const e=this.rules.block.blockquote.exec(t);if(e){const t=e[0].replace(/^ *> ?/gm,"");return{type:"blockquote",raw:e[0],tokens:this.lexer.blockTokens(t,[]),text:t}}}list(t){let e=this.rules.block.list.exec(t);if(e){let n,i,s,r,a,l,o,c,p,u,d,h,g=e[1].trim();const m=g.length>1,f={type:"list",raw:"",ordered:m,start:m?+g.slice(0,-1):"",loose:!1,items:[]};g=m?`\\d{1,9}\\${g.slice(-1)}`:`\\${g}`,this.options.pedantic&&(g=m?g:"[*+-]");const k=new RegExp(`^( {0,3}${g})((?: [^\\n]*)?(?:\\n|$))`);for(;t&&(h=!1,e=k.exec(t))&&!this.rules.block.hr.test(t);){if(n=e[0],t=t.substring(n.length),c=e[2].split("\n",1)[0],p=t.split("\n",1)[0],this.options.pedantic?(r=2,d=c.trimLeft()):(r=e[2].search(/[^ ]/),r=r>4?1:r,d=c.slice(r),r+=e[1].length),l=!1,!c&&/^ *$/.test(p)&&(n+=p+"\n",t=t.substring(p.length+1),h=!0),!h){const e=new RegExp(`^ {0,${Math.min(3,r-1)}}(?:[*+-]|\\d{1,9}[.)])`);for(;t&&(u=t.split("\n",1)[0],c=u,this.options.pedantic&&(c=c.replace(/^ {1,4}(?=( {4})*[^ ])/g," ")),!e.test(c));){if(c.search(/[^ ]/)>=r||!c.trim())d+="\n"+c.slice(r);else{if(l)break;d+="\n"+c}l||c.trim()||(l=!0),n+=u+"\n",t=t.substring(u.length+1)}}f.loose||(o?f.loose=!0:/\n *\n *$/.test(n)&&(o=!0)),this.options.gfm&&(i=/^\[[ xX]\] /.exec(d),i&&(s="[ ] "!==i[0],d=d.replace(/^\[[ xX]\] +/,""))),f.items.push({type:"list_item",raw:n,task:!!i,checked:s,loose:!1,text:d}),f.raw+=n}f.items[f.items.length-1].raw=n.trimRight(),f.items[f.items.length-1].text=d.trimRight(),f.raw=f.raw.trimRight();const w=f.items.length;for(a=0;a"space"===t.type)),e=t.every((t=>{const e=t.raw.split("");let n=0;for(const t of e)if("\n"===t&&(n+=1),n>1)return!0;return!1}));!f.loose&&t.length&&e&&(f.loose=!0,f.items[a].loose=!0)}return f}}html(t){const e=this.rules.block.html.exec(t);if(e){const t={type:"html",raw:e[0],pre:!this.options.sanitizer&&("pre"===e[1]||"script"===e[1]||"style"===e[1]),text:e[0]};return this.options.sanitize&&(t.type="paragraph",t.text=this.options.sanitizer?this.options.sanitizer(e[0]):o(e[0]),t.tokens=[],this.lexer.inline(t.text,t.tokens)),t}}def(t){const e=this.rules.block.def.exec(t);if(e){e[3]&&(e[3]=e[3].substring(1,e[3].length-1));return{type:"def",tag:e[1].toLowerCase().replace(/\s+/g," "),raw:e[0],href:e[2],title:e[3]}}}table(t){const e=this.rules.block.table.exec(t);if(e){const t={type:"table",header:v(e[1]).map((t=>({text:t}))),align:e[2].replace(/^ *|\| *$/g,"").split(/ *\| */),rows:e[3]&&e[3].trim()?e[3].replace(/\n[ \t]*$/,"").split("\n"):[]};if(t.header.length===t.align.length){t.raw=e[0];let n,i,s,r,a=t.align.length;for(n=0;n({text:t})));for(a=t.header.length,i=0;i /i.test(e[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&/^<(pre|code|kbd|script)(\s|>)/i.test(e[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(e[0])&&(this.lexer.state.inRawBlock=!1),{type:this.options.sanitize?"text":"html",raw:e[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(e[0]):o(e[0]):e[0]}}link(t){const e=this.rules.inline.link.exec(t);if(e){const t=e[2].trim();if(!this.options.pedantic&&/^$/.test(t))return;const e=S(t.slice(0,-1),"\\");if((t.length-e.length)%2==0)return}else{const t=function(t,e){if(-1===t.indexOf(e[1]))return-1;const n=t.length;let i=0,s=0;for(;s-1){const n=(0===e[0].indexOf("!")?5:4)+e[1].length+t;e[2]=e[2].substring(0,t),e[0]=e[0].substring(0,n).trim(),e[3]=""}}let n=e[2],i="";if(this.options.pedantic){const t=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(n);t&&(n=t[1],i=t[3])}else i=e[3]?e[3].slice(1,-1):"";return n=n.trim(),/^$/.test(t)?n.slice(1):n.slice(1,-1)),z(e,{href:n?n.replace(this.rules.inline._escapes,"$1"):n,title:i?i.replace(this.rules.inline._escapes,"$1"):i},e[0],this.lexer)}}reflink(t,e){let n;if((n=this.rules.inline.reflink.exec(t))||(n=this.rules.inline.nolink.exec(t))){let t=(n[2]||n[1]).replace(/\s+/g," ");if(t=e[t.toLowerCase()],!t||!t.href){const t=n[0].charAt(0);return{type:"text",raw:t,text:t}}return z(n,t,n[0],this.lexer)}}emStrong(t,e,n=""){let i=this.rules.inline.emStrong.lDelim.exec(t);if(!i)return;if(i[3]&&n.match(/[\p{L}\p{N}]/u))return;const s=i[1]||i[2]||"";if(!s||s&&(""===n||this.rules.inline.punctuation.exec(n))){const n=i[0].length-1;let s,r,a=n,l=0;const o="*"===i[0][0]?this.rules.inline.emStrong.rDelimAst:this.rules.inline.emStrong.rDelimUnd;for(o.lastIndex=0,e=e.slice(-1*t.length+n);null!=(i=o.exec(e));){if(s=i[1]||i[2]||i[3]||i[4]||i[5]||i[6],!s)continue;if(r=s.length,i[3]||i[4]){a+=r;continue}if((i[5]||i[6])&&n%3&&!((n+r)%3)){l+=r;continue}if(a-=r,a>0)continue;if(r=Math.min(r,r+a+l),Math.min(n,r)%2){const e=t.slice(1,n+i.index+r);return{type:"em",raw:t.slice(0,n+i.index+r+1),text:e,tokens:this.lexer.inlineTokens(e,[])}}const e=t.slice(2,n+i.index+r-1);return{type:"strong",raw:t.slice(0,n+i.index+r+1),text:e,tokens:this.lexer.inlineTokens(e,[])}}}}codespan(t){const e=this.rules.inline.code.exec(t);if(e){let t=e[2].replace(/\n/g," ");const n=/[^ ]/.test(t),i=/^ /.test(t)&&/ $/.test(t);return n&&i&&(t=t.substring(1,t.length-1)),t=o(t,!0),{type:"codespan",raw:e[0],text:t}}}br(t){const e=this.rules.inline.br.exec(t);if(e)return{type:"br",raw:e[0]}}del(t){const e=this.rules.inline.del.exec(t);if(e)return{type:"del",raw:e[0],text:e[2],tokens:this.lexer.inlineTokens(e[2],[])}}autolink(t,e){const n=this.rules.inline.autolink.exec(t);if(n){let t,i;return"@"===n[2]?(t=o(this.options.mangle?e(n[1]):n[1]),i="mailto:"+t):(t=o(n[1]),i=t),{type:"link",raw:n[0],text:t,href:i,tokens:[{type:"text",raw:t,text:t}]}}}url(t,e){let n;if(n=this.rules.inline.url.exec(t)){let t,i;if("@"===n[2])t=o(this.options.mangle?e(n[0]):n[0]),i="mailto:"+t;else{let e;do{e=n[0],n[0]=this.rules.inline._backpedal.exec(n[0])[0]}while(e!==n[0]);t=o(n[0]),i="www."===n[1]?"http://"+t:t}return{type:"link",raw:n[0],text:t,href:i,tokens:[{type:"text",raw:t,text:t}]}}}inlineText(t,e){const n=this.rules.inline.text.exec(t);if(n){let t;return t=this.lexer.state.inRawBlock?this.options.sanitize?this.options.sanitizer?this.options.sanitizer(n[0]):o(n[0]):n[0]:o(this.options.smartypants?e(n[0]):n[0]),{type:"text",raw:n[0],text:t}}}}const E={newline:/^(?: *(?:\n|$))+/,code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,fences:/^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( {0,3}bull)( [^\n]+?)?(?:\n|$)/,html:"^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))",def:/^ {0,3}\[(label)\]: *(?:\n *)?([^\s>]+)>?(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,table:b,lheading:/^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,_paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,text:/^[^\n]+/,_label:/(?!\s*\])(?:\\.|[^\[\]\\])+/,_title:/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/};E.def=d(E.def).replace("label",E._label).replace("title",E._title).getRegex(),E.bullet=/(?:[*+-]|\d{1,9}[.)])/,E.listItemStart=d(/^( *)(bull) */).replace("bull",E.bullet).getRegex(),E.list=d(E.list).replace(/bull/g,E.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+E.def.source+")").getRegex(),E._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",E._comment=/|$)/,E.html=d(E.html,"i").replace("comment",E._comment).replace("tag",E._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),E.paragraph=d(E._paragraph).replace("hr",E.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",E._tag).getRegex(),E.blockquote=d(E.blockquote).replace("paragraph",E.paragraph).getRegex(),E.normal=y({},E),E.gfm=y({},E.normal,{table:"^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"}),E.gfm.table=d(E.gfm.table).replace("hr",E.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",E._tag).getRegex(),E.gfm.paragraph=d(E._paragraph).replace("hr",E.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("table",E.gfm.table).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",E._tag).getRegex(),E.pedantic=y({},E.normal,{html:d("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?\\1> *(?:\\n{2,}|\\s*$)| \\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",E._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:b,paragraph:d(E.normal._paragraph).replace("hr",E.hr).replace("heading"," *#{1,6} *[^\n]").replace("lheading",E.lheading).replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").getRegex()});const $={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:b,tag:"^comment|^[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^",link:/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(ref)\]/,nolink:/^!?\[(ref)\](?:\[\])?/,reflinkSearch:"reflink|nolink(?!\\()",emStrong:{lDelim:/^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,rDelimAst:/^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,rDelimUnd:/^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/},code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,br:/^( {2,}|\\)\n(?!\s*$)/,del:b,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\.5&&(n="x"+n.toString(16)),i+=""+n+";";return i}$._punctuation="!\"#$%&'()+\\-.,/:;<=>?@\\[\\]`^{|}~",$.punctuation=d($.punctuation).replace(/punctuation/g,$._punctuation).getRegex(),$.blockSkip=/\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g,$.escapedEmSt=/\\\*|\\_/g,$._comment=d(E._comment).replace("(?:--\x3e|$)","--\x3e").getRegex(),$.emStrong.lDelim=d($.emStrong.lDelim).replace(/punct/g,$._punctuation).getRegex(),$.emStrong.rDelimAst=d($.emStrong.rDelimAst,"g").replace(/punct/g,$._punctuation).getRegex(),$.emStrong.rDelimUnd=d($.emStrong.rDelimUnd,"g").replace(/punct/g,$._punctuation).getRegex(),$._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,$._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,$._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,$.autolink=d($.autolink).replace("scheme",$._scheme).replace("email",$._email).getRegex(),$._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,$.tag=d($.tag).replace("comment",$._comment).replace("attribute",$._attribute).getRegex(),$._label=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,$._href=/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/,$._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,$.link=d($.link).replace("label",$._label).replace("href",$._href).replace("title",$._title).getRegex(),$.reflink=d($.reflink).replace("label",$._label).replace("ref",E._label).getRegex(),$.nolink=d($.nolink).replace("ref",E._label).getRegex(),$.reflinkSearch=d($.reflinkSearch,"g").replace("reflink",$.reflink).replace("nolink",$.nolink).getRegex(),$.normal=y({},$),$.pedantic=y({},$.normal,{strong:{start:/^__|\*\*/,middle:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,endAst:/\*\*(?!\*)/g,endUnd:/__(?!_)/g},em:{start:/^_|\*/,middle:/^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,endAst:/\*(?!\*)/g,endUnd:/_(?!_)/g},link:d(/^!?\[(label)\]\((.*?)\)/).replace("label",$._label).getRegex(),reflink:d(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",$._label).getRegex()}),$.gfm=y({},$.normal,{escape:d($.escape).replace("])","~|])").getRegex(),_extended_email:/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,url:/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\!!(n=i.call({lexer:this},t,e))&&(t=t.substring(n.raw.length),e.push(n),!0)))))if(n=this.tokenizer.space(t))t=t.substring(n.raw.length),1===n.raw.length&&e.length>0?e[e.length-1].raw+="\n":e.push(n);else if(n=this.tokenizer.code(t))t=t.substring(n.raw.length),i=e[e.length-1],!i||"paragraph"!==i.type&&"text"!==i.type?e.push(n):(i.raw+="\n"+n.raw,i.text+="\n"+n.text,this.inlineQueue[this.inlineQueue.length-1].src=i.text);else if(n=this.tokenizer.fences(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.heading(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.hr(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.blockquote(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.list(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.html(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.def(t))t=t.substring(n.raw.length),i=e[e.length-1],!i||"paragraph"!==i.type&&"text"!==i.type?this.tokens.links[n.tag]||(this.tokens.links[n.tag]={href:n.href,title:n.title}):(i.raw+="\n"+n.raw,i.text+="\n"+n.raw,this.inlineQueue[this.inlineQueue.length-1].src=i.text);else if(n=this.tokenizer.table(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.lheading(t))t=t.substring(n.raw.length),e.push(n);else{if(s=t,this.options.extensions&&this.options.extensions.startBlock){let e=1/0;const n=t.slice(1);let i;this.options.extensions.startBlock.forEach((function(t){i=t.call({lexer:this},n),"number"==typeof i&&i>=0&&(e=Math.min(e,i))})),e<1/0&&e>=0&&(s=t.substring(0,e+1))}if(this.state.top&&(n=this.tokenizer.paragraph(s)))i=e[e.length-1],r&&"paragraph"===i.type?(i.raw+="\n"+n.raw,i.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=i.text):e.push(n),r=s.length!==t.length,t=t.substring(n.raw.length);else if(n=this.tokenizer.text(t))t=t.substring(n.raw.length),i=e[e.length-1],i&&"text"===i.type?(i.raw+="\n"+n.raw,i.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=i.text):e.push(n);else if(t){const e="Infinite loop on byte: "+t.charCodeAt(0);if(this.options.silent){console.error(e);break}throw new Error(e)}}return this.state.top=!0,e}inline(t,e){this.inlineQueue.push({src:t,tokens:e})}inlineTokens(t,e=[]){let n,i,s,r,a,l,o=t;if(this.tokens.links){const t=Object.keys(this.tokens.links);if(t.length>0)for(;null!=(r=this.tokenizer.rules.inline.reflinkSearch.exec(o));)t.includes(r[0].slice(r[0].lastIndexOf("[")+1,-1))&&(o=o.slice(0,r.index)+"["+_("a",r[0].length-2)+"]"+o.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;null!=(r=this.tokenizer.rules.inline.blockSkip.exec(o));)o=o.slice(0,r.index)+"["+_("a",r[0].length-2)+"]"+o.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;null!=(r=this.tokenizer.rules.inline.escapedEmSt.exec(o));)o=o.slice(0,r.index)+"++"+o.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);for(;t;)if(a||(l=""),a=!1,!(this.options.extensions&&this.options.extensions.inline&&this.options.extensions.inline.some((i=>!!(n=i.call({lexer:this},t,e))&&(t=t.substring(n.raw.length),e.push(n),!0)))))if(n=this.tokenizer.escape(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.tag(t))t=t.substring(n.raw.length),i=e[e.length-1],i&&"text"===n.type&&"text"===i.type?(i.raw+=n.raw,i.text+=n.text):e.push(n);else if(n=this.tokenizer.link(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.reflink(t,this.tokens.links))t=t.substring(n.raw.length),i=e[e.length-1],i&&"text"===n.type&&"text"===i.type?(i.raw+=n.raw,i.text+=n.text):e.push(n);else if(n=this.tokenizer.emStrong(t,o,l))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.codespan(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.br(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.del(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.autolink(t,R))t=t.substring(n.raw.length),e.push(n);else if(this.state.inLink||!(n=this.tokenizer.url(t,R))){if(s=t,this.options.extensions&&this.options.extensions.startInline){let e=1/0;const n=t.slice(1);let i;this.options.extensions.startInline.forEach((function(t){i=t.call({lexer:this},n),"number"==typeof i&&i>=0&&(e=Math.min(e,i))})),e<1/0&&e>=0&&(s=t.substring(0,e+1))}if(n=this.tokenizer.inlineText(s,L))t=t.substring(n.raw.length),"_"!==n.raw.slice(-1)&&(l=n.raw.slice(-1)),a=!0,i=e[e.length-1],i&&"text"===i.type?(i.raw+=n.raw,i.text+=n.text):e.push(n);else if(t){const e="Infinite loop on byte: "+t.charCodeAt(0);if(this.options.silent){console.error(e);break}throw new Error(e)}}else t=t.substring(n.raw.length),e.push(n);return e}}class C{constructor(t){this.options=t||e}code(t,e,n){const i=(e||"").match(/\S*/)[0];if(this.options.highlight){const e=this.options.highlight(t,i);null!=e&&e!==t&&(n=!0,t=e)}return t=t.replace(/\n$/,"")+"\n",i?''+(n?t:o(t,!0))+"
\n":""+(n?t:o(t,!0))+"
\n"}blockquote(t){return"\n"+t+" \n"}html(t){return t}heading(t,e,n,i){return this.options.headerIds?"\n":""+t+" \n"}hr(){return this.options.xhtml?" \n":" \n"}list(t,e,n){const i=e?"ol":"ul";return"<"+i+(e&&1!==n?' start="'+n+'"':"")+">\n"+t+""+i+">\n"}listitem(t){return""+t+" \n"}checkbox(t){return" "}paragraph(t){return""+t+"
\n"}table(t,e){return e&&(e=""+e+" "),"\n"}tablerow(t){return"\n"+t+" \n"}tablecell(t,e){const n=e.header?"th":"td";return(e.align?"<"+n+' align="'+e.align+'">':"<"+n+">")+t+""+n+">\n"}strong(t){return""+t+" "}em(t){return""+t+" "}codespan(t){return""+t+"
"}br(){return this.options.xhtml?" ":" "}del(t){return""+t+""}link(t,e,n){if(null===(t=m(this.options.sanitize,this.options.baseUrl,t)))return n;let i='"+n+" ",i}image(t,e,n){if(null===(t=m(this.options.sanitize,this.options.baseUrl,t)))return n;let i=' ":">",i}text(t){return t}}class M{strong(t){return t}em(t){return t}codespan(t){return t}del(t){return t}html(t){return t}text(t){return t}link(t,e,n){return""+n}image(t,e,n){return""+n}br(){return""}}class q{constructor(){this.seen={}}serialize(t){return t.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-")}getNextSafeSlug(t,e){let n=t,i=0;if(this.seen.hasOwnProperty(n)){i=this.seen[t];do{i++,n=t+"-"+i}while(this.seen.hasOwnProperty(n))}return e||(this.seen[t]=i,this.seen[n]=0),n}slug(t,e={}){const n=this.serialize(t);return this.getNextSafeSlug(n,e.dryrun)}}class O{constructor(t){this.options=t||e,this.options.renderer=this.options.renderer||new C,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new M,this.slugger=new q}static parse(t,e){return new O(e).parse(t)}static parseInline(t,e){return new O(e).parseInline(t)}parse(t,e=!0){let n,i,s,r,a,l,o,c,u,d,h,g,m,f,k,w,x,b,y,v="";const S=t.length;for(n=0;n0&&"paragraph"===k.tokens[0].type?(k.tokens[0].text=b+" "+k.tokens[0].text,k.tokens[0].tokens&&k.tokens[0].tokens.length>0&&"text"===k.tokens[0].tokens[0].type&&(k.tokens[0].tokens[0].text=b+" "+k.tokens[0].tokens[0].text)):k.tokens.unshift({type:"text",text:b}):f+=b),f+=this.parse(k.tokens,m),u+=this.renderer.listitem(f,x,w);v+=this.renderer.list(u,h,g);continue;case"html":v+=this.renderer.html(d.text);continue;case"paragraph":v+=this.renderer.paragraph(this.parseInline(d.tokens));continue;case"text":for(u=d.tokens?this.parseInline(d.tokens):d.text;n+1{i(t.text,t.lang,(function(e,n){if(e)return r(e);null!=n&&n!==t.text&&(t.text=n,t.escaped=!0),a--,0===a&&r()}))}),0))})),void(0===a&&r())}try{const n=I.lex(t,e);return e.walkTokens&&P.walkTokens(n,e.walkTokens),O.parse(n,e)}catch(t){if(t.message+="\nPlease report this to https://github.com/markedjs/marked.",e.silent)return" An error occurred:
"+o(t.message+"",!0)+" ";throw t}}P.options=P.setOptions=function(t){var n;return y(P.defaults,t),n=P.defaults,e=n,P},P.getDefaults=t,P.defaults=e,P.use=function(...t){const e=y({},...t),n=P.defaults.extensions||{renderers:{},childTokens:{}};let i;t.forEach((t=>{if(t.extensions&&(i=!0,t.extensions.forEach((t=>{if(!t.name)throw new Error("extension name required");if(t.renderer){const e=n.renderers?n.renderers[t.name]:null;n.renderers[t.name]=e?function(...n){let i=t.renderer.apply(this,n);return!1===i&&(i=e.apply(this,n)),i}:t.renderer}if(t.tokenizer){if(!t.level||"block"!==t.level&&"inline"!==t.level)throw new Error("extension level must be 'block' or 'inline'");n[t.level]?n[t.level].unshift(t.tokenizer):n[t.level]=[t.tokenizer],t.start&&("block"===t.level?n.startBlock?n.startBlock.push(t.start):n.startBlock=[t.start]:"inline"===t.level&&(n.startInline?n.startInline.push(t.start):n.startInline=[t.start]))}t.childTokens&&(n.childTokens[t.name]=t.childTokens)}))),t.renderer){const n=P.defaults.renderer||new C;for(const e in t.renderer){const i=n[e];n[e]=(...s)=>{let r=t.renderer[e].apply(n,s);return!1===r&&(r=i.apply(n,s)),r}}e.renderer=n}if(t.tokenizer){const n=P.defaults.tokenizer||new A;for(const e in t.tokenizer){const i=n[e];n[e]=(...s)=>{let r=t.tokenizer[e].apply(n,s);return!1===r&&(r=i.apply(n,s)),r}}e.tokenizer=n}if(t.walkTokens){const n=P.defaults.walkTokens;e.walkTokens=function(e){t.walkTokens.call(this,e),n&&n.call(this,e)}}i&&(e.extensions=n),P.setOptions(e)}))},P.walkTokens=function(t,e){for(const n of t)switch(e.call(P,n),n.type){case"table":for(const t of n.header)P.walkTokens(t.tokens,e);for(const t of n.rows)for(const n of t)P.walkTokens(n.tokens,e);break;case"list":P.walkTokens(n.items,e);break;default:P.defaults.extensions&&P.defaults.extensions.childTokens&&P.defaults.extensions.childTokens[n.type]?P.defaults.extensions.childTokens[n.type].forEach((function(t){P.walkTokens(n[t],e)})):n.tokens&&P.walkTokens(n.tokens,e)}},P.parseInline=function(t,e){if(null==t)throw new Error("marked.parseInline(): input parameter is undefined or null");if("string"!=typeof t)throw new Error("marked.parseInline(): input parameter is of type "+Object.prototype.toString.call(t)+", string expected");T(e=y({},P.defaults,e||{}));try{const n=I.lexInline(t,e);return e.walkTokens&&P.walkTokens(n,e.walkTokens),O.parseInline(n,e)}catch(t){if(t.message+="\nPlease report this to https://github.com/markedjs/marked.",e.silent)return"An error occurred:
"+o(t.message+"",!0)+" ";throw t}},P.Parser=O,P.parser=O.parse,P.Renderer=C,P.TextRenderer=M,P.Lexer=I,P.lexer=I.lex,P.Tokenizer=A,P.Slugger=q,P.parse=P;export default()=>{let t,e,n=null;function i(){if(n&&!n.closed)n.focus();else{if(n=window.open("about:blank","reveal.js - Notes","width=1100,height=700"),n.marked=P,n.document.write("\x3c!--\n\tNOTE: You need to build the notes plugin after making changes to this file.\n--\x3e\n\n\t\n\t\t \n\n\t\treveal.js - Speaker View \n\n\t\t\n\t\n\n\t\n\n\t\tLoading speaker view...
\n\n\t\t
\n\t\tUpcoming
\n\t\t\n\t\t\t
\n\t\t\t\t
Time Click to Reset \n\t\t\t\t
\n\t\t\t\t\t0:00 AM \n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t00 :00 :00 \n\t\t\t\t
\n\t\t\t\t
\n\n\t\t\t\t
Pacing – Time to finish current slide \n\t\t\t\t
\n\t\t\t\t\t00 :00 :00 \n\t\t\t\t
\n\t\t\t
\n\n\t\t\t
\n\t\t\t\t
Notes \n\t\t\t\t
\n\t\t\t
\n\t\t
\n\t\t\n\t\t\t \n\t\t\t \n\t\t
\n\n\t\t
-
+
\ No newline at end of file
diff --git a/plugin/print-pdf/print-pdf.js b/plugin/print-pdf/print-pdf.js
deleted file mode 100644
index f62aedc8e67..00000000000
--- a/plugin/print-pdf/print-pdf.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * phantomjs script for printing presentations to PDF.
- *
- * Example:
- * phantomjs print-pdf.js "http://revealjs.com?print-pdf" reveal-demo.pdf
- *
- * @author Manuel Bieh (https://github.com/manuelbieh)
- * @author Hakim El Hattab (https://github.com/hakimel)
- * @author Manuel Riezebosch (https://github.com/riezebosch)
- */
-
-// html2pdf.js
-var system = require( 'system' );
-
-var probePage = new WebPage();
-var printPage = new WebPage();
-
-var inputFile = system.args[1] || 'index.html?print-pdf';
-var outputFile = system.args[2] || 'slides.pdf';
-
-if( outputFile.match( /\.pdf$/gi ) === null ) {
- outputFile += '.pdf';
-}
-
-console.log( 'Export PDF: Reading reveal.js config [1/4]' );
-
-probePage.open( inputFile, function( status ) {
-
- console.log( 'Export PDF: Preparing print layout [2/4]' );
-
- var config = probePage.evaluate( function() {
- return Reveal.getConfig();
- } );
-
- if( config ) {
-
- printPage.paperSize = {
- width: Math.floor( config.width * ( 1 + config.margin ) ),
- height: Math.floor( config.height * ( 1 + config.margin ) ),
- border: 0
- };
-
- printPage.open( inputFile, function( status ) {
- console.log( 'Export PDF: Preparing pdf [3/4]')
- printPage.evaluate( function() {
- Reveal.isReady() ? window.callPhantom() : Reveal.addEventListener( 'pdf-ready', window.callPhantom );
- } );
- } );
-
- printPage.onCallback = function( data ) {
- // For some reason we need to "jump the queue" for syntax highlighting to work.
- // See: http://stackoverflow.com/a/3580132/129269
- setTimeout( function() {
- console.log( 'Export PDF: Writing file [4/4]' );
- printPage.render( outputFile );
- console.log( 'Export PDF: Finished successfully!' );
- phantom.exit();
- }, 0 );
- };
- }
- else {
-
- console.log( 'Export PDF: Unable to read reveal.js config. Make sure the input address points to a reveal.js page.' );
- phantom.exit( 1 );
-
- }
-} );
diff --git a/plugin/search/plugin.js b/plugin/search/plugin.js
new file mode 100644
index 00000000000..5d09ce6ab41
--- /dev/null
+++ b/plugin/search/plugin.js
@@ -0,0 +1,243 @@
+/*!
+ * Handles finding a text string anywhere in the slides and showing the next occurrence to the user
+ * by navigatating to that slide and highlighting it.
+ *
+ * @author Jon Snyder , February 2013
+ */
+
+const Plugin = () => {
+
+ // The reveal.js instance this plugin is attached to
+ let deck;
+
+ let searchElement;
+ let searchButton;
+ let searchInput;
+
+ let matchedSlides;
+ let currentMatchedIndex;
+ let searchboxDirty;
+ let hilitor;
+
+ function render() {
+
+ searchElement = document.createElement( 'div' );
+ searchElement.classList.add( 'searchbox' );
+ searchElement.style.position = 'absolute';
+ searchElement.style.top = '10px';
+ searchElement.style.right = '10px';
+ searchElement.style.zIndex = 10;
+
+ //embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/:
+ searchElement.innerHTML = `
+ `;
+
+ searchInput = searchElement.querySelector( '.searchinput' );
+ searchInput.style.width = '240px';
+ searchInput.style.fontSize = '14px';
+ searchInput.style.padding = '4px 6px';
+ searchInput.style.color = '#000';
+ searchInput.style.background = '#fff';
+ searchInput.style.borderRadius = '2px';
+ searchInput.style.border = '0';
+ searchInput.style.outline = '0';
+ searchInput.style.boxShadow = '0 2px 18px rgba(0, 0, 0, 0.2)';
+ searchInput.style['-webkit-appearance'] = 'none';
+
+ deck.getRevealElement().appendChild( searchElement );
+
+ // searchButton.addEventListener( 'click', function(event) {
+ // doSearch();
+ // }, false );
+
+ searchInput.addEventListener( 'keyup', function( event ) {
+ switch (event.keyCode) {
+ case 13:
+ event.preventDefault();
+ doSearch();
+ searchboxDirty = false;
+ break;
+ default:
+ searchboxDirty = true;
+ }
+ }, false );
+
+ closeSearch();
+
+ }
+
+ function openSearch() {
+ if( !searchElement ) render();
+
+ searchElement.style.display = 'inline';
+ searchInput.focus();
+ searchInput.select();
+ }
+
+ function closeSearch() {
+ if( !searchElement ) render();
+
+ searchElement.style.display = 'none';
+ if(hilitor) hilitor.remove();
+ }
+
+ function toggleSearch() {
+ if( !searchElement ) render();
+
+ if (searchElement.style.display !== 'inline') {
+ openSearch();
+ }
+ else {
+ closeSearch();
+ }
+ }
+
+ function doSearch() {
+ //if there's been a change in the search term, perform a new search:
+ if (searchboxDirty) {
+ var searchstring = searchInput.value;
+
+ if (searchstring === '') {
+ if(hilitor) hilitor.remove();
+ matchedSlides = null;
+ }
+ else {
+ //find the keyword amongst the slides
+ hilitor = new Hilitor("slidecontent");
+ matchedSlides = hilitor.apply(searchstring);
+ currentMatchedIndex = 0;
+ }
+ }
+
+ if (matchedSlides) {
+ //navigate to the next slide that has the keyword, wrapping to the first if necessary
+ if (matchedSlides.length && (matchedSlides.length <= currentMatchedIndex)) {
+ currentMatchedIndex = 0;
+ }
+ if (matchedSlides.length > currentMatchedIndex) {
+ deck.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v);
+ currentMatchedIndex++;
+ }
+ }
+ }
+
+ // Original JavaScript code by Chirp Internet: www.chirp.com.au
+ // Please acknowledge use of this code by including this header.
+ // 2/2013 jon: modified regex to display any match, not restricted to word boundaries.
+ function Hilitor(id, tag) {
+
+ var targetNode = document.getElementById(id) || document.body;
+ var hiliteTag = tag || "EM";
+ var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM)$");
+ var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
+ var wordColor = [];
+ var colorIdx = 0;
+ var matchRegex = "";
+ var matchingSlides = [];
+
+ this.setRegex = function(input)
+ {
+ input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|");
+ matchRegex = new RegExp("(" + input + ")","i");
+ }
+
+ this.getRegex = function()
+ {
+ return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " ");
+ }
+
+ // recursively apply word highlighting
+ this.hiliteWords = function(node)
+ {
+ if(node == undefined || !node) return;
+ if(!matchRegex) return;
+ if(skipTags.test(node.nodeName)) return;
+
+ if(node.hasChildNodes()) {
+ for(var i=0; i < node.childNodes.length; i++)
+ this.hiliteWords(node.childNodes[i]);
+ }
+ if(node.nodeType == 3) { // NODE_TEXT
+ var nv, regs;
+ if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
+ //find the slide's section element and save it in our list of matching slides
+ var secnode = node;
+ while (secnode != null && secnode.nodeName != 'SECTION') {
+ secnode = secnode.parentNode;
+ }
+
+ var slideIndex = deck.getIndices(secnode);
+ var slidelen = matchingSlides.length;
+ var alreadyAdded = false;
+ for (var i=0; i < slidelen; i++) {
+ if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) {
+ alreadyAdded = true;
+ }
+ }
+ if (! alreadyAdded) {
+ matchingSlides.push(slideIndex);
+ }
+
+ if(!wordColor[regs[0].toLowerCase()]) {
+ wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
+ }
+
+ var match = document.createElement(hiliteTag);
+ match.appendChild(document.createTextNode(regs[0]));
+ match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
+ match.style.fontStyle = "inherit";
+ match.style.color = "#000";
+
+ var after = node.splitText(regs.index);
+ after.nodeValue = after.nodeValue.substring(regs[0].length);
+ node.parentNode.insertBefore(match, after);
+ }
+ }
+ };
+
+ // remove highlighting
+ this.remove = function()
+ {
+ var arr = document.getElementsByTagName(hiliteTag);
+ var el;
+ while(arr.length && (el = arr[0])) {
+ el.parentNode.replaceChild(el.firstChild, el);
+ }
+ };
+
+ // start highlighting at target node
+ this.apply = function(input)
+ {
+ if(input == undefined || !input) return;
+ this.remove();
+ this.setRegex(input);
+ this.hiliteWords(targetNode);
+ return matchingSlides;
+ };
+
+ }
+
+ return {
+
+ id: 'search',
+
+ init: reveal => {
+
+ deck = reveal;
+ deck.registerKeyboardShortcut( 'CTRL + Shift + F', 'Search' );
+
+ document.addEventListener( 'keydown', function( event ) {
+ if( event.key == "F" && (event.ctrlKey || event.metaKey) ) { //Control+Shift+f
+ event.preventDefault();
+ toggleSearch();
+ }
+ }, false );
+
+ },
+
+ open: openSearch
+
+ }
+};
+
+export default Plugin;
\ No newline at end of file
diff --git a/plugin/search/search.esm.js b/plugin/search/search.esm.js
new file mode 100644
index 00000000000..d362036dfe6
--- /dev/null
+++ b/plugin/search/search.esm.js
@@ -0,0 +1,7 @@
+/*!
+ * Handles finding a text string anywhere in the slides and showing the next occurrence to the user
+ * by navigatating to that slide and highlighting it.
+ *
+ * @author Jon Snyder , February 2013
+ */
+export default()=>{let e,t,n,l,i,o,r;function s(){t=document.createElement("div"),t.classList.add("searchbox"),t.style.position="absolute",t.style.top="10px",t.style.right="10px",t.style.zIndex=10,t.innerHTML=' \n\t\t',n=t.querySelector(".searchinput"),n.style.width="240px",n.style.fontSize="14px",n.style.padding="4px 6px",n.style.color="#000",n.style.background="#fff",n.style.borderRadius="2px",n.style.border="0",n.style.outline="0",n.style.boxShadow="0 2px 18px rgba(0, 0, 0, 0.2)",n.style["-webkit-appearance"]="none",e.getRevealElement().appendChild(t),n.addEventListener("keyup",(function(t){if(13===t.keyCode)t.preventDefault(),function(){if(o){var t=n.value;""===t?(r&&r.remove(),l=null):(r=new c("slidecontent"),l=r.apply(t),i=0)}l&&(l.length&&l.length<=i&&(i=0),l.length>i&&(e.slide(l[i].h,l[i].v),i++))}(),o=!1;else o=!0}),!1),d()}function a(){t||s(),t.style.display="inline",n.focus(),n.select()}function d(){t||s(),t.style.display="none",r&&r.remove()}function c(t,n){var l=document.getElementById(t)||document.body,i=n||"EM",o=new RegExp("^(?:"+i+"|SCRIPT|FORM)$"),r=["#ff6","#a0ffff","#9f9","#f99","#f6f"],s=[],a=0,d="",c=[];this.setRegex=function(e){e=e.replace(/^[^\w]+|[^\w]+$/g,"").replace(/[^\w'-]+/g,"|"),d=new RegExp("("+e+")","i")},this.getRegex=function(){return d.toString().replace(/^\/\\b\(|\)\\b\/i$/g,"").replace(/\|/g," ")},this.hiliteWords=function(t){if(null!=t&&t&&d&&!o.test(t.nodeName)){if(t.hasChildNodes())for(var n=0;n{e=n,e.registerKeyboardShortcut("CTRL + Shift + F","Search"),document.addEventListener("keydown",(function(e){"F"==e.key&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),t||s(),"inline"!==t.style.display?a():d())}),!1)},open:a}};
diff --git a/plugin/search/search.js b/plugin/search/search.js
index 21c03671120..dc96e1dccc0 100644
--- a/plugin/search/search.js
+++ b/plugin/search/search.js
@@ -1,206 +1,7 @@
-/*
- * Handles finding a text string anywhere in the slides and showing the next occurrence to the user
- * by navigatating to that slide and highlighting it.
- *
- * By Jon Snyder , February 2013
- */
-
-var RevealSearch = (function() {
-
- var matchedSlides;
- var currentMatchedIndex;
- var searchboxDirty;
- var myHilitor;
-
-// Original JavaScript code by Chirp Internet: www.chirp.com.au
-// Please acknowledge use of this code by including this header.
-// 2/2013 jon: modified regex to display any match, not restricted to word boundaries.
-
-function Hilitor(id, tag)
-{
-
- var targetNode = document.getElementById(id) || document.body;
- var hiliteTag = tag || "EM";
- var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM)$");
- var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
- var wordColor = [];
- var colorIdx = 0;
- var matchRegex = "";
- var matchingSlides = [];
-
- this.setRegex = function(input)
- {
- input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|");
- matchRegex = new RegExp("(" + input + ")","i");
- }
-
- this.getRegex = function()
- {
- return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " ");
- }
-
- // recursively apply word highlighting
- this.hiliteWords = function(node)
- {
- if(node == undefined || !node) return;
- if(!matchRegex) return;
- if(skipTags.test(node.nodeName)) return;
-
- if(node.hasChildNodes()) {
- for(var i=0; i < node.childNodes.length; i++)
- this.hiliteWords(node.childNodes[i]);
- }
- if(node.nodeType == 3) { // NODE_TEXT
- if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
- //find the slide's section element and save it in our list of matching slides
- var secnode = node;
- while (secnode != null && secnode.nodeName != 'SECTION') {
- secnode = secnode.parentNode;
- }
-
- var slideIndex = Reveal.getIndices(secnode);
- var slidelen = matchingSlides.length;
- var alreadyAdded = false;
- for (var i=0; i < slidelen; i++) {
- if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) {
- alreadyAdded = true;
- }
- }
- if (! alreadyAdded) {
- matchingSlides.push(slideIndex);
- }
-
- if(!wordColor[regs[0].toLowerCase()]) {
- wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
- }
-
- var match = document.createElement(hiliteTag);
- match.appendChild(document.createTextNode(regs[0]));
- match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
- match.style.fontStyle = "inherit";
- match.style.color = "#000";
-
- var after = node.splitText(regs.index);
- after.nodeValue = after.nodeValue.substring(regs[0].length);
- node.parentNode.insertBefore(match, after);
- }
- }
- };
-
- // remove highlighting
- this.remove = function()
- {
- var arr = document.getElementsByTagName(hiliteTag);
- while(arr.length && (el = arr[0])) {
- el.parentNode.replaceChild(el.firstChild, el);
- }
- };
-
- // start highlighting at target node
- this.apply = function(input)
- {
- if(input == undefined || !input) return;
- this.remove();
- this.setRegex(input);
- this.hiliteWords(targetNode);
- return matchingSlides;
- };
-
-}
-
- function openSearch() {
- //ensure the search term input dialog is visible and has focus:
- var inputboxdiv = document.getElementById("searchinputdiv");
- var inputbox = document.getElementById("searchinput");
- inputboxdiv.style.display = "inline";
- inputbox.focus();
- inputbox.select();
- }
-
- function closeSearch() {
- var inputboxdiv = document.getElementById("searchinputdiv");
- inputboxdiv.style.display = "none";
- if(myHilitor) myHilitor.remove();
- }
-
- function toggleSearch() {
- var inputboxdiv = document.getElementById("searchinputdiv");
- if (inputboxdiv.style.display !== "inline") {
- openSearch();
- }
- else {
- closeSearch();
- }
- }
-
- function doSearch() {
- //if there's been a change in the search term, perform a new search:
- if (searchboxDirty) {
- var searchstring = document.getElementById("searchinput").value;
-
- if (searchstring === '') {
- if(myHilitor) myHilitor.remove();
- matchedSlides = null;
- }
- else {
- //find the keyword amongst the slides
- myHilitor = new Hilitor("slidecontent");
- matchedSlides = myHilitor.apply(searchstring);
- currentMatchedIndex = 0;
- }
- }
-
- if (matchedSlides) {
- //navigate to the next slide that has the keyword, wrapping to the first if necessary
- if (matchedSlides.length && (matchedSlides.length <= currentMatchedIndex)) {
- currentMatchedIndex = 0;
- }
- if (matchedSlides.length > currentMatchedIndex) {
- Reveal.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v);
- currentMatchedIndex++;
- }
- }
- }
-
- var dom = {};
- dom.wrapper = document.querySelector( '.reveal' );
-
- if( !dom.wrapper.querySelector( '.searchbox' ) ) {
- var searchElement = document.createElement( 'div' );
- searchElement.id = "searchinputdiv";
- searchElement.classList.add( 'searchdiv' );
- searchElement.style.position = 'absolute';
- searchElement.style.top = '10px';
- searchElement.style.right = '10px';
- searchElement.style.zIndex = 10;
- //embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/:
- searchElement.innerHTML = ' ';
- dom.wrapper.appendChild( searchElement );
- }
-
- document.getElementById( 'searchbutton' ).addEventListener( 'click', function(event) {
- doSearch();
- }, false );
-
- document.getElementById( 'searchinput' ).addEventListener( 'keyup', function( event ) {
- switch (event.keyCode) {
- case 13:
- event.preventDefault();
- doSearch();
- searchboxDirty = false;
- break;
- default:
- searchboxDirty = true;
- }
- }, false );
-
- document.addEventListener( 'keydown', function( event ) {
- if( event.key == "F" && (event.ctrlKey || event.metaKey) ) { //Control+Shift+f
- event.preventDefault();
- toggleSearch();
- }
- }, false );
- if( window.Reveal ) Reveal.registerKeyboardShortcut( 'CTRL + Shift + F', 'Search' );
- closeSearch();
- return { open: openSearch };
-})();
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).RevealSearch=t()}(this,(function(){"use strict";
+/*!
+ * Handles finding a text string anywhere in the slides and showing the next occurrence to the user
+ * by navigatating to that slide and highlighting it.
+ *
+ * @author Jon Snyder , February 2013
+ */return()=>{let e,t,n,l,o,i,r;function s(){t=document.createElement("div"),t.classList.add("searchbox"),t.style.position="absolute",t.style.top="10px",t.style.right="10px",t.style.zIndex=10,t.innerHTML=' \n\t\t',n=t.querySelector(".searchinput"),n.style.width="240px",n.style.fontSize="14px",n.style.padding="4px 6px",n.style.color="#000",n.style.background="#fff",n.style.borderRadius="2px",n.style.border="0",n.style.outline="0",n.style.boxShadow="0 2px 18px rgba(0, 0, 0, 0.2)",n.style["-webkit-appearance"]="none",e.getRevealElement().appendChild(t),n.addEventListener("keyup",(function(t){if(13===t.keyCode)t.preventDefault(),function(){if(i){var t=n.value;""===t?(r&&r.remove(),l=null):(r=new c("slidecontent"),l=r.apply(t),o=0)}l&&(l.length&&l.length<=o&&(o=0),l.length>o&&(e.slide(l[o].h,l[o].v),o++))}(),i=!1;else i=!0}),!1),d()}function a(){t||s(),t.style.display="inline",n.focus(),n.select()}function d(){t||s(),t.style.display="none",r&&r.remove()}function c(t,n){var l=document.getElementById(t)||document.body,o=n||"EM",i=new RegExp("^(?:"+o+"|SCRIPT|FORM)$"),r=["#ff6","#a0ffff","#9f9","#f99","#f6f"],s=[],a=0,d="",c=[];this.setRegex=function(e){e=e.replace(/^[^\w]+|[^\w]+$/g,"").replace(/[^\w'-]+/g,"|"),d=new RegExp("("+e+")","i")},this.getRegex=function(){return d.toString().replace(/^\/\\b\(|\)\\b\/i$/g,"").replace(/\|/g," ")},this.hiliteWords=function(t){if(null!=t&&t&&d&&!i.test(t.nodeName)){if(t.hasChildNodes())for(var n=0;n{e=n,e.registerKeyboardShortcut("CTRL + Shift + F","Search"),document.addEventListener("keydown",(function(e){"F"==e.key&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),t||s(),"inline"!==t.style.display?a():d())}),!1)},open:a}}}));
diff --git a/plugin/zoom-js/zoom.js b/plugin/zoom/plugin.js
similarity index 76%
rename from plugin/zoom-js/zoom.js
rename to plugin/zoom/plugin.js
index 92c3ba5b75e..960fb810890 100644
--- a/plugin/zoom-js/zoom.js
+++ b/plugin/zoom/plugin.js
@@ -1,33 +1,41 @@
-// Custom reveal.js integration
-var RevealZoom = (function(){
+/*!
+ * reveal.js Zoom plugin
+ */
+const Plugin = {
- return {
- init: function() {
+ id: 'zoom',
- Reveal.getRevealElement().addEventListener( 'mousedown', function( event ) {
- var defaultModifier = /Linux/.test( window.navigator.platform ) ? 'ctrl' : 'alt';
+ init: function( reveal ) {
- var modifier = ( Reveal.getConfig().zoomKey ? Reveal.getConfig().zoomKey : defaultModifier ) + 'Key';
- var zoomLevel = ( Reveal.getConfig().zoomLevel ? Reveal.getConfig().zoomLevel : 2 );
+ reveal.getRevealElement().addEventListener( 'mousedown', function( event ) {
+ var defaultModifier = /Linux/.test( window.navigator.platform ) ? 'ctrl' : 'alt';
- if( event[ modifier ] && !Reveal.isOverview() ) {
- event.preventDefault();
+ var modifier = ( reveal.getConfig().zoomKey ? reveal.getConfig().zoomKey : defaultModifier ) + 'Key';
+ var zoomLevel = ( reveal.getConfig().zoomLevel ? reveal.getConfig().zoomLevel : 2 );
- zoom.to({
- x: event.clientX,
- y: event.clientY,
- scale: zoomLevel,
- pan: false
- });
- }
- } );
+ if( event[ modifier ] && !reveal.isOverview() ) {
+ event.preventDefault();
+
+ zoom.to({
+ x: event.clientX,
+ y: event.clientY,
+ scale: zoomLevel,
+ pan: false
+ });
+ }
+ } );
+
+ },
+
+ destroy: () => {
+
+ zoom.reset();
- }
}
-})();
+};
-Reveal.registerPlugin( 'zoom', RevealZoom );
+export default () => Plugin;
/*!
* zoom.js 0.3 (modified for use with reveal.js)
@@ -50,19 +58,11 @@ var zoom = (function(){
panUpdateInterval = -1;
// Check for transform support so that we can fallback otherwise
- var supportsTransforms = 'WebkitTransform' in document.body.style ||
- 'MozTransform' in document.body.style ||
- 'msTransform' in document.body.style ||
- 'OTransform' in document.body.style ||
- 'transform' in document.body.style;
+ var supportsTransforms = 'transform' in document.body.style;
if( supportsTransforms ) {
// The easing that will be applied when we zoom in/out
document.body.style.transition = 'transform 0.8s ease';
- document.body.style.OTransition = '-o-transform 0.8s ease';
- document.body.style.msTransition = '-ms-transform 0.8s ease';
- document.body.style.MozTransition = '-moz-transform 0.8s ease';
- document.body.style.WebkitTransition = '-webkit-transform 0.8s ease';
}
// Zoom out if the user hits escape
@@ -103,10 +103,6 @@ var zoom = (function(){
// Reset
if( scale === 1 ) {
document.body.style.transform = '';
- document.body.style.OTransform = '';
- document.body.style.msTransform = '';
- document.body.style.MozTransform = '';
- document.body.style.WebkitTransform = '';
}
// Scale
else {
@@ -114,16 +110,7 @@ var zoom = (function(){
transform = 'translate('+ -rect.x +'px,'+ -rect.y +'px) scale('+ scale +')';
document.body.style.transformOrigin = origin;
- document.body.style.OTransformOrigin = origin;
- document.body.style.msTransformOrigin = origin;
- document.body.style.MozTransformOrigin = origin;
- document.body.style.WebkitTransformOrigin = origin;
-
document.body.style.transform = transform;
- document.body.style.OTransform = transform;
- document.body.style.msTransform = transform;
- document.body.style.MozTransform = transform;
- document.body.style.WebkitTransform = transform;
}
}
else {
diff --git a/plugin/zoom/zoom.esm.js b/plugin/zoom/zoom.esm.js
new file mode 100644
index 00000000000..3b66c57f8c6
--- /dev/null
+++ b/plugin/zoom/zoom.esm.js
@@ -0,0 +1,11 @@
+/*!
+ * reveal.js Zoom plugin
+ */
+const e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(o){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;o[i]&&!e.isOverview()&&(o.preventDefault(),t.to({x:o.clientX,y:o.clientY,scale:d,pan:!1}))}))},destroy:()=>{t.reset()}};var t=function(){var e=1,o=0,n=0,i=-1,d=-1,l="transform"in document.body.style;function s(t,o){var n=r();if(t.width=t.width||1,t.height=t.height||1,t.x-=(window.innerWidth-t.width*o)/2,t.y-=(window.innerHeight-t.height*o)/2,l)if(1===o)document.body.style.transform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-t.x+"px,"+-t.y+"px) scale("+o+")";document.body.style.transformOrigin=i,document.body.style.transform=d}else 1===o?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+t.x)/o+"px",document.body.style.top=-(n.y+t.y)/o+"px",document.body.style.width=100*o+"%",document.body.style.height=100*o+"%",document.body.style.zoom=o);e=o,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function c(){var t=.12*window.innerWidth,i=.12*window.innerHeight,d=r();nwindow.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),owindow.innerWidth-t&&window.scroll(d.x+(1-(window.innerWidth-o)/t)*(14/e),d.y)}function r(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return l&&(document.body.style.transition="transform 0.8s ease"),document.addEventListener("keyup",(function(o){1!==e&&27===o.keyCode&&t.out()})),document.addEventListener("mousemove",(function(t){1!==e&&(o=t.clientX,n=t.clientY)})),{to:function(o){if(1!==e)t.out();else{if(o.x=o.x||0,o.y=o.y||0,o.element){var n=o.element.getBoundingClientRect();o.x=n.left-20,o.y=n.top-20,o.width=n.width+40,o.height=n.height+40}void 0!==o.width&&void 0!==o.height&&(o.scale=Math.max(Math.min(window.innerWidth/o.width,window.innerHeight/o.height),1)),o.scale>1&&(o.x*=o.scale,o.y*=o.scale,s(o,o.scale),!1!==o.pan&&(i=setTimeout((function(){d=setInterval(c,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),s({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();
+/*!
+ * zoom.js 0.3 (modified for use with reveal.js)
+ * http://lab.hakim.se/zoom-js
+ * MIT licensed
+ *
+ * Copyright (C) 2011-2014 Hakim El Hattab, http://hakim.se
+ */export default()=>e;
diff --git a/plugin/zoom/zoom.js b/plugin/zoom/zoom.js
new file mode 100644
index 00000000000..7ac212754ac
--- /dev/null
+++ b/plugin/zoom/zoom.js
@@ -0,0 +1,11 @@
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).RevealZoom=t()}(this,(function(){"use strict";
+/*!
+ * reveal.js Zoom plugin
+ */const e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(o){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;o[i]&&!e.isOverview()&&(o.preventDefault(),t.to({x:o.clientX,y:o.clientY,scale:d,pan:!1}))}))},destroy:()=>{t.reset()}};var t=function(){var e=1,o=0,n=0,i=-1,d=-1,l="transform"in document.body.style;function s(t,o){var n=r();if(t.width=t.width||1,t.height=t.height||1,t.x-=(window.innerWidth-t.width*o)/2,t.y-=(window.innerHeight-t.height*o)/2,l)if(1===o)document.body.style.transform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-t.x+"px,"+-t.y+"px) scale("+o+")";document.body.style.transformOrigin=i,document.body.style.transform=d}else 1===o?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+t.x)/o+"px",document.body.style.top=-(n.y+t.y)/o+"px",document.body.style.width=100*o+"%",document.body.style.height=100*o+"%",document.body.style.zoom=o);e=o,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function c(){var t=.12*window.innerWidth,i=.12*window.innerHeight,d=r();nwindow.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),owindow.innerWidth-t&&window.scroll(d.x+(1-(window.innerWidth-o)/t)*(14/e),d.y)}function r(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return l&&(document.body.style.transition="transform 0.8s ease"),document.addEventListener("keyup",(function(o){1!==e&&27===o.keyCode&&t.out()})),document.addEventListener("mousemove",(function(t){1!==e&&(o=t.clientX,n=t.clientY)})),{to:function(o){if(1!==e)t.out();else{if(o.x=o.x||0,o.y=o.y||0,o.element){var n=o.element.getBoundingClientRect();o.x=n.left-20,o.y=n.top-20,o.width=n.width+40,o.height=n.height+40}void 0!==o.width&&void 0!==o.height&&(o.scale=Math.max(Math.min(window.innerWidth/o.width,window.innerHeight/o.height),1)),o.scale>1&&(o.x*=o.scale,o.y*=o.scale,s(o,o.scale),!1!==o.pan&&(i=setTimeout((function(){d=setInterval(c,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),s({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();
+/*!
+ * zoom.js 0.3 (modified for use with reveal.js)
+ * http://lab.hakim.se/zoom-js
+ * MIT licensed
+ *
+ * Copyright (C) 2011-2014 Hakim El Hattab, http://hakim.se
+ */return()=>e}));
diff --git a/test/examples/embedded-media.html b/test/examples/embedded-media.html
deleted file mode 100644
index 91457e4928c..00000000000
--- a/test/examples/embedded-media.html
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-
-
-
- reveal.js - Embedded Media
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/test/qunit-2.5.0.css b/test/qunit-2.5.0.css
deleted file mode 100644
index 21ac68b8f9b..00000000000
--- a/test/qunit-2.5.0.css
+++ /dev/null
@@ -1,436 +0,0 @@
-/*!
- * QUnit 2.5.0
- * https://qunitjs.com/
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license
- * https://jquery.org/license
- *
- * Date: 2018-01-10T02:56Z
- */
-
-/** Font Family and Sizes */
-
-#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult {
- font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
-}
-
-#qunit-testrunner-toolbar, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
-#qunit-tests { font-size: smaller; }
-
-
-/** Resets */
-
-#qunit-tests, #qunit-header, #qunit-banner, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
- margin: 0;
- padding: 0;
-}
-
-
-/** Header (excluding toolbar) */
-
-#qunit-header {
- padding: 0.5em 0 0.5em 1em;
-
- color: #8699A4;
- background-color: #0D3349;
-
- font-size: 1.5em;
- line-height: 1em;
- font-weight: 400;
-
- border-radius: 5px 5px 0 0;
-}
-
-#qunit-header a {
- text-decoration: none;
- color: #C2CCD1;
-}
-
-#qunit-header a:hover,
-#qunit-header a:focus {
- color: #FFF;
-}
-
-#qunit-banner {
- height: 5px;
-}
-
-#qunit-filteredTest {
- padding: 0.5em 1em 0.5em 1em;
- color: #366097;
- background-color: #F4FF77;
-}
-
-#qunit-userAgent {
- padding: 0.5em 1em 0.5em 1em;
- color: #FFF;
- background-color: #2B81AF;
- text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
-}
-
-
-/** Toolbar */
-
-#qunit-testrunner-toolbar {
- padding: 0.5em 1em 0.5em 1em;
- color: #5E740B;
- background-color: #EEE;
-}
-
-#qunit-testrunner-toolbar .clearfix {
- height: 0;
- clear: both;
-}
-
-#qunit-testrunner-toolbar label {
- display: inline-block;
-}
-
-#qunit-testrunner-toolbar input[type=checkbox],
-#qunit-testrunner-toolbar input[type=radio] {
- margin: 3px;
- vertical-align: -2px;
-}
-
-#qunit-testrunner-toolbar input[type=text] {
- box-sizing: border-box;
- height: 1.6em;
-}
-
-.qunit-url-config,
-.qunit-filter,
-#qunit-modulefilter {
- display: inline-block;
- line-height: 2.1em;
-}
-
-.qunit-filter,
-#qunit-modulefilter {
- float: right;
- position: relative;
- margin-left: 1em;
-}
-
-.qunit-url-config label {
- margin-right: 0.5em;
-}
-
-#qunit-modulefilter-search {
- box-sizing: border-box;
- width: 400px;
-}
-
-#qunit-modulefilter-search-container:after {
- position: absolute;
- right: 0.3em;
- content: "\25bc";
- color: black;
-}
-
-#qunit-modulefilter-dropdown {
- /* align with #qunit-modulefilter-search */
- box-sizing: border-box;
- width: 400px;
- position: absolute;
- right: 0;
- top: 50%;
- margin-top: 0.8em;
-
- border: 1px solid #D3D3D3;
- border-top: none;
- border-radius: 0 0 .25em .25em;
- color: #000;
- background-color: #F5F5F5;
- z-index: 99;
-}
-
-#qunit-modulefilter-dropdown a {
- color: inherit;
- text-decoration: none;
-}
-
-#qunit-modulefilter-dropdown .clickable.checked {
- font-weight: bold;
- color: #000;
- background-color: #D2E0E6;
-}
-
-#qunit-modulefilter-dropdown .clickable:hover {
- color: #FFF;
- background-color: #0D3349;
-}
-
-#qunit-modulefilter-actions {
- display: block;
- overflow: auto;
-
- /* align with #qunit-modulefilter-dropdown-list */
- font: smaller/1.5em sans-serif;
-}
-
-#qunit-modulefilter-dropdown #qunit-modulefilter-actions > * {
- box-sizing: border-box;
- max-height: 2.8em;
- display: block;
- padding: 0.4em;
-}
-
-#qunit-modulefilter-dropdown #qunit-modulefilter-actions > button {
- float: right;
- font: inherit;
-}
-
-#qunit-modulefilter-dropdown #qunit-modulefilter-actions > :last-child {
- /* insert padding to align with checkbox margins */
- padding-left: 3px;
-}
-
-#qunit-modulefilter-dropdown-list {
- max-height: 200px;
- overflow-y: auto;
- margin: 0;
- border-top: 2px groove threedhighlight;
- padding: 0.4em 0 0;
- font: smaller/1.5em sans-serif;
-}
-
-#qunit-modulefilter-dropdown-list li {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-#qunit-modulefilter-dropdown-list .clickable {
- display: block;
- padding-left: 0.15em;
-}
-
-
-/** Tests: Pass/Fail */
-
-#qunit-tests {
- list-style-position: inside;
-}
-
-#qunit-tests li {
- padding: 0.4em 1em 0.4em 1em;
- border-bottom: 1px solid #FFF;
- list-style-position: inside;
-}
-
-#qunit-tests > li {
- display: none;
-}
-
-#qunit-tests li.running,
-#qunit-tests li.pass,
-#qunit-tests li.fail,
-#qunit-tests li.skipped,
-#qunit-tests li.aborted {
- display: list-item;
-}
-
-#qunit-tests.hidepass {
- position: relative;
-}
-
-#qunit-tests.hidepass li.running,
-#qunit-tests.hidepass li.pass:not(.todo) {
- visibility: hidden;
- position: absolute;
- width: 0;
- height: 0;
- padding: 0;
- border: 0;
- margin: 0;
-}
-
-#qunit-tests li strong {
- cursor: pointer;
-}
-
-#qunit-tests li.skipped strong {
- cursor: default;
-}
-
-#qunit-tests li a {
- padding: 0.5em;
- color: #C2CCD1;
- text-decoration: none;
-}
-
-#qunit-tests li p a {
- padding: 0.25em;
- color: #6B6464;
-}
-#qunit-tests li a:hover,
-#qunit-tests li a:focus {
- color: #000;
-}
-
-#qunit-tests li .runtime {
- float: right;
- font-size: smaller;
-}
-
-.qunit-assert-list {
- margin-top: 0.5em;
- padding: 0.5em;
-
- background-color: #FFF;
-
- border-radius: 5px;
-}
-
-.qunit-source {
- margin: 0.6em 0 0.3em;
-}
-
-.qunit-collapsed {
- display: none;
-}
-
-#qunit-tests table {
- border-collapse: collapse;
- margin-top: 0.2em;
-}
-
-#qunit-tests th {
- text-align: right;
- vertical-align: top;
- padding: 0 0.5em 0 0;
-}
-
-#qunit-tests td {
- vertical-align: top;
-}
-
-#qunit-tests pre {
- margin: 0;
- white-space: pre-wrap;
- word-wrap: break-word;
-}
-
-#qunit-tests del {
- color: #374E0C;
- background-color: #E0F2BE;
- text-decoration: none;
-}
-
-#qunit-tests ins {
- color: #500;
- background-color: #FFCACA;
- text-decoration: none;
-}
-
-/*** Test Counts */
-
-#qunit-tests b.counts { color: #000; }
-#qunit-tests b.passed { color: #5E740B; }
-#qunit-tests b.failed { color: #710909; }
-
-#qunit-tests li li {
- padding: 5px;
- background-color: #FFF;
- border-bottom: none;
- list-style-position: inside;
-}
-
-/*** Passing Styles */
-
-#qunit-tests li li.pass {
- color: #3C510C;
- background-color: #FFF;
- border-left: 10px solid #C6E746;
-}
-
-#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
-#qunit-tests .pass .test-name { color: #366097; }
-
-#qunit-tests .pass .test-actual,
-#qunit-tests .pass .test-expected { color: #999; }
-
-#qunit-banner.qunit-pass { background-color: #C6E746; }
-
-/*** Failing Styles */
-
-#qunit-tests li li.fail {
- color: #710909;
- background-color: #FFF;
- border-left: 10px solid #EE5757;
- white-space: pre;
-}
-
-#qunit-tests > li:last-child {
- border-radius: 0 0 5px 5px;
-}
-
-#qunit-tests .fail { color: #000; background-color: #EE5757; }
-#qunit-tests .fail .test-name,
-#qunit-tests .fail .module-name { color: #000; }
-
-#qunit-tests .fail .test-actual { color: #EE5757; }
-#qunit-tests .fail .test-expected { color: #008000; }
-
-#qunit-banner.qunit-fail { background-color: #EE5757; }
-
-
-/*** Aborted tests */
-#qunit-tests .aborted { color: #000; background-color: orange; }
-/*** Skipped tests */
-
-#qunit-tests .skipped {
- background-color: #EBECE9;
-}
-
-#qunit-tests .qunit-todo-label,
-#qunit-tests .qunit-skipped-label {
- background-color: #F4FF77;
- display: inline-block;
- font-style: normal;
- color: #366097;
- line-height: 1.8em;
- padding: 0 0.5em;
- margin: -0.4em 0.4em -0.4em 0;
-}
-
-#qunit-tests .qunit-todo-label {
- background-color: #EEE;
-}
-
-/** Result */
-
-#qunit-testresult {
- color: #2B81AF;
- background-color: #D2E0E6;
-
- border-bottom: 1px solid #FFF;
-}
-#qunit-testresult .clearfix {
- height: 0;
- clear: both;
-}
-#qunit-testresult .module-name {
- font-weight: 700;
-}
-#qunit-testresult-display {
- padding: 0.5em 1em 0.5em 1em;
- width: 85%;
- float:left;
-}
-#qunit-testresult-controls {
- padding: 0.5em 1em 0.5em 1em;
- width: 10%;
- float:left;
-}
-
-/** Fixture */
-
-#qunit-fixture {
- position: absolute;
- top: -10000px;
- left: -10000px;
- width: 1000px;
- height: 1000px;
-}
diff --git a/test/qunit-2.5.0.js b/test/qunit-2.5.0.js
deleted file mode 100644
index db72a26ef19..00000000000
--- a/test/qunit-2.5.0.js
+++ /dev/null
@@ -1,5188 +0,0 @@
-/*!
- * QUnit 2.5.0
- * https://qunitjs.com/
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license
- * https://jquery.org/license
- *
- * Date: 2018-01-10T02:56Z
- */
-(function (global$1) {
- 'use strict';
-
- global$1 = global$1 && global$1.hasOwnProperty('default') ? global$1['default'] : global$1;
-
- var window = global$1.window;
- var self$1 = global$1.self;
- var console = global$1.console;
- var setTimeout = global$1.setTimeout;
- var clearTimeout = global$1.clearTimeout;
-
- var document = window && window.document;
- var navigator = window && window.navigator;
-
- var localSessionStorage = function () {
- var x = "qunit-test-string";
- try {
- global$1.sessionStorage.setItem(x, x);
- global$1.sessionStorage.removeItem(x);
- return global$1.sessionStorage;
- } catch (e) {
- return undefined;
- }
- }();
-
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
- return typeof obj;
- } : function (obj) {
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- };
-
-
-
-
-
-
-
-
-
-
-
- var classCallCheck = function (instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- };
-
- var createClass = function () {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
-
- return function (Constructor, protoProps, staticProps) {
- if (protoProps) defineProperties(Constructor.prototype, protoProps);
- if (staticProps) defineProperties(Constructor, staticProps);
- return Constructor;
- };
- }();
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- var toConsumableArray = function (arr) {
- if (Array.isArray(arr)) {
- for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
-
- return arr2;
- } else {
- return Array.from(arr);
- }
- };
-
- var toString = Object.prototype.toString;
- var hasOwn = Object.prototype.hasOwnProperty;
- var now = Date.now || function () {
- return new Date().getTime();
- };
-
- var defined = {
- document: window && window.document !== undefined,
- setTimeout: setTimeout !== undefined
- };
-
- // Returns a new Array with the elements that are in a but not in b
- function diff(a, b) {
- var i,
- j,
- result = a.slice();
-
- for (i = 0; i < result.length; i++) {
- for (j = 0; j < b.length; j++) {
- if (result[i] === b[j]) {
- result.splice(i, 1);
- i--;
- break;
- }
- }
- }
- return result;
- }
-
- /**
- * Determines whether an element exists in a given array or not.
- *
- * @method inArray
- * @param {Any} elem
- * @param {Array} array
- * @return {Boolean}
- */
- function inArray(elem, array) {
- return array.indexOf(elem) !== -1;
- }
-
- /**
- * Makes a clone of an object using only Array or Object as base,
- * and copies over the own enumerable properties.
- *
- * @param {Object} obj
- * @return {Object} New object with only the own properties (recursively).
- */
- function objectValues(obj) {
- var key,
- val,
- vals = is("array", obj) ? [] : {};
- for (key in obj) {
- if (hasOwn.call(obj, key)) {
- val = obj[key];
- vals[key] = val === Object(val) ? objectValues(val) : val;
- }
- }
- return vals;
- }
-
- function extend(a, b, undefOnly) {
- for (var prop in b) {
- if (hasOwn.call(b, prop)) {
- if (b[prop] === undefined) {
- delete a[prop];
- } else if (!(undefOnly && typeof a[prop] !== "undefined")) {
- a[prop] = b[prop];
- }
- }
- }
-
- return a;
- }
-
- function objectType(obj) {
- if (typeof obj === "undefined") {
- return "undefined";
- }
-
- // Consider: typeof null === object
- if (obj === null) {
- return "null";
- }
-
- var match = toString.call(obj).match(/^\[object\s(.*)\]$/),
- type = match && match[1];
-
- switch (type) {
- case "Number":
- if (isNaN(obj)) {
- return "nan";
- }
- return "number";
- case "String":
- case "Boolean":
- case "Array":
- case "Set":
- case "Map":
- case "Date":
- case "RegExp":
- case "Function":
- case "Symbol":
- return type.toLowerCase();
- default:
- return typeof obj === "undefined" ? "undefined" : _typeof(obj);
- }
- }
-
- // Safe object type checking
- function is(type, obj) {
- return objectType(obj) === type;
- }
-
- // Based on Java's String.hashCode, a simple but not
- // rigorously collision resistant hashing function
- function generateHash(module, testName) {
- var str = module + "\x1C" + testName;
- var hash = 0;
-
- for (var i = 0; i < str.length; i++) {
- hash = (hash << 5) - hash + str.charCodeAt(i);
- hash |= 0;
- }
-
- // Convert the possibly negative integer hash code into an 8 character hex string, which isn't
- // strictly necessary but increases user understanding that the id is a SHA-like hash
- var hex = (0x100000000 + hash).toString(16);
- if (hex.length < 8) {
- hex = "0000000" + hex;
- }
-
- return hex.slice(-8);
- }
-
- // Test for equality any JavaScript type.
- // Authors: Philippe Rathé , David Chan
- var equiv = (function () {
-
- // Value pairs queued for comparison. Used for breadth-first processing order, recursion
- // detection and avoiding repeated comparison (see below for details).
- // Elements are { a: val, b: val }.
- var pairs = [];
-
- var getProto = Object.getPrototypeOf || function (obj) {
- return obj.__proto__;
- };
-
- function useStrictEquality(a, b) {
-
- // This only gets called if a and b are not strict equal, and is used to compare on
- // the primitive values inside object wrappers. For example:
- // `var i = 1;`
- // `var j = new Number(1);`
- // Neither a nor b can be null, as a !== b and they have the same type.
- if ((typeof a === "undefined" ? "undefined" : _typeof(a)) === "object") {
- a = a.valueOf();
- }
- if ((typeof b === "undefined" ? "undefined" : _typeof(b)) === "object") {
- b = b.valueOf();
- }
-
- return a === b;
- }
-
- function compareConstructors(a, b) {
- var protoA = getProto(a);
- var protoB = getProto(b);
-
- // Comparing constructors is more strict than using `instanceof`
- if (a.constructor === b.constructor) {
- return true;
- }
-
- // Ref #851
- // If the obj prototype descends from a null constructor, treat it
- // as a null prototype.
- if (protoA && protoA.constructor === null) {
- protoA = null;
- }
- if (protoB && protoB.constructor === null) {
- protoB = null;
- }
-
- // Allow objects with no prototype to be equivalent to
- // objects with Object as their constructor.
- if (protoA === null && protoB === Object.prototype || protoB === null && protoA === Object.prototype) {
- return true;
- }
-
- return false;
- }
-
- function getRegExpFlags(regexp) {
- return "flags" in regexp ? regexp.flags : regexp.toString().match(/[gimuy]*$/)[0];
- }
-
- function isContainer(val) {
- return ["object", "array", "map", "set"].indexOf(objectType(val)) !== -1;
- }
-
- function breadthFirstCompareChild(a, b) {
-
- // If a is a container not reference-equal to b, postpone the comparison to the
- // end of the pairs queue -- unless (a, b) has been seen before, in which case skip
- // over the pair.
- if (a === b) {
- return true;
- }
- if (!isContainer(a)) {
- return typeEquiv(a, b);
- }
- if (pairs.every(function (pair) {
- return pair.a !== a || pair.b !== b;
- })) {
-
- // Not yet started comparing this pair
- pairs.push({ a: a, b: b });
- }
- return true;
- }
-
- var callbacks = {
- "string": useStrictEquality,
- "boolean": useStrictEquality,
- "number": useStrictEquality,
- "null": useStrictEquality,
- "undefined": useStrictEquality,
- "symbol": useStrictEquality,
- "date": useStrictEquality,
-
- "nan": function nan() {
- return true;
- },
-
- "regexp": function regexp(a, b) {
- return a.source === b.source &&
-
- // Include flags in the comparison
- getRegExpFlags(a) === getRegExpFlags(b);
- },
-
- // abort (identical references / instance methods were skipped earlier)
- "function": function _function() {
- return false;
- },
-
- "array": function array(a, b) {
- var i, len;
-
- len = a.length;
- if (len !== b.length) {
-
- // Safe and faster
- return false;
- }
-
- for (i = 0; i < len; i++) {
-
- // Compare non-containers; queue non-reference-equal containers
- if (!breadthFirstCompareChild(a[i], b[i])) {
- return false;
- }
- }
- return true;
- },
-
- // Define sets a and b to be equivalent if for each element aVal in a, there
- // is some element bVal in b such that aVal and bVal are equivalent. Element
- // repetitions are not counted, so these are equivalent:
- // a = new Set( [ {}, [], [] ] );
- // b = new Set( [ {}, {}, [] ] );
- "set": function set$$1(a, b) {
- var innerEq,
- outerEq = true;
-
- if (a.size !== b.size) {
-
- // This optimization has certain quirks because of the lack of
- // repetition counting. For instance, adding the same
- // (reference-identical) element to two equivalent sets can
- // make them non-equivalent.
- return false;
- }
-
- a.forEach(function (aVal) {
-
- // Short-circuit if the result is already known. (Using for...of
- // with a break clause would be cleaner here, but it would cause
- // a syntax error on older Javascript implementations even if
- // Set is unused)
- if (!outerEq) {
- return;
- }
-
- innerEq = false;
-
- b.forEach(function (bVal) {
- var parentPairs;
-
- // Likewise, short-circuit if the result is already known
- if (innerEq) {
- return;
- }
-
- // Swap out the global pairs list, as the nested call to
- // innerEquiv will clobber its contents
- parentPairs = pairs;
- if (innerEquiv(bVal, aVal)) {
- innerEq = true;
- }
-
- // Replace the global pairs list
- pairs = parentPairs;
- });
-
- if (!innerEq) {
- outerEq = false;
- }
- });
-
- return outerEq;
- },
-
- // Define maps a and b to be equivalent if for each key-value pair (aKey, aVal)
- // in a, there is some key-value pair (bKey, bVal) in b such that
- // [ aKey, aVal ] and [ bKey, bVal ] are equivalent. Key repetitions are not
- // counted, so these are equivalent:
- // a = new Map( [ [ {}, 1 ], [ {}, 1 ], [ [], 1 ] ] );
- // b = new Map( [ [ {}, 1 ], [ [], 1 ], [ [], 1 ] ] );
- "map": function map(a, b) {
- var innerEq,
- outerEq = true;
-
- if (a.size !== b.size) {
-
- // This optimization has certain quirks because of the lack of
- // repetition counting. For instance, adding the same
- // (reference-identical) key-value pair to two equivalent maps
- // can make them non-equivalent.
- return false;
- }
-
- a.forEach(function (aVal, aKey) {
-
- // Short-circuit if the result is already known. (Using for...of
- // with a break clause would be cleaner here, but it would cause
- // a syntax error on older Javascript implementations even if
- // Map is unused)
- if (!outerEq) {
- return;
- }
-
- innerEq = false;
-
- b.forEach(function (bVal, bKey) {
- var parentPairs;
-
- // Likewise, short-circuit if the result is already known
- if (innerEq) {
- return;
- }
-
- // Swap out the global pairs list, as the nested call to
- // innerEquiv will clobber its contents
- parentPairs = pairs;
- if (innerEquiv([bVal, bKey], [aVal, aKey])) {
- innerEq = true;
- }
-
- // Replace the global pairs list
- pairs = parentPairs;
- });
-
- if (!innerEq) {
- outerEq = false;
- }
- });
-
- return outerEq;
- },
-
- "object": function object(a, b) {
- var i,
- aProperties = [],
- bProperties = [];
-
- if (compareConstructors(a, b) === false) {
- return false;
- }
-
- // Be strict: don't ensure hasOwnProperty and go deep
- for (i in a) {
-
- // Collect a's properties
- aProperties.push(i);
-
- // Skip OOP methods that look the same
- if (a.constructor !== Object && typeof a.constructor !== "undefined" && typeof a[i] === "function" && typeof b[i] === "function" && a[i].toString() === b[i].toString()) {
- continue;
- }
-
- // Compare non-containers; queue non-reference-equal containers
- if (!breadthFirstCompareChild(a[i], b[i])) {
- return false;
- }
- }
-
- for (i in b) {
-
- // Collect b's properties
- bProperties.push(i);
- }
-
- // Ensures identical properties name
- return typeEquiv(aProperties.sort(), bProperties.sort());
- }
- };
-
- function typeEquiv(a, b) {
- var type = objectType(a);
-
- // Callbacks for containers will append to the pairs queue to achieve breadth-first
- // search order. The pairs queue is also used to avoid reprocessing any pair of
- // containers that are reference-equal to a previously visited pair (a special case
- // this being recursion detection).
- //
- // Because of this approach, once typeEquiv returns a false value, it should not be
- // called again without clearing the pair queue else it may wrongly report a visited
- // pair as being equivalent.
- return objectType(b) === type && callbacks[type](a, b);
- }
-
- function innerEquiv(a, b) {
- var i, pair;
-
- // We're done when there's nothing more to compare
- if (arguments.length < 2) {
- return true;
- }
-
- // Clear the global pair queue and add the top-level values being compared
- pairs = [{ a: a, b: b }];
-
- for (i = 0; i < pairs.length; i++) {
- pair = pairs[i];
-
- // Perform type-specific comparison on any pairs that are not strictly
- // equal. For container types, that comparison will postpone comparison
- // of any sub-container pair to the end of the pair queue. This gives
- // breadth-first search order. It also avoids the reprocessing of
- // reference-equal siblings, cousins etc, which can have a significant speed
- // impact when comparing a container of small objects each of which has a
- // reference to the same (singleton) large object.
- if (pair.a !== pair.b && !typeEquiv(pair.a, pair.b)) {
- return false;
- }
- }
-
- // ...across all consecutive argument pairs
- return arguments.length === 2 || innerEquiv.apply(this, [].slice.call(arguments, 1));
- }
-
- return function () {
- var result = innerEquiv.apply(undefined, arguments);
-
- // Release any retained objects
- pairs.length = 0;
- return result;
- };
- })();
-
- /**
- * Config object: Maintain internal state
- * Later exposed as QUnit.config
- * `config` initialized at top of scope
- */
- var config = {
-
- // The queue of tests to run
- queue: [],
-
- // Block until document ready
- blocking: true,
-
- // By default, run previously failed tests first
- // very useful in combination with "Hide passed tests" checked
- reorder: true,
-
- // By default, modify document.title when suite is done
- altertitle: true,
-
- // HTML Reporter: collapse every test except the first failing test
- // If false, all failing tests will be expanded
- collapse: true,
-
- // By default, scroll to top of the page when suite is done
- scrolltop: true,
-
- // Depth up-to which object will be dumped
- maxDepth: 5,
-
- // When enabled, all tests must call expect()
- requireExpects: false,
-
- // Placeholder for user-configurable form-exposed URL parameters
- urlConfig: [],
-
- // Set of all modules.
- modules: [],
-
- // The first unnamed module
- currentModule: {
- name: "",
- tests: [],
- childModules: [],
- testsRun: 0,
- unskippedTestsRun: 0,
- hooks: {
- before: [],
- beforeEach: [],
- afterEach: [],
- after: []
- }
- },
-
- callbacks: {},
-
- // The storage module to use for reordering tests
- storage: localSessionStorage
- };
-
- // take a predefined QUnit.config and extend the defaults
- var globalConfig = window && window.QUnit && window.QUnit.config;
-
- // only extend the global config if there is no QUnit overload
- if (window && window.QUnit && !window.QUnit.version) {
- extend(config, globalConfig);
- }
-
- // Push a loose unnamed module to the modules collection
- config.modules.push(config.currentModule);
-
- // Based on jsDump by Ariel Flesler
- // http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html
- var dump = (function () {
- function quote(str) {
- return "\"" + str.toString().replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + "\"";
- }
- function literal(o) {
- return o + "";
- }
- function join(pre, arr, post) {
- var s = dump.separator(),
- base = dump.indent(),
- inner = dump.indent(1);
- if (arr.join) {
- arr = arr.join("," + s + inner);
- }
- if (!arr) {
- return pre + post;
- }
- return [pre, inner + arr, base + post].join(s);
- }
- function array(arr, stack) {
- var i = arr.length,
- ret = new Array(i);
-
- if (dump.maxDepth && dump.depth > dump.maxDepth) {
- return "[object Array]";
- }
-
- this.up();
- while (i--) {
- ret[i] = this.parse(arr[i], undefined, stack);
- }
- this.down();
- return join("[", ret, "]");
- }
-
- function isArray(obj) {
- return (
-
- //Native Arrays
- toString.call(obj) === "[object Array]" ||
-
- // NodeList objects
- typeof obj.length === "number" && obj.item !== undefined && (obj.length ? obj.item(0) === obj[0] : obj.item(0) === null && obj[0] === undefined)
- );
- }
-
- var reName = /^function (\w+)/,
- dump = {
-
- // The objType is used mostly internally, you can fix a (custom) type in advance
- parse: function parse(obj, objType, stack) {
- stack = stack || [];
- var res,
- parser,
- parserType,
- objIndex = stack.indexOf(obj);
-
- if (objIndex !== -1) {
- return "recursion(" + (objIndex - stack.length) + ")";
- }
-
- objType = objType || this.typeOf(obj);
- parser = this.parsers[objType];
- parserType = typeof parser === "undefined" ? "undefined" : _typeof(parser);
-
- if (parserType === "function") {
- stack.push(obj);
- res = parser.call(this, obj, stack);
- stack.pop();
- return res;
- }
- return parserType === "string" ? parser : this.parsers.error;
- },
- typeOf: function typeOf(obj) {
- var type;
-
- if (obj === null) {
- type = "null";
- } else if (typeof obj === "undefined") {
- type = "undefined";
- } else if (is("regexp", obj)) {
- type = "regexp";
- } else if (is("date", obj)) {
- type = "date";
- } else if (is("function", obj)) {
- type = "function";
- } else if (obj.setInterval !== undefined && obj.document !== undefined && obj.nodeType === undefined) {
- type = "window";
- } else if (obj.nodeType === 9) {
- type = "document";
- } else if (obj.nodeType) {
- type = "node";
- } else if (isArray(obj)) {
- type = "array";
- } else if (obj.constructor === Error.prototype.constructor) {
- type = "error";
- } else {
- type = typeof obj === "undefined" ? "undefined" : _typeof(obj);
- }
- return type;
- },
-
- separator: function separator() {
- if (this.multiline) {
- return this.HTML ? " " : "\n";
- } else {
- return this.HTML ? " " : " ";
- }
- },
-
- // Extra can be a number, shortcut for increasing-calling-decreasing
- indent: function indent(extra) {
- if (!this.multiline) {
- return "";
- }
- var chr = this.indentChar;
- if (this.HTML) {
- chr = chr.replace(/\t/g, " ").replace(/ /g, " ");
- }
- return new Array(this.depth + (extra || 0)).join(chr);
- },
- up: function up(a) {
- this.depth += a || 1;
- },
- down: function down(a) {
- this.depth -= a || 1;
- },
- setParser: function setParser(name, parser) {
- this.parsers[name] = parser;
- },
-
- // The next 3 are exposed so you can use them
- quote: quote,
- literal: literal,
- join: join,
- depth: 1,
- maxDepth: config.maxDepth,
-
- // This is the list of parsers, to modify them, use dump.setParser
- parsers: {
- window: "[Window]",
- document: "[Document]",
- error: function error(_error) {
- return "Error(\"" + _error.message + "\")";
- },
- unknown: "[Unknown]",
- "null": "null",
- "undefined": "undefined",
- "function": function _function(fn) {
- var ret = "function",
-
-
- // Functions never have name in IE
- name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];
-
- if (name) {
- ret += " " + name;
- }
- ret += "(";
-
- ret = [ret, dump.parse(fn, "functionArgs"), "){"].join("");
- return join(ret, dump.parse(fn, "functionCode"), "}");
- },
- array: array,
- nodelist: array,
- "arguments": array,
- object: function object(map, stack) {
- var keys,
- key,
- val,
- i,
- nonEnumerableProperties,
- ret = [];
-
- if (dump.maxDepth && dump.depth > dump.maxDepth) {
- return "[object Object]";
- }
-
- dump.up();
- keys = [];
- for (key in map) {
- keys.push(key);
- }
-
- // Some properties are not always enumerable on Error objects.
- nonEnumerableProperties = ["message", "name"];
- for (i in nonEnumerableProperties) {
- key = nonEnumerableProperties[i];
- if (key in map && !inArray(key, keys)) {
- keys.push(key);
- }
- }
- keys.sort();
- for (i = 0; i < keys.length; i++) {
- key = keys[i];
- val = map[key];
- ret.push(dump.parse(key, "key") + ": " + dump.parse(val, undefined, stack));
- }
- dump.down();
- return join("{", ret, "}");
- },
- node: function node(_node) {
- var len,
- i,
- val,
- open = dump.HTML ? "<" : "<",
- close = dump.HTML ? ">" : ">",
- tag = _node.nodeName.toLowerCase(),
- ret = open + tag,
- attrs = _node.attributes;
-
- if (attrs) {
- for (i = 0, len = attrs.length; i < len; i++) {
- val = attrs[i].nodeValue;
-
- // IE6 includes all attributes in .attributes, even ones not explicitly
- // set. Those have values like undefined, null, 0, false, "" or
- // "inherit".
- if (val && val !== "inherit") {
- ret += " " + attrs[i].nodeName + "=" + dump.parse(val, "attribute");
- }
- }
- }
- ret += close;
-
- // Show content of TextNode or CDATASection
- if (_node.nodeType === 3 || _node.nodeType === 4) {
- ret += _node.nodeValue;
- }
-
- return ret + open + "/" + tag + close;
- },
-
- // Function calls it internally, it's the arguments part of the function
- functionArgs: function functionArgs(fn) {
- var args,
- l = fn.length;
-
- if (!l) {
- return "";
- }
-
- args = new Array(l);
- while (l--) {
-
- // 97 is 'a'
- args[l] = String.fromCharCode(97 + l);
- }
- return " " + args.join(", ") + " ";
- },
-
- // Object calls it internally, the key part of an item in a map
- key: quote,
-
- // Function calls it internally, it's the content of the function
- functionCode: "[code]",
-
- // Node calls it internally, it's a html attribute value
- attribute: quote,
- string: quote,
- date: quote,
- regexp: literal,
- number: literal,
- "boolean": literal,
- symbol: function symbol(sym) {
- return sym.toString();
- }
- },
-
- // If true, entities are escaped ( <, >, \t, space and \n )
- HTML: false,
-
- // Indentation unit
- indentChar: " ",
-
- // If true, items in a collection, are separated by a \n, else just a space.
- multiline: true
- };
-
- return dump;
- })();
-
- var LISTENERS = Object.create(null);
- var SUPPORTED_EVENTS = ["runStart", "suiteStart", "testStart", "assertion", "testEnd", "suiteEnd", "runEnd"];
-
- /**
- * Emits an event with the specified data to all currently registered listeners.
- * Callbacks will fire in the order in which they are registered (FIFO). This
- * function is not exposed publicly; it is used by QUnit internals to emit
- * logging events.
- *
- * @private
- * @method emit
- * @param {String} eventName
- * @param {Object} data
- * @return {Void}
- */
- function emit(eventName, data) {
- if (objectType(eventName) !== "string") {
- throw new TypeError("eventName must be a string when emitting an event");
- }
-
- // Clone the callbacks in case one of them registers a new callback
- var originalCallbacks = LISTENERS[eventName];
- var callbacks = originalCallbacks ? [].concat(toConsumableArray(originalCallbacks)) : [];
-
- for (var i = 0; i < callbacks.length; i++) {
- callbacks[i](data);
- }
- }
-
- /**
- * Registers a callback as a listener to the specified event.
- *
- * @public
- * @method on
- * @param {String} eventName
- * @param {Function} callback
- * @return {Void}
- */
- function on(eventName, callback) {
- if (objectType(eventName) !== "string") {
- throw new TypeError("eventName must be a string when registering a listener");
- } else if (!inArray(eventName, SUPPORTED_EVENTS)) {
- var events = SUPPORTED_EVENTS.join(", ");
- throw new Error("\"" + eventName + "\" is not a valid event; must be one of: " + events + ".");
- } else if (objectType(callback) !== "function") {
- throw new TypeError("callback must be a function when registering a listener");
- }
-
- if (!LISTENERS[eventName]) {
- LISTENERS[eventName] = [];
- }
-
- // Don't register the same callback more than once
- if (!inArray(callback, LISTENERS[eventName])) {
- LISTENERS[eventName].push(callback);
- }
- }
-
- // Register logging callbacks
- function registerLoggingCallbacks(obj) {
- var i,
- l,
- key,
- callbackNames = ["begin", "done", "log", "testStart", "testDone", "moduleStart", "moduleDone"];
-
- function registerLoggingCallback(key) {
- var loggingCallback = function loggingCallback(callback) {
- if (objectType(callback) !== "function") {
- throw new Error("QUnit logging methods require a callback function as their first parameters.");
- }
-
- config.callbacks[key].push(callback);
- };
-
- return loggingCallback;
- }
-
- for (i = 0, l = callbackNames.length; i < l; i++) {
- key = callbackNames[i];
-
- // Initialize key collection of logging callback
- if (objectType(config.callbacks[key]) === "undefined") {
- config.callbacks[key] = [];
- }
-
- obj[key] = registerLoggingCallback(key);
- }
- }
-
- function runLoggingCallbacks(key, args) {
- var i, l, callbacks;
-
- callbacks = config.callbacks[key];
- for (i = 0, l = callbacks.length; i < l; i++) {
- callbacks[i](args);
- }
- }
-
- // Doesn't support IE9, it will return undefined on these browsers
- // See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
- var fileName = (sourceFromStacktrace(0) || "").replace(/(:\d+)+\)?/, "").replace(/.+\//, "");
-
- function extractStacktrace(e, offset) {
- offset = offset === undefined ? 4 : offset;
-
- var stack, include, i;
-
- if (e && e.stack) {
- stack = e.stack.split("\n");
- if (/^error$/i.test(stack[0])) {
- stack.shift();
- }
- if (fileName) {
- include = [];
- for (i = offset; i < stack.length; i++) {
- if (stack[i].indexOf(fileName) !== -1) {
- break;
- }
- include.push(stack[i]);
- }
- if (include.length) {
- return include.join("\n");
- }
- }
- return stack[offset];
- }
- }
-
- function sourceFromStacktrace(offset) {
- var error = new Error();
-
- // Support: Safari <=7 only, IE <=10 - 11 only
- // Not all browsers generate the `stack` property for `new Error()`, see also #636
- if (!error.stack) {
- try {
- throw error;
- } catch (err) {
- error = err;
- }
- }
-
- return extractStacktrace(error, offset);
- }
-
- var priorityCount = 0;
- var unitSampler = void 0;
-
- /**
- * Advances the ProcessingQueue to the next item if it is ready.
- * @param {Boolean} last
- */
- function advance() {
- var start = now();
- config.depth = (config.depth || 0) + 1;
-
- while (config.queue.length && !config.blocking) {
- var elapsedTime = now() - start;
-
- if (!defined.setTimeout || config.updateRate <= 0 || elapsedTime < config.updateRate) {
- if (priorityCount > 0) {
- priorityCount--;
- }
-
- config.queue.shift()();
- } else {
- setTimeout(advance);
- break;
- }
- }
-
- config.depth--;
-
- if (!config.blocking && !config.queue.length && config.depth === 0) {
- done();
- }
- }
-
- function addToQueueImmediate(callback) {
- if (objectType(callback) === "array") {
- while (callback.length) {
- addToQueueImmediate(callback.pop());
- }
-
- return;
- }
-
- config.queue.unshift(callback);
- priorityCount++;
- }
-
- /**
- * Adds a function to the ProcessingQueue for execution.
- * @param {Function|Array} callback
- * @param {Boolean} priority
- * @param {String} seed
- */
- function addToQueue(callback, prioritize, seed) {
- if (prioritize) {
- config.queue.splice(priorityCount++, 0, callback);
- } else if (seed) {
- if (!unitSampler) {
- unitSampler = unitSamplerGenerator(seed);
- }
-
- // Insert into a random position after all prioritized items
- var index = Math.floor(unitSampler() * (config.queue.length - priorityCount + 1));
- config.queue.splice(priorityCount + index, 0, callback);
- } else {
- config.queue.push(callback);
- }
- }
-
- /**
- * Creates a seeded "sample" generator which is used for randomizing tests.
- */
- function unitSamplerGenerator(seed) {
-
- // 32-bit xorshift, requires only a nonzero seed
- // http://excamera.com/sphinx/article-xorshift.html
- var sample = parseInt(generateHash(seed), 16) || -1;
- return function () {
- sample ^= sample << 13;
- sample ^= sample >>> 17;
- sample ^= sample << 5;
-
- // ECMAScript has no unsigned number type
- if (sample < 0) {
- sample += 0x100000000;
- }
-
- return sample / 0x100000000;
- };
- }
-
- /**
- * This function is called when the ProcessingQueue is done processing all
- * items. It handles emitting the final run events.
- */
- function done() {
- var storage = config.storage;
-
- ProcessingQueue.finished = true;
-
- var runtime = now() - config.started;
- var passed = config.stats.all - config.stats.bad;
-
- emit("runEnd", globalSuite.end(true));
- runLoggingCallbacks("done", {
- passed: passed,
- failed: config.stats.bad,
- total: config.stats.all,
- runtime: runtime
- });
-
- // Clear own storage items if all tests passed
- if (storage && config.stats.bad === 0) {
- for (var i = storage.length - 1; i >= 0; i--) {
- var key = storage.key(i);
-
- if (key.indexOf("qunit-test-") === 0) {
- storage.removeItem(key);
- }
- }
- }
- }
-
- var ProcessingQueue = {
- finished: false,
- add: addToQueue,
- addImmediate: addToQueueImmediate,
- advance: advance
- };
-
- var TestReport = function () {
- function TestReport(name, suite, options) {
- classCallCheck(this, TestReport);
-
- this.name = name;
- this.suiteName = suite.name;
- this.fullName = suite.fullName.concat(name);
- this.runtime = 0;
- this.assertions = [];
-
- this.skipped = !!options.skip;
- this.todo = !!options.todo;
-
- this.valid = options.valid;
-
- this._startTime = 0;
- this._endTime = 0;
-
- suite.pushTest(this);
- }
-
- createClass(TestReport, [{
- key: "start",
- value: function start(recordTime) {
- if (recordTime) {
- this._startTime = Date.now();
- }
-
- return {
- name: this.name,
- suiteName: this.suiteName,
- fullName: this.fullName.slice()
- };
- }
- }, {
- key: "end",
- value: function end(recordTime) {
- if (recordTime) {
- this._endTime = Date.now();
- }
-
- return extend(this.start(), {
- runtime: this.getRuntime(),
- status: this.getStatus(),
- errors: this.getFailedAssertions(),
- assertions: this.getAssertions()
- });
- }
- }, {
- key: "pushAssertion",
- value: function pushAssertion(assertion) {
- this.assertions.push(assertion);
- }
- }, {
- key: "getRuntime",
- value: function getRuntime() {
- return this._endTime - this._startTime;
- }
- }, {
- key: "getStatus",
- value: function getStatus() {
- if (this.skipped) {
- return "skipped";
- }
-
- var testPassed = this.getFailedAssertions().length > 0 ? this.todo : !this.todo;
-
- if (!testPassed) {
- return "failed";
- } else if (this.todo) {
- return "todo";
- } else {
- return "passed";
- }
- }
- }, {
- key: "getFailedAssertions",
- value: function getFailedAssertions() {
- return this.assertions.filter(function (assertion) {
- return !assertion.passed;
- });
- }
- }, {
- key: "getAssertions",
- value: function getAssertions() {
- return this.assertions.slice();
- }
-
- // Remove actual and expected values from assertions. This is to prevent
- // leaking memory throughout a test suite.
-
- }, {
- key: "slimAssertions",
- value: function slimAssertions() {
- this.assertions = this.assertions.map(function (assertion) {
- delete assertion.actual;
- delete assertion.expected;
- return assertion;
- });
- }
- }]);
- return TestReport;
- }();
-
- var focused$1 = false;
-
- function Test(settings) {
- var i, l;
-
- ++Test.count;
-
- this.expected = null;
- this.assertions = [];
- this.semaphore = 0;
- this.module = config.currentModule;
- this.stack = sourceFromStacktrace(3);
- this.steps = [];
- this.timeout = undefined;
-
- // If a module is skipped, all its tests and the tests of the child suites
- // should be treated as skipped even if they are defined as `only` or `todo`.
- // As for `todo` module, all its tests will be treated as `todo` except for
- // tests defined as `skip` which will be left intact.
- //
- // So, if a test is defined as `todo` and is inside a skipped module, we should
- // then treat that test as if was defined as `skip`.
- if (this.module.skip) {
- settings.skip = true;
- settings.todo = false;
-
- // Skipped tests should be left intact
- } else if (this.module.todo && !settings.skip) {
- settings.todo = true;
- }
-
- extend(this, settings);
-
- this.testReport = new TestReport(settings.testName, this.module.suiteReport, {
- todo: settings.todo,
- skip: settings.skip,
- valid: this.valid()
- });
-
- // Register unique strings
- for (i = 0, l = this.module.tests; i < l.length; i++) {
- if (this.module.tests[i].name === this.testName) {
- this.testName += " ";
- }
- }
-
- this.testId = generateHash(this.module.name, this.testName);
-
- this.module.tests.push({
- name: this.testName,
- testId: this.testId,
- skip: !!settings.skip
- });
-
- if (settings.skip) {
-
- // Skipped tests will fully ignore any sent callback
- this.callback = function () {};
- this.async = false;
- this.expected = 0;
- } else {
- if (typeof this.callback !== "function") {
- var method = this.todo ? "todo" : "test";
-
- // eslint-disable-next-line max-len
- throw new TypeError("You must provide a function as a test callback to QUnit." + method + "(\"" + settings.testName + "\")");
- }
-
- this.assert = new Assert(this);
- }
- }
-
- Test.count = 0;
-
- function getNotStartedModules(startModule) {
- var module = startModule,
- modules = [];
-
- while (module && module.testsRun === 0) {
- modules.push(module);
- module = module.parentModule;
- }
-
- return modules;
- }
-
- Test.prototype = {
- before: function before() {
- var i,
- startModule,
- module = this.module,
- notStartedModules = getNotStartedModules(module);
-
- for (i = notStartedModules.length - 1; i >= 0; i--) {
- startModule = notStartedModules[i];
- startModule.stats = { all: 0, bad: 0, started: now() };
- emit("suiteStart", startModule.suiteReport.start(true));
- runLoggingCallbacks("moduleStart", {
- name: startModule.name,
- tests: startModule.tests
- });
- }
-
- config.current = this;
-
- this.testEnvironment = extend({}, module.testEnvironment);
-
- this.started = now();
- emit("testStart", this.testReport.start(true));
- runLoggingCallbacks("testStart", {
- name: this.testName,
- module: module.name,
- testId: this.testId,
- previousFailure: this.previousFailure
- });
-
- if (!config.pollution) {
- saveGlobal();
- }
- },
-
- run: function run() {
- var promise;
-
- config.current = this;
-
- this.callbackStarted = now();
-
- if (config.notrycatch) {
- runTest(this);
- return;
- }
-
- try {
- runTest(this);
- } catch (e) {
- this.pushFailure("Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + (e.message || e), extractStacktrace(e, 0));
-
- // Else next test will carry the responsibility
- saveGlobal();
-
- // Restart the tests if they're blocking
- if (config.blocking) {
- internalRecover(this);
- }
- }
-
- function runTest(test) {
- promise = test.callback.call(test.testEnvironment, test.assert);
- test.resolvePromise(promise);
-
- // If the test has a "lock" on it, but the timeout is 0, then we push a
- // failure as the test should be synchronous.
- if (test.timeout === 0 && test.semaphore !== 0) {
- pushFailure("Test did not finish synchronously even though assert.timeout( 0 ) was used.", sourceFromStacktrace(2));
- }
- }
- },
-
- after: function after() {
- checkPollution();
- },
-
- queueHook: function queueHook(hook, hookName, hookOwner) {
- var _this = this;
-
- var callHook = function callHook() {
- var promise = hook.call(_this.testEnvironment, _this.assert);
- _this.resolvePromise(promise, hookName);
- };
-
- var runHook = function runHook() {
- if (hookName === "before") {
- if (hookOwner.unskippedTestsRun !== 0) {
- return;
- }
-
- _this.preserveEnvironment = true;
- }
-
- if (hookName === "after" && hookOwner.unskippedTestsRun !== numberOfUnskippedTests(hookOwner) - 1 && config.queue.length > 2) {
- return;
- }
-
- config.current = _this;
- if (config.notrycatch) {
- callHook();
- return;
- }
- try {
- callHook();
- } catch (error) {
- _this.pushFailure(hookName + " failed on " + _this.testName + ": " + (error.message || error), extractStacktrace(error, 0));
- }
- };
-
- return runHook;
- },
-
-
- // Currently only used for module level hooks, can be used to add global level ones
- hooks: function hooks(handler) {
- var hooks = [];
-
- function processHooks(test, module) {
- if (module.parentModule) {
- processHooks(test, module.parentModule);
- }
-
- if (module.hooks[handler].length) {
- for (var i = 0; i < module.hooks[handler].length; i++) {
- hooks.push(test.queueHook(module.hooks[handler][i], handler, module));
- }
- }
- }
-
- // Hooks are ignored on skipped tests
- if (!this.skip) {
- processHooks(this, this.module);
- }
-
- return hooks;
- },
-
-
- finish: function finish() {
- config.current = this;
- if (config.requireExpects && this.expected === null) {
- this.pushFailure("Expected number of assertions to be defined, but expect() was " + "not called.", this.stack);
- } else if (this.expected !== null && this.expected !== this.assertions.length) {
- this.pushFailure("Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack);
- } else if (this.expected === null && !this.assertions.length) {
- this.pushFailure("Expected at least one assertion, but none were run - call " + "expect(0) to accept zero assertions.", this.stack);
- }
-
- var i,
- module = this.module,
- moduleName = module.name,
- testName = this.testName,
- skipped = !!this.skip,
- todo = !!this.todo,
- bad = 0,
- storage = config.storage;
-
- this.runtime = now() - this.started;
-
- config.stats.all += this.assertions.length;
- module.stats.all += this.assertions.length;
-
- for (i = 0; i < this.assertions.length; i++) {
- if (!this.assertions[i].result) {
- bad++;
- config.stats.bad++;
- module.stats.bad++;
- }
- }
-
- notifyTestsRan(module, skipped);
-
- // Store result when possible
- if (storage) {
- if (bad) {
- storage.setItem("qunit-test-" + moduleName + "-" + testName, bad);
- } else {
- storage.removeItem("qunit-test-" + moduleName + "-" + testName);
- }
- }
-
- // After emitting the js-reporters event we cleanup the assertion data to
- // avoid leaking it. It is not used by the legacy testDone callbacks.
- emit("testEnd", this.testReport.end(true));
- this.testReport.slimAssertions();
-
- runLoggingCallbacks("testDone", {
- name: testName,
- module: moduleName,
- skipped: skipped,
- todo: todo,
- failed: bad,
- passed: this.assertions.length - bad,
- total: this.assertions.length,
- runtime: skipped ? 0 : this.runtime,
-
- // HTML Reporter use
- assertions: this.assertions,
- testId: this.testId,
-
- // Source of Test
- source: this.stack
- });
-
- if (module.testsRun === numberOfTests(module)) {
- logSuiteEnd(module);
-
- // Check if the parent modules, iteratively, are done. If that the case,
- // we emit the `suiteEnd` event and trigger `moduleDone` callback.
- var parent = module.parentModule;
- while (parent && parent.testsRun === numberOfTests(parent)) {
- logSuiteEnd(parent);
- parent = parent.parentModule;
- }
- }
-
- config.current = undefined;
-
- function logSuiteEnd(module) {
- emit("suiteEnd", module.suiteReport.end(true));
- runLoggingCallbacks("moduleDone", {
- name: module.name,
- tests: module.tests,
- failed: module.stats.bad,
- passed: module.stats.all - module.stats.bad,
- total: module.stats.all,
- runtime: now() - module.stats.started
- });
- }
- },
-
- preserveTestEnvironment: function preserveTestEnvironment() {
- if (this.preserveEnvironment) {
- this.module.testEnvironment = this.testEnvironment;
- this.testEnvironment = extend({}, this.module.testEnvironment);
- }
- },
-
- queue: function queue() {
- var test = this;
-
- if (!this.valid()) {
- return;
- }
-
- function runTest() {
-
- // Each of these can by async
- ProcessingQueue.addImmediate([function () {
- test.before();
- }, test.hooks("before"), function () {
- test.preserveTestEnvironment();
- }, test.hooks("beforeEach"), function () {
- test.run();
- }, test.hooks("afterEach").reverse(), test.hooks("after").reverse(), function () {
- test.after();
- }, function () {
- test.finish();
- }]);
- }
-
- var previousFailCount = config.storage && +config.storage.getItem("qunit-test-" + this.module.name + "-" + this.testName);
-
- // Prioritize previously failed tests, detected from storage
- var prioritize = config.reorder && !!previousFailCount;
-
- this.previousFailure = !!previousFailCount;
-
- ProcessingQueue.add(runTest, prioritize, config.seed);
-
- // If the queue has already finished, we manually process the new test
- if (ProcessingQueue.finished) {
- ProcessingQueue.advance();
- }
- },
-
-
- pushResult: function pushResult(resultInfo) {
- if (this !== config.current) {
- throw new Error("Assertion occurred after test had finished.");
- }
-
- // Destructure of resultInfo = { result, actual, expected, message, negative }
- var source,
- details = {
- module: this.module.name,
- name: this.testName,
- result: resultInfo.result,
- message: resultInfo.message,
- actual: resultInfo.actual,
- testId: this.testId,
- negative: resultInfo.negative || false,
- runtime: now() - this.started,
- todo: !!this.todo
- };
-
- if (hasOwn.call(resultInfo, "expected")) {
- details.expected = resultInfo.expected;
- }
-
- if (!resultInfo.result) {
- source = resultInfo.source || sourceFromStacktrace();
-
- if (source) {
- details.source = source;
- }
- }
-
- this.logAssertion(details);
-
- this.assertions.push({
- result: !!resultInfo.result,
- message: resultInfo.message
- });
- },
-
- pushFailure: function pushFailure(message, source, actual) {
- if (!(this instanceof Test)) {
- throw new Error("pushFailure() assertion outside test context, was " + sourceFromStacktrace(2));
- }
-
- this.pushResult({
- result: false,
- message: message || "error",
- actual: actual || null,
- source: source
- });
- },
-
- /**
- * Log assertion details using both the old QUnit.log interface and
- * QUnit.on( "assertion" ) interface.
- *
- * @private
- */
- logAssertion: function logAssertion(details) {
- runLoggingCallbacks("log", details);
-
- var assertion = {
- passed: details.result,
- actual: details.actual,
- expected: details.expected,
- message: details.message,
- stack: details.source,
- todo: details.todo
- };
- this.testReport.pushAssertion(assertion);
- emit("assertion", assertion);
- },
-
-
- resolvePromise: function resolvePromise(promise, phase) {
- var then,
- resume,
- message,
- test = this;
- if (promise != null) {
- then = promise.then;
- if (objectType(then) === "function") {
- resume = internalStop(test);
- if (config.notrycatch) {
- then.call(promise, function () {
- resume();
- });
- } else {
- then.call(promise, function () {
- resume();
- }, function (error) {
- message = "Promise rejected " + (!phase ? "during" : phase.replace(/Each$/, "")) + " \"" + test.testName + "\": " + (error && error.message || error);
- test.pushFailure(message, extractStacktrace(error, 0));
-
- // Else next test will carry the responsibility
- saveGlobal();
-
- // Unblock
- resume();
- });
- }
- }
- }
- },
-
- valid: function valid() {
- var filter = config.filter,
- regexFilter = /^(!?)\/([\w\W]*)\/(i?$)/.exec(filter),
- module = config.module && config.module.toLowerCase(),
- fullName = this.module.name + ": " + this.testName;
-
- function moduleChainNameMatch(testModule) {
- var testModuleName = testModule.name ? testModule.name.toLowerCase() : null;
- if (testModuleName === module) {
- return true;
- } else if (testModule.parentModule) {
- return moduleChainNameMatch(testModule.parentModule);
- } else {
- return false;
- }
- }
-
- function moduleChainIdMatch(testModule) {
- return inArray(testModule.moduleId, config.moduleId) || testModule.parentModule && moduleChainIdMatch(testModule.parentModule);
- }
-
- // Internally-generated tests are always valid
- if (this.callback && this.callback.validTest) {
- return true;
- }
-
- if (config.moduleId && config.moduleId.length > 0 && !moduleChainIdMatch(this.module)) {
-
- return false;
- }
-
- if (config.testId && config.testId.length > 0 && !inArray(this.testId, config.testId)) {
-
- return false;
- }
-
- if (module && !moduleChainNameMatch(this.module)) {
- return false;
- }
-
- if (!filter) {
- return true;
- }
-
- return regexFilter ? this.regexFilter(!!regexFilter[1], regexFilter[2], regexFilter[3], fullName) : this.stringFilter(filter, fullName);
- },
-
- regexFilter: function regexFilter(exclude, pattern, flags, fullName) {
- var regex = new RegExp(pattern, flags);
- var match = regex.test(fullName);
-
- return match !== exclude;
- },
-
- stringFilter: function stringFilter(filter, fullName) {
- filter = filter.toLowerCase();
- fullName = fullName.toLowerCase();
-
- var include = filter.charAt(0) !== "!";
- if (!include) {
- filter = filter.slice(1);
- }
-
- // If the filter matches, we need to honour include
- if (fullName.indexOf(filter) !== -1) {
- return include;
- }
-
- // Otherwise, do the opposite
- return !include;
- }
- };
-
- function pushFailure() {
- if (!config.current) {
- throw new Error("pushFailure() assertion outside test context, in " + sourceFromStacktrace(2));
- }
-
- // Gets current test obj
- var currentTest = config.current;
-
- return currentTest.pushFailure.apply(currentTest, arguments);
- }
-
- function saveGlobal() {
- config.pollution = [];
-
- if (config.noglobals) {
- for (var key in global$1) {
- if (hasOwn.call(global$1, key)) {
-
- // In Opera sometimes DOM element ids show up here, ignore them
- if (/^qunit-test-output/.test(key)) {
- continue;
- }
- config.pollution.push(key);
- }
- }
- }
- }
-
- function checkPollution() {
- var newGlobals,
- deletedGlobals,
- old = config.pollution;
-
- saveGlobal();
-
- newGlobals = diff(config.pollution, old);
- if (newGlobals.length > 0) {
- pushFailure("Introduced global variable(s): " + newGlobals.join(", "));
- }
-
- deletedGlobals = diff(old, config.pollution);
- if (deletedGlobals.length > 0) {
- pushFailure("Deleted global variable(s): " + deletedGlobals.join(", "));
- }
- }
-
- // Will be exposed as QUnit.test
- function test(testName, callback) {
- if (focused$1) {
- return;
- }
-
- var newTest = new Test({
- testName: testName,
- callback: callback
- });
-
- newTest.queue();
- }
-
- function todo(testName, callback) {
- if (focused$1) {
- return;
- }
-
- var newTest = new Test({
- testName: testName,
- callback: callback,
- todo: true
- });
-
- newTest.queue();
- }
-
- // Will be exposed as QUnit.skip
- function skip(testName) {
- if (focused$1) {
- return;
- }
-
- var test = new Test({
- testName: testName,
- skip: true
- });
-
- test.queue();
- }
-
- // Will be exposed as QUnit.only
- function only(testName, callback) {
- if (focused$1) {
- return;
- }
-
- config.queue.length = 0;
- focused$1 = true;
-
- var newTest = new Test({
- testName: testName,
- callback: callback
- });
-
- newTest.queue();
- }
-
- // Put a hold on processing and return a function that will release it.
- function internalStop(test) {
- test.semaphore += 1;
- config.blocking = true;
-
- // Set a recovery timeout, if so configured.
- if (defined.setTimeout) {
- var timeoutDuration = void 0;
-
- if (typeof test.timeout === "number") {
- timeoutDuration = test.timeout;
- } else if (typeof config.testTimeout === "number") {
- timeoutDuration = config.testTimeout;
- }
-
- if (typeof timeoutDuration === "number" && timeoutDuration > 0) {
- clearTimeout(config.timeout);
- config.timeout = setTimeout(function () {
- pushFailure("Test took longer than " + timeoutDuration + "ms; test timed out.", sourceFromStacktrace(2));
- internalRecover(test);
- }, timeoutDuration);
- }
- }
-
- var released = false;
- return function resume() {
- if (released) {
- return;
- }
-
- released = true;
- test.semaphore -= 1;
- internalStart(test);
- };
- }
-
- // Forcefully release all processing holds.
- function internalRecover(test) {
- test.semaphore = 0;
- internalStart(test);
- }
-
- // Release a processing hold, scheduling a resumption attempt if no holds remain.
- function internalStart(test) {
-
- // If semaphore is non-numeric, throw error
- if (isNaN(test.semaphore)) {
- test.semaphore = 0;
-
- pushFailure("Invalid value on test.semaphore", sourceFromStacktrace(2));
- return;
- }
-
- // Don't start until equal number of stop-calls
- if (test.semaphore > 0) {
- return;
- }
-
- // Throw an Error if start is called more often than stop
- if (test.semaphore < 0) {
- test.semaphore = 0;
-
- pushFailure("Tried to restart test while already started (test's semaphore was 0 already)", sourceFromStacktrace(2));
- return;
- }
-
- // Add a slight delay to allow more assertions etc.
- if (defined.setTimeout) {
- if (config.timeout) {
- clearTimeout(config.timeout);
- }
- config.timeout = setTimeout(function () {
- if (test.semaphore > 0) {
- return;
- }
-
- if (config.timeout) {
- clearTimeout(config.timeout);
- }
-
- begin();
- });
- } else {
- begin();
- }
- }
-
- function collectTests(module) {
- var tests = [].concat(module.tests);
- var modules = [].concat(toConsumableArray(module.childModules));
-
- // Do a breadth-first traversal of the child modules
- while (modules.length) {
- var nextModule = modules.shift();
- tests.push.apply(tests, nextModule.tests);
- modules.push.apply(modules, toConsumableArray(nextModule.childModules));
- }
-
- return tests;
- }
-
- function numberOfTests(module) {
- return collectTests(module).length;
- }
-
- function numberOfUnskippedTests(module) {
- return collectTests(module).filter(function (test) {
- return !test.skip;
- }).length;
- }
-
- function notifyTestsRan(module, skipped) {
- module.testsRun++;
- if (!skipped) {
- module.unskippedTestsRun++;
- }
- while (module = module.parentModule) {
- module.testsRun++;
- if (!skipped) {
- module.unskippedTestsRun++;
- }
- }
- }
-
- /**
- * Returns a function that proxies to the given method name on the globals
- * console object. The proxy will also detect if the console doesn't exist and
- * will appropriately no-op. This allows support for IE9, which doesn't have a
- * console if the developer tools are not open.
- */
- function consoleProxy(method) {
- return function () {
- if (console) {
- console[method].apply(console, arguments);
- }
- };
- }
-
- var Logger = {
- warn: consoleProxy("warn")
- };
-
- var Assert = function () {
- function Assert(testContext) {
- classCallCheck(this, Assert);
-
- this.test = testContext;
- }
-
- // Assert helpers
-
- createClass(Assert, [{
- key: "timeout",
- value: function timeout(duration) {
- if (typeof duration !== "number") {
- throw new Error("You must pass a number as the duration to assert.timeout");
- }
-
- this.test.timeout = duration;
- }
-
- // Documents a "step", which is a string value, in a test as a passing assertion
-
- }, {
- key: "step",
- value: function step(message) {
- var result = !!message;
-
- this.test.steps.push(message);
-
- return this.pushResult({
- result: result,
- message: message || "You must provide a message to assert.step"
- });
- }
-
- // Verifies the steps in a test match a given array of string values
-
- }, {
- key: "verifySteps",
- value: function verifySteps(steps, message) {
- this.deepEqual(this.test.steps, steps, message);
- this.test.steps.length = 0;
- }
-
- // Specify the number of expected assertions to guarantee that failed test
- // (no assertions are run at all) don't slip through.
-
- }, {
- key: "expect",
- value: function expect(asserts) {
- if (arguments.length === 1) {
- this.test.expected = asserts;
- } else {
- return this.test.expected;
- }
- }
-
- // Put a hold on processing and return a function that will release it a maximum of once.
-
- }, {
- key: "async",
- value: function async(count) {
- var test$$1 = this.test;
-
- var popped = false,
- acceptCallCount = count;
-
- if (typeof acceptCallCount === "undefined") {
- acceptCallCount = 1;
- }
-
- var resume = internalStop(test$$1);
-
- return function done() {
- if (config.current !== test$$1) {
- throw Error("assert.async callback called after test finished.");
- }
-
- if (popped) {
- test$$1.pushFailure("Too many calls to the `assert.async` callback", sourceFromStacktrace(2));
- return;
- }
-
- acceptCallCount -= 1;
- if (acceptCallCount > 0) {
- return;
- }
-
- popped = true;
- resume();
- };
- }
-
- // Exports test.push() to the user API
- // Alias of pushResult.
-
- }, {
- key: "push",
- value: function push(result, actual, expected, message, negative) {
- Logger.warn("assert.push is deprecated and will be removed in QUnit 3.0." + " Please use assert.pushResult instead (https://api.qunitjs.com/assert/pushResult).");
-
- var currentAssert = this instanceof Assert ? this : config.current.assert;
- return currentAssert.pushResult({
- result: result,
- actual: actual,
- expected: expected,
- message: message,
- negative: negative
- });
- }
- }, {
- key: "pushResult",
- value: function pushResult(resultInfo) {
-
- // Destructure of resultInfo = { result, actual, expected, message, negative }
- var assert = this;
- var currentTest = assert instanceof Assert && assert.test || config.current;
-
- // Backwards compatibility fix.
- // Allows the direct use of global exported assertions and QUnit.assert.*
- // Although, it's use is not recommended as it can leak assertions
- // to other tests from async tests, because we only get a reference to the current test,
- // not exactly the test where assertion were intended to be called.
- if (!currentTest) {
- throw new Error("assertion outside test context, in " + sourceFromStacktrace(2));
- }
-
- if (!(assert instanceof Assert)) {
- assert = currentTest.assert;
- }
-
- return assert.test.pushResult(resultInfo);
- }
- }, {
- key: "ok",
- value: function ok(result, message) {
- if (!message) {
- message = result ? "okay" : "failed, expected argument to be truthy, was: " + dump.parse(result);
- }
-
- this.pushResult({
- result: !!result,
- actual: result,
- expected: true,
- message: message
- });
- }
- }, {
- key: "notOk",
- value: function notOk(result, message) {
- if (!message) {
- message = !result ? "okay" : "failed, expected argument to be falsy, was: " + dump.parse(result);
- }
-
- this.pushResult({
- result: !result,
- actual: result,
- expected: false,
- message: message
- });
- }
- }, {
- key: "equal",
- value: function equal(actual, expected, message) {
-
- // eslint-disable-next-line eqeqeq
- var result = expected == actual;
-
- this.pushResult({
- result: result,
- actual: actual,
- expected: expected,
- message: message
- });
- }
- }, {
- key: "notEqual",
- value: function notEqual(actual, expected, message) {
-
- // eslint-disable-next-line eqeqeq
- var result = expected != actual;
-
- this.pushResult({
- result: result,
- actual: actual,
- expected: expected,
- message: message,
- negative: true
- });
- }
- }, {
- key: "propEqual",
- value: function propEqual(actual, expected, message) {
- actual = objectValues(actual);
- expected = objectValues(expected);
-
- this.pushResult({
- result: equiv(actual, expected),
- actual: actual,
- expected: expected,
- message: message
- });
- }
- }, {
- key: "notPropEqual",
- value: function notPropEqual(actual, expected, message) {
- actual = objectValues(actual);
- expected = objectValues(expected);
-
- this.pushResult({
- result: !equiv(actual, expected),
- actual: actual,
- expected: expected,
- message: message,
- negative: true
- });
- }
- }, {
- key: "deepEqual",
- value: function deepEqual(actual, expected, message) {
- this.pushResult({
- result: equiv(actual, expected),
- actual: actual,
- expected: expected,
- message: message
- });
- }
- }, {
- key: "notDeepEqual",
- value: function notDeepEqual(actual, expected, message) {
- this.pushResult({
- result: !equiv(actual, expected),
- actual: actual,
- expected: expected,
- message: message,
- negative: true
- });
- }
- }, {
- key: "strictEqual",
- value: function strictEqual(actual, expected, message) {
- this.pushResult({
- result: expected === actual,
- actual: actual,
- expected: expected,
- message: message
- });
- }
- }, {
- key: "notStrictEqual",
- value: function notStrictEqual(actual, expected, message) {
- this.pushResult({
- result: expected !== actual,
- actual: actual,
- expected: expected,
- message: message,
- negative: true
- });
- }
- }, {
- key: "throws",
- value: function throws(block, expected, message) {
- var actual = void 0,
- result = false;
-
- var currentTest = this instanceof Assert && this.test || config.current;
-
- // 'expected' is optional unless doing string comparison
- if (objectType(expected) === "string") {
- if (message == null) {
- message = expected;
- expected = null;
- } else {
- throw new Error("throws/raises does not accept a string value for the expected argument.\n" + "Use a non-string object value (e.g. regExp) instead if it's necessary.");
- }
- }
-
- currentTest.ignoreGlobalErrors = true;
- try {
- block.call(currentTest.testEnvironment);
- } catch (e) {
- actual = e;
- }
- currentTest.ignoreGlobalErrors = false;
-
- if (actual) {
- var expectedType = objectType(expected);
-
- // We don't want to validate thrown error
- if (!expected) {
- result = true;
- expected = null;
-
- // Expected is a regexp
- } else if (expectedType === "regexp") {
- result = expected.test(errorString(actual));
-
- // Expected is a constructor, maybe an Error constructor
- } else if (expectedType === "function" && actual instanceof expected) {
- result = true;
-
- // Expected is an Error object
- } else if (expectedType === "object") {
- result = actual instanceof expected.constructor && actual.name === expected.name && actual.message === expected.message;
-
- // Expected is a validation function which returns true if validation passed
- } else if (expectedType === "function" && expected.call({}, actual) === true) {
- expected = null;
- result = true;
- }
- }
-
- currentTest.assert.pushResult({
- result: result,
- actual: actual,
- expected: expected,
- message: message
- });
- }
- }, {
- key: "rejects",
- value: function rejects(promise, expected, message) {
- var result = false;
-
- var currentTest = this instanceof Assert && this.test || config.current;
-
- // 'expected' is optional unless doing string comparison
- if (objectType(expected) === "string") {
- if (message === undefined) {
- message = expected;
- expected = undefined;
- } else {
- message = "assert.rejects does not accept a string value for the expected " + "argument.\nUse a non-string object value (e.g. validator function) instead " + "if necessary.";
-
- currentTest.assert.pushResult({
- result: false,
- message: message
- });
-
- return;
- }
- }
-
- var then = promise && promise.then;
- if (objectType(then) !== "function") {
- var _message = "The value provided to `assert.rejects` in " + "\"" + currentTest.testName + "\" was not a promise.";
-
- currentTest.assert.pushResult({
- result: false,
- message: _message,
- actual: promise
- });
-
- return;
- }
-
- var done = this.async();
-
- return then.call(promise, function handleFulfillment() {
- var message = "The promise returned by the `assert.rejects` callback in " + "\"" + currentTest.testName + "\" did not reject.";
-
- currentTest.assert.pushResult({
- result: false,
- message: message,
- actual: promise
- });
-
- done();
- }, function handleRejection(actual) {
- if (actual) {
- var expectedType = objectType(expected);
-
- // We don't want to validate
- if (expected === undefined) {
- result = true;
- expected = null;
-
- // Expected is a regexp
- } else if (expectedType === "regexp") {
- result = expected.test(errorString(actual));
-
- // Expected is a constructor, maybe an Error constructor
- } else if (expectedType === "function" && actual instanceof expected) {
- result = true;
-
- // Expected is an Error object
- } else if (expectedType === "object") {
- result = actual instanceof expected.constructor && actual.name === expected.name && actual.message === expected.message;
-
- // Expected is a validation function which returns true if validation passed
- } else {
- if (expectedType === "function") {
- result = expected.call({}, actual) === true;
- expected = null;
-
- // Expected is some other invalid type
- } else {
- result = false;
- message = "invalid expected value provided to `assert.rejects` " + "callback in \"" + currentTest.testName + "\": " + expectedType + ".";
- }
- }
- }
-
- currentTest.assert.pushResult({
- result: result,
- actual: actual,
- expected: expected,
- message: message
- });
-
- done();
- });
- }
- }]);
- return Assert;
- }();
-
- // Provide an alternative to assert.throws(), for environments that consider throws a reserved word
- // Known to us are: Closure Compiler, Narwhal
- // eslint-disable-next-line dot-notation
-
-
- Assert.prototype.raises = Assert.prototype["throws"];
-
- /**
- * Converts an error into a simple string for comparisons.
- *
- * @param {Error} error
- * @return {String}
- */
- function errorString(error) {
- var resultErrorString = error.toString();
-
- if (resultErrorString.substring(0, 7) === "[object") {
- var name = error.name ? error.name.toString() : "Error";
- var message = error.message ? error.message.toString() : "";
-
- if (name && message) {
- return name + ": " + message;
- } else if (name) {
- return name;
- } else if (message) {
- return message;
- } else {
- return "Error";
- }
- } else {
- return resultErrorString;
- }
- }
-
- /* global module, exports, define */
- function exportQUnit(QUnit) {
-
- if (defined.document) {
-
- // QUnit may be defined when it is preconfigured but then only QUnit and QUnit.config may be defined.
- if (window.QUnit && window.QUnit.version) {
- throw new Error("QUnit has already been defined.");
- }
-
- window.QUnit = QUnit;
- }
-
- // For nodejs
- if (typeof module !== "undefined" && module && module.exports) {
- module.exports = QUnit;
-
- // For consistency with CommonJS environments' exports
- module.exports.QUnit = QUnit;
- }
-
- // For CommonJS with exports, but without module.exports, like Rhino
- if (typeof exports !== "undefined" && exports) {
- exports.QUnit = QUnit;
- }
-
- if (typeof define === "function" && define.amd) {
- define(function () {
- return QUnit;
- });
- QUnit.config.autostart = false;
- }
-
- // For Web/Service Workers
- if (self$1 && self$1.WorkerGlobalScope && self$1 instanceof self$1.WorkerGlobalScope) {
- self$1.QUnit = QUnit;
- }
- }
-
- var SuiteReport = function () {
- function SuiteReport(name, parentSuite) {
- classCallCheck(this, SuiteReport);
-
- this.name = name;
- this.fullName = parentSuite ? parentSuite.fullName.concat(name) : [];
-
- this.tests = [];
- this.childSuites = [];
-
- if (parentSuite) {
- parentSuite.pushChildSuite(this);
- }
- }
-
- createClass(SuiteReport, [{
- key: "start",
- value: function start(recordTime) {
- if (recordTime) {
- this._startTime = Date.now();
- }
-
- return {
- name: this.name,
- fullName: this.fullName.slice(),
- tests: this.tests.map(function (test) {
- return test.start();
- }),
- childSuites: this.childSuites.map(function (suite) {
- return suite.start();
- }),
- testCounts: {
- total: this.getTestCounts().total
- }
- };
- }
- }, {
- key: "end",
- value: function end(recordTime) {
- if (recordTime) {
- this._endTime = Date.now();
- }
-
- return {
- name: this.name,
- fullName: this.fullName.slice(),
- tests: this.tests.map(function (test) {
- return test.end();
- }),
- childSuites: this.childSuites.map(function (suite) {
- return suite.end();
- }),
- testCounts: this.getTestCounts(),
- runtime: this.getRuntime(),
- status: this.getStatus()
- };
- }
- }, {
- key: "pushChildSuite",
- value: function pushChildSuite(suite) {
- this.childSuites.push(suite);
- }
- }, {
- key: "pushTest",
- value: function pushTest(test) {
- this.tests.push(test);
- }
- }, {
- key: "getRuntime",
- value: function getRuntime() {
- return this._endTime - this._startTime;
- }
- }, {
- key: "getTestCounts",
- value: function getTestCounts() {
- var counts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { passed: 0, failed: 0, skipped: 0, todo: 0, total: 0 };
-
- counts = this.tests.reduce(function (counts, test) {
- if (test.valid) {
- counts[test.getStatus()]++;
- counts.total++;
- }
-
- return counts;
- }, counts);
-
- return this.childSuites.reduce(function (counts, suite) {
- return suite.getTestCounts(counts);
- }, counts);
- }
- }, {
- key: "getStatus",
- value: function getStatus() {
- var _getTestCounts = this.getTestCounts(),
- total = _getTestCounts.total,
- failed = _getTestCounts.failed,
- skipped = _getTestCounts.skipped,
- todo = _getTestCounts.todo;
-
- if (failed) {
- return "failed";
- } else {
- if (skipped === total) {
- return "skipped";
- } else if (todo === total) {
- return "todo";
- } else {
- return "passed";
- }
- }
- }
- }]);
- return SuiteReport;
- }();
-
- // Handle an unhandled exception. By convention, returns true if further
- // error handling should be suppressed and false otherwise.
- // In this case, we will only suppress further error handling if the
- // "ignoreGlobalErrors" configuration option is enabled.
- function onError(error) {
- for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
- args[_key - 1] = arguments[_key];
- }
-
- if (config.current) {
- if (config.current.ignoreGlobalErrors) {
- return true;
- }
- pushFailure.apply(undefined, [error.message, error.fileName + ":" + error.lineNumber].concat(args));
- } else {
- test("global failure", extend(function () {
- pushFailure.apply(undefined, [error.message, error.fileName + ":" + error.lineNumber].concat(args));
- }, { validTest: true }));
- }
-
- return false;
- }
-
- // Handle an unhandled rejection
- function onUnhandledRejection(reason) {
- var resultInfo = {
- result: false,
- message: reason.message || "error",
- actual: reason,
- source: reason.stack || sourceFromStacktrace(3)
- };
-
- var currentTest = config.current;
- if (currentTest) {
- currentTest.assert.pushResult(resultInfo);
- } else {
- test("global failure", extend(function (assert) {
- assert.pushResult(resultInfo);
- }, { validTest: true }));
- }
- }
-
- var focused = false;
- var QUnit = {};
- var globalSuite = new SuiteReport();
-
- // The initial "currentModule" represents the global (or top-level) module that
- // is not explicitly defined by the user, therefore we add the "globalSuite" to
- // it since each module has a suiteReport associated with it.
- config.currentModule.suiteReport = globalSuite;
-
- var moduleStack = [];
- var globalStartCalled = false;
- var runStarted = false;
-
- // Figure out if we're running the tests from a server or not
- QUnit.isLocal = !(defined.document && window.location.protocol !== "file:");
-
- // Expose the current QUnit version
- QUnit.version = "2.5.0";
-
- function createModule(name, testEnvironment, modifiers) {
- var parentModule = moduleStack.length ? moduleStack.slice(-1)[0] : null;
- var moduleName = parentModule !== null ? [parentModule.name, name].join(" > ") : name;
- var parentSuite = parentModule ? parentModule.suiteReport : globalSuite;
-
- var skip$$1 = parentModule !== null && parentModule.skip || modifiers.skip;
- var todo$$1 = parentModule !== null && parentModule.todo || modifiers.todo;
-
- var module = {
- name: moduleName,
- parentModule: parentModule,
- tests: [],
- moduleId: generateHash(moduleName),
- testsRun: 0,
- unskippedTestsRun: 0,
- childModules: [],
- suiteReport: new SuiteReport(name, parentSuite),
-
- // Pass along `skip` and `todo` properties from parent module, in case
- // there is one, to childs. And use own otherwise.
- // This property will be used to mark own tests and tests of child suites
- // as either `skipped` or `todo`.
- skip: skip$$1,
- todo: skip$$1 ? false : todo$$1
- };
-
- var env = {};
- if (parentModule) {
- parentModule.childModules.push(module);
- extend(env, parentModule.testEnvironment);
- }
- extend(env, testEnvironment);
- module.testEnvironment = env;
-
- config.modules.push(module);
- return module;
- }
-
- function processModule(name, options, executeNow) {
- var modifiers = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
-
- var module = createModule(name, options, modifiers);
-
- // Move any hooks to a 'hooks' object
- var testEnvironment = module.testEnvironment;
- var hooks = module.hooks = {};
-
- setHookFromEnvironment(hooks, testEnvironment, "before");
- setHookFromEnvironment(hooks, testEnvironment, "beforeEach");
- setHookFromEnvironment(hooks, testEnvironment, "afterEach");
- setHookFromEnvironment(hooks, testEnvironment, "after");
-
- function setHookFromEnvironment(hooks, environment, name) {
- var potentialHook = environment[name];
- hooks[name] = typeof potentialHook === "function" ? [potentialHook] : [];
- delete environment[name];
- }
-
- var moduleFns = {
- before: setHookFunction(module, "before"),
- beforeEach: setHookFunction(module, "beforeEach"),
- afterEach: setHookFunction(module, "afterEach"),
- after: setHookFunction(module, "after")
- };
-
- var currentModule = config.currentModule;
- if (objectType(executeNow) === "function") {
- moduleStack.push(module);
- config.currentModule = module;
- executeNow.call(module.testEnvironment, moduleFns);
- moduleStack.pop();
- module = module.parentModule || currentModule;
- }
-
- config.currentModule = module;
- }
-
- // TODO: extract this to a new file alongside its related functions
- function module$1(name, options, executeNow) {
- if (focused) {
- return;
- }
-
- if (arguments.length === 2) {
- if (objectType(options) === "function") {
- executeNow = options;
- options = undefined;
- }
- }
-
- processModule(name, options, executeNow);
- }
-
- module$1.only = function () {
- if (focused) {
- return;
- }
-
- config.modules.length = 0;
- config.queue.length = 0;
-
- module$1.apply(undefined, arguments);
-
- focused = true;
- };
-
- module$1.skip = function (name, options, executeNow) {
- if (focused) {
- return;
- }
-
- if (arguments.length === 2) {
- if (objectType(options) === "function") {
- executeNow = options;
- options = undefined;
- }
- }
-
- processModule(name, options, executeNow, { skip: true });
- };
-
- module$1.todo = function (name, options, executeNow) {
- if (focused) {
- return;
- }
-
- if (arguments.length === 2) {
- if (objectType(options) === "function") {
- executeNow = options;
- options = undefined;
- }
- }
-
- processModule(name, options, executeNow, { todo: true });
- };
-
- extend(QUnit, {
- on: on,
-
- module: module$1,
-
- test: test,
-
- todo: todo,
-
- skip: skip,
-
- only: only,
-
- start: function start(count) {
- var globalStartAlreadyCalled = globalStartCalled;
-
- if (!config.current) {
- globalStartCalled = true;
-
- if (runStarted) {
- throw new Error("Called start() while test already started running");
- } else if (globalStartAlreadyCalled || count > 1) {
- throw new Error("Called start() outside of a test context too many times");
- } else if (config.autostart) {
- throw new Error("Called start() outside of a test context when " + "QUnit.config.autostart was true");
- } else if (!config.pageLoaded) {
-
- // The page isn't completely loaded yet, so we set autostart and then
- // load if we're in Node or wait for the browser's load event.
- config.autostart = true;
-
- // Starts from Node even if .load was not previously called. We still return
- // early otherwise we'll wind up "beginning" twice.
- if (!defined.document) {
- QUnit.load();
- }
-
- return;
- }
- } else {
- throw new Error("QUnit.start cannot be called inside a test context.");
- }
-
- scheduleBegin();
- },
-
- config: config,
-
- is: is,
-
- objectType: objectType,
-
- extend: extend,
-
- load: function load() {
- config.pageLoaded = true;
-
- // Initialize the configuration options
- extend(config, {
- stats: { all: 0, bad: 0 },
- started: 0,
- updateRate: 1000,
- autostart: true,
- filter: ""
- }, true);
-
- if (!runStarted) {
- config.blocking = false;
-
- if (config.autostart) {
- scheduleBegin();
- }
- }
- },
-
- stack: function stack(offset) {
- offset = (offset || 0) + 2;
- return sourceFromStacktrace(offset);
- },
-
- onError: onError,
-
- onUnhandledRejection: onUnhandledRejection
- });
-
- QUnit.pushFailure = pushFailure;
- QUnit.assert = Assert.prototype;
- QUnit.equiv = equiv;
- QUnit.dump = dump;
-
- registerLoggingCallbacks(QUnit);
-
- function scheduleBegin() {
-
- runStarted = true;
-
- // Add a slight delay to allow definition of more modules and tests.
- if (defined.setTimeout) {
- setTimeout(function () {
- begin();
- });
- } else {
- begin();
- }
- }
-
- function begin() {
- var i,
- l,
- modulesLog = [];
-
- // If the test run hasn't officially begun yet
- if (!config.started) {
-
- // Record the time of the test run's beginning
- config.started = now();
-
- // Delete the loose unnamed module if unused.
- if (config.modules[0].name === "" && config.modules[0].tests.length === 0) {
- config.modules.shift();
- }
-
- // Avoid unnecessary information by not logging modules' test environments
- for (i = 0, l = config.modules.length; i < l; i++) {
- modulesLog.push({
- name: config.modules[i].name,
- tests: config.modules[i].tests
- });
- }
-
- // The test run is officially beginning now
- emit("runStart", globalSuite.start(true));
- runLoggingCallbacks("begin", {
- totalTests: Test.count,
- modules: modulesLog
- });
- }
-
- config.blocking = false;
- ProcessingQueue.advance();
- }
-
- function setHookFunction(module, hookName) {
- return function setHook(callback) {
- module.hooks[hookName].push(callback);
- };
- }
-
- exportQUnit(QUnit);
-
- (function () {
-
- if (typeof window === "undefined" || typeof document === "undefined") {
- return;
- }
-
- var config = QUnit.config,
- hasOwn = Object.prototype.hasOwnProperty;
-
- // Stores fixture HTML for resetting later
- function storeFixture() {
-
- // Avoid overwriting user-defined values
- if (hasOwn.call(config, "fixture")) {
- return;
- }
-
- var fixture = document.getElementById("qunit-fixture");
- if (fixture) {
- config.fixture = fixture.innerHTML;
- }
- }
-
- QUnit.begin(storeFixture);
-
- // Resets the fixture DOM element if available.
- function resetFixture() {
- if (config.fixture == null) {
- return;
- }
-
- var fixture = document.getElementById("qunit-fixture");
- if (fixture) {
- fixture.innerHTML = config.fixture;
- }
- }
-
- QUnit.testStart(resetFixture);
- })();
-
- (function () {
-
- // Only interact with URLs via window.location
- var location = typeof window !== "undefined" && window.location;
- if (!location) {
- return;
- }
-
- var urlParams = getUrlParams();
-
- QUnit.urlParams = urlParams;
-
- // Match module/test by inclusion in an array
- QUnit.config.moduleId = [].concat(urlParams.moduleId || []);
- QUnit.config.testId = [].concat(urlParams.testId || []);
-
- // Exact case-insensitive match of the module name
- QUnit.config.module = urlParams.module;
-
- // Regular expression or case-insenstive substring match against "moduleName: testName"
- QUnit.config.filter = urlParams.filter;
-
- // Test order randomization
- if (urlParams.seed === true) {
-
- // Generate a random seed if the option is specified without a value
- QUnit.config.seed = Math.random().toString(36).slice(2);
- } else if (urlParams.seed) {
- QUnit.config.seed = urlParams.seed;
- }
-
- // Add URL-parameter-mapped config values with UI form rendering data
- QUnit.config.urlConfig.push({
- id: "hidepassed",
- label: "Hide passed tests",
- tooltip: "Only show tests and assertions that fail. Stored as query-strings."
- }, {
- id: "noglobals",
- label: "Check for Globals",
- tooltip: "Enabling this will test if any test introduces new properties on the " + "global object (`window` in Browsers). Stored as query-strings."
- }, {
- id: "notrycatch",
- label: "No try-catch",
- tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging " + "exceptions in IE reasonable. Stored as query-strings."
- });
-
- QUnit.begin(function () {
- var i,
- option,
- urlConfig = QUnit.config.urlConfig;
-
- for (i = 0; i < urlConfig.length; i++) {
-
- // Options can be either strings or objects with nonempty "id" properties
- option = QUnit.config.urlConfig[i];
- if (typeof option !== "string") {
- option = option.id;
- }
-
- if (QUnit.config[option] === undefined) {
- QUnit.config[option] = urlParams[option];
- }
- }
- });
-
- function getUrlParams() {
- var i, param, name, value;
- var urlParams = Object.create(null);
- var params = location.search.slice(1).split("&");
- var length = params.length;
-
- for (i = 0; i < length; i++) {
- if (params[i]) {
- param = params[i].split("=");
- name = decodeQueryParam(param[0]);
-
- // Allow just a key to turn on a flag, e.g., test.html?noglobals
- value = param.length === 1 || decodeQueryParam(param.slice(1).join("="));
- if (name in urlParams) {
- urlParams[name] = [].concat(urlParams[name], value);
- } else {
- urlParams[name] = value;
- }
- }
- }
-
- return urlParams;
- }
-
- function decodeQueryParam(param) {
- return decodeURIComponent(param.replace(/\+/g, "%20"));
- }
- })();
-
- var stats = {
- passedTests: 0,
- failedTests: 0,
- skippedTests: 0,
- todoTests: 0
- };
-
- // Escape text for attribute or text content.
- function escapeText(s) {
- if (!s) {
- return "";
- }
- s = s + "";
-
- // Both single quotes and double quotes (for attributes)
- return s.replace(/['"<>&]/g, function (s) {
- switch (s) {
- case "'":
- return "'";
- case "\"":
- return """;
- case "<":
- return "<";
- case ">":
- return ">";
- case "&":
- return "&";
- }
- });
- }
-
- (function () {
-
- // Don't load the HTML Reporter on non-browser environments
- if (typeof window === "undefined" || !window.document) {
- return;
- }
-
- var config = QUnit.config,
- document$$1 = window.document,
- collapseNext = false,
- hasOwn = Object.prototype.hasOwnProperty,
- unfilteredUrl = setUrl({ filter: undefined, module: undefined,
- moduleId: undefined, testId: undefined }),
- modulesList = [];
-
- function addEvent(elem, type, fn) {
- elem.addEventListener(type, fn, false);
- }
-
- function removeEvent(elem, type, fn) {
- elem.removeEventListener(type, fn, false);
- }
-
- function addEvents(elems, type, fn) {
- var i = elems.length;
- while (i--) {
- addEvent(elems[i], type, fn);
- }
- }
-
- function hasClass(elem, name) {
- return (" " + elem.className + " ").indexOf(" " + name + " ") >= 0;
- }
-
- function addClass(elem, name) {
- if (!hasClass(elem, name)) {
- elem.className += (elem.className ? " " : "") + name;
- }
- }
-
- function toggleClass(elem, name, force) {
- if (force || typeof force === "undefined" && !hasClass(elem, name)) {
- addClass(elem, name);
- } else {
- removeClass(elem, name);
- }
- }
-
- function removeClass(elem, name) {
- var set = " " + elem.className + " ";
-
- // Class name may appear multiple times
- while (set.indexOf(" " + name + " ") >= 0) {
- set = set.replace(" " + name + " ", " ");
- }
-
- // Trim for prettiness
- elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, "");
- }
-
- function id(name) {
- return document$$1.getElementById && document$$1.getElementById(name);
- }
-
- function abortTests() {
- var abortButton = id("qunit-abort-tests-button");
- if (abortButton) {
- abortButton.disabled = true;
- abortButton.innerHTML = "Aborting...";
- }
- QUnit.config.queue.length = 0;
- return false;
- }
-
- function interceptNavigation(ev) {
- applyUrlParams();
-
- if (ev && ev.preventDefault) {
- ev.preventDefault();
- }
-
- return false;
- }
-
- function getUrlConfigHtml() {
- var i,
- j,
- val,
- escaped,
- escapedTooltip,
- selection = false,
- urlConfig = config.urlConfig,
- urlConfigHtml = "";
-
- for (i = 0; i < urlConfig.length; i++) {
-
- // Options can be either strings or objects with nonempty "id" properties
- val = config.urlConfig[i];
- if (typeof val === "string") {
- val = {
- id: val,
- label: val
- };
- }
-
- escaped = escapeText(val.id);
- escapedTooltip = escapeText(val.tooltip);
-
- if (!val.value || typeof val.value === "string") {
- urlConfigHtml += " " + escapeText(val.label) + " ";
- } else {
- urlConfigHtml += "" + val.label + ": ";
-
- if (QUnit.is("array", val.value)) {
- for (j = 0; j < val.value.length; j++) {
- escaped = escapeText(val.value[j]);
- urlConfigHtml += "" + escaped + " ";
- }
- } else {
- for (j in val.value) {
- if (hasOwn.call(val.value, j)) {
- urlConfigHtml += "" + escapeText(val.value[j]) + " ";
- }
- }
- }
- if (config[val.id] && !selection) {
- escaped = escapeText(config[val.id]);
- urlConfigHtml += "" + escaped + " ";
- }
- urlConfigHtml += " ";
- }
- }
-
- return urlConfigHtml;
- }
-
- // Handle "click" events on toolbar checkboxes and "change" for select menus.
- // Updates the URL with the new state of `config.urlConfig` values.
- function toolbarChanged() {
- var updatedUrl,
- value,
- tests,
- field = this,
- params = {};
-
- // Detect if field is a select menu or a checkbox
- if ("selectedIndex" in field) {
- value = field.options[field.selectedIndex].value || undefined;
- } else {
- value = field.checked ? field.defaultValue || true : undefined;
- }
-
- params[field.name] = value;
- updatedUrl = setUrl(params);
-
- // Check if we can apply the change without a page refresh
- if ("hidepassed" === field.name && "replaceState" in window.history) {
- QUnit.urlParams[field.name] = value;
- config[field.name] = value || false;
- tests = id("qunit-tests");
- if (tests) {
- toggleClass(tests, "hidepass", value || false);
- }
- window.history.replaceState(null, "", updatedUrl);
- } else {
- window.location = updatedUrl;
- }
- }
-
- function setUrl(params) {
- var key,
- arrValue,
- i,
- querystring = "?",
- location = window.location;
-
- params = QUnit.extend(QUnit.extend({}, QUnit.urlParams), params);
-
- for (key in params) {
-
- // Skip inherited or undefined properties
- if (hasOwn.call(params, key) && params[key] !== undefined) {
-
- // Output a parameter for each value of this key
- // (but usually just one)
- arrValue = [].concat(params[key]);
- for (i = 0; i < arrValue.length; i++) {
- querystring += encodeURIComponent(key);
- if (arrValue[i] !== true) {
- querystring += "=" + encodeURIComponent(arrValue[i]);
- }
- querystring += "&";
- }
- }
- }
- return location.protocol + "//" + location.host + location.pathname + querystring.slice(0, -1);
- }
-
- function applyUrlParams() {
- var i,
- selectedModules = [],
- modulesList = id("qunit-modulefilter-dropdown-list").getElementsByTagName("input"),
- filter = id("qunit-filter-input").value;
-
- for (i = 0; i < modulesList.length; i++) {
- if (modulesList[i].checked) {
- selectedModules.push(modulesList[i].value);
- }
- }
-
- window.location = setUrl({
- filter: filter === "" ? undefined : filter,
- moduleId: selectedModules.length === 0 ? undefined : selectedModules,
-
- // Remove module and testId filter
- module: undefined,
- testId: undefined
- });
- }
-
- function toolbarUrlConfigContainer() {
- var urlConfigContainer = document$$1.createElement("span");
-
- urlConfigContainer.innerHTML = getUrlConfigHtml();
- addClass(urlConfigContainer, "qunit-url-config");
-
- addEvents(urlConfigContainer.getElementsByTagName("input"), "change", toolbarChanged);
- addEvents(urlConfigContainer.getElementsByTagName("select"), "change", toolbarChanged);
-
- return urlConfigContainer;
- }
-
- function abortTestsButton() {
- var button = document$$1.createElement("button");
- button.id = "qunit-abort-tests-button";
- button.innerHTML = "Abort";
- addEvent(button, "click", abortTests);
- return button;
- }
-
- function toolbarLooseFilter() {
- var filter = document$$1.createElement("form"),
- label = document$$1.createElement("label"),
- input = document$$1.createElement("input"),
- button = document$$1.createElement("button");
-
- addClass(filter, "qunit-filter");
-
- label.innerHTML = "Filter: ";
-
- input.type = "text";
- input.value = config.filter || "";
- input.name = "filter";
- input.id = "qunit-filter-input";
-
- button.innerHTML = "Go";
-
- label.appendChild(input);
-
- filter.appendChild(label);
- filter.appendChild(document$$1.createTextNode(" "));
- filter.appendChild(button);
- addEvent(filter, "submit", interceptNavigation);
-
- return filter;
- }
-
- function moduleListHtml() {
- var i,
- checked,
- html = "";
-
- for (i = 0; i < config.modules.length; i++) {
- if (config.modules[i].name !== "") {
- checked = config.moduleId.indexOf(config.modules[i].moduleId) > -1;
- html += " " + escapeText(config.modules[i].name) + " ";
- }
- }
-
- return html;
- }
-
- function toolbarModuleFilter() {
- var allCheckbox,
- commit,
- reset,
- moduleFilter = document$$1.createElement("form"),
- label = document$$1.createElement("label"),
- moduleSearch = document$$1.createElement("input"),
- dropDown = document$$1.createElement("div"),
- actions = document$$1.createElement("span"),
- dropDownList = document$$1.createElement("ul"),
- dirty = false;
-
- moduleSearch.id = "qunit-modulefilter-search";
- addEvent(moduleSearch, "input", searchInput);
- addEvent(moduleSearch, "input", searchFocus);
- addEvent(moduleSearch, "focus", searchFocus);
- addEvent(moduleSearch, "click", searchFocus);
-
- label.id = "qunit-modulefilter-search-container";
- label.innerHTML = "Module: ";
- label.appendChild(moduleSearch);
-
- actions.id = "qunit-modulefilter-actions";
- actions.innerHTML = "Apply " + "Reset " + " All modules ";
- allCheckbox = actions.lastChild.firstChild;
- commit = actions.firstChild;
- reset = commit.nextSibling;
- addEvent(commit, "click", applyUrlParams);
-
- dropDownList.id = "qunit-modulefilter-dropdown-list";
- dropDownList.innerHTML = moduleListHtml();
-
- dropDown.id = "qunit-modulefilter-dropdown";
- dropDown.style.display = "none";
- dropDown.appendChild(actions);
- dropDown.appendChild(dropDownList);
- addEvent(dropDown, "change", selectionChange);
- selectionChange();
-
- moduleFilter.id = "qunit-modulefilter";
- moduleFilter.appendChild(label);
- moduleFilter.appendChild(dropDown);
- addEvent(moduleFilter, "submit", interceptNavigation);
- addEvent(moduleFilter, "reset", function () {
-
- // Let the reset happen, then update styles
- window.setTimeout(selectionChange);
- });
-
- // Enables show/hide for the dropdown
- function searchFocus() {
- if (dropDown.style.display !== "none") {
- return;
- }
-
- dropDown.style.display = "block";
- addEvent(document$$1, "click", hideHandler);
- addEvent(document$$1, "keydown", hideHandler);
-
- // Hide on Escape keydown or outside-container click
- function hideHandler(e) {
- var inContainer = moduleFilter.contains(e.target);
-
- if (e.keyCode === 27 || !inContainer) {
- if (e.keyCode === 27 && inContainer) {
- moduleSearch.focus();
- }
- dropDown.style.display = "none";
- removeEvent(document$$1, "click", hideHandler);
- removeEvent(document$$1, "keydown", hideHandler);
- moduleSearch.value = "";
- searchInput();
- }
- }
- }
-
- // Processes module search box input
- function searchInput() {
- var i,
- item,
- searchText = moduleSearch.value.toLowerCase(),
- listItems = dropDownList.children;
-
- for (i = 0; i < listItems.length; i++) {
- item = listItems[i];
- if (!searchText || item.textContent.toLowerCase().indexOf(searchText) > -1) {
- item.style.display = "";
- } else {
- item.style.display = "none";
- }
- }
- }
-
- // Processes selection changes
- function selectionChange(evt) {
- var i,
- item,
- checkbox = evt && evt.target || allCheckbox,
- modulesList = dropDownList.getElementsByTagName("input"),
- selectedNames = [];
-
- toggleClass(checkbox.parentNode, "checked", checkbox.checked);
-
- dirty = false;
- if (checkbox.checked && checkbox !== allCheckbox) {
- allCheckbox.checked = false;
- removeClass(allCheckbox.parentNode, "checked");
- }
- for (i = 0; i < modulesList.length; i++) {
- item = modulesList[i];
- if (!evt) {
- toggleClass(item.parentNode, "checked", item.checked);
- } else if (checkbox === allCheckbox && checkbox.checked) {
- item.checked = false;
- removeClass(item.parentNode, "checked");
- }
- dirty = dirty || item.checked !== item.defaultChecked;
- if (item.checked) {
- selectedNames.push(item.parentNode.textContent);
- }
- }
-
- commit.style.display = reset.style.display = dirty ? "" : "none";
- moduleSearch.placeholder = selectedNames.join(", ") || allCheckbox.parentNode.textContent;
- moduleSearch.title = "Type to filter list. Current selection:\n" + (selectedNames.join("\n") || allCheckbox.parentNode.textContent);
- }
-
- return moduleFilter;
- }
-
- function appendToolbar() {
- var toolbar = id("qunit-testrunner-toolbar");
-
- if (toolbar) {
- toolbar.appendChild(toolbarUrlConfigContainer());
- toolbar.appendChild(toolbarModuleFilter());
- toolbar.appendChild(toolbarLooseFilter());
- toolbar.appendChild(document$$1.createElement("div")).className = "clearfix";
- }
- }
-
- function appendHeader() {
- var header = id("qunit-header");
-
- if (header) {
- header.innerHTML = "" + header.innerHTML + " ";
- }
- }
-
- function appendBanner() {
- var banner = id("qunit-banner");
-
- if (banner) {
- banner.className = "";
- }
- }
-
- function appendTestResults() {
- var tests = id("qunit-tests"),
- result = id("qunit-testresult"),
- controls;
-
- if (result) {
- result.parentNode.removeChild(result);
- }
-
- if (tests) {
- tests.innerHTML = "";
- result = document$$1.createElement("p");
- result.id = "qunit-testresult";
- result.className = "result";
- tests.parentNode.insertBefore(result, tests);
- result.innerHTML = "Running...
" + "
" + "
";
- controls = id("qunit-testresult-controls");
- }
-
- if (controls) {
- controls.appendChild(abortTestsButton());
- }
- }
-
- function appendFilteredTest() {
- var testId = QUnit.config.testId;
- if (!testId || testId.length <= 0) {
- return "";
- }
- return "Rerunning selected tests: " + escapeText(testId.join(", ")) + "
Run all tests ";
- }
-
- function appendUserAgent() {
- var userAgent = id("qunit-userAgent");
-
- if (userAgent) {
- userAgent.innerHTML = "";
- userAgent.appendChild(document$$1.createTextNode("QUnit " + QUnit.version + "; " + navigator.userAgent));
- }
- }
-
- function appendInterface() {
- var qunit = id("qunit");
-
- if (qunit) {
- qunit.innerHTML = "" + " " + "
" + appendFilteredTest() + " " + " ";
- }
-
- appendHeader();
- appendBanner();
- appendTestResults();
- appendUserAgent();
- appendToolbar();
- }
-
- function appendTestsList(modules) {
- var i, l, x, z, test, moduleObj;
-
- for (i = 0, l = modules.length; i < l; i++) {
- moduleObj = modules[i];
-
- for (x = 0, z = moduleObj.tests.length; x < z; x++) {
- test = moduleObj.tests[x];
-
- appendTest(test.name, test.testId, moduleObj.name);
- }
- }
- }
-
- function appendTest(name, testId, moduleName) {
- var title,
- rerunTrigger,
- testBlock,
- assertList,
- tests = id("qunit-tests");
-
- if (!tests) {
- return;
- }
-
- title = document$$1.createElement("strong");
- title.innerHTML = getNameHtml(name, moduleName);
-
- rerunTrigger = document$$1.createElement("a");
- rerunTrigger.innerHTML = "Rerun";
- rerunTrigger.href = setUrl({ testId: testId });
-
- testBlock = document$$1.createElement("li");
- testBlock.appendChild(title);
- testBlock.appendChild(rerunTrigger);
- testBlock.id = "qunit-test-output-" + testId;
-
- assertList = document$$1.createElement("ol");
- assertList.className = "qunit-assert-list";
-
- testBlock.appendChild(assertList);
-
- tests.appendChild(testBlock);
- }
-
- // HTML Reporter initialization and load
- QUnit.begin(function (details) {
- var i, moduleObj, tests;
-
- // Sort modules by name for the picker
- for (i = 0; i < details.modules.length; i++) {
- moduleObj = details.modules[i];
- if (moduleObj.name) {
- modulesList.push(moduleObj.name);
- }
- }
- modulesList.sort(function (a, b) {
- return a.localeCompare(b);
- });
-
- // Initialize QUnit elements
- appendInterface();
- appendTestsList(details.modules);
- tests = id("qunit-tests");
- if (tests && config.hidepassed) {
- addClass(tests, "hidepass");
- }
- });
-
- QUnit.done(function (details) {
- var banner = id("qunit-banner"),
- tests = id("qunit-tests"),
- abortButton = id("qunit-abort-tests-button"),
- totalTests = stats.passedTests + stats.skippedTests + stats.todoTests + stats.failedTests,
- html = [totalTests, " tests completed in ", details.runtime, " milliseconds, with ", stats.failedTests, " failed, ", stats.skippedTests, " skipped, and ", stats.todoTests, " todo. ", "", details.passed, " assertions of ", details.total, " passed, ", details.failed, " failed."].join(""),
- test,
- assertLi,
- assertList;
-
- // Update remaing tests to aborted
- if (abortButton && abortButton.disabled) {
- html = "Tests aborted after " + details.runtime + " milliseconds.";
-
- for (var i = 0; i < tests.children.length; i++) {
- test = tests.children[i];
- if (test.className === "" || test.className === "running") {
- test.className = "aborted";
- assertList = test.getElementsByTagName("ol")[0];
- assertLi = document$$1.createElement("li");
- assertLi.className = "fail";
- assertLi.innerHTML = "Test aborted.";
- assertList.appendChild(assertLi);
- }
- }
- }
-
- if (banner && (!abortButton || abortButton.disabled === false)) {
- banner.className = stats.failedTests ? "qunit-fail" : "qunit-pass";
- }
-
- if (abortButton) {
- abortButton.parentNode.removeChild(abortButton);
- }
-
- if (tests) {
- id("qunit-testresult-display").innerHTML = html;
- }
-
- if (config.altertitle && document$$1.title) {
-
- // Show ✖ for good, ✔ for bad suite result in title
- // use escape sequences in case file gets loaded with non-utf-8
- // charset
- document$$1.title = [stats.failedTests ? "\u2716" : "\u2714", document$$1.title.replace(/^[\u2714\u2716] /i, "")].join(" ");
- }
-
- // Scroll back to top to show results
- if (config.scrolltop && window.scrollTo) {
- window.scrollTo(0, 0);
- }
- });
-
- function getNameHtml(name, module) {
- var nameHtml = "";
-
- if (module) {
- nameHtml = "" + escapeText(module) + " : ";
- }
-
- nameHtml += "" + escapeText(name) + " ";
-
- return nameHtml;
- }
-
- QUnit.testStart(function (details) {
- var running, testBlock, bad;
-
- testBlock = id("qunit-test-output-" + details.testId);
- if (testBlock) {
- testBlock.className = "running";
- } else {
-
- // Report later registered tests
- appendTest(details.name, details.testId, details.module);
- }
-
- running = id("qunit-testresult-display");
- if (running) {
- bad = QUnit.config.reorder && details.previousFailure;
-
- running.innerHTML = [bad ? "Rerunning previously failed test: " : "Running: ", getNameHtml(details.name, details.module)].join("");
- }
- });
-
- function stripHtml(string) {
-
- // Strip tags, html entity and whitespaces
- return string.replace(/<\/?[^>]+(>|$)/g, "").replace(/\"/g, "").replace(/\s+/g, "");
- }
-
- QUnit.log(function (details) {
- var assertList,
- assertLi,
- message,
- expected,
- actual,
- diff,
- showDiff = false,
- testItem = id("qunit-test-output-" + details.testId);
-
- if (!testItem) {
- return;
- }
-
- message = escapeText(details.message) || (details.result ? "okay" : "failed");
- message = "" + message + " ";
- message += "@ " + details.runtime + " ms ";
-
- // The pushFailure doesn't provide details.expected
- // when it calls, it's implicit to also not show expected and diff stuff
- // Also, we need to check details.expected existence, as it can exist and be undefined
- if (!details.result && hasOwn.call(details, "expected")) {
- if (details.negative) {
- expected = "NOT " + QUnit.dump.parse(details.expected);
- } else {
- expected = QUnit.dump.parse(details.expected);
- }
-
- actual = QUnit.dump.parse(details.actual);
- message += "Expected: " + escapeText(expected) + " ";
-
- if (actual !== expected) {
-
- message += "Result: " + escapeText(actual) + " ";
-
- if (typeof details.actual === "number" && typeof details.expected === "number") {
- if (!isNaN(details.actual) && !isNaN(details.expected)) {
- showDiff = true;
- diff = details.actual - details.expected;
- diff = (diff > 0 ? "+" : "") + diff;
- }
- } else if (typeof details.actual !== "boolean" && typeof details.expected !== "boolean") {
- diff = QUnit.diff(expected, actual);
-
- // don't show diff if there is zero overlap
- showDiff = stripHtml(diff).length !== stripHtml(expected).length + stripHtml(actual).length;
- }
-
- if (showDiff) {
- message += "Diff: " + diff + " ";
- }
- } else if (expected.indexOf("[object Array]") !== -1 || expected.indexOf("[object Object]") !== -1) {
- message += "Message: " + "Diff suppressed as the depth of object is more than current max depth (" + QUnit.config.maxDepth + ").Hint: Use QUnit.dump.maxDepth
to " + " run with a higher max depth or " + "Rerun without max depth.
";
- } else {
- message += "Message: " + "Diff suppressed as the expected and actual results have an equivalent" + " serialization ";
- }
-
- if (details.source) {
- message += "Source: " + escapeText(details.source) + " ";
- }
-
- message += "
";
-
- // This occurs when pushFailure is set and we have an extracted stack trace
- } else if (!details.result && details.source) {
- message += "" + "Source: " + escapeText(details.source) + " " + "
";
- }
-
- assertList = testItem.getElementsByTagName("ol")[0];
-
- assertLi = document$$1.createElement("li");
- assertLi.className = details.result ? "pass" : "fail";
- assertLi.innerHTML = message;
- assertList.appendChild(assertLi);
- });
-
- QUnit.testDone(function (details) {
- var testTitle,
- time,
- testItem,
- assertList,
- good,
- bad,
- testCounts,
- skipped,
- sourceName,
- tests = id("qunit-tests");
-
- if (!tests) {
- return;
- }
-
- testItem = id("qunit-test-output-" + details.testId);
-
- assertList = testItem.getElementsByTagName("ol")[0];
-
- good = details.passed;
- bad = details.failed;
-
- // This test passed if it has no unexpected failed assertions
- var testPassed = details.failed > 0 ? details.todo : !details.todo;
-
- if (testPassed) {
-
- // Collapse the passing tests
- addClass(assertList, "qunit-collapsed");
- } else if (config.collapse) {
- if (!collapseNext) {
-
- // Skip collapsing the first failing test
- collapseNext = true;
- } else {
-
- // Collapse remaining tests
- addClass(assertList, "qunit-collapsed");
- }
- }
-
- // The testItem.firstChild is the test name
- testTitle = testItem.firstChild;
-
- testCounts = bad ? "" + bad + " , " + "" + good + " , " : "";
-
- testTitle.innerHTML += " (" + testCounts + details.assertions.length + ") ";
-
- if (details.skipped) {
- stats.skippedTests++;
-
- testItem.className = "skipped";
- skipped = document$$1.createElement("em");
- skipped.className = "qunit-skipped-label";
- skipped.innerHTML = "skipped";
- testItem.insertBefore(skipped, testTitle);
- } else {
- addEvent(testTitle, "click", function () {
- toggleClass(assertList, "qunit-collapsed");
- });
-
- testItem.className = testPassed ? "pass" : "fail";
-
- if (details.todo) {
- var todoLabel = document$$1.createElement("em");
- todoLabel.className = "qunit-todo-label";
- todoLabel.innerHTML = "todo";
- testItem.className += " todo";
- testItem.insertBefore(todoLabel, testTitle);
- }
-
- time = document$$1.createElement("span");
- time.className = "runtime";
- time.innerHTML = details.runtime + " ms";
- testItem.insertBefore(time, assertList);
-
- if (!testPassed) {
- stats.failedTests++;
- } else if (details.todo) {
- stats.todoTests++;
- } else {
- stats.passedTests++;
- }
- }
-
- // Show the source of the test when showing assertions
- if (details.source) {
- sourceName = document$$1.createElement("p");
- sourceName.innerHTML = "Source: " + details.source;
- addClass(sourceName, "qunit-source");
- if (testPassed) {
- addClass(sourceName, "qunit-collapsed");
- }
- addEvent(testTitle, "click", function () {
- toggleClass(sourceName, "qunit-collapsed");
- });
- testItem.appendChild(sourceName);
- }
- });
-
- // Avoid readyState issue with phantomjs
- // Ref: #818
- var notPhantom = function (p) {
- return !(p && p.version && p.version.major > 0);
- }(window.phantom);
-
- if (notPhantom && document$$1.readyState === "complete") {
- QUnit.load();
- } else {
- addEvent(window, "load", QUnit.load);
- }
-
- // Wrap window.onerror. We will call the original window.onerror to see if
- // the existing handler fully handles the error; if not, we will call the
- // QUnit.onError function.
- var originalWindowOnError = window.onerror;
-
- // Cover uncaught exceptions
- // Returning true will suppress the default browser handler,
- // returning false will let it run.
- window.onerror = function (message, fileName, lineNumber) {
- var ret = false;
- if (originalWindowOnError) {
- for (var _len = arguments.length, args = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
- args[_key - 3] = arguments[_key];
- }
-
- ret = originalWindowOnError.call.apply(originalWindowOnError, [this, message, fileName, lineNumber].concat(args));
- }
-
- // Treat return value as window.onerror itself does,
- // Only do our handling if not suppressed.
- if (ret !== true) {
- var error = {
- message: message,
- fileName: fileName,
- lineNumber: lineNumber
- };
-
- ret = QUnit.onError(error);
- }
-
- return ret;
- };
-
- // Listen for unhandled rejections, and call QUnit.onUnhandledRejection
- window.addEventListener("unhandledrejection", function (event) {
- QUnit.onUnhandledRejection(event.reason);
- });
- })();
-
- /*
- * This file is a modified version of google-diff-match-patch's JavaScript implementation
- * (https://code.google.com/p/google-diff-match-patch/source/browse/trunk/javascript/diff_match_patch_uncompressed.js),
- * modifications are licensed as more fully set forth in LICENSE.txt.
- *
- * The original source of google-diff-match-patch is attributable and licensed as follows:
- *
- * Copyright 2006 Google Inc.
- * https://code.google.com/p/google-diff-match-patch/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * More Info:
- * https://code.google.com/p/google-diff-match-patch/
- *
- * Usage: QUnit.diff(expected, actual)
- *
- */
- QUnit.diff = function () {
- function DiffMatchPatch() {}
-
- // DIFF FUNCTIONS
-
- /**
- * The data structure representing a diff is an array of tuples:
- * [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']]
- * which means: delete 'Hello', add 'Goodbye' and keep ' world.'
- */
- var DIFF_DELETE = -1,
- DIFF_INSERT = 1,
- DIFF_EQUAL = 0;
-
- /**
- * Find the differences between two texts. Simplifies the problem by stripping
- * any common prefix or suffix off the texts before diffing.
- * @param {string} text1 Old string to be diffed.
- * @param {string} text2 New string to be diffed.
- * @param {boolean=} optChecklines Optional speedup flag. If present and false,
- * then don't run a line-level diff first to identify the changed areas.
- * Defaults to true, which does a faster, slightly less optimal diff.
- * @return {!Array.} Array of diff tuples.
- */
- DiffMatchPatch.prototype.DiffMain = function (text1, text2, optChecklines) {
- var deadline, checklines, commonlength, commonprefix, commonsuffix, diffs;
-
- // The diff must be complete in up to 1 second.
- deadline = new Date().getTime() + 1000;
-
- // Check for null inputs.
- if (text1 === null || text2 === null) {
- throw new Error("Null input. (DiffMain)");
- }
-
- // Check for equality (speedup).
- if (text1 === text2) {
- if (text1) {
- return [[DIFF_EQUAL, text1]];
- }
- return [];
- }
-
- if (typeof optChecklines === "undefined") {
- optChecklines = true;
- }
-
- checklines = optChecklines;
-
- // Trim off common prefix (speedup).
- commonlength = this.diffCommonPrefix(text1, text2);
- commonprefix = text1.substring(0, commonlength);
- text1 = text1.substring(commonlength);
- text2 = text2.substring(commonlength);
-
- // Trim off common suffix (speedup).
- commonlength = this.diffCommonSuffix(text1, text2);
- commonsuffix = text1.substring(text1.length - commonlength);
- text1 = text1.substring(0, text1.length - commonlength);
- text2 = text2.substring(0, text2.length - commonlength);
-
- // Compute the diff on the middle block.
- diffs = this.diffCompute(text1, text2, checklines, deadline);
-
- // Restore the prefix and suffix.
- if (commonprefix) {
- diffs.unshift([DIFF_EQUAL, commonprefix]);
- }
- if (commonsuffix) {
- diffs.push([DIFF_EQUAL, commonsuffix]);
- }
- this.diffCleanupMerge(diffs);
- return diffs;
- };
-
- /**
- * Reduce the number of edits by eliminating operationally trivial equalities.
- * @param {!Array.} diffs Array of diff tuples.
- */
- DiffMatchPatch.prototype.diffCleanupEfficiency = function (diffs) {
- var changes, equalities, equalitiesLength, lastequality, pointer, preIns, preDel, postIns, postDel;
- changes = false;
- equalities = []; // Stack of indices where equalities are found.
- equalitiesLength = 0; // Keeping our own length var is faster in JS.
- /** @type {?string} */
- lastequality = null;
-
- // Always equal to diffs[equalities[equalitiesLength - 1]][1]
- pointer = 0; // Index of current position.
-
- // Is there an insertion operation before the last equality.
- preIns = false;
-
- // Is there a deletion operation before the last equality.
- preDel = false;
-
- // Is there an insertion operation after the last equality.
- postIns = false;
-
- // Is there a deletion operation after the last equality.
- postDel = false;
- while (pointer < diffs.length) {
-
- // Equality found.
- if (diffs[pointer][0] === DIFF_EQUAL) {
- if (diffs[pointer][1].length < 4 && (postIns || postDel)) {
-
- // Candidate found.
- equalities[equalitiesLength++] = pointer;
- preIns = postIns;
- preDel = postDel;
- lastequality = diffs[pointer][1];
- } else {
-
- // Not a candidate, and can never become one.
- equalitiesLength = 0;
- lastequality = null;
- }
- postIns = postDel = false;
-
- // An insertion or deletion.
- } else {
-
- if (diffs[pointer][0] === DIFF_DELETE) {
- postDel = true;
- } else {
- postIns = true;
- }
-
- /*
- * Five types to be split:
- * A BXYC D
- * A XC D
- * A BXC
- * AXC D
- * A BXC
- */
- if (lastequality && (preIns && preDel && postIns && postDel || lastequality.length < 2 && preIns + preDel + postIns + postDel === 3)) {
-
- // Duplicate record.
- diffs.splice(equalities[equalitiesLength - 1], 0, [DIFF_DELETE, lastequality]);
-
- // Change second copy to insert.
- diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;
- equalitiesLength--; // Throw away the equality we just deleted;
- lastequality = null;
- if (preIns && preDel) {
-
- // No changes made which could affect previous entry, keep going.
- postIns = postDel = true;
- equalitiesLength = 0;
- } else {
- equalitiesLength--; // Throw away the previous equality.
- pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1;
- postIns = postDel = false;
- }
- changes = true;
- }
- }
- pointer++;
- }
-
- if (changes) {
- this.diffCleanupMerge(diffs);
- }
- };
-
- /**
- * Convert a diff array into a pretty HTML report.
- * @param {!Array.} diffs Array of diff tuples.
- * @param {integer} string to be beautified.
- * @return {string} HTML representation.
- */
- DiffMatchPatch.prototype.diffPrettyHtml = function (diffs) {
- var op,
- data,
- x,
- html = [];
- for (x = 0; x < diffs.length; x++) {
- op = diffs[x][0]; // Operation (insert, delete, equal)
- data = diffs[x][1]; // Text of change.
- switch (op) {
- case DIFF_INSERT:
- html[x] = "" + escapeText(data) + " ";
- break;
- case DIFF_DELETE:
- html[x] = "" + escapeText(data) + "";
- break;
- case DIFF_EQUAL:
- html[x] = "" + escapeText(data) + " ";
- break;
- }
- }
- return html.join("");
- };
-
- /**
- * Determine the common prefix of two strings.
- * @param {string} text1 First string.
- * @param {string} text2 Second string.
- * @return {number} The number of characters common to the start of each
- * string.
- */
- DiffMatchPatch.prototype.diffCommonPrefix = function (text1, text2) {
- var pointermid, pointermax, pointermin, pointerstart;
-
- // Quick check for common null cases.
- if (!text1 || !text2 || text1.charAt(0) !== text2.charAt(0)) {
- return 0;
- }
-
- // Binary search.
- // Performance analysis: https://neil.fraser.name/news/2007/10/09/
- pointermin = 0;
- pointermax = Math.min(text1.length, text2.length);
- pointermid = pointermax;
- pointerstart = 0;
- while (pointermin < pointermid) {
- if (text1.substring(pointerstart, pointermid) === text2.substring(pointerstart, pointermid)) {
- pointermin = pointermid;
- pointerstart = pointermin;
- } else {
- pointermax = pointermid;
- }
- pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
- }
- return pointermid;
- };
-
- /**
- * Determine the common suffix of two strings.
- * @param {string} text1 First string.
- * @param {string} text2 Second string.
- * @return {number} The number of characters common to the end of each string.
- */
- DiffMatchPatch.prototype.diffCommonSuffix = function (text1, text2) {
- var pointermid, pointermax, pointermin, pointerend;
-
- // Quick check for common null cases.
- if (!text1 || !text2 || text1.charAt(text1.length - 1) !== text2.charAt(text2.length - 1)) {
- return 0;
- }
-
- // Binary search.
- // Performance analysis: https://neil.fraser.name/news/2007/10/09/
- pointermin = 0;
- pointermax = Math.min(text1.length, text2.length);
- pointermid = pointermax;
- pointerend = 0;
- while (pointermin < pointermid) {
- if (text1.substring(text1.length - pointermid, text1.length - pointerend) === text2.substring(text2.length - pointermid, text2.length - pointerend)) {
- pointermin = pointermid;
- pointerend = pointermin;
- } else {
- pointermax = pointermid;
- }
- pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
- }
- return pointermid;
- };
-
- /**
- * Find the differences between two texts. Assumes that the texts do not
- * have any common prefix or suffix.
- * @param {string} text1 Old string to be diffed.
- * @param {string} text2 New string to be diffed.
- * @param {boolean} checklines Speedup flag. If false, then don't run a
- * line-level diff first to identify the changed areas.
- * If true, then run a faster, slightly less optimal diff.
- * @param {number} deadline Time when the diff should be complete by.
- * @return {!Array.} Array of diff tuples.
- * @private
- */
- DiffMatchPatch.prototype.diffCompute = function (text1, text2, checklines, deadline) {
- var diffs, longtext, shorttext, i, hm, text1A, text2A, text1B, text2B, midCommon, diffsA, diffsB;
-
- if (!text1) {
-
- // Just add some text (speedup).
- return [[DIFF_INSERT, text2]];
- }
-
- if (!text2) {
-
- // Just delete some text (speedup).
- return [[DIFF_DELETE, text1]];
- }
-
- longtext = text1.length > text2.length ? text1 : text2;
- shorttext = text1.length > text2.length ? text2 : text1;
- i = longtext.indexOf(shorttext);
- if (i !== -1) {
-
- // Shorter text is inside the longer text (speedup).
- diffs = [[DIFF_INSERT, longtext.substring(0, i)], [DIFF_EQUAL, shorttext], [DIFF_INSERT, longtext.substring(i + shorttext.length)]];
-
- // Swap insertions for deletions if diff is reversed.
- if (text1.length > text2.length) {
- diffs[0][0] = diffs[2][0] = DIFF_DELETE;
- }
- return diffs;
- }
-
- if (shorttext.length === 1) {
-
- // Single character string.
- // After the previous speedup, the character can't be an equality.
- return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];
- }
-
- // Check to see if the problem can be split in two.
- hm = this.diffHalfMatch(text1, text2);
- if (hm) {
-
- // A half-match was found, sort out the return data.
- text1A = hm[0];
- text1B = hm[1];
- text2A = hm[2];
- text2B = hm[3];
- midCommon = hm[4];
-
- // Send both pairs off for separate processing.
- diffsA = this.DiffMain(text1A, text2A, checklines, deadline);
- diffsB = this.DiffMain(text1B, text2B, checklines, deadline);
-
- // Merge the results.
- return diffsA.concat([[DIFF_EQUAL, midCommon]], diffsB);
- }
-
- if (checklines && text1.length > 100 && text2.length > 100) {
- return this.diffLineMode(text1, text2, deadline);
- }
-
- return this.diffBisect(text1, text2, deadline);
- };
-
- /**
- * Do the two texts share a substring which is at least half the length of the
- * longer text?
- * This speedup can produce non-minimal diffs.
- * @param {string} text1 First string.
- * @param {string} text2 Second string.
- * @return {Array.} Five element Array, containing the prefix of
- * text1, the suffix of text1, the prefix of text2, the suffix of
- * text2 and the common middle. Or null if there was no match.
- * @private
- */
- DiffMatchPatch.prototype.diffHalfMatch = function (text1, text2) {
- var longtext, shorttext, dmp, text1A, text2B, text2A, text1B, midCommon, hm1, hm2, hm;
-
- longtext = text1.length > text2.length ? text1 : text2;
- shorttext = text1.length > text2.length ? text2 : text1;
- if (longtext.length < 4 || shorttext.length * 2 < longtext.length) {
- return null; // Pointless.
- }
- dmp = this; // 'this' becomes 'window' in a closure.
-
- /**
- * Does a substring of shorttext exist within longtext such that the substring
- * is at least half the length of longtext?
- * Closure, but does not reference any external variables.
- * @param {string} longtext Longer string.
- * @param {string} shorttext Shorter string.
- * @param {number} i Start index of quarter length substring within longtext.
- * @return {Array.} Five element Array, containing the prefix of
- * longtext, the suffix of longtext, the prefix of shorttext, the suffix
- * of shorttext and the common middle. Or null if there was no match.
- * @private
- */
- function diffHalfMatchI(longtext, shorttext, i) {
- var seed, j, bestCommon, prefixLength, suffixLength, bestLongtextA, bestLongtextB, bestShorttextA, bestShorttextB;
-
- // Start with a 1/4 length substring at position i as a seed.
- seed = longtext.substring(i, i + Math.floor(longtext.length / 4));
- j = -1;
- bestCommon = "";
- while ((j = shorttext.indexOf(seed, j + 1)) !== -1) {
- prefixLength = dmp.diffCommonPrefix(longtext.substring(i), shorttext.substring(j));
- suffixLength = dmp.diffCommonSuffix(longtext.substring(0, i), shorttext.substring(0, j));
- if (bestCommon.length < suffixLength + prefixLength) {
- bestCommon = shorttext.substring(j - suffixLength, j) + shorttext.substring(j, j + prefixLength);
- bestLongtextA = longtext.substring(0, i - suffixLength);
- bestLongtextB = longtext.substring(i + prefixLength);
- bestShorttextA = shorttext.substring(0, j - suffixLength);
- bestShorttextB = shorttext.substring(j + prefixLength);
- }
- }
- if (bestCommon.length * 2 >= longtext.length) {
- return [bestLongtextA, bestLongtextB, bestShorttextA, bestShorttextB, bestCommon];
- } else {
- return null;
- }
- }
-
- // First check if the second quarter is the seed for a half-match.
- hm1 = diffHalfMatchI(longtext, shorttext, Math.ceil(longtext.length / 4));
-
- // Check again based on the third quarter.
- hm2 = diffHalfMatchI(longtext, shorttext, Math.ceil(longtext.length / 2));
- if (!hm1 && !hm2) {
- return null;
- } else if (!hm2) {
- hm = hm1;
- } else if (!hm1) {
- hm = hm2;
- } else {
-
- // Both matched. Select the longest.
- hm = hm1[4].length > hm2[4].length ? hm1 : hm2;
- }
-
- // A half-match was found, sort out the return data.
- if (text1.length > text2.length) {
- text1A = hm[0];
- text1B = hm[1];
- text2A = hm[2];
- text2B = hm[3];
- } else {
- text2A = hm[0];
- text2B = hm[1];
- text1A = hm[2];
- text1B = hm[3];
- }
- midCommon = hm[4];
- return [text1A, text1B, text2A, text2B, midCommon];
- };
-
- /**
- * Do a quick line-level diff on both strings, then rediff the parts for
- * greater accuracy.
- * This speedup can produce non-minimal diffs.
- * @param {string} text1 Old string to be diffed.
- * @param {string} text2 New string to be diffed.
- * @param {number} deadline Time when the diff should be complete by.
- * @return {!Array.} Array of diff tuples.
- * @private
- */
- DiffMatchPatch.prototype.diffLineMode = function (text1, text2, deadline) {
- var a, diffs, linearray, pointer, countInsert, countDelete, textInsert, textDelete, j;
-
- // Scan the text on a line-by-line basis first.
- a = this.diffLinesToChars(text1, text2);
- text1 = a.chars1;
- text2 = a.chars2;
- linearray = a.lineArray;
-
- diffs = this.DiffMain(text1, text2, false, deadline);
-
- // Convert the diff back to original text.
- this.diffCharsToLines(diffs, linearray);
-
- // Eliminate freak matches (e.g. blank lines)
- this.diffCleanupSemantic(diffs);
-
- // Rediff any replacement blocks, this time character-by-character.
- // Add a dummy entry at the end.
- diffs.push([DIFF_EQUAL, ""]);
- pointer = 0;
- countDelete = 0;
- countInsert = 0;
- textDelete = "";
- textInsert = "";
- while (pointer < diffs.length) {
- switch (diffs[pointer][0]) {
- case DIFF_INSERT:
- countInsert++;
- textInsert += diffs[pointer][1];
- break;
- case DIFF_DELETE:
- countDelete++;
- textDelete += diffs[pointer][1];
- break;
- case DIFF_EQUAL:
-
- // Upon reaching an equality, check for prior redundancies.
- if (countDelete >= 1 && countInsert >= 1) {
-
- // Delete the offending records and add the merged ones.
- diffs.splice(pointer - countDelete - countInsert, countDelete + countInsert);
- pointer = pointer - countDelete - countInsert;
- a = this.DiffMain(textDelete, textInsert, false, deadline);
- for (j = a.length - 1; j >= 0; j--) {
- diffs.splice(pointer, 0, a[j]);
- }
- pointer = pointer + a.length;
- }
- countInsert = 0;
- countDelete = 0;
- textDelete = "";
- textInsert = "";
- break;
- }
- pointer++;
- }
- diffs.pop(); // Remove the dummy entry at the end.
-
- return diffs;
- };
-
- /**
- * Find the 'middle snake' of a diff, split the problem in two
- * and return the recursively constructed diff.
- * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.
- * @param {string} text1 Old string to be diffed.
- * @param {string} text2 New string to be diffed.
- * @param {number} deadline Time at which to bail if not yet complete.
- * @return {!Array.} Array of diff tuples.
- * @private
- */
- DiffMatchPatch.prototype.diffBisect = function (text1, text2, deadline) {
- var text1Length, text2Length, maxD, vOffset, vLength, v1, v2, x, delta, front, k1start, k1end, k2start, k2end, k2Offset, k1Offset, x1, x2, y1, y2, d, k1, k2;
-
- // Cache the text lengths to prevent multiple calls.
- text1Length = text1.length;
- text2Length = text2.length;
- maxD = Math.ceil((text1Length + text2Length) / 2);
- vOffset = maxD;
- vLength = 2 * maxD;
- v1 = new Array(vLength);
- v2 = new Array(vLength);
-
- // Setting all elements to -1 is faster in Chrome & Firefox than mixing
- // integers and undefined.
- for (x = 0; x < vLength; x++) {
- v1[x] = -1;
- v2[x] = -1;
- }
- v1[vOffset + 1] = 0;
- v2[vOffset + 1] = 0;
- delta = text1Length - text2Length;
-
- // If the total number of characters is odd, then the front path will collide
- // with the reverse path.
- front = delta % 2 !== 0;
-
- // Offsets for start and end of k loop.
- // Prevents mapping of space beyond the grid.
- k1start = 0;
- k1end = 0;
- k2start = 0;
- k2end = 0;
- for (d = 0; d < maxD; d++) {
-
- // Bail out if deadline is reached.
- if (new Date().getTime() > deadline) {
- break;
- }
-
- // Walk the front path one step.
- for (k1 = -d + k1start; k1 <= d - k1end; k1 += 2) {
- k1Offset = vOffset + k1;
- if (k1 === -d || k1 !== d && v1[k1Offset - 1] < v1[k1Offset + 1]) {
- x1 = v1[k1Offset + 1];
- } else {
- x1 = v1[k1Offset - 1] + 1;
- }
- y1 = x1 - k1;
- while (x1 < text1Length && y1 < text2Length && text1.charAt(x1) === text2.charAt(y1)) {
- x1++;
- y1++;
- }
- v1[k1Offset] = x1;
- if (x1 > text1Length) {
-
- // Ran off the right of the graph.
- k1end += 2;
- } else if (y1 > text2Length) {
-
- // Ran off the bottom of the graph.
- k1start += 2;
- } else if (front) {
- k2Offset = vOffset + delta - k1;
- if (k2Offset >= 0 && k2Offset < vLength && v2[k2Offset] !== -1) {
-
- // Mirror x2 onto top-left coordinate system.
- x2 = text1Length - v2[k2Offset];
- if (x1 >= x2) {
-
- // Overlap detected.
- return this.diffBisectSplit(text1, text2, x1, y1, deadline);
- }
- }
- }
- }
-
- // Walk the reverse path one step.
- for (k2 = -d + k2start; k2 <= d - k2end; k2 += 2) {
- k2Offset = vOffset + k2;
- if (k2 === -d || k2 !== d && v2[k2Offset - 1] < v2[k2Offset + 1]) {
- x2 = v2[k2Offset + 1];
- } else {
- x2 = v2[k2Offset - 1] + 1;
- }
- y2 = x2 - k2;
- while (x2 < text1Length && y2 < text2Length && text1.charAt(text1Length - x2 - 1) === text2.charAt(text2Length - y2 - 1)) {
- x2++;
- y2++;
- }
- v2[k2Offset] = x2;
- if (x2 > text1Length) {
-
- // Ran off the left of the graph.
- k2end += 2;
- } else if (y2 > text2Length) {
-
- // Ran off the top of the graph.
- k2start += 2;
- } else if (!front) {
- k1Offset = vOffset + delta - k2;
- if (k1Offset >= 0 && k1Offset < vLength && v1[k1Offset] !== -1) {
- x1 = v1[k1Offset];
- y1 = vOffset + x1 - k1Offset;
-
- // Mirror x2 onto top-left coordinate system.
- x2 = text1Length - x2;
- if (x1 >= x2) {
-
- // Overlap detected.
- return this.diffBisectSplit(text1, text2, x1, y1, deadline);
- }
- }
- }
- }
- }
-
- // Diff took too long and hit the deadline or
- // number of diffs equals number of characters, no commonality at all.
- return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];
- };
-
- /**
- * Given the location of the 'middle snake', split the diff in two parts
- * and recurse.
- * @param {string} text1 Old string to be diffed.
- * @param {string} text2 New string to be diffed.
- * @param {number} x Index of split point in text1.
- * @param {number} y Index of split point in text2.
- * @param {number} deadline Time at which to bail if not yet complete.
- * @return {!Array.} Array of diff tuples.
- * @private
- */
- DiffMatchPatch.prototype.diffBisectSplit = function (text1, text2, x, y, deadline) {
- var text1a, text1b, text2a, text2b, diffs, diffsb;
- text1a = text1.substring(0, x);
- text2a = text2.substring(0, y);
- text1b = text1.substring(x);
- text2b = text2.substring(y);
-
- // Compute both diffs serially.
- diffs = this.DiffMain(text1a, text2a, false, deadline);
- diffsb = this.DiffMain(text1b, text2b, false, deadline);
-
- return diffs.concat(diffsb);
- };
-
- /**
- * Reduce the number of edits by eliminating semantically trivial equalities.
- * @param {!Array.} diffs Array of diff tuples.
- */
- DiffMatchPatch.prototype.diffCleanupSemantic = function (diffs) {
- var changes, equalities, equalitiesLength, lastequality, pointer, lengthInsertions2, lengthDeletions2, lengthInsertions1, lengthDeletions1, deletion, insertion, overlapLength1, overlapLength2;
- changes = false;
- equalities = []; // Stack of indices where equalities are found.
- equalitiesLength = 0; // Keeping our own length var is faster in JS.
- /** @type {?string} */
- lastequality = null;
-
- // Always equal to diffs[equalities[equalitiesLength - 1]][1]
- pointer = 0; // Index of current position.
-
- // Number of characters that changed prior to the equality.
- lengthInsertions1 = 0;
- lengthDeletions1 = 0;
-
- // Number of characters that changed after the equality.
- lengthInsertions2 = 0;
- lengthDeletions2 = 0;
- while (pointer < diffs.length) {
- if (diffs[pointer][0] === DIFF_EQUAL) {
- // Equality found.
- equalities[equalitiesLength++] = pointer;
- lengthInsertions1 = lengthInsertions2;
- lengthDeletions1 = lengthDeletions2;
- lengthInsertions2 = 0;
- lengthDeletions2 = 0;
- lastequality = diffs[pointer][1];
- } else {
- // An insertion or deletion.
- if (diffs[pointer][0] === DIFF_INSERT) {
- lengthInsertions2 += diffs[pointer][1].length;
- } else {
- lengthDeletions2 += diffs[pointer][1].length;
- }
-
- // Eliminate an equality that is smaller or equal to the edits on both
- // sides of it.
- if (lastequality && lastequality.length <= Math.max(lengthInsertions1, lengthDeletions1) && lastequality.length <= Math.max(lengthInsertions2, lengthDeletions2)) {
-
- // Duplicate record.
- diffs.splice(equalities[equalitiesLength - 1], 0, [DIFF_DELETE, lastequality]);
-
- // Change second copy to insert.
- diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;
-
- // Throw away the equality we just deleted.
- equalitiesLength--;
-
- // Throw away the previous equality (it needs to be reevaluated).
- equalitiesLength--;
- pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1;
-
- // Reset the counters.
- lengthInsertions1 = 0;
- lengthDeletions1 = 0;
- lengthInsertions2 = 0;
- lengthDeletions2 = 0;
- lastequality = null;
- changes = true;
- }
- }
- pointer++;
- }
-
- // Normalize the diff.
- if (changes) {
- this.diffCleanupMerge(diffs);
- }
-
- // Find any overlaps between deletions and insertions.
- // e.g: abcxxxxxxdef
- // -> abcxxxdef
- // e.g: xxxabcdefxxx
- // -> def xxxabc
- // Only extract an overlap if it is as big as the edit ahead or behind it.
- pointer = 1;
- while (pointer < diffs.length) {
- if (diffs[pointer - 1][0] === DIFF_DELETE && diffs[pointer][0] === DIFF_INSERT) {
- deletion = diffs[pointer - 1][1];
- insertion = diffs[pointer][1];
- overlapLength1 = this.diffCommonOverlap(deletion, insertion);
- overlapLength2 = this.diffCommonOverlap(insertion, deletion);
- if (overlapLength1 >= overlapLength2) {
- if (overlapLength1 >= deletion.length / 2 || overlapLength1 >= insertion.length / 2) {
-
- // Overlap found. Insert an equality and trim the surrounding edits.
- diffs.splice(pointer, 0, [DIFF_EQUAL, insertion.substring(0, overlapLength1)]);
- diffs[pointer - 1][1] = deletion.substring(0, deletion.length - overlapLength1);
- diffs[pointer + 1][1] = insertion.substring(overlapLength1);
- pointer++;
- }
- } else {
- if (overlapLength2 >= deletion.length / 2 || overlapLength2 >= insertion.length / 2) {
-
- // Reverse overlap found.
- // Insert an equality and swap and trim the surrounding edits.
- diffs.splice(pointer, 0, [DIFF_EQUAL, deletion.substring(0, overlapLength2)]);
-
- diffs[pointer - 1][0] = DIFF_INSERT;
- diffs[pointer - 1][1] = insertion.substring(0, insertion.length - overlapLength2);
- diffs[pointer + 1][0] = DIFF_DELETE;
- diffs[pointer + 1][1] = deletion.substring(overlapLength2);
- pointer++;
- }
- }
- pointer++;
- }
- pointer++;
- }
- };
-
- /**
- * Determine if the suffix of one string is the prefix of another.
- * @param {string} text1 First string.
- * @param {string} text2 Second string.
- * @return {number} The number of characters common to the end of the first
- * string and the start of the second string.
- * @private
- */
- DiffMatchPatch.prototype.diffCommonOverlap = function (text1, text2) {
- var text1Length, text2Length, textLength, best, length, pattern, found;
-
- // Cache the text lengths to prevent multiple calls.
- text1Length = text1.length;
- text2Length = text2.length;
-
- // Eliminate the null case.
- if (text1Length === 0 || text2Length === 0) {
- return 0;
- }
-
- // Truncate the longer string.
- if (text1Length > text2Length) {
- text1 = text1.substring(text1Length - text2Length);
- } else if (text1Length < text2Length) {
- text2 = text2.substring(0, text1Length);
- }
- textLength = Math.min(text1Length, text2Length);
-
- // Quick check for the worst case.
- if (text1 === text2) {
- return textLength;
- }
-
- // Start by looking for a single character match
- // and increase length until no match is found.
- // Performance analysis: https://neil.fraser.name/news/2010/11/04/
- best = 0;
- length = 1;
- while (true) {
- pattern = text1.substring(textLength - length);
- found = text2.indexOf(pattern);
- if (found === -1) {
- return best;
- }
- length += found;
- if (found === 0 || text1.substring(textLength - length) === text2.substring(0, length)) {
- best = length;
- length++;
- }
- }
- };
-
- /**
- * Split two texts into an array of strings. Reduce the texts to a string of
- * hashes where each Unicode character represents one line.
- * @param {string} text1 First string.
- * @param {string} text2 Second string.
- * @return {{chars1: string, chars2: string, lineArray: !Array.}}
- * An object containing the encoded text1, the encoded text2 and
- * the array of unique strings.
- * The zeroth element of the array of unique strings is intentionally blank.
- * @private
- */
- DiffMatchPatch.prototype.diffLinesToChars = function (text1, text2) {
- var lineArray, lineHash, chars1, chars2;
- lineArray = []; // E.g. lineArray[4] === 'Hello\n'
- lineHash = {}; // E.g. lineHash['Hello\n'] === 4
-
- // '\x00' is a valid character, but various debuggers don't like it.
- // So we'll insert a junk entry to avoid generating a null character.
- lineArray[0] = "";
-
- /**
- * Split a text into an array of strings. Reduce the texts to a string of
- * hashes where each Unicode character represents one line.
- * Modifies linearray and linehash through being a closure.
- * @param {string} text String to encode.
- * @return {string} Encoded string.
- * @private
- */
- function diffLinesToCharsMunge(text) {
- var chars, lineStart, lineEnd, lineArrayLength, line;
- chars = "";
-
- // Walk the text, pulling out a substring for each line.
- // text.split('\n') would would temporarily double our memory footprint.
- // Modifying text would create many large strings to garbage collect.
- lineStart = 0;
- lineEnd = -1;
-
- // Keeping our own length variable is faster than looking it up.
- lineArrayLength = lineArray.length;
- while (lineEnd < text.length - 1) {
- lineEnd = text.indexOf("\n", lineStart);
- if (lineEnd === -1) {
- lineEnd = text.length - 1;
- }
- line = text.substring(lineStart, lineEnd + 1);
- lineStart = lineEnd + 1;
-
- var lineHashExists = lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : lineHash[line] !== undefined;
-
- if (lineHashExists) {
- chars += String.fromCharCode(lineHash[line]);
- } else {
- chars += String.fromCharCode(lineArrayLength);
- lineHash[line] = lineArrayLength;
- lineArray[lineArrayLength++] = line;
- }
- }
- return chars;
- }
-
- chars1 = diffLinesToCharsMunge(text1);
- chars2 = diffLinesToCharsMunge(text2);
- return {
- chars1: chars1,
- chars2: chars2,
- lineArray: lineArray
- };
- };
-
- /**
- * Rehydrate the text in a diff from a string of line hashes to real lines of
- * text.
- * @param {!Array.} diffs Array of diff tuples.
- * @param {!Array.} lineArray Array of unique strings.
- * @private
- */
- DiffMatchPatch.prototype.diffCharsToLines = function (diffs, lineArray) {
- var x, chars, text, y;
- for (x = 0; x < diffs.length; x++) {
- chars = diffs[x][1];
- text = [];
- for (y = 0; y < chars.length; y++) {
- text[y] = lineArray[chars.charCodeAt(y)];
- }
- diffs[x][1] = text.join("");
- }
- };
-
- /**
- * Reorder and merge like edit sections. Merge equalities.
- * Any edit section can move as long as it doesn't cross an equality.
- * @param {!Array.} diffs Array of diff tuples.
- */
- DiffMatchPatch.prototype.diffCleanupMerge = function (diffs) {
- var pointer, countDelete, countInsert, textInsert, textDelete, commonlength, changes, diffPointer, position;
- diffs.push([DIFF_EQUAL, ""]); // Add a dummy entry at the end.
- pointer = 0;
- countDelete = 0;
- countInsert = 0;
- textDelete = "";
- textInsert = "";
-
- while (pointer < diffs.length) {
- switch (diffs[pointer][0]) {
- case DIFF_INSERT:
- countInsert++;
- textInsert += diffs[pointer][1];
- pointer++;
- break;
- case DIFF_DELETE:
- countDelete++;
- textDelete += diffs[pointer][1];
- pointer++;
- break;
- case DIFF_EQUAL:
-
- // Upon reaching an equality, check for prior redundancies.
- if (countDelete + countInsert > 1) {
- if (countDelete !== 0 && countInsert !== 0) {
-
- // Factor out any common prefixes.
- commonlength = this.diffCommonPrefix(textInsert, textDelete);
- if (commonlength !== 0) {
- if (pointer - countDelete - countInsert > 0 && diffs[pointer - countDelete - countInsert - 1][0] === DIFF_EQUAL) {
- diffs[pointer - countDelete - countInsert - 1][1] += textInsert.substring(0, commonlength);
- } else {
- diffs.splice(0, 0, [DIFF_EQUAL, textInsert.substring(0, commonlength)]);
- pointer++;
- }
- textInsert = textInsert.substring(commonlength);
- textDelete = textDelete.substring(commonlength);
- }
-
- // Factor out any common suffixies.
- commonlength = this.diffCommonSuffix(textInsert, textDelete);
- if (commonlength !== 0) {
- diffs[pointer][1] = textInsert.substring(textInsert.length - commonlength) + diffs[pointer][1];
- textInsert = textInsert.substring(0, textInsert.length - commonlength);
- textDelete = textDelete.substring(0, textDelete.length - commonlength);
- }
- }
-
- // Delete the offending records and add the merged ones.
- if (countDelete === 0) {
- diffs.splice(pointer - countInsert, countDelete + countInsert, [DIFF_INSERT, textInsert]);
- } else if (countInsert === 0) {
- diffs.splice(pointer - countDelete, countDelete + countInsert, [DIFF_DELETE, textDelete]);
- } else {
- diffs.splice(pointer - countDelete - countInsert, countDelete + countInsert, [DIFF_DELETE, textDelete], [DIFF_INSERT, textInsert]);
- }
- pointer = pointer - countDelete - countInsert + (countDelete ? 1 : 0) + (countInsert ? 1 : 0) + 1;
- } else if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) {
-
- // Merge this equality with the previous one.
- diffs[pointer - 1][1] += diffs[pointer][1];
- diffs.splice(pointer, 1);
- } else {
- pointer++;
- }
- countInsert = 0;
- countDelete = 0;
- textDelete = "";
- textInsert = "";
- break;
- }
- }
- if (diffs[diffs.length - 1][1] === "") {
- diffs.pop(); // Remove the dummy entry at the end.
- }
-
- // Second pass: look for single edits surrounded on both sides by equalities
- // which can be shifted sideways to eliminate an equality.
- // e.g: ABA C -> AB AC
- changes = false;
- pointer = 1;
-
- // Intentionally ignore the first and last element (don't need checking).
- while (pointer < diffs.length - 1) {
- if (diffs[pointer - 1][0] === DIFF_EQUAL && diffs[pointer + 1][0] === DIFF_EQUAL) {
-
- diffPointer = diffs[pointer][1];
- position = diffPointer.substring(diffPointer.length - diffs[pointer - 1][1].length);
-
- // This is a single edit surrounded by equalities.
- if (position === diffs[pointer - 1][1]) {
-
- // Shift the edit over the previous equality.
- diffs[pointer][1] = diffs[pointer - 1][1] + diffs[pointer][1].substring(0, diffs[pointer][1].length - diffs[pointer - 1][1].length);
- diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];
- diffs.splice(pointer - 1, 1);
- changes = true;
- } else if (diffPointer.substring(0, diffs[pointer + 1][1].length) === diffs[pointer + 1][1]) {
-
- // Shift the edit over the next equality.
- diffs[pointer - 1][1] += diffs[pointer + 1][1];
- diffs[pointer][1] = diffs[pointer][1].substring(diffs[pointer + 1][1].length) + diffs[pointer + 1][1];
- diffs.splice(pointer + 1, 1);
- changes = true;
- }
- }
- pointer++;
- }
-
- // If shifts were made, the diff needs reordering and another shift sweep.
- if (changes) {
- this.diffCleanupMerge(diffs);
- }
- };
-
- return function (o, n) {
- var diff, output, text;
- diff = new DiffMatchPatch();
- output = diff.DiffMain(o, n);
- diff.diffCleanupEfficiency(output);
- text = diff.diffPrettyHtml(output);
-
- return text;
- };
- }();
-
-}((function() { return this; }())));
diff --git a/test/simple.md b/test/simple.md
index c72a4407953..97bae7e5e87 100644
--- a/test/simple.md
+++ b/test/simple.md
@@ -9,4 +9,4 @@ var a = 1;
-## Slide 2
+## Slide 2
\ No newline at end of file
diff --git a/test/test-auto-animate.html b/test/test-auto-animate.html
new file mode 100644
index 00000000000..a9c71f78020
--- /dev/null
+++ b/test/test-auto-animate.html
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+ reveal.js - Test Auto-Animate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Non-auto-animate slide
+
+
+
+
+
+
+
+ Non-auto-animate slide
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/test-dependencies-async.html b/test/test-dependencies-async.html
index b36c31b5d14..de1404212ae 100644
--- a/test/test-dependencies-async.html
+++ b/test/test-dependencies-async.html
@@ -6,8 +6,9 @@
reveal.js - Test Async Dependencies
-
-
+
+
+
@@ -25,13 +26,12 @@
-
-
-
+
@@ -25,21 +26,13 @@
-
-
-
+
diff --git a/test/test-grid-navigation.html b/test/test-grid-navigation.html
index 21e7636c7b4..837764c2878 100644
--- a/test/test-grid-navigation.html
+++ b/test/test-grid-navigation.html
@@ -6,8 +6,9 @@
reveal.js - Test Grid
-
-
+
+
+
@@ -37,13 +38,15 @@
-
-
-
+
diff --git a/test/test-iframe-backgrounds.html b/test/test-iframe-backgrounds.html
index 15888bcbe7b..7df99a14ebf 100644
--- a/test/test-iframe-backgrounds.html
+++ b/test/test-iframe-backgrounds.html
@@ -6,8 +6,9 @@
reveal.js - Test Iframe Backgrounds
-
-
+
+
+
@@ -19,24 +20,23 @@
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
diff --git a/test/test-iframes.html b/test/test-iframes.html
index 979bb7d6093..fa4b434f431 100644
--- a/test/test-iframes.html
+++ b/test/test-iframes.html
@@ -6,8 +6,9 @@
reveal.js - Test Iframes
-
-
+
+
+
@@ -30,13 +31,12 @@
-
-
-
+
diff --git a/test/test-markdown-element-attributes.html b/test/test-markdown-element-attributes.html
deleted file mode 100644
index 741131f6743..00000000000
--- a/test/test-markdown-element-attributes.html
+++ /dev/null
@@ -1,132 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/test/test-markdown-element-attributes.js b/test/test-markdown-element-attributes.js
deleted file mode 100644
index fc87b7b0aae..00000000000
--- a/test/test-markdown-element-attributes.js
+++ /dev/null
@@ -1,44 +0,0 @@
-Reveal.addEventListener( 'ready', function() {
-
- QUnit.module( 'Markdown' );
-
- QUnit.test( 'Vertical separator', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 4, 'found four slides' );
- });
-
- QUnit.test( 'Attributes on element header in vertical slides', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.fade-out' ).length, 1, 'found one vertical slide with class fragment.fade-out on header' );
- assert.strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.shrink' ).length, 1, 'found one vertical slide with class fragment.shrink on header' );
- });
-
- QUnit.test( 'Attributes on element paragraphs in vertical slides', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides section>section p.fragment.grow' ).length, 2, 'found a vertical slide with two paragraphs with class fragment.grow' );
- });
-
- QUnit.test( 'Attributes on element list items in vertical slides', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides section>section li.fragment.grow' ).length, 3, 'found a vertical slide with three list items with class fragment.grow' );
- });
-
- QUnit.test( 'Attributes on element paragraphs in horizontal slides', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-red' ).length, 4, 'found a horizontal slide with four paragraphs with class fragment.grow' );
- });
-
- QUnit.test( 'Attributes on element list items in horizontal slides', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides section li.fragment.highlight-green' ).length, 5, 'found a horizontal slide with five list items with class fragment.roll-in' );
- });
-
- QUnit.test( 'Attributes on element image in horizontal slides', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides section img.reveal.stretch' ).length, 1, 'found a horizontal slide with stretched image, class img.reveal.stretch' );
- });
-
- QUnit.test( 'Attributes on elements in vertical slides with default element attribute separator', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides section h2.fragment.highlight-red' ).length, 2, 'found two h2 titles with fragment highlight-red in vertical slides with default element attribute separator' );
- });
-
- QUnit.test( 'Attributes on elements in single slides with default element attribute separator', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-blue' ).length, 3, 'found three elements with fragment highlight-blue in single slide with default element attribute separator' );
- });
-
-} );
-
-Reveal.initialize();
diff --git a/test/test-markdown-external.html b/test/test-markdown-external.html
deleted file mode 100644
index 93cd9839903..00000000000
--- a/test/test-markdown-external.html
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/test/test-markdown-external.js b/test/test-markdown-external.js
deleted file mode 100644
index f924986551f..00000000000
--- a/test/test-markdown-external.js
+++ /dev/null
@@ -1,20 +0,0 @@
-Reveal.addEventListener( 'ready', function() {
-
- QUnit.module( 'Markdown' );
-
- QUnit.test( 'Vertical separator', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' );
- });
-
- QUnit.test( 'Horizontal separator', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section' ).length, 2, 'found two slides' );
- });
-
- QUnit.test( 'Language highlighter', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.hljs-keyword' ).length, 1, 'got rendered highlight tag.' );
- assert.strictEqual( document.querySelector( '.hljs-keyword' ).innerHTML, 'var', 'the same keyword: var.' );
- });
-
-} );
-
-Reveal.initialize();
diff --git a/test/test-markdown-options.html b/test/test-markdown-options.html
deleted file mode 100644
index 5391a195f99..00000000000
--- a/test/test-markdown-options.html
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/test/test-markdown-options.js b/test/test-markdown-options.js
deleted file mode 100644
index ef616594370..00000000000
--- a/test/test-markdown-options.js
+++ /dev/null
@@ -1,27 +0,0 @@
-Reveal.addEventListener( 'ready', function() {
-
- QUnit.module( 'Markdown' );
-
- QUnit.test( 'Options are set', function( assert ) {
- assert.strictEqual( marked.defaults.smartypants, true );
- });
-
- QUnit.test( 'Smart quotes are activated', function( assert ) {
- var text = document.querySelector( '.reveal .slides>section>p' ).textContent;
-
- assert.strictEqual( /['"]/.test( text ), false );
- assert.strictEqual( /[“”‘’]/.test( text ), true );
- });
-
-} );
-
-Reveal.initialize({
- dependencies: [
- { src: '../plugin/markdown/marked.js' },
- // Test loading JS files with query strings
- { src: '../plugin/markdown/markdown.js?query=string' },
- ],
- markdown: {
- smartypants: true
- }
-});
diff --git a/test/test-markdown-slide-attributes.html b/test/test-markdown-slide-attributes.html
deleted file mode 100644
index ba9e7100002..00000000000
--- a/test/test-markdown-slide-attributes.html
+++ /dev/null
@@ -1,127 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/test/test-markdown-slide-attributes.js b/test/test-markdown-slide-attributes.js
deleted file mode 100644
index b44323a1c2d..00000000000
--- a/test/test-markdown-slide-attributes.js
+++ /dev/null
@@ -1,44 +0,0 @@
-Reveal.addEventListener( 'ready', function() {
-
- QUnit.module( 'Markdown' );
-
- QUnit.test( 'Vertical separator', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 6, 'found six vertical slides' );
- });
-
- QUnit.test( 'Id on slide', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section#slide2' ).length, 1, 'found one slide with id slide2' );
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section a[href="#/slide2"]' ).length, 1, 'found one slide with a link to slide2' );
- });
-
- QUnit.test( 'data-background attributes', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A0C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#ff0000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C6916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
- });
-
- QUnit.test( 'data-transition attributes', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="zoom"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="fade"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
- assert.strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="zoom"]' ).length, 1, 'found one slide with data-transition="zoom"' );
- });
-
- QUnit.test( 'data-background attributes with default separator', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A7C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#f70000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C7916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
- });
-
- QUnit.test( 'data-transition attributes with default separator', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="concave"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="page"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
- assert.strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="concave"]' ).length, 1, 'found one slide with data-transition="zoom"' );
- });
-
- QUnit.test( 'data-transition attributes with inline content', function( assert ) {
- assert.strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#ff0000"]' ).length, 3, 'found three horizontal slides with data-background="#ff0000"' );
- });
-
-} );
-
-Reveal.initialize();
diff --git a/test/test-markdown.html b/test/test-markdown.html
index e1e5926e8b4..2460aa80328 100644
--- a/test/test-markdown.html
+++ b/test/test-markdown.html
@@ -6,8 +6,9 @@