diff --git a/inst/reveal.js-5.2.1/js/components/playback.js b/inst/reveal.js-5.2.1/js/components/playback.js
new file mode 100644
index 0000000..06fa7ba
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/components/playback.js
@@ -0,0 +1,165 @@
+/**
+ * UI component that lets the use control auto-slide
+ * playback via play/pause.
+ */
+export default class Playback {
+
+	/**
+	 * @param {HTMLElement} container The component will append
+	 * itself to this
+	 * @param {function} progressCheck A method which will be
+	 * called frequently to get the current playback progress on
+	 * a range of 0-1
+	 */
+	constructor( container, progressCheck ) {
+
+		// Cosmetics
+		this.diameter = 100;
+		this.diameter2 = this.diameter/2;
+		this.thickness = 6;
+
+		// Flags if we are currently playing
+		this.playing = false;
+
+		// Current progress on a 0-1 range
+		this.progress = 0;
+
+		// Used to loop the animation smoothly
+		this.progressOffset = 1;
+
+		this.container = container;
+		this.progressCheck = progressCheck;
+
+		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( value ) {
+
+		const wasPlaying = this.playing;
+
+		this.playing = value;
+
+		// Start repainting if we weren't already
+		if( !wasPlaying && this.playing ) {
+			this.animate();
+		}
+		else {
+			this.render();
+		}
+
+	}
+
+	animate() {
+
+		const progressBefore = this.progress;
+
+		this.progress = this.progressCheck();
+
+		// When we loop, offset the progress so that it eases
+		// smoothly rather than immediately resetting
+		if( progressBefore > 0.8 && this.progress < 0.2 ) {
+			this.progressOffset = this.progress;
+		}
+
+		this.render();
+
+		if( this.playing ) {
+			requestAnimationFrame( this.animate.bind( this ) );
+		}
+
+	}
+
+	/**
+	 * Renders the current progress and playback state.
+	 */
+	render() {
+
+		let progress = this.playing ? this.progress : 0,
+			radius = ( this.diameter2 ) - this.thickness,
+			x = this.diameter2,
+			y = this.diameter2,
+			iconSize = 28;
+
+		// Ease towards 1
+		this.progressOffset += ( 1 - this.progressOffset ) * 0.1;
+
+		const endAngle = ( - Math.PI / 2 ) + ( progress * ( Math.PI * 2 ) );
+		const startAngle = ( - Math.PI / 2 ) + ( this.progressOffset * ( Math.PI * 2 ) );
+
+		this.context.save();
+		this.context.clearRect( 0, 0, this.diameter, this.diameter );
+
+		// Solid background color
+		this.context.beginPath();
+		this.context.arc( x, y, radius + 4, 0, Math.PI * 2, false );
+		this.context.fillStyle = 'rgba( 0, 0, 0, 0.4 )';
+		this.context.fill();
+
+		// Draw progress track
+		this.context.beginPath();
+		this.context.arc( x, y, radius, 0, Math.PI * 2, false );
+		this.context.lineWidth = this.thickness;
+		this.context.strokeStyle = 'rgba( 255, 255, 255, 0.2 )';
+		this.context.stroke();
+
+		if( this.playing ) {
+			// Draw progress on top of track
+			this.context.beginPath();
+			this.context.arc( x, y, radius, startAngle, endAngle, false );
+			this.context.lineWidth = this.thickness;
+			this.context.strokeStyle = '#fff';
+			this.context.stroke();
+		}
+
+		this.context.translate( x - ( iconSize / 2 ), y - ( iconSize / 2 ) );
+
+		// Draw play/pause icons
+		if( this.playing ) {
+			this.context.fillStyle = '#fff';
+			this.context.fillRect( 0, 0, iconSize / 2 - 4, iconSize );
+			this.context.fillRect( iconSize / 2 + 4, 0, iconSize / 2 - 4, iconSize );
+		}
+		else {
+			this.context.beginPath();
+			this.context.translate( 4, 0 );
+			this.context.moveTo( 0, 0 );
+			this.context.lineTo( iconSize - 4, iconSize / 2 );
+			this.context.lineTo( 0, iconSize );
+			this.context.fillStyle = '#fff';
+			this.context.fill();
+		}
+
+		this.context.restore();
+
+	}
+
+	on( type, listener ) {
+		this.canvas.addEventListener( type, listener, false );
+	}
+
+	off( type, listener ) {
+		this.canvas.removeEventListener( type, listener, false );
+	}
+
+	destroy() {
+
+		this.playing = false;
+
+		if( this.canvas.parentNode ) {
+			this.container.removeChild( this.canvas );
+		}
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/config.js b/inst/reveal.js-5.2.1/js/config.js
new file mode 100644
index 0000000..5ce9d07
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/config.js
@@ -0,0 +1,333 @@
+/**
+ * The default reveal.js config object.
+ */
+export default {
+
+	// The "normal" size of the presentation, aspect ratio will be preserved
+	// when the presentation is scaled to fit different resolutions
+	width: 1280,
+	height: 720,
+
+	// Factor of the display size that should remain empty around the content
+	margin: 0.04,
+
+	// Bounds for smallest/largest possible scale to apply to content
+	minScale: 0.2,
+	maxScale: 2.0,
+
+	// Display presentation control arrows.
+	// - true: Display controls on all screens
+	// - false: Hide controls on all screens
+	// - "speaker-only": Only display controls in the speaker view
+	controls: true,
+
+	// Help the user learn the controls by providing hints, for example by
+	// bouncing the down arrow when they first encounter a vertical slide
+	controlsTutorial: true,
+
+	// Determines where controls appear, "edges" or "bottom-right"
+	controlsLayout: 'bottom-right',
+
+	// Visibility rule for backwards navigation arrows; "faded", "hidden"
+	// or "visible"
+	controlsBackArrows: 'faded',
+
+	// Display a presentation progress bar
+	progress: true,
+
+	// Display the page number of the current slide
+	// - true:    Show slide number
+	// - false:   Hide slide number
+	//
+	// Can optionally be set as a string that specifies the number formatting:
+	// - "h.v":	  Horizontal . vertical slide number (default)
+	// - "h/v":	  Horizontal / vertical slide number
+	// - "c":	  Flattened slide number
+	// - "c/t":	  Flattened slide number / total slides
+	//
+	// Alternatively, you can provide a function that returns the slide
+	// number for the current slide. The function should take in a slide
+	// object and return an array with one string [slideNumber] or
+	// three strings [n1,delimiter,n2]. See #formatSlideNumber().
+	slideNumber: false,
+
+	// Can be used to limit the contexts in which the slide number appears
+	// - "all":      Always show the slide number
+	// - "print":    Only when printing to PDF
+	// - "speaker":  Only in the speaker view
+	showSlideNumber: 'all',
+
+	// Use 1 based indexing for # links to match slide number (default is zero
+	// based)
+	hashOneBasedIndex: false,
+
+	// Add the current slide number to the URL hash so that reloading the
+	// page/copying the URL will return you to the same slide
+	hash: false,
+
+	// Flags if we should monitor the hash and change slides accordingly
+	respondToHashChanges: true,
+
+	// Enable support for jump-to-slide navigation shortcuts
+	jumpToSlide: true,
+
+	// Push each slide change to the browser history.  Implies `hash: true`
+	history: false,
+
+	// Enable keyboard shortcuts for navigation
+	keyboard: true,
+
+	// Optional function that blocks keyboard events when returning false
+	//
+	// If you set this to 'focused', we will only capture keyboard events
+	// for embedded decks when they are in focus
+	keyboardCondition: null,
+
+	// Disables the default reveal.js slide layout (scaling and centering)
+	// so that you can use custom CSS layout
+	disableLayout: false,
+
+	// Enable the slide overview mode
+	overview: true,
+
+	// Vertical centering of slides
+	center: true,
+
+	// Enables touch navigation on devices with touch input
+	touch: true,
+
+	// Loop the presentation
+	loop: false,
+
+	// Change the presentation direction to be RTL
+	rtl: false,
+
+	// Changes the behavior of our navigation directions.
+	//
+	// "default"
+	// Left/right arrow keys step between horizontal slides, up/down
+	// arrow keys step between vertical slides. Space key steps through
+	// all slides (both horizontal and vertical).
+	//
+	// "linear"
+	// Removes the up/down arrows. Left/right arrows step through all
+	// slides (both horizontal and vertical).
+	//
+	// "grid"
+	// When this is enabled, stepping left/right from a vertical stack
+	// to an adjacent vertical stack will land you at the same vertical
+	// index.
+	//
+	// Consider a deck with six slides ordered in two vertical stacks:
+	// 1.1    2.1
+	// 1.2    2.2
+	// 1.3    2.3
+	//
+	// If you're on slide 1.3 and navigate right, you will normally move
+	// from 1.3 -> 2.1. If "grid" is used, the same navigation takes you
+	// from 1.3 -> 2.3.
+	navigationMode: 'default',
+
+	// Randomizes the order of slides each time the presentation loads
+	shuffle: false,
+
+	// Turns fragments on and off globally
+	fragments: true,
+
+	// Flags whether to include the current fragment in the URL,
+	// so that reloading brings you to the same fragment position
+	fragmentInURL: true,
+
+	// Flags if the presentation is running in an embedded mode,
+	// i.e. contained within a limited portion of the screen
+	embedded: false,
+
+	// Flags if we should show a help overlay when the question-mark
+	// key is pressed
+	help: true,
+
+	// Flags if it should be possible to pause the presentation (blackout)
+	pause: true,
+
+	// Flags if speaker notes should be visible to all viewers
+	showNotes: false,
+
+	// Flags if slides with data-visibility="hidden" should be kep visible
+	showHiddenSlides: false,
+
+	// Global override for autoplaying embedded media (video/audio/iframe)
+	// - null:   Media will only autoplay if data-autoplay is present
+	// - true:   All media will autoplay, regardless of individual setting
+	// - false:  No media will autoplay, regardless of individual setting
+	autoPlayMedia: null,
+
+	// Global override for preloading lazy-loaded iframes
+	// - null:   Iframes with data-src AND data-preload will be loaded when within
+	//           the viewDistance, iframes with only data-src will be loaded when visible
+	// - true:   All iframes with data-src will be loaded when within the viewDistance
+	// - false:  All iframes with data-src will be loaded only when visible
+	preloadIframes: null,
+
+	// Can be used to globally disable auto-animation
+	autoAnimate: true,
+
+	// Optionally provide a custom element matcher that will be
+	// used to dictate which elements we can animate between.
+	autoAnimateMatcher: null,
+
+	// Default settings for our auto-animate transitions, can be
+	// overridden per-slide or per-element via data arguments
+	autoAnimateEasing: 'ease',
+	autoAnimateDuration: 1.0,
+	autoAnimateUnmatched: true,
+
+	// CSS properties that can be auto-animated. Position & scale
+	// is matched separately so there's no need to include styles
+	// like top/right/bottom/left, width/height or margin.
+	autoAnimateStyles: [
+		'opacity',
+		'color',
+		'background-color',
+		'padding',
+		'font-size',
+		'line-height',
+		'letter-spacing',
+		'border-width',
+		'border-color',
+		'border-radius',
+		'outline',
+		'outline-offset'
+	],
+
+	// Controls automatic progression to the next slide
+	// - 0:      Auto-sliding only happens if the data-autoslide HTML attribute
+	//           is present on the current slide or fragment
+	// - 1+:     All slides will progress automatically at the given interval
+	// - false:  No auto-sliding, even if data-autoslide is present
+	autoSlide: 0,
+
+	// Stop auto-sliding after user input
+	autoSlideStoppable: true,
+
+	// Use this method for navigation when auto-sliding (defaults to navigateNext)
+	autoSlideMethod: null,
+
+	// Specify the average time in seconds that you think you will spend
+	// presenting each slide. This is used to show a pacing timer in the
+	// speaker view
+	defaultTiming: null,
+
+	// Enable slide navigation via mouse wheel
+	mouseWheel: false,
+
+	// Opens links in an iframe preview overlay
+	// Add `data-preview-link` and `data-preview-link="false"` to customise each link
+	// individually
+	previewLinks: false,
+
+	// Exposes the reveal.js API through window.postMessage
+	postMessage: true,
+
+	// Dispatches all reveal.js events to the parent window through postMessage
+	postMessageEvents: false,
+
+	// Focuses body when page changes visibility to ensure keyboard shortcuts work
+	focusBodyOnPageVisibilityChange: true,
+
+	// Transition style
+	transition: 'slide', // none/fade/slide/convex/concave/zoom
+
+	// Transition speed
+	transitionSpeed: 'default', // default/fast/slow
+
+	// Transition style for full page slide backgrounds
+	backgroundTransition: 'fade', // none/fade/slide/convex/concave/zoom
+
+	// Parallax background image
+	parallaxBackgroundImage: '', // CSS syntax, e.g. "a.jpg"
+
+	// Parallax background size
+	parallaxBackgroundSize: '', // CSS syntax, e.g. "3000px 2000px"
+
+	// Parallax background repeat
+	parallaxBackgroundRepeat: '', // repeat/repeat-x/repeat-y/no-repeat/initial/inherit
+
+	// Parallax background position
+	parallaxBackgroundPosition: '', // CSS syntax, e.g. "top left"
+
+	// Amount of pixels to move the parallax background per slide step
+	parallaxBackgroundHorizontal: null,
+	parallaxBackgroundVertical: null,
+
+	// Can be used to initialize reveal.js in one of the following views:
+	// - print:   Render the presentation so that it can be printed to PDF
+	// - scroll:  Show the presentation as a tall scrollable page with scroll
+	//            triggered animations
+	view: null,
+
+	// Adjusts the height of each slide in the scroll view.
+	// - full:       Each slide is as tall as the viewport
+	// - compact:    Slides are as small as possible, allowing multiple slides
+	//               to be visible in parallel on tall devices
+	scrollLayout: 'full',
+
+	// Control how scroll snapping works in the scroll view.
+	// - false:   	No snapping, scrolling is continuous
+	// - proximity:  Snap when close to a slide
+	// - mandatory:  Always snap to the closest slide
+	//
+	// Only applies to presentations in scroll view.
+	scrollSnap: 'mandatory',
+
+	// Enables and configure the scroll view progress bar.
+	// - 'auto':    Show the scrollbar while scrolling, hide while idle
+	// - true:      Always show the scrollbar
+	// - false:     Never show the scrollbar
+	scrollProgress: 'auto',
+
+	// Automatically activate the scroll view when we the viewport falls
+	// below the given width.
+	scrollActivationWidth: 435,
+
+	// The maximum number of pages a single slide can expand onto when printing
+	// to PDF, unlimited by default
+	pdfMaxPagesPerSlide: Number.POSITIVE_INFINITY,
+
+	// Prints each fragment on a separate slide
+	pdfSeparateFragments: true,
+
+	// Offset used to reduce the height of content within exported PDF pages.
+	// This exists to account for environment differences based on how you
+	// print to PDF. CLI printing options, like phantomjs and wkpdf, can end
+	// on precisely the total height of the document whereas in-browser
+	// printing has to end one pixel before.
+	pdfPageHeightOffset: -1,
+
+	// Number of slides away from the current that are visible
+	viewDistance: 3,
+
+	// Number of slides away from the current that are visible on mobile
+	// devices. It is advisable to set this to a lower number than
+	// viewDistance in order to save resources.
+	mobileViewDistance: 2,
+
+	// The display mode that will be used to show slides
+	display: 'block',
+
+	// Hide cursor if inactive
+	hideInactiveCursor: true,
+
+	// Time before the cursor is hidden (in ms)
+	hideCursorTime: 5000,
+
+	// Should we automatically sort and set indices for fragments
+	// at each sync? (See Reveal.sync)
+	sortFragmentsOnSync: true,
+
+	// Script dependencies to load
+	dependencies: [],
+
+	// Plugin objects to register and use for this presentation
+	plugins: []
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/controllers/autoanimate.js b/inst/reveal.js-5.2.1/js/controllers/autoanimate.js
new file mode 100644
index 0000000..6a706e3
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/autoanimate.js
@@ -0,0 +1,627 @@
+import { queryAll, extend, createStyleSheet, matches, closest } from '../utils/util.js'
+import { FRAGMENT_STYLE_REGEX } from '../utils/constants.js'
+
+// Counter used to generate unique IDs for auto-animated elements
+let autoAnimateCounter = 0;
+
+/**
+ * Automatically animates matching elements across
+ * slides with the [data-auto-animate] attribute.
+ */
+export default class AutoAnimate {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+	}
+
+	/**
+	 * Runs an auto-animation between the given slides.
+	 *
+	 * @param  {HTMLElement} fromSlide
+	 * @param  {HTMLElement} toSlide
+	 */
+	run( fromSlide, toSlide ) {
+
+		// Clean up after prior animations
+		this.reset();
+
+		let allSlides = this.Reveal.getSlides();
+		let toSlideIndex = allSlides.indexOf( toSlide );
+		let fromSlideIndex = allSlides.indexOf( fromSlide );
+
+		// Ensure that;
+		// 1. Both slides exist.
+		// 2. Both slides are auto-animate targets with the same
+		//    data-auto-animate-id value (including null if absent on both).
+		// 3. data-auto-animate-restart isn't set on the physically latter
+		//    slide (independent of slide direction).
+		if( fromSlide && toSlide && fromSlide.hasAttribute( 'data-auto-animate' ) && toSlide.hasAttribute( 'data-auto-animate' )
+				&& fromSlide.getAttribute( 'data-auto-animate-id' ) === toSlide.getAttribute( 'data-auto-animate-id' ) 
+				&& !( toSlideIndex > fromSlideIndex ? toSlide : fromSlide ).hasAttribute( 'data-auto-animate-restart' ) ) {
+
+			// Create a new auto-animate sheet
+			this.autoAnimateStyleSheet = this.autoAnimateStyleSheet || createStyleSheet();
+
+			let animationOptions = this.getAutoAnimateOptions( toSlide );
+
+			// Set our starting state
+			fromSlide.dataset.autoAnimate = 'pending';
+			toSlide.dataset.autoAnimate = 'pending';
+
+			// Flag the navigation direction, needed for fragment buildup
+			animationOptions.slideDirection = toSlideIndex > fromSlideIndex ? 'forward' : 'backward';
+
+			// If the from-slide is hidden because it has moved outside
+			// the view distance, we need to temporarily show it while
+			// measuring
+			let fromSlideIsHidden = fromSlide.style.display === 'none';
+			if( fromSlideIsHidden ) fromSlide.style.display = this.Reveal.getConfig().display;
+
+			// Inject our auto-animate styles for this transition
+			let css = this.getAutoAnimatableElements( fromSlide, toSlide ).map( elements => {
+				return this.autoAnimateElements( elements.from, elements.to, elements.options || {}, animationOptions, autoAnimateCounter++ );
+			} );
+
+			if( fromSlideIsHidden ) fromSlide.style.display = 'none';
+
+			// Animate unmatched elements, if enabled
+			if( toSlide.dataset.autoAnimateUnmatched !== 'false' && this.Reveal.getConfig().autoAnimateUnmatched === true ) {
+
+				// Our default timings for unmatched elements
+				let defaultUnmatchedDuration = animationOptions.duration * 0.8,
+					defaultUnmatchedDelay = animationOptions.duration * 0.2;
+
+				this.getUnmatchedAutoAnimateElements( toSlide ).forEach( unmatchedElement => {
+
+					let unmatchedOptions = this.getAutoAnimateOptions( unmatchedElement, animationOptions );
+					let id = 'unmatched';
+
+					// If there is a duration or delay set specifically for this
+					// element our unmatched elements should adhere to those
+					if( unmatchedOptions.duration !== animationOptions.duration || unmatchedOptions.delay !== animationOptions.delay ) {
+						id = 'unmatched-' + autoAnimateCounter++;
+						css.push( `[data-auto-animate="running"] [data-auto-animate-target="${id}"] { transition: opacity ${unmatchedOptions.duration}s ease ${unmatchedOptions.delay}s; }` );
+					}
+
+					unmatchedElement.dataset.autoAnimateTarget = id;
+
+				}, this );
+
+				// Our default transition for unmatched elements
+				css.push( `[data-auto-animate="running"] [data-auto-animate-target="unmatched"] { transition: opacity ${defaultUnmatchedDuration}s ease ${defaultUnmatchedDelay}s; }` );
+
+			}
+
+			// Setting the whole chunk of CSS at once is the most
+			// efficient way to do this. Using sheet.insertRule
+			// is multiple factors slower.
+			this.autoAnimateStyleSheet.innerHTML = css.join( '' );
+
+			// Start the animation next cycle
+			requestAnimationFrame( () => {
+				if( this.autoAnimateStyleSheet ) {
+					// This forces our newly injected styles to be applied in Firefox
+					getComputedStyle( this.autoAnimateStyleSheet ).fontWeight;
+
+					toSlide.dataset.autoAnimate = 'running';
+				}
+			} );
+
+			this.Reveal.dispatchEvent({
+				type: 'autoanimate',
+				data: {
+					fromSlide,
+					toSlide,
+					sheet: this.autoAnimateStyleSheet
+				}
+			});
+
+		}
+
+	}
+
+	/**
+	 * Rolls back all changes that we've made to the DOM so
+	 * that as part of animating.
+	 */
+	reset() {
+
+		// Reset slides
+		queryAll( this.Reveal.getRevealElement(), '[data-auto-animate]:not([data-auto-animate=""])' ).forEach( element => {
+			element.dataset.autoAnimate = '';
+		} );
+
+		// Reset elements
+		queryAll( this.Reveal.getRevealElement(), '[data-auto-animate-target]' ).forEach( element => {
+			delete element.dataset.autoAnimateTarget;
+		} );
+
+		// Remove the animation sheet
+		if( this.autoAnimateStyleSheet && this.autoAnimateStyleSheet.parentNode ) {
+			this.autoAnimateStyleSheet.parentNode.removeChild( this.autoAnimateStyleSheet );
+			this.autoAnimateStyleSheet = null;
+		}
+
+	}
+
+	/**
+	 * Creates a FLIP animation where the `to` element starts out
+	 * in the `from` element position and animates to its original
+	 * state.
+	 *
+	 * @param {HTMLElement} from
+	 * @param {HTMLElement} to
+	 * @param {Object} elementOptions Options for this element pair
+	 * @param {Object} animationOptions Options set at the slide level
+	 * @param {String} id Unique ID that we can use to identify this
+	 * auto-animate element in the DOM
+	 */
+	autoAnimateElements( from, to, elementOptions, animationOptions, id ) {
+
+		// 'from' elements are given a data-auto-animate-target with no value,
+		// 'to' elements are are given a data-auto-animate-target with an ID
+		from.dataset.autoAnimateTarget = '';
+		to.dataset.autoAnimateTarget = id;
+
+		// Each element may override any of the auto-animate options
+		// like transition easing, duration and delay via data-attributes
+		let options = this.getAutoAnimateOptions( to, animationOptions );
+
+		// If we're using a custom element matcher the element options
+		// may contain additional transition overrides
+		if( typeof elementOptions.delay !== 'undefined' ) options.delay = elementOptions.delay;
+		if( typeof elementOptions.duration !== 'undefined' ) options.duration = elementOptions.duration;
+		if( typeof elementOptions.easing !== 'undefined' ) options.easing = elementOptions.easing;
+
+		let fromProps = this.getAutoAnimatableProperties( 'from', from, elementOptions ),
+			toProps = this.getAutoAnimatableProperties( 'to', to, elementOptions );
+
+		if( to.classList.contains( 'fragment' ) ) {
+
+			// Don't auto-animate the opacity of fragments to avoid
+			// conflicts with fragment animations
+			delete toProps.styles['opacity'];
+
+		}
+
+		// If translation and/or scaling are enabled, css transform
+		// the 'to' element so that it matches the position and size
+		// of the 'from' element
+		if( elementOptions.translate !== false || elementOptions.scale !== false ) {
+
+			let presentationScale = this.Reveal.getScale();
+
+			let delta = {
+				x: ( fromProps.x - toProps.x ) / presentationScale,
+				y: ( fromProps.y - toProps.y ) / presentationScale,
+				scaleX: fromProps.width / toProps.width,
+				scaleY: fromProps.height / toProps.height
+			};
+
+			// Limit decimal points to avoid 0.0001px blur and stutter
+			delta.x = Math.round( delta.x * 1000 ) / 1000;
+			delta.y = Math.round( delta.y * 1000 ) / 1000;
+			delta.scaleX = Math.round( delta.scaleX * 1000 ) / 1000;
+			delta.scaleX = Math.round( delta.scaleX * 1000 ) / 1000;
+
+			let translate = elementOptions.translate !== false && ( delta.x !== 0 || delta.y !== 0 ),
+				scale = elementOptions.scale !== false && ( delta.scaleX !== 0 || delta.scaleY !== 0 );
+
+			// No need to transform if nothing's changed
+			if( translate || scale ) {
+
+				let transform = [];
+
+				if( translate ) transform.push( `translate(${delta.x}px, ${delta.y}px)` );
+				if( scale ) transform.push( `scale(${delta.scaleX}, ${delta.scaleY})` );
+
+				fromProps.styles['transform'] = transform.join( ' ' );
+				fromProps.styles['transform-origin'] = 'top left';
+
+				toProps.styles['transform'] = 'none';
+
+			}
+
+		}
+
+		// Delete all unchanged 'to' styles
+		for( let propertyName in toProps.styles ) {
+			const toValue = toProps.styles[propertyName];
+			const fromValue = fromProps.styles[propertyName];
+
+			if( toValue === fromValue ) {
+				delete toProps.styles[propertyName];
+			}
+			else {
+				// If these property values were set via a custom matcher providing
+				// an explicit 'from' and/or 'to' value, we always inject those values.
+				if( toValue.explicitValue === true ) {
+					toProps.styles[propertyName] = toValue.value;
+				}
+
+				if( fromValue.explicitValue === true ) {
+					fromProps.styles[propertyName] = fromValue.value;
+				}
+			}
+		}
+
+		let css = '';
+
+		let toStyleProperties = Object.keys( toProps.styles );
+
+		// Only create animate this element IF at least one style
+		// property has changed
+		if( toStyleProperties.length > 0 ) {
+
+			// Instantly move to the 'from' state
+			fromProps.styles['transition'] = 'none';
+
+			// Animate towards the 'to' state
+			toProps.styles['transition'] = `all ${options.duration}s ${options.easing} ${options.delay}s`;
+			toProps.styles['transition-property'] = toStyleProperties.join( ', ' );
+			toProps.styles['will-change'] = toStyleProperties.join( ', ' );
+
+			// Build up our custom CSS. We need to override inline styles
+			// so we need to make our styles vErY IMPORTANT!1!!
+			let fromCSS = Object.keys( fromProps.styles ).map( propertyName => {
+				return propertyName + ': ' + fromProps.styles[propertyName] + ' !important;';
+			} ).join( '' );
+
+			let toCSS = Object.keys( toProps.styles ).map( propertyName => {
+				return propertyName + ': ' + toProps.styles[propertyName] + ' !important;';
+			} ).join( '' );
+
+			css = 	'[data-auto-animate-target="'+ id +'"] {'+ fromCSS +'}' +
+					'[data-auto-animate="running"] [data-auto-animate-target="'+ id +'"] {'+ toCSS +'}';
+
+		}
+
+		return css;
+
+	}
+
+	/**
+	 * Returns the auto-animate options for the given element.
+	 *
+	 * @param {HTMLElement} element Element to pick up options
+	 * from, either a slide or an animation target
+	 * @param {Object} [inheritedOptions] Optional set of existing
+	 * options
+	 */
+	getAutoAnimateOptions( element, inheritedOptions ) {
+
+		let options = {
+			easing: this.Reveal.getConfig().autoAnimateEasing,
+			duration: this.Reveal.getConfig().autoAnimateDuration,
+			delay: 0
+		};
+
+		options = extend( options, inheritedOptions );
+
+		// Inherit options from parent elements
+		if( element.parentNode ) {
+			let autoAnimatedParent = closest( element.parentNode, '[data-auto-animate-target]' );
+			if( autoAnimatedParent ) {
+				options = this.getAutoAnimateOptions( autoAnimatedParent, options );
+			}
+		}
+
+		if( element.dataset.autoAnimateEasing ) {
+			options.easing = element.dataset.autoAnimateEasing;
+		}
+
+		if( element.dataset.autoAnimateDuration ) {
+			options.duration = parseFloat( element.dataset.autoAnimateDuration );
+		}
+
+		if( element.dataset.autoAnimateDelay ) {
+			options.delay = parseFloat( element.dataset.autoAnimateDelay );
+		}
+
+		return options;
+
+	}
+
+	/**
+	 * Returns an object containing all of the properties
+	 * that can be auto-animated for the given element and
+	 * their current computed values.
+	 *
+	 * @param {String} direction 'from' or 'to'
+	 */
+	getAutoAnimatableProperties( direction, element, elementOptions ) {
+
+		let config = this.Reveal.getConfig();
+
+		let properties = { styles: [] };
+
+		// Position and size
+		if( elementOptions.translate !== false || elementOptions.scale !== false ) {
+			let bounds;
+
+			// Custom auto-animate may optionally return a custom tailored
+			// measurement function
+			if( typeof elementOptions.measure === 'function' ) {
+				bounds = elementOptions.measure( element );
+			}
+			else {
+				if( config.center ) {
+					// More precise, but breaks when used in combination
+					// with zoom for scaling the deck ¯\_(ツ)_/¯
+					bounds = element.getBoundingClientRect();
+				}
+				else {
+					let scale = this.Reveal.getScale();
+					bounds = {
+						x: element.offsetLeft * scale,
+						y: element.offsetTop * scale,
+						width: element.offsetWidth * scale,
+						height: element.offsetHeight * scale
+					};
+				}
+			}
+
+			properties.x = bounds.x;
+			properties.y = bounds.y;
+			properties.width = bounds.width;
+			properties.height = bounds.height;
+		}
+
+		const computedStyles = getComputedStyle( element );
+
+		// CSS styles
+		( elementOptions.styles || config.autoAnimateStyles ).forEach( style => {
+			let value;
+
+			// `style` is either the property name directly, or an object
+			// definition of a style property
+			if( typeof style === 'string' ) style = { property: style };
+
+			if( typeof style.from !== 'undefined' && direction === 'from' ) {
+				value = { value: style.from, explicitValue: true };
+			}
+			else if( typeof style.to !== 'undefined' && direction === 'to' ) {
+				value = { value: style.to, explicitValue: true };
+			}
+			else {
+				// Use a unitless value for line-height so that it inherits properly
+				if( style.property === 'line-height' ) {
+					value = parseFloat( computedStyles['line-height'] ) / parseFloat( computedStyles['font-size'] );
+				}
+
+				if( isNaN(value) ) {
+					value = computedStyles[style.property];
+				}
+			}
+
+			if( value !== '' ) {
+				properties.styles[style.property] = value;
+			}
+		} );
+
+		return properties;
+
+	}
+
+	/**
+	 * Get a list of all element pairs that we can animate
+	 * between the given slides.
+	 *
+	 * @param {HTMLElement} fromSlide
+	 * @param {HTMLElement} toSlide
+	 *
+	 * @return {Array} Each value is an array where [0] is
+	 * the element we're animating from and [1] is the
+	 * element we're animating to
+	 */
+	getAutoAnimatableElements( fromSlide, toSlide ) {
+
+		let matcher = typeof this.Reveal.getConfig().autoAnimateMatcher === 'function' ? this.Reveal.getConfig().autoAnimateMatcher : this.getAutoAnimatePairs;
+
+		let pairs = matcher.call( this, fromSlide, toSlide );
+
+		let reserved = [];
+
+		// Remove duplicate pairs
+		return pairs.filter( ( pair, index ) => {
+			if( reserved.indexOf( pair.to ) === -1 ) {
+				reserved.push( pair.to );
+				return true;
+			}
+		} );
+
+	}
+
+	/**
+	 * Identifies matching elements between slides.
+	 *
+	 * You can specify a custom matcher function by using
+	 * the `autoAnimateMatcher` config option.
+	 */
+	getAutoAnimatePairs( fromSlide, toSlide ) {
+
+		let pairs = [];
+
+		const codeNodes = 'pre';
+		const textNodes = 'h1, h2, h3, h4, h5, h6, p, li';
+		const mediaNodes = 'img, video, iframe';
+
+		// Explicit matches via data-id
+		this.findAutoAnimateMatches( pairs, fromSlide, toSlide, '[data-id]', node => {
+			return node.nodeName + ':::' + node.getAttribute( 'data-id' );
+		} );
+
+		// Text
+		this.findAutoAnimateMatches( pairs, fromSlide, toSlide, textNodes, node => {
+			return node.nodeName + ':::' + node.textContent.trim();
+		} );
+
+		// Media
+		this.findAutoAnimateMatches( pairs, fromSlide, toSlide, mediaNodes, node => {
+			return node.nodeName + ':::' + ( node.getAttribute( 'src' ) || node.getAttribute( 'data-src' ) );
+		} );
+
+		// Code
+		this.findAutoAnimateMatches( pairs, fromSlide, toSlide, codeNodes, node => {
+			return node.nodeName + ':::' + node.textContent.trim();
+		} );
+
+		pairs.forEach( pair => {
+			// Disable scale transformations on text nodes, we transition
+			// each individual text property instead
+			if( matches( pair.from, textNodes ) ) {
+				pair.options = { scale: false };
+			}
+			// Animate individual lines of code
+			else if( matches( pair.from, codeNodes ) ) {
+
+				// Transition the code block's width and height instead of scaling
+				// to prevent its content from being squished
+				pair.options = { scale: false, styles: [ 'width', 'height' ] };
+
+				// Lines of code
+				this.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-code', node => {
+					return node.textContent;
+				}, {
+					scale: false,
+					styles: [],
+					measure: this.getLocalBoundingBox.bind( this )
+				} );
+
+				// Line numbers
+				this.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-numbers[data-line-number]', node => {
+					return node.getAttribute( 'data-line-number' );
+				}, {
+					scale: false,
+					styles: [ 'width' ],
+					measure: this.getLocalBoundingBox.bind( this )
+				} );
+
+			}
+
+		}, this );
+
+		return pairs;
+
+	}
+
+	/**
+	 * Helper method which returns a bounding box based on
+	 * the given elements offset coordinates.
+	 *
+	 * @param {HTMLElement} element
+	 * @return {Object} x, y, width, height
+	 */
+	getLocalBoundingBox( element ) {
+
+		const presentationScale = this.Reveal.getScale();
+
+		return {
+			x: Math.round( ( element.offsetLeft * presentationScale ) * 100 ) / 100,
+			y: Math.round( ( element.offsetTop * presentationScale ) * 100 ) / 100,
+			width: Math.round( ( element.offsetWidth * presentationScale ) * 100 ) / 100,
+			height: Math.round( ( element.offsetHeight * presentationScale ) * 100 ) / 100
+		};
+
+	}
+
+	/**
+	 * Finds matching elements between two slides.
+	 *
+	 * @param {Array} pairs            	List of pairs to push matches to
+	 * @param {HTMLElement} fromScope   Scope within the from element exists
+	 * @param {HTMLElement} toScope     Scope within the to element exists
+	 * @param {String} selector         CSS selector of the element to match
+	 * @param {Function} serializer     A function that accepts an element and returns
+	 *                                  a stringified ID based on its contents
+	 * @param {Object} animationOptions Optional config options for this pair
+	 */
+	findAutoAnimateMatches( pairs, fromScope, toScope, selector, serializer, animationOptions ) {
+
+		let fromMatches = {};
+		let toMatches = {};
+
+		[].slice.call( fromScope.querySelectorAll( selector ) ).forEach( ( element, i ) => {
+			const key = serializer( element );
+			if( typeof key === 'string' && key.length ) {
+				fromMatches[key] = fromMatches[key] || [];
+				fromMatches[key].push( element );
+			}
+		} );
+
+		[].slice.call( toScope.querySelectorAll( selector ) ).forEach( ( element, i ) => {
+			const key = serializer( element );
+			toMatches[key] = toMatches[key] || [];
+			toMatches[key].push( element );
+
+			let fromElement;
+
+			// Retrieve the 'from' element
+			if( fromMatches[key] ) {
+				const primaryIndex = toMatches[key].length - 1;
+				const secondaryIndex = fromMatches[key].length - 1;
+
+				// If there are multiple identical from elements, retrieve
+				// the one at the same index as our to-element.
+				if( fromMatches[key][ primaryIndex ] ) {
+					fromElement = fromMatches[key][ primaryIndex ];
+					fromMatches[key][ primaryIndex ] = null;
+				}
+				// If there are no matching from-elements at the same index,
+				// use the last one.
+				else if( fromMatches[key][ secondaryIndex ] ) {
+					fromElement = fromMatches[key][ secondaryIndex ];
+					fromMatches[key][ secondaryIndex ] = null;
+				}
+			}
+
+			// If we've got a matching pair, push it to the list of pairs
+			if( fromElement ) {
+				pairs.push({
+					from: fromElement,
+					to: element,
+					options: animationOptions
+				});
+			}
+		} );
+
+	}
+
+	/**
+	 * Returns a all elements within the given scope that should
+	 * be considered unmatched in an auto-animate transition. If
+	 * fading of unmatched elements is turned on, these elements
+	 * will fade when going between auto-animate slides.
+	 *
+	 * Note that parents of auto-animate targets are NOT considered
+	 * unmatched since fading them would break the auto-animation.
+	 *
+	 * @param {HTMLElement} rootElement
+	 * @return {Array}
+	 */
+	getUnmatchedAutoAnimateElements( rootElement ) {
+
+		return [].slice.call( rootElement.children ).reduce( ( result, element ) => {
+
+			const containsAnimatedElements = element.querySelector( '[data-auto-animate-target]' );
+
+			// The element is unmatched if
+			// - It is not an auto-animate target
+			// - It does not contain any auto-animate targets
+			if( !element.hasAttribute( 'data-auto-animate-target' ) && !containsAnimatedElements ) {
+				result.push( element );
+			}
+
+			if( element.querySelector( '[data-auto-animate-target]' ) ) {
+				result = result.concat( this.getUnmatchedAutoAnimateElements( element ) );
+			}
+
+			return result;
+
+		}, [] );
+
+	}
+
+}
diff --git a/inst/reveal.js-5.2.1/js/controllers/backgrounds.js b/inst/reveal.js-5.2.1/js/controllers/backgrounds.js
new file mode 100644
index 0000000..93143a7
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/backgrounds.js
@@ -0,0 +1,470 @@
+import { queryAll } from '../utils/util.js'
+import { colorToRgb, colorBrightness } from '../utils/color.js'
+
+/**
+ * Creates and updates slide backgrounds.
+ */
+export default class Backgrounds {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+	}
+
+	render() {
+
+		this.element = document.createElement( 'div' );
+		this.element.className = 'backgrounds';
+		this.Reveal.getRevealElement().appendChild( this.element );
+
+	}
+
+	/**
+	 * Creates the slide background elements and appends them
+	 * to the background container. One element is created per
+	 * slide no matter if the given slide has visible background.
+	 */
+	create() {
+
+		// Clear prior backgrounds
+		this.element.innerHTML = '';
+		this.element.classList.add( 'no-transition' );
+
+		// Iterate over all horizontal slides
+		this.Reveal.getHorizontalSlides().forEach( slideh => {
+
+			let backgroundStack = this.createBackground( slideh, this.element );
+
+			// Iterate over all vertical slides
+			queryAll( slideh, 'section' ).forEach( slidev => {
+
+				this.createBackground( slidev, backgroundStack );
+
+				backgroundStack.classList.add( 'stack' );
+
+			} );
+
+		} );
+
+		// Add parallax background if specified
+		if( 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;
+
+			// Make sure the below properties are set on the element - these properties are
+			// needed for proper transitions to be set on the element via CSS. To remove
+			// annoying background slide-in effect when the presentation starts, apply
+			// these properties after short time delay
+			setTimeout( () => {
+				this.Reveal.getRevealElement().classList.add( 'has-parallax-background' );
+			}, 1 );
+
+		}
+		else {
+
+			this.element.style.backgroundImage = '';
+			this.Reveal.getRevealElement().classList.remove( 'has-parallax-background' );
+
+		}
+
+	}
+
+	/**
+	 * Creates a background for the given slide.
+	 *
+	 * @param {HTMLElement} slide
+	 * @param {HTMLElement} container The element that the background
+	 * should be appended to
+	 * @return {HTMLElement} New background div
+	 */
+	createBackground( slide, container ) {
+
+		// Main slide background element
+		let element = document.createElement( 'div' );
+		element.className = 'slide-background ' + slide.className.replace( /present|past|future/, '' );
+
+		// Inner background element that wraps images/videos/iframes
+		let contentElement = document.createElement( 'div' );
+		contentElement.className = 'slide-background-content';
+
+		element.appendChild( contentElement );
+		container.appendChild( element );
+
+		slide.slideBackgroundElement = element;
+		slide.slideBackgroundContentElement = contentElement;
+
+		// Syncs the background to reflect all current background settings
+		this.sync( slide );
+
+		return element;
+
+	}
+
+	/**
+	 * Renders all of the visual properties of a slide background
+	 * based on the various background attributes.
+	 *
+	 * @param {HTMLElement} slide
+	 */
+	sync( slide ) {
+
+		const element = slide.slideBackgroundElement,
+			contentElement = slide.slideBackgroundContentElement;
+
+		const data = {
+			background: slide.getAttribute( 'data-background' ),
+			backgroundSize: slide.getAttribute( 'data-background-size' ),
+			backgroundImage: slide.getAttribute( 'data-background-image' ),
+			backgroundVideo: slide.getAttribute( 'data-background-video' ),
+			backgroundIframe: slide.getAttribute( 'data-background-iframe' ),
+			backgroundColor: slide.getAttribute( 'data-background-color' ),
+			backgroundGradient: slide.getAttribute( 'data-background-gradient' ),
+			backgroundRepeat: slide.getAttribute( 'data-background-repeat' ),
+			backgroundPosition: slide.getAttribute( 'data-background-position' ),
+			backgroundTransition: slide.getAttribute( 'data-background-transition' ),
+			backgroundOpacity: slide.getAttribute( 'data-background-opacity' ),
+		};
+
+		const dataPreload = slide.hasAttribute( 'data-preload' );
+
+		// Reset the prior background state in case this is not the
+		// initial sync
+		slide.classList.remove( 'has-dark-background' );
+		slide.classList.remove( 'has-light-background' );
+
+		element.removeAttribute( 'data-loaded' );
+		element.removeAttribute( 'data-background-hash' );
+		element.removeAttribute( 'data-background-size' );
+		element.removeAttribute( 'data-background-transition' );
+		element.style.backgroundColor = '';
+
+		contentElement.style.backgroundSize = '';
+		contentElement.style.backgroundRepeat = '';
+		contentElement.style.backgroundPosition = '';
+		contentElement.style.backgroundImage = '';
+		contentElement.style.opacity = '';
+		contentElement.innerHTML = '';
+
+		if( data.background ) {
+			// Auto-wrap image urls in url(...)
+			if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp|webp)([?#\s]|$)/gi.test( data.background ) ) {
+				slide.setAttribute( 'data-background-image', data.background );
+			}
+			else {
+				element.style.background = data.background;
+			}
+		}
+
+		// Create a hash for this combination of background settings.
+		// This is used to determine when two slide backgrounds are
+		// the same.
+		if( data.background || data.backgroundColor || data.backgroundGradient || data.backgroundImage || data.backgroundVideo || data.backgroundIframe ) {
+			element.setAttribute( 'data-background-hash', data.background +
+															data.backgroundSize +
+															data.backgroundImage +
+															data.backgroundVideo +
+															data.backgroundIframe +
+															data.backgroundColor +
+															data.backgroundGradient +
+															data.backgroundRepeat +
+															data.backgroundPosition +
+															data.backgroundTransition +
+															data.backgroundOpacity );
+		}
+
+		// Additional and optional background properties
+		if( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize );
+		if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
+		if( data.backgroundGradient ) element.style.backgroundImage = data.backgroundGradient;
+		if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );
+
+		if( dataPreload ) element.setAttribute( 'data-preload', '' );
+
+		// Background image options are set on the content wrapper
+		if( data.backgroundSize ) contentElement.style.backgroundSize = data.backgroundSize;
+		if( data.backgroundRepeat ) contentElement.style.backgroundRepeat = data.backgroundRepeat;
+		if( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition;
+		if( data.backgroundOpacity ) contentElement.style.opacity = data.backgroundOpacity;
+
+		const contrastClass = this.getContrastClass( slide );
+
+		if( typeof contrastClass === 'string' ) {
+			slide.classList.add( contrastClass );
+		}
+
+	}
+
+	/**
+	 * Returns a class name that can be applied to a slide to indicate
+	 * if it has a light or dark background.
+	 *
+	 * @param {*} slide
+	 *
+	 * @returns {string|null}
+	 */
+	getContrastClass( slide ) {
+
+		const element = slide.slideBackgroundElement;
+
+		// If this slide has a background color, we add a class that
+		// signals if it is light or dark. If the slide has no background
+		// color, no class will be added
+		let contrastColor = slide.getAttribute( 'data-background-color' );
+
+		// If no bg color was found, or it cannot be converted by colorToRgb, check the computed background
+		if( !contrastColor || !colorToRgb( contrastColor ) ) {
+			let computedBackgroundStyle = window.getComputedStyle( element );
+			if( computedBackgroundStyle && computedBackgroundStyle.backgroundColor ) {
+				contrastColor = computedBackgroundStyle.backgroundColor;
+			}
+		}
+
+		if( contrastColor ) {
+			const rgb = colorToRgb( contrastColor );
+
+			// Ignore fully transparent backgrounds. Some browsers return
+			// rgba(0,0,0,0) when reading the computed background color of
+			// an element with no background
+			if( rgb && rgb.a !== 0 ) {
+				if( colorBrightness( contrastColor ) < 128 ) {
+					return 'has-dark-background';
+				}
+				else {
+					return 'has-light-background';
+				}
+			}
+		}
+
+		return null;
+
+	}
+
+	/**
+	 * Bubble the 'has-light-background'/'has-dark-background' classes.
+	 */
+	bubbleSlideContrastClassToElement( slide, target ) {
+
+		[ 'has-light-background', 'has-dark-background' ].forEach( classToBubble => {
+			if( slide.classList.contains( classToBubble ) ) {
+				target.classList.add( classToBubble );
+			}
+			else {
+				target.classList.remove( classToBubble );
+			}
+		}, this );
+
+	}
+
+	/**
+	 * Updates the background elements to reflect the current
+	 * slide.
+	 *
+	 * @param {boolean} includeAll If true, the backgrounds of
+	 * all vertical slides (not just the present) will be updated.
+	 */
+	update( includeAll = false ) {
+
+		let config = this.Reveal.getConfig();
+		let currentSlide = this.Reveal.getCurrentSlide();
+		let indices = this.Reveal.getIndices();
+
+		let currentBackground = null;
+
+		// Reverse past/future classes when in RTL mode
+		let horizontalPast = config.rtl ? 'future' : 'past',
+			horizontalFuture = config.rtl ? 'past' : 'future';
+
+		// Update the classes of all backgrounds to match the
+		// states of their slides (past/present/future)
+		Array.from( this.element.childNodes ).forEach( ( backgroundh, h ) => {
+
+			backgroundh.classList.remove( 'past', 'present', 'future' );
+
+			if( h < indices.h ) {
+				backgroundh.classList.add( horizontalPast );
+			}
+			else if ( h > indices.h ) {
+				backgroundh.classList.add( horizontalFuture );
+			}
+			else {
+				backgroundh.classList.add( 'present' );
+
+				// Store a reference to the current background element
+				currentBackground = backgroundh;
+			}
+
+			if( includeAll || h === indices.h ) {
+				queryAll( backgroundh, '.slide-background' ).forEach( ( backgroundv, v ) => {
+
+					backgroundv.classList.remove( 'past', 'present', 'future' );
+
+					const indexv = typeof indices.v === 'number' ? indices.v : 0;
+
+					if( v < indexv ) {
+						backgroundv.classList.add( 'past' );
+					}
+					else if ( v > indexv ) {
+						backgroundv.classList.add( 'future' );
+					}
+					else {
+						backgroundv.classList.add( 'present' );
+
+						// Only if this is the present horizontal and vertical slide
+						if( h === indices.h ) currentBackground = backgroundv;
+					}
+
+				} );
+			}
+
+		} );
+
+		// The previous background may refer to a DOM element that has
+		// been removed after a presentation is synced & bgs are recreated
+		if( this.previousBackground && !this.previousBackground.closest( 'body' ) ) {
+			this.previousBackground = null;
+		}
+
+		if( currentBackground && this.previousBackground ) {
+
+			// Don't transition between identical backgrounds. This
+			// prevents unwanted flicker.
+			let previousBackgroundHash = this.previousBackground.getAttribute( 'data-background-hash' );
+			let currentBackgroundHash = currentBackground.getAttribute( 'data-background-hash' );
+
+			if( currentBackgroundHash && currentBackgroundHash === previousBackgroundHash && currentBackground !== this.previousBackground ) {
+				this.element.classList.add( 'no-transition' );
+
+				// If multiple slides have the same background video, carry
+				// the <video> element forward so that it plays continuously
+				// across multiple slides
+				const currentVideo = currentBackground.querySelector( 'video' );
+				const previousVideo = this.previousBackground.querySelector( 'video' );
+
+				if( currentVideo && previousVideo ) {
+
+					const currentVideoParent = currentVideo.parentNode;
+					const previousVideoParent = previousVideo.parentNode;
+
+					// Swap the two videos
+					previousVideoParent.appendChild( currentVideo );
+					currentVideoParent.appendChild( previousVideo );
+
+				}
+			}
+
+		}
+
+		const backgroundChanged = currentBackground !== this.previousBackground;
+
+		// Stop content inside of previous backgrounds
+		if( backgroundChanged && this.previousBackground ) {
+
+			this.Reveal.slideContent.stopEmbeddedContent( this.previousBackground, { unloadIframes: !this.Reveal.slideContent.shouldPreload( this.previousBackground ) } );
+
+		}
+
+		// Start content in the current background
+		if( backgroundChanged && currentBackground ) {
+
+			this.Reveal.slideContent.startEmbeddedContent( currentBackground );
+
+			let currentBackgroundContent = currentBackground.querySelector( '.slide-background-content' );
+			if( currentBackgroundContent ) {
+
+				let backgroundImageURL = currentBackgroundContent.style.backgroundImage || '';
+
+				// Restart GIFs (doesn't work in Firefox)
+				if( /\.gif/i.test( backgroundImageURL ) ) {
+					currentBackgroundContent.style.backgroundImage = '';
+					window.getComputedStyle( currentBackgroundContent ).opacity;
+					currentBackgroundContent.style.backgroundImage = backgroundImageURL;
+				}
+
+			}
+
+			this.previousBackground = currentBackground;
+
+		}
+
+		// If there's a background brightness flag for this slide,
+		// bubble it to the .reveal container
+		if( currentSlide ) {
+			this.bubbleSlideContrastClassToElement( currentSlide, this.Reveal.getRevealElement() );
+		}
+
+		// Allow the first background to apply without transition
+		setTimeout( () => {
+			this.element.classList.remove( 'no-transition' );
+		}, 10 );
+
+	}
+
+	/**
+	 * Updates the position of the parallax background based
+	 * on the current slide index.
+	 */
+	updateParallax() {
+
+		let indices = this.Reveal.getIndices();
+
+		if( this.Reveal.getConfig().parallaxBackgroundImage ) {
+
+			let horizontalSlides = this.Reveal.getHorizontalSlides(),
+				verticalSlides = this.Reveal.getVerticalSlides();
+
+			let backgroundSize = this.element.style.backgroundSize.split( ' ' ),
+				backgroundWidth, backgroundHeight;
+
+			if( backgroundSize.length === 1 ) {
+				backgroundWidth = backgroundHeight = parseInt( backgroundSize[0], 10 );
+			}
+			else {
+				backgroundWidth = parseInt( backgroundSize[0], 10 );
+				backgroundHeight = parseInt( backgroundSize[1], 10 );
+			}
+
+			let slideWidth = this.element.offsetWidth,
+				horizontalSlideCount = horizontalSlides.length,
+				horizontalOffsetMultiplier,
+				horizontalOffset;
+
+			if( typeof this.Reveal.getConfig().parallaxBackgroundHorizontal === 'number' ) {
+				horizontalOffsetMultiplier = this.Reveal.getConfig().parallaxBackgroundHorizontal;
+			}
+			else {
+				horizontalOffsetMultiplier = horizontalSlideCount > 1 ? ( backgroundWidth - slideWidth ) / ( horizontalSlideCount-1 ) : 0;
+			}
+
+			horizontalOffset = horizontalOffsetMultiplier * indices.h * -1;
+
+			let slideHeight = this.element.offsetHeight,
+				verticalSlideCount = verticalSlides.length,
+				verticalOffsetMultiplier,
+				verticalOffset;
+
+			if( typeof this.Reveal.getConfig().parallaxBackgroundVertical === 'number' ) {
+				verticalOffsetMultiplier = this.Reveal.getConfig().parallaxBackgroundVertical;
+			}
+			else {
+				verticalOffsetMultiplier = ( backgroundHeight - slideHeight ) / ( verticalSlideCount-1 );
+			}
+
+			verticalOffset = verticalSlideCount > 0 ?  verticalOffsetMultiplier * indices.v : 0;
+
+			this.element.style.backgroundPosition = horizontalOffset + 'px ' + -verticalOffset + 'px';
+
+		}
+
+	}
+
+	destroy() {
+
+		this.element.remove();
+
+	}
+
+}
diff --git a/inst/reveal.js-5.2.1/js/controllers/controls.js b/inst/reveal.js-5.2.1/js/controllers/controls.js
new file mode 100644
index 0000000..7c52a0f
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/controls.js
@@ -0,0 +1,287 @@
+import { queryAll, enterFullscreen } from '../utils/util.js'
+import { isAndroid } from '../utils/device.js'
+
+/**
+ * Manages our presentation controls. This includes both
+ * the built-in control arrows as well as event monitoring
+ * of any elements within the presentation with either of the
+ * following helper classes:
+ * - .navigate-up
+ * - .navigate-right
+ * - .navigate-down
+ * - .navigate-left
+ * - .navigate-next
+ * - .navigate-prev
+ * - .enter-fullscreen
+ */
+export default class Controls {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		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 );
+		this.onEnterFullscreen = this.onEnterFullscreen.bind( this );
+
+	}
+
+	render() {
+
+		const rtl = this.Reveal.getConfig().rtl;
+		const revealElement = this.Reveal.getRevealElement();
+
+		this.element = document.createElement( 'aside' );
+		this.element.className = 'controls';
+		this.element.innerHTML =
+			`<button class="navigate-left" aria-label="${ rtl ? 'next slide' : 'previous slide' }"><div class="controls-arrow"></div></button>
+			<button class="navigate-right" aria-label="${ rtl ? 'previous slide' : 'next slide' }"><div class="controls-arrow"></div></button>
+			<button class="navigate-up" aria-label="above slide"><div class="controls-arrow"></div></button>
+			<button class="navigate-down" aria-label="below slide"><div class="controls-arrow"></div></button>`;
+
+		this.Reveal.getRevealElement().appendChild( this.element );
+
+		// There can be multiple instances of controls throughout the page
+		this.controlsLeft = queryAll( revealElement, '.navigate-left' );
+		this.controlsRight = queryAll( revealElement, '.navigate-right' );
+		this.controlsUp = queryAll( revealElement, '.navigate-up' );
+		this.controlsDown = queryAll( revealElement, '.navigate-down' );
+		this.controlsPrev = queryAll( revealElement, '.navigate-prev' );
+		this.controlsNext = queryAll( revealElement, '.navigate-next' );
+		this.controlsFullscreen = queryAll( revealElement, '.enter-fullscreen' );
+
+		// The left, right and down arrows in the standard reveal.js controls
+		this.controlsRightArrow = this.element.querySelector( '.navigate-right' );
+		this.controlsLeftArrow = this.element.querySelector( '.navigate-left' );
+		this.controlsDownArrow = this.element.querySelector( '.navigate-down' );
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		this.element.style.display = (
+			config.controls &&
+			(config.controls !== 'speaker-only' || this.Reveal.isSpeakerNotes())
+		) ? 'block' : 'none';
+
+		this.element.setAttribute( 'data-controls-layout', config.controlsLayout );
+		this.element.setAttribute( 'data-controls-back-arrows', config.controlsBackArrows );
+
+	}
+
+	bind() {
+
+		// Listen to both touch and click events, in case the device
+		// supports both
+		let pointerEvents = [ 'touchstart', 'click' ];
+
+		// Only support touch for Android, fixes double navigations in
+		// stock browser
+		if( isAndroid ) {
+			pointerEvents = [ 'touchstart' ];
+		}
+
+		pointerEvents.forEach( eventName => {
+			this.controlsLeft.forEach( el => el.addEventListener( eventName, this.onNavigateLeftClicked, false ) );
+			this.controlsRight.forEach( el => el.addEventListener( eventName, this.onNavigateRightClicked, false ) );
+			this.controlsUp.forEach( el => el.addEventListener( eventName, this.onNavigateUpClicked, false ) );
+			this.controlsDown.forEach( el => el.addEventListener( eventName, this.onNavigateDownClicked, false ) );
+			this.controlsPrev.forEach( el => el.addEventListener( eventName, this.onNavigatePrevClicked, false ) );
+			this.controlsNext.forEach( el => el.addEventListener( eventName, this.onNavigateNextClicked, false ) );
+			this.controlsFullscreen.forEach( el => el.addEventListener( eventName, this.onEnterFullscreen, false ) );
+		} );
+
+	}
+
+	unbind() {
+
+		[ 'touchstart', 'click' ].forEach( eventName => {
+			this.controlsLeft.forEach( el => el.removeEventListener( eventName, this.onNavigateLeftClicked, false ) );
+			this.controlsRight.forEach( el => el.removeEventListener( eventName, this.onNavigateRightClicked, false ) );
+			this.controlsUp.forEach( el => el.removeEventListener( eventName, this.onNavigateUpClicked, false ) );
+			this.controlsDown.forEach( el => el.removeEventListener( eventName, this.onNavigateDownClicked, false ) );
+			this.controlsPrev.forEach( el => el.removeEventListener( eventName, this.onNavigatePrevClicked, false ) );
+			this.controlsNext.forEach( el => el.removeEventListener( eventName, this.onNavigateNextClicked, false ) );
+			this.controlsFullscreen.forEach( el => el.removeEventListener( eventName, this.onEnterFullscreen, false ) );
+		} );
+
+	}
+
+	/**
+	 * Updates the state of all control/navigation arrows.
+	 */
+	update() {
+
+		let routes = this.Reveal.availableRoutes();
+
+		// Remove the 'enabled' class from all directions
+		[...this.controlsLeft, ...this.controlsRight, ...this.controlsUp, ...this.controlsDown, ...this.controlsPrev, ...this.controlsNext].forEach( node => {
+			node.classList.remove( 'enabled', 'fragmented' );
+
+			// Set 'disabled' attribute on all directions
+			node.setAttribute( 'disabled', 'disabled' );
+		} );
+
+		// Add the 'enabled' class to the available routes; remove 'disabled' attribute to enable buttons
+		if( routes.left ) this.controlsLeft.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
+		if( routes.right ) this.controlsRight.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
+		if( routes.up ) this.controlsUp.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
+		if( routes.down ) this.controlsDown.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
+
+		// Prev/next buttons
+		if( routes.left || routes.up ) this.controlsPrev.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
+		if( routes.right || routes.down ) this.controlsNext.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
+
+		// Highlight fragment directions
+		let currentSlide = this.Reveal.getCurrentSlide();
+		if( currentSlide ) {
+
+			let fragmentsRoutes = this.Reveal.fragments.availableRoutes();
+
+			// Always apply fragment decorator to prev/next buttons
+			if( fragmentsRoutes.prev ) this.controlsPrev.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
+			if( fragmentsRoutes.next ) this.controlsNext.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
+
+			const isVerticalStack = this.Reveal.isVerticalSlide( currentSlide );
+			const hasVerticalSiblings = isVerticalStack &&
+																	currentSlide.parentElement &&
+																	currentSlide.parentElement.querySelectorAll( ':scope > section' ).length > 1;
+
+			// Apply fragment decorators to directional buttons based on
+			// what slide axis they are in
+			if( isVerticalStack && hasVerticalSiblings ) {
+				if( fragmentsRoutes.prev ) this.controlsUp.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
+				if( fragmentsRoutes.next ) this.controlsDown.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
+			}
+			else {
+				if( fragmentsRoutes.prev ) this.controlsLeft.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
+				if( fragmentsRoutes.next ) this.controlsRight.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
+			}
+
+		}
+
+		if( this.Reveal.getConfig().controlsTutorial ) {
+
+			let indices = this.Reveal.getIndices();
+
+			// Highlight control arrows with an animation to ensure
+			// that the viewer knows how to navigate
+			if( !this.Reveal.hasNavigatedVertically() && routes.down ) {
+				this.controlsDownArrow.classList.add( 'highlight' );
+			}
+			else {
+				this.controlsDownArrow.classList.remove( 'highlight' );
+
+				if( this.Reveal.getConfig().rtl ) {
+
+					if( !this.Reveal.hasNavigatedHorizontally() && routes.left && indices.v === 0 ) {
+						this.controlsLeftArrow.classList.add( 'highlight' );
+					}
+					else {
+						this.controlsLeftArrow.classList.remove( 'highlight' );
+					}
+
+				} else {
+
+					if( !this.Reveal.hasNavigatedHorizontally() && routes.right && indices.v === 0 ) {
+						this.controlsRightArrow.classList.add( 'highlight' );
+					}
+					else {
+						this.controlsRightArrow.classList.remove( 'highlight' );
+					}
+				}
+			}
+		}
+	}
+
+	destroy() {
+
+		this.unbind();
+		this.element.remove();
+
+	}
+
+	/**
+	 * Event handlers for navigation control buttons.
+	 */
+	onNavigateLeftClicked( event ) {
+
+		event.preventDefault();
+		this.Reveal.onUserInput();
+
+		if( this.Reveal.getConfig().navigationMode === 'linear' ) {
+			this.Reveal.prev();
+		}
+		else {
+			this.Reveal.left();
+		}
+
+	}
+
+	onNavigateRightClicked( event ) {
+
+		event.preventDefault();
+		this.Reveal.onUserInput();
+
+		if( this.Reveal.getConfig().navigationMode === 'linear' ) {
+			this.Reveal.next();
+		}
+		else {
+			this.Reveal.right();
+		}
+
+	}
+
+	onNavigateUpClicked( event ) {
+
+		event.preventDefault();
+		this.Reveal.onUserInput();
+
+		this.Reveal.up();
+
+	}
+
+	onNavigateDownClicked( event ) {
+
+		event.preventDefault();
+		this.Reveal.onUserInput();
+
+		this.Reveal.down();
+
+	}
+
+	onNavigatePrevClicked( event ) {
+
+		event.preventDefault();
+		this.Reveal.onUserInput();
+
+		this.Reveal.prev();
+
+	}
+
+	onNavigateNextClicked( event ) {
+
+		event.preventDefault();
+		this.Reveal.onUserInput();
+
+		this.Reveal.next();
+
+	}
+
+	onEnterFullscreen( event ) {
+
+		const config = this.Reveal.getConfig();
+		const viewport = this.Reveal.getViewportElement();
+
+		enterFullscreen( config.embedded ? viewport : viewport.parentElement );
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/controllers/focus.js b/inst/reveal.js-5.2.1/js/controllers/focus.js
new file mode 100644
index 0000000..3e68c3f
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/focus.js
@@ -0,0 +1,103 @@
+import { closest } from '../utils/util.js'
+
+/**
+ * Manages focus when a presentation is embedded. This
+ * helps us only capture keyboard from the presentation
+ * a user is currently interacting with in a page where
+ * multiple presentations are embedded.
+ */
+
+const STATE_FOCUS = 'focus';
+const STATE_BLUR = 'blur';
+
+export default class Focus {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		this.onRevealPointerDown = this.onRevealPointerDown.bind( this );
+		this.onDocumentPointerDown = this.onDocumentPointerDown.bind( this );
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		if( config.embedded ) {
+			this.blur();
+		}
+		else {
+			this.focus();
+			this.unbind();
+		}
+
+	}
+
+	bind() {
+
+		if( this.Reveal.getConfig().embedded ) {
+			this.Reveal.getRevealElement().addEventListener( 'pointerdown', this.onRevealPointerDown, false );
+		}
+
+	}
+
+	unbind() {
+
+		this.Reveal.getRevealElement().removeEventListener( 'pointerdown', this.onRevealPointerDown, false );
+		document.removeEventListener( 'pointerdown', this.onDocumentPointerDown, false );
+
+	}
+
+	focus() {
+
+		if( this.state !== STATE_FOCUS ) {
+			this.Reveal.getRevealElement().classList.add( 'focused' );
+			document.addEventListener( 'pointerdown', this.onDocumentPointerDown, false );
+		}
+
+		this.state = STATE_FOCUS;
+
+	}
+
+	blur() {
+
+		if( this.state !== STATE_BLUR ) {
+			this.Reveal.getRevealElement().classList.remove( 'focused' );
+			document.removeEventListener( 'pointerdown', this.onDocumentPointerDown, false );
+		}
+
+		this.state = STATE_BLUR;
+
+	}
+
+	isFocused() {
+
+		return this.state === STATE_FOCUS;
+
+	}
+
+	destroy() {
+
+		this.Reveal.getRevealElement().classList.remove( 'focused' );
+
+	}
+
+	onRevealPointerDown( event ) {
+
+		this.focus();
+
+	}
+
+	onDocumentPointerDown( event ) {
+
+		let revealElement = closest( event.target, '.reveal' );
+		if( !revealElement || revealElement !== this.Reveal.getRevealElement() ) {
+			this.blur();
+		}
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/controllers/fragments.js b/inst/reveal.js-5.2.1/js/controllers/fragments.js
new file mode 100644
index 0000000..0a84530
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/fragments.js
@@ -0,0 +1,375 @@
+import { extend, queryAll } from '../utils/util.js'
+
+/**
+ * Handles sorting and navigation of slide fragments.
+ * Fragments are elements within a slide that are
+ * revealed/animated incrementally.
+ */
+export default class Fragments {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		if( config.fragments === false ) {
+			this.disable();
+		}
+		else if( oldConfig.fragments === false ) {
+			this.enable();
+		}
+
+	}
+
+	/**
+	 * If fragments are disabled in the deck, they should all be
+	 * visible rather than stepped through.
+	 */
+	disable() {
+
+		queryAll( this.Reveal.getSlidesElement(), '.fragment' ).forEach( element => {
+			element.classList.add( 'visible' );
+			element.classList.remove( 'current-fragment' );
+		} );
+
+	}
+
+	/**
+	 * Reverse of #disable(). Only called if fragments have
+	 * previously been disabled.
+	 */
+	enable() {
+
+		queryAll( this.Reveal.getSlidesElement(), '.fragment' ).forEach( element => {
+			element.classList.remove( 'visible' );
+			element.classList.remove( 'current-fragment' );
+		} );
+
+	}
+
+	/**
+	 * Returns an object describing the available fragment
+	 * directions.
+	 *
+	 * @return {{prev: boolean, next: boolean}}
+	 */
+	availableRoutes() {
+
+		let currentSlide = this.Reveal.getCurrentSlide();
+		if( currentSlide && this.Reveal.getConfig().fragments ) {
+			let fragments = currentSlide.querySelectorAll( '.fragment:not(.disabled)' );
+			let hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.disabled):not(.visible)' );
+
+			return {
+				prev: fragments.length - hiddenFragments.length > 0,
+				next: !!hiddenFragments.length
+			};
+		}
+		else {
+			return { prev: false, next: false };
+		}
+
+	}
+
+	/**
+	 * Return a sorted fragments list, ordered by an increasing
+	 * "data-fragment-index" attribute.
+	 *
+	 * Fragments will be revealed in the order that they are returned by
+	 * this function, so you can use the index attributes to control the
+	 * order of fragment appearance.
+	 *
+	 * To maintain a sensible default fragment order, fragments are presumed
+	 * to be passed in document order. This function adds a "fragment-index"
+	 * attribute to each node if such an attribute is not already present,
+	 * and sets that attribute to an integer value which is the position of
+	 * the fragment within the fragments list.
+	 *
+	 * @param {object[]|*} fragments
+	 * @param {boolean} grouped If true the returned array will contain
+	 * nested arrays for all fragments with the same index
+	 * @return {object[]} sorted Sorted array of fragments
+	 */
+	sort( fragments, grouped = false ) {
+
+		fragments = Array.from( fragments );
+
+		let ordered = [],
+			unordered = [],
+			sorted = [];
+
+		// Group ordered and unordered elements
+		fragments.forEach( fragment => {
+			if( fragment.hasAttribute( 'data-fragment-index' ) ) {
+				let index = parseInt( fragment.getAttribute( 'data-fragment-index' ), 10 );
+
+				if( !ordered[index] ) {
+					ordered[index] = [];
+				}
+
+				ordered[index].push( fragment );
+			}
+			else {
+				unordered.push( [ fragment ] );
+			}
+		} );
+
+		// Append fragments without explicit indices in their
+		// DOM order
+		ordered = ordered.concat( unordered );
+
+		// Manually count the index up per group to ensure there
+		// are no gaps
+		let index = 0;
+
+		// Push all fragments in their sorted order to an array,
+		// this flattens the groups
+		ordered.forEach( group => {
+			group.forEach( fragment => {
+				sorted.push( fragment );
+				fragment.setAttribute( 'data-fragment-index', index );
+			} );
+
+			index ++;
+		} );
+
+		return grouped === true ? ordered : sorted;
+
+	}
+
+	/**
+	 * Sorts and formats all of fragments in the
+	 * presentation.
+	 */
+	sortAll() {
+
+		this.Reveal.getHorizontalSlides().forEach( horizontalSlide => {
+
+			let verticalSlides = queryAll( horizontalSlide, 'section' );
+			verticalSlides.forEach( ( verticalSlide, y ) => {
+
+				this.sort( verticalSlide.querySelectorAll( '.fragment' ) );
+
+			}, this );
+
+			if( verticalSlides.length === 0 ) this.sort( horizontalSlide.querySelectorAll( '.fragment' ) );
+
+		} );
+
+	}
+
+	/**
+	 * Refreshes the fragments on the current slide so that they
+	 * have the appropriate classes (.visible + .current-fragment).
+	 *
+	 * @param {number} [index] The index of the current fragment
+	 * @param {array} [fragments] Array containing all fragments
+	 * in the current slide
+	 *
+	 * @return {{shown: array, hidden: array}}
+	 */
+	update( index, fragments, slide = this.Reveal.getCurrentSlide() ) {
+
+		let changedFragments = {
+			shown: [],
+			hidden: []
+		};
+
+		if( slide && this.Reveal.getConfig().fragments ) {
+
+			fragments = fragments || this.sort( slide.querySelectorAll( '.fragment' ) );
+
+			if( fragments.length ) {
+
+				let maxIndex = 0;
+
+				if( typeof index !== 'number' ) {
+					let currentFragment = this.sort( slide.querySelectorAll( '.fragment.visible' ) ).pop();
+					if( currentFragment ) {
+						index = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
+					}
+				}
+
+				Array.from( fragments ).forEach( ( el, i ) => {
+
+					if( el.hasAttribute( 'data-fragment-index' ) ) {
+						i = parseInt( el.getAttribute( 'data-fragment-index' ), 10 );
+					}
+
+					maxIndex = Math.max( maxIndex, i );
+
+					// Visible fragments
+					if( i <= index ) {
+						let wasVisible = el.classList.contains( 'visible' )
+						el.classList.add( 'visible' );
+						el.classList.remove( 'current-fragment' );
+
+						if( i === index ) {
+							// Announce the fragments one by one to the Screen Reader
+							this.Reveal.announceStatus( this.Reveal.getStatusText( el ) );
+
+							el.classList.add( 'current-fragment' );
+							this.Reveal.slideContent.startEmbeddedContent( el );
+						}
+
+						if( !wasVisible ) {
+							changedFragments.shown.push( el )
+							this.Reveal.dispatchEvent({
+								target: el,
+								type: 'visible',
+								bubbles: false
+							});
+						}
+					}
+					// Hidden fragments
+					else {
+						let wasVisible = el.classList.contains( 'visible' )
+						el.classList.remove( 'visible' );
+						el.classList.remove( 'current-fragment' );
+
+						if( wasVisible ) {
+							this.Reveal.slideContent.stopEmbeddedContent( el );
+							changedFragments.hidden.push( el );
+							this.Reveal.dispatchEvent({
+								target: el,
+								type: 'hidden',
+								bubbles: false
+							});
+						}
+					}
+
+				} );
+
+				// Write the current fragment index to the slide <section>.
+				// This can be used by end users to apply styles based on
+				// the current fragment index.
+				index = typeof index === 'number' ? index : -1;
+				index = Math.max( Math.min( index, maxIndex ), -1 );
+				slide.setAttribute( 'data-fragment', index );
+
+			}
+
+		}
+
+		if( changedFragments.hidden.length ) {
+			this.Reveal.dispatchEvent({
+				type: 'fragmenthidden',
+				data: {
+					fragment: changedFragments.hidden[0],
+					fragments: changedFragments.hidden
+				}
+			});
+		}
+
+		if( changedFragments.shown.length ) {
+			this.Reveal.dispatchEvent({
+				type: 'fragmentshown',
+				data: {
+					fragment: changedFragments.shown[0],
+					fragments: changedFragments.shown
+				}
+			});
+		}
+
+		return changedFragments;
+
+	}
+
+	/**
+	 * Formats the fragments on the given slide so that they have
+	 * valid indices. Call this if fragments are changed in the DOM
+	 * after reveal.js has already initialized.
+	 *
+	 * @param {HTMLElement} slide
+	 * @return {Array} a list of the HTML fragments that were synced
+	 */
+	sync( slide = this.Reveal.getCurrentSlide() ) {
+
+		return this.sort( slide.querySelectorAll( '.fragment' ) );
+
+	}
+
+	/**
+	 * Navigate to the specified slide fragment.
+	 *
+	 * @param {?number} index The index of the fragment that
+	 * should be shown, -1 means all are invisible
+	 * @param {number} offset Integer offset to apply to the
+	 * fragment index
+	 *
+	 * @return {boolean} true if a change was made in any
+	 * fragments visibility as part of this call
+	 */
+	goto( index, offset = 0 ) {
+
+		let currentSlide = this.Reveal.getCurrentSlide();
+		if( currentSlide && this.Reveal.getConfig().fragments ) {
+
+			let fragments = this.sort( currentSlide.querySelectorAll( '.fragment:not(.disabled)' ) );
+			if( fragments.length ) {
+
+				// If no index is specified, find the current
+				if( typeof index !== 'number' ) {
+					let lastVisibleFragment = this.sort( currentSlide.querySelectorAll( '.fragment:not(.disabled).visible' ) ).pop();
+
+					if( lastVisibleFragment ) {
+						index = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
+					}
+					else {
+						index = -1;
+					}
+				}
+
+				// Apply the offset if there is one
+				index += offset;
+
+				let changedFragments = this.update( index, fragments );
+
+				this.Reveal.controls.update();
+				this.Reveal.progress.update();
+
+				if( this.Reveal.getConfig().fragmentInURL ) {
+					this.Reveal.location.writeURL();
+				}
+
+				return !!( changedFragments.shown.length || changedFragments.hidden.length );
+
+			}
+
+		}
+
+		return false;
+
+	}
+
+	/**
+	 * Navigate to the next slide fragment.
+	 *
+	 * @return {boolean} true if there was a next fragment,
+	 * false otherwise
+	 */
+	next() {
+
+		return this.goto( null, 1 );
+
+	}
+
+	/**
+	 * Navigate to the previous slide fragment.
+	 *
+	 * @return {boolean} true if there was a previous fragment,
+	 * false otherwise
+	 */
+	prev() {
+
+		return this.goto( null, -1 );
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/controllers/jumptoslide.js b/inst/reveal.js-5.2.1/js/controllers/jumptoslide.js
new file mode 100644
index 0000000..0aaa2b1
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/jumptoslide.js
@@ -0,0 +1,197 @@
+import {
+	SLIDE_NUMBER_FORMAT_CURRENT,
+	SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL
+} from "../utils/constants";
+
+/**
+ * Makes it possible to jump to a slide by entering its
+ * slide number or id.
+ */
+export default class JumpToSlide {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		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() {
+
+		if( this.isVisible() ) {
+			this.element.remove();
+			this.jumpInput.value = '';
+
+			clearTimeout( this.jumpTimeout );
+			delete this.jumpTimeout;
+		}
+
+	}
+
+	isVisible() {
+
+		return !!this.element.parentNode;
+
+	}
+
+	/**
+	 * Parses the current input and jumps to the given slide.
+	 */
+	jump() {
+
+		clearTimeout( this.jumpTimeout );
+		delete this.jumpTimeout;
+
+		let query = this.jumpInput.value.trim( '' );
+		let indices;
+
+		// When slide numbers are formatted to be a single linear number
+		// (instead of showing a separate horizontal/vertical index) we
+		// use the same format for slide jumps
+		if( /^\d+$/.test( query ) ) {
+			const slideNumberFormat = this.Reveal.getConfig().slideNumber;
+			if( slideNumberFormat === SLIDE_NUMBER_FORMAT_CURRENT || slideNumberFormat === SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL ) {
+				const slide = this.Reveal.getSlides()[ parseInt( query, 10 ) - 1 ];
+				if( slide ) {
+					indices = this.Reveal.getIndices( slide );
+				}
+			}
+		}
+
+		if( !indices ) {
+			// If the query uses "horizontal.vertical" format, convert to
+			// "horizontal/vertical" so that our URL parser can understand
+			if( /^\d+\.\d+$/.test( query ) ) {
+				query = query.replace( '.', '/' );
+			}
+
+			indices = this.Reveal.location.getIndicesFromHash( query, { oneBasedIndex: true } );
+		}
+
+		// Still no valid index? Fall back on a text search
+		if( !indices && /\S+/i.test( query ) && query.length > 1 ) {
+			indices = this.search( query );
+		}
+
+		if( indices && query !== '' ) {
+			this.Reveal.slide( indices.h, indices.v, indices.f );
+			return true;
+		}
+		else {
+			this.Reveal.slide( this.indicesOnShow.h, this.indicesOnShow.v, this.indicesOnShow.f );
+			return false;
+		}
+
+	}
+
+	jumpAfter( delay ) {
+
+		clearTimeout( this.jumpTimeout );
+		this.jumpTimeout = setTimeout( () => this.jump(), delay );
+
+	}
+
+	/**
+	 * A lofi search that looks for the given query in all
+	 * of our slides and returns the first match.
+	 */
+	search( query ) {
+
+		const regex = new RegExp( '\\b' + query.trim() + '\\b', 'i' );
+
+		const slide = this.Reveal.getSlides().find( ( slide ) => {
+			return regex.test( slide.innerText );
+		} );
+
+		if( slide ) {
+			return this.Reveal.getIndices( slide );
+		}
+		else {
+			return null;
+		}
+
+	}
+
+	/**
+	 * Reverts back to the slide we were on when jump to slide was
+	 * invoked.
+	 */
+	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( event ) {
+
+		if( event.keyCode === 13 ) {
+			this.confirm();
+		}
+		else if( event.keyCode === 27 ) {
+			this.cancel();
+
+			event.stopImmediatePropagation();
+		}
+
+	}
+
+	onInput( event ) {
+
+		this.jumpAfter( 200 );
+
+	}
+
+	onBlur() {
+
+		setTimeout( () => this.hide(), 1 );
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/controllers/keyboard.js b/inst/reveal.js-5.2.1/js/controllers/keyboard.js
new file mode 100644
index 0000000..f09cd93
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/keyboard.js
@@ -0,0 +1,408 @@
+import { enterFullscreen } from '../utils/util.js'
+
+/**
+ * Handles all reveal.js keyboard interactions.
+ */
+export default class Keyboard {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		// A key:value map of keyboard keys and descriptions of
+		// the actions they trigger
+		this.shortcuts = {};
+
+		// Holds custom key code mappings
+		this.bindings = {};
+
+		this.onDocumentKeyDown = this.onDocumentKeyDown.bind( this );
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		if( config.navigationMode === 'linear' ) {
+			this.shortcuts['&#8594;  ,  &#8595;  ,  SPACE  ,  N  ,  L  ,  J'] = 'Next slide';
+			this.shortcuts['&#8592;  ,  &#8593;  ,  P  ,  H  ,  K']           = 'Previous slide';
+		}
+		else {
+			this.shortcuts['N  ,  SPACE']   = 'Next slide';
+			this.shortcuts['P  ,  Shift SPACE']             = 'Previous slide';
+			this.shortcuts['&#8592;  ,  H'] = 'Navigate left';
+			this.shortcuts['&#8594;  ,  L'] = 'Navigate right';
+			this.shortcuts['&#8593;  ,  K'] = 'Navigate up';
+			this.shortcuts['&#8595;  ,  J'] = 'Navigate down';
+		}
+
+		this.shortcuts['Alt + &#8592;/&#8593/&#8594;/&#8595;']        = 'Navigate without fragments';
+		this.shortcuts['Shift + &#8592;/&#8593/&#8594;/&#8595;']      = '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';
+
+	}
+
+	/**
+	 * Starts listening for keyboard events.
+	 */
+	bind() {
+
+		document.addEventListener( 'keydown', this.onDocumentKeyDown, false );
+
+	}
+
+	/**
+	 * Stops listening for keyboard events.
+	 */
+	unbind() {
+
+		document.removeEventListener( 'keydown', this.onDocumentKeyDown, false );
+
+	}
+
+	/**
+	 * Add a custom key binding with optional description to
+	 * be added to the help screen.
+	 */
+	addKeyBinding( binding, callback ) {
+
+		if( typeof binding === 'object' && binding.keyCode ) {
+			this.bindings[binding.keyCode] = {
+				callback: callback,
+				key: binding.key,
+				description: binding.description
+			};
+		}
+		else {
+			this.bindings[binding] = {
+				callback: callback,
+				key: null,
+				description: null
+			};
+		}
+
+	}
+
+	/**
+	 * Removes the specified custom key binding.
+	 */
+	removeKeyBinding( keyCode ) {
+
+		delete this.bindings[keyCode];
+
+	}
+
+	/**
+	 * Programmatically triggers a keyboard event
+	 *
+	 * @param {int} keyCode
+	 */
+	triggerKey( keyCode ) {
+
+		this.onDocumentKeyDown( { keyCode } );
+
+	}
+
+	/**
+	 * Registers a new shortcut to include in the help overlay
+	 *
+	 * @param {String} key
+	 * @param {String} value
+	 */
+	registerKeyboardShortcut( key, value ) {
+
+		this.shortcuts[key] = value;
+
+	}
+
+	getShortcuts() {
+
+		return this.shortcuts;
+
+	}
+
+	getBindings() {
+
+		return this.bindings;
+
+	}
+
+	/**
+	 * Handler for the document level 'keydown' event.
+	 *
+	 * @param {object} event
+	 */
+	onDocumentKeyDown( event ) {
+
+		let config = this.Reveal.getConfig();
+
+		// If there's a condition specified and it returns false,
+		// ignore this event
+		if( typeof config.keyboardCondition === 'function' && config.keyboardCondition(event) === false ) {
+			return true;
+		}
+
+		// If keyboardCondition is set, only capture keyboard events
+		// for embedded decks when they are focused
+		if( config.keyboardCondition === 'focused' && !this.Reveal.isFocused() ) {
+			return true;
+		}
+
+		// Shorthand
+		let keyCode = event.keyCode;
+
+		// Remember if auto-sliding was paused so we can toggle it
+		let autoSlideWasPaused = !this.Reveal.isAutoSliding();
+
+		this.Reveal.onUserInput( event );
+
+		// Is there a focused element that could be using the keyboard?
+		let activeElementIsCE = document.activeElement && document.activeElement.isContentEditable === true;
+		let activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName );
+		let activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className);
+
+		// Whitelist certain modifiers for slide navigation shortcuts
+		let keyCodeUsesModifier = [32, 37, 38, 39, 40, 63, 78, 80, 191].indexOf( event.keyCode ) !== -1;
+
+		// Prevent all other events when a modifier is pressed
+		let unusedModifier = 	!( keyCodeUsesModifier && event.shiftKey || event.altKey ) &&
+								( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey );
+
+		// Disregard the event if there's a focused element or a
+		// keyboard modifier key is present
+		if( activeElementIsCE || activeElementIsInput || activeElementIsNotes || unusedModifier ) return;
+
+		// While paused only allow resume keyboard events; 'b', 'v', '.'
+		let resumeKeyCodes = [66,86,190,191,112];
+		let key;
+
+		// Custom key bindings for togglePause should be able to resume
+		if( typeof config.keyboard === 'object' ) {
+			for( key in config.keyboard ) {
+				if( config.keyboard[key] === 'togglePause' ) {
+					resumeKeyCodes.push( parseInt( key, 10 ) );
+				}
+			}
+		}
+
+		if( this.Reveal.isOverlayOpen() && !["Escape", "f", "c", "b", "."].includes(event.key) ) {
+			return false;
+		}
+
+		if( this.Reveal.isPaused() && resumeKeyCodes.indexOf( keyCode ) === -1 ) {
+			return false;
+		}
+
+		// Use linear navigation if we're configured to OR if
+		// the presentation is one-dimensional
+		let useLinearMode = config.navigationMode === 'linear' || !this.Reveal.hasHorizontalSlides() || !this.Reveal.hasVerticalSlides();
+
+		let triggered = false;
+
+		// 1. User defined key bindings
+		if( typeof config.keyboard === 'object' ) {
+
+			for( key in config.keyboard ) {
+
+				// Check if this binding matches the pressed key
+				if( parseInt( key, 10 ) === keyCode ) {
+
+					let value = config.keyboard[ key ];
+
+					// Callback function
+					if( typeof value === 'function' ) {
+						value.apply( null, [ event ] );
+					}
+					// String shortcuts to reveal.js API
+					else if( typeof value === 'string' && typeof this.Reveal[ value ] === 'function' ) {
+						this.Reveal[ value ].call();
+					}
+
+					triggered = true;
+
+				}
+
+			}
+
+		}
+
+		// 2. Registered custom key bindings
+		if( triggered === false ) {
+
+			for( key in this.bindings ) {
+
+				// Check if this binding matches the pressed key
+				if( parseInt( key, 10 ) === keyCode ) {
+
+					let action = this.bindings[ key ].callback;
+
+					// Callback function
+					if( typeof action === 'function' ) {
+						action.apply( null, [ event ] );
+					}
+					// String shortcuts to reveal.js API
+					else if( typeof action === 'string' && typeof this.Reveal[ action ] === 'function' ) {
+						this.Reveal[ action ].call();
+					}
+
+					triggered = true;
+				}
+			}
+		}
+
+		// 3. System defined key bindings
+		if( triggered === false ) {
+
+			// Assume true and try to prove false
+			triggered = true;
+
+			// P, PAGE UP
+			if( keyCode === 80 || keyCode === 33 ) {
+				this.Reveal.prev({skipFragments: event.altKey});
+			}
+			// N, PAGE DOWN
+			else if( keyCode === 78 || keyCode === 34 ) {
+				this.Reveal.next({skipFragments: event.altKey});
+			}
+			// H, LEFT
+			else if( keyCode === 72 || keyCode === 37 ) {
+				if( event.shiftKey ) {
+					this.Reveal.slide( 0 );
+				}
+				else if( !this.Reveal.overview.isActive() && useLinearMode ) {
+					if( config.rtl ) {
+						this.Reveal.next({skipFragments: event.altKey});
+					}
+					else {
+						this.Reveal.prev({skipFragments: event.altKey});
+					}
+				}
+				else {
+					this.Reveal.left({skipFragments: event.altKey});
+				}
+			}
+			// L, RIGHT
+			else if( keyCode === 76 || keyCode === 39 ) {
+				if( event.shiftKey ) {
+					this.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 );
+				}
+				else if( !this.Reveal.overview.isActive() && useLinearMode ) {
+					if( config.rtl ) {
+						this.Reveal.prev({skipFragments: event.altKey});
+					}
+					else {
+						this.Reveal.next({skipFragments: event.altKey});
+					}
+				}
+				else {
+					this.Reveal.right({skipFragments: event.altKey});
+				}
+			}
+			// K, UP
+			else if( keyCode === 75 || keyCode === 38 ) {
+				if( event.shiftKey ) {
+					this.Reveal.slide( undefined, 0 );
+				}
+				else if( !this.Reveal.overview.isActive() && useLinearMode ) {
+					this.Reveal.prev({skipFragments: event.altKey});
+				}
+				else {
+					this.Reveal.up({skipFragments: event.altKey});
+				}
+			}
+			// J, DOWN
+			else if( keyCode === 74 || keyCode === 40 ) {
+				if( event.shiftKey ) {
+					this.Reveal.slide( undefined, Number.MAX_VALUE );
+				}
+				else if( !this.Reveal.overview.isActive() && useLinearMode ) {
+					this.Reveal.next({skipFragments: event.altKey});
+				}
+				else {
+					this.Reveal.down({skipFragments: event.altKey});
+				}
+			}
+			// HOME
+			else if( keyCode === 36 ) {
+				this.Reveal.slide( 0 );
+			}
+			// END
+			else if( keyCode === 35 ) {
+				this.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 );
+			}
+			// SPACE
+			else if( keyCode === 32 ) {
+				if( this.Reveal.overview.isActive() ) {
+					this.Reveal.overview.deactivate();
+				}
+				if( event.shiftKey ) {
+					this.Reveal.prev({skipFragments: event.altKey});
+				}
+				else {
+					this.Reveal.next({skipFragments: event.altKey});
+				}
+			}
+			// TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS "BLACK SCREEN" BUTTON
+			else if( [58, 59, 66, 86, 190].includes( keyCode ) || ( keyCode === 191 && !event.shiftKey ) ) {
+				this.Reveal.togglePause();
+			}
+			// F
+			else if( keyCode === 70 ) {
+				enterFullscreen( config.embedded ? this.Reveal.getViewportElement() : document.documentElement );
+			}
+			// A
+			else if( keyCode === 65 ) {
+				if( config.autoSlideStoppable ) {
+					this.Reveal.toggleAutoSlide( autoSlideWasPaused );
+				}
+			}
+			// G
+			else if( keyCode === 71 ) {
+				if( config.jumpToSlide ) {
+					this.Reveal.toggleJumpToSlide();
+				}
+			}
+			// C
+			else if( keyCode === 67 && this.Reveal.isOverlayOpen() ) {
+				this.Reveal.closeOverlay();
+			}
+			// ?
+			else if( ( keyCode === 63 || keyCode === 191 ) && event.shiftKey ) {
+				this.Reveal.toggleHelp();
+			}
+			// F1
+			else if( keyCode === 112 ) {
+				this.Reveal.toggleHelp();
+			}
+			else {
+				triggered = false;
+			}
+
+		}
+
+		// If the input resulted in a triggered action we should prevent
+		// the browsers default behavior
+		if( triggered ) {
+			event.preventDefault && event.preventDefault();
+		}
+		// ESC or O key
+		else if( keyCode === 27 || keyCode === 79 ) {
+			if( this.Reveal.closeOverlay() === false ) {
+				this.Reveal.overview.toggle();
+			}
+
+			event.preventDefault && event.preventDefault();
+		}
+
+		// If auto-sliding is enabled we need to cue up
+		// another timeout
+		this.Reveal.cueAutoSlide();
+
+	}
+
+}
diff --git a/inst/reveal.js-5.2.1/js/controllers/location.js b/inst/reveal.js-5.2.1/js/controllers/location.js
new file mode 100644
index 0000000..2299d47
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/location.js
@@ -0,0 +1,247 @@
+/**
+ * Reads and writes the URL based on reveal.js' current state.
+ */
+export default class Location {
+
+	// The minimum number of milliseconds that must pass between
+	// calls to history.replaceState
+	MAX_REPLACE_STATE_FREQUENCY = 1000
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		// Delays updates to the URL due to a Chrome thumbnailer bug
+		this.writeURLTimeout = 0;
+
+		this.replaceStateTimestamp = 0;
+
+		this.onWindowHashChange = this.onWindowHashChange.bind( this );
+
+	}
+
+	bind() {
+
+		window.addEventListener( 'hashchange', this.onWindowHashChange, false );
+
+	}
+
+	unbind() {
+
+		window.removeEventListener( 'hashchange', this.onWindowHashChange, false );
+
+	}
+
+	/**
+	 * Returns the slide indices for the given hash link.
+	 *
+	 * @param {string} [hash] the hash string that we want to
+	 * find the indices for
+	 *
+	 * @returns slide indices or null
+	 */
+	getIndicesFromHash( hash=window.location.hash, options={} ) {
+
+		// Attempt to parse the hash as either an index or name
+		let name = hash.replace( /^#\/?/, '' );
+		let bits = name.split( '/' );
+
+		// If the first bit is not fully numeric and there is a name we
+		// can assume that this is a named link
+		if( !/^[0-9]*$/.test( bits[0] ) && name.length ) {
+			let slide;
+
+			let f;
+
+			// Parse named links with fragments (#/named-link/2)
+			if( /\/[-\d]+$/g.test( name ) ) {
+				f = parseInt( name.split( '/' ).pop(), 10 );
+				f = isNaN(f) ? undefined : f;
+				name = name.split( '/' ).shift();
+			}
+
+			// Ensure the named link is a valid HTML ID attribute
+			try {
+				slide = document
+					.getElementById( decodeURIComponent( name ) )
+					.closest('.slides section');
+			}
+			catch ( error ) { }
+
+			if( slide ) {
+				return { ...this.Reveal.getIndices( slide ), f };
+			}
+		}
+		else {
+			const config = this.Reveal.getConfig();
+			let hashIndexBase = config.hashOneBasedIndex || options.oneBasedIndex ? 1 : 0;
+
+			// Read the index components of the hash
+			let h = ( parseInt( bits[0], 10 ) - hashIndexBase ) || 0,
+				v = ( parseInt( bits[1], 10 ) - hashIndexBase ) || 0,
+				f;
+
+			if( config.fragmentInURL ) {
+				f = parseInt( bits[2], 10 );
+				if( isNaN( f ) ) {
+					f = undefined;
+				}
+			}
+
+			return { h, v, f };
+		}
+
+		// The hash couldn't be parsed or no matching named link was found
+		return null
+
+	}
+
+	/**
+	 * Reads the current URL (hash) and navigates accordingly.
+	 */
+	readURL() {
+
+		const currentIndices = this.Reveal.getIndices();
+		const newIndices = this.getIndicesFromHash();
+
+		if( newIndices ) {
+			if( ( newIndices.h !== currentIndices.h || newIndices.v !== currentIndices.v || newIndices.f !== undefined ) ) {
+					this.Reveal.slide( newIndices.h, newIndices.v, newIndices.f );
+			}
+		}
+		// If no new indices are available, we're trying to navigate to
+		// a slide hash that does not exist
+		else {
+			this.Reveal.slide( currentIndices.h || 0, currentIndices.v || 0 );
+		}
+
+	}
+
+	/**
+	 * Updates the page URL (hash) to reflect the current
+	 * state.
+	 *
+	 * @param {number} delay The time in ms to wait before
+	 * writing the hash
+	 */
+	writeURL( delay ) {
+
+		let config = this.Reveal.getConfig();
+		let currentSlide = this.Reveal.getCurrentSlide();
+
+		// Make sure there's never more than one timeout running
+		clearTimeout( this.writeURLTimeout );
+
+		// If a delay is specified, timeout this call
+		if( typeof delay === 'number' ) {
+			this.writeURLTimeout = setTimeout( this.writeURL, delay );
+		}
+		else if( currentSlide ) {
+
+			let hash = this.getHash();
+
+			// If we're configured to push to history OR the history
+			// API is not available.
+			if( config.history ) {
+				window.location.hash = hash;
+			}
+			// If we're configured to reflect the current slide in the
+			// URL without pushing to history.
+			else if( config.hash ) {
+				// If the hash is empty, don't add it to the URL
+				if( hash === '/' ) {
+					this.debouncedReplaceState( window.location.pathname + window.location.search );
+				}
+				else {
+					this.debouncedReplaceState( '#' + hash );
+				}
+			}
+			// UPDATE: The below nuking of all hash changes breaks
+			// anchors on pages where reveal.js is running. Removed
+			// in 4.0. Why was it here in the first place? ¯\_(ツ)_/¯
+			//
+			// If history and hash are both disabled, a hash may still
+			// be added to the URL by clicking on a href with a hash
+			// target. Counter this by always removing the hash.
+			// else {
+			// 	window.history.replaceState( null, null, window.location.pathname + window.location.search );
+			// }
+
+		}
+
+	}
+
+	replaceState( url ) {
+
+		window.history.replaceState( null, null, url );
+		this.replaceStateTimestamp = Date.now();
+
+	}
+
+	debouncedReplaceState( url ) {
+
+		clearTimeout( this.replaceStateTimeout );
+
+		if( Date.now() - this.replaceStateTimestamp > this.MAX_REPLACE_STATE_FREQUENCY ) {
+			this.replaceState( url );
+		}
+		else {
+			this.replaceStateTimeout = setTimeout( () => this.replaceState( url ), this.MAX_REPLACE_STATE_FREQUENCY );
+		}
+
+	}
+
+	/**
+	 * Return a hash URL that will resolve to the given slide location.
+	 *
+	 * @param {HTMLElement} [slide=currentSlide] The slide to link to
+	 */
+	getHash( slide ) {
+
+		let url = '/';
+
+		// Attempt to create a named link based on the slide's ID
+		let s = slide || this.Reveal.getCurrentSlide();
+		let id = s ? s.getAttribute( 'id' ) : null;
+		if( id ) {
+			id = encodeURIComponent( id );
+		}
+
+		let index = this.Reveal.getIndices( slide );
+		if( !this.Reveal.getConfig().fragmentInURL ) {
+			index.f = undefined;
+		}
+
+		// If the current slide has an ID, use that as a named link,
+		// but we don't support named links with a fragment index
+		if( typeof id === 'string' && id.length ) {
+			url = '/' + id;
+
+			// If there is also a fragment, append that at the end
+			// of the named link, like: #/named-link/2
+			if( index.f >= 0 ) url += '/' + index.f;
+		}
+		// Otherwise use the /h/v index
+		else {
+			let hashIndexBase = this.Reveal.getConfig().hashOneBasedIndex ? 1 : 0;
+			if( index.h > 0 || index.v > 0 || index.f >= 0 ) url += index.h + hashIndexBase;
+			if( index.v > 0 || index.f >= 0 ) url += '/' + (index.v + hashIndexBase );
+			if( index.f >= 0 ) url += '/' + index.f;
+		}
+
+		return url;
+
+	}
+
+	/**
+	 * Handler for the window level 'hashchange' event.
+	 *
+	 * @param {object} [event]
+	 */
+	onWindowHashChange( event ) {
+
+		this.readURL();
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/controllers/notes.js b/inst/reveal.js-5.2.1/js/controllers/notes.js
new file mode 100644
index 0000000..8af918c
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/notes.js
@@ -0,0 +1,126 @@
+/**
+ * Handles the showing of speaker notes
+ */
+export default class Notes {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+	}
+
+	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 );
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		if( config.showNotes ) {
+			this.element.setAttribute( 'data-layout', typeof config.showNotes === 'string' ? config.showNotes : 'inline' );
+		}
+
+	}
+
+	/**
+	 * Pick up notes from the current slide and display them
+	 * to the viewer.
+	 *
+	 * @see {@link config.showNotes}
+	 */
+	update() {
+
+		if( this.Reveal.getConfig().showNotes &&
+			this.element && this.Reveal.getCurrentSlide() &&
+			!this.Reveal.isScrollView() &&
+			!this.Reveal.isPrintView()
+		) {
+			this.element.innerHTML = this.getSlideNotes() || '<span class="notes-placeholder">No notes on this slide.</span>';
+		}
+
+	}
+
+	/**
+	 * Updates the visibility of the speaker notes sidebar that
+	 * is used to share annotated slides. The notes sidebar is
+	 * only visible if showNotes is true and there are notes on
+	 * one or more slides in the deck.
+	 */
+	updateVisibility() {
+
+		if( this.Reveal.getConfig().showNotes &&
+			this.hasNotes() &&
+			!this.Reveal.isScrollView() &&
+			!this.Reveal.isPrintView()
+		) {
+			this.Reveal.getRevealElement().classList.add( 'show-notes' );
+		}
+		else {
+			this.Reveal.getRevealElement().classList.remove( 'show-notes' );
+		}
+
+	}
+
+	/**
+	 * Checks if there are speaker notes for ANY slide in the
+	 * presentation.
+	 */
+	hasNotes() {
+
+		return this.Reveal.getSlidesElement().querySelectorAll( '[data-notes], aside.notes' ).length > 0;
+
+	}
+
+	/**
+	 * Checks if this presentation is running inside of the
+	 * speaker notes window.
+	 *
+	 * @return {boolean}
+	 */
+	isSpeakerNotesWindow() {
+
+		return !!window.location.search.match( /receiver/gi );
+
+	}
+
+	/**
+	 * Retrieves the speaker notes from a slide. Notes can be
+	 * defined in two ways:
+	 * 1. As a data-notes attribute on the slide <section>
+	 * 2. With <aside class="notes"> elements inside the slide
+	 *
+	 * @param {HTMLElement} [slide=currentSlide]
+	 * @return {(string|null)}
+	 */
+	getSlideNotes( slide = this.Reveal.getCurrentSlide() ) {
+
+		// Notes can be specified via the data-notes attribute...
+		if( slide.hasAttribute( 'data-notes' ) ) {
+			return slide.getAttribute( 'data-notes' );
+		}
+
+		// ... or using <aside class="notes"> elements
+		let notesElements = slide.querySelectorAll( 'aside.notes' );
+		if( notesElements ) {
+			return Array.from(notesElements).map( notesElement => notesElement.innerHTML ).join( '\n' );
+		}
+
+		return null;
+
+	}
+
+	destroy() {
+
+		this.element.remove();
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/controllers/overlay.js b/inst/reveal.js-5.2.1/js/controllers/overlay.js
new file mode 100644
index 0000000..e56321c
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/overlay.js
@@ -0,0 +1,389 @@
+/**
+ * Handles the display of reveal.js' overlay elements used
+ * to preview iframes, images & videos.
+ */
+export default class Overlay {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		this.onSlidesClicked = this.onSlidesClicked.bind( this );
+
+		this.iframeTriggerSelector = null;
+		this.mediaTriggerSelector = '[data-preview-image], [data-preview-video]';
+
+		this.stateProps = ['previewIframe', 'previewImage', 'previewVideo', 'previewFit'];
+		this.state = {};
+
+	}
+
+	update() {
+
+		// Enable link previews globally
+		if( this.Reveal.getConfig().previewLinks ) {
+			this.iframeTriggerSelector = 'a[href]:not([data-preview-link=false]), [data-preview-link]:not(a):not([data-preview-link=false])';
+		}
+		// Enable link previews for individual elements
+		else {
+			this.iframeTriggerSelector = '[data-preview-link]:not([data-preview-link=false])';
+		}
+
+		const hasLinkPreviews = this.Reveal.getSlidesElement().querySelectorAll( this.iframeTriggerSelector ).length > 0;
+		const hasMediaPreviews = this.Reveal.getSlidesElement().querySelectorAll( this.mediaTriggerSelector ).length > 0;
+
+		// Only add the listener when there are previewable elements in the slides
+		if( hasLinkPreviews || hasMediaPreviews ) {
+			this.Reveal.getSlidesElement().addEventListener( 'click', this.onSlidesClicked, false );
+		}
+		else {
+			this.Reveal.getSlidesElement().removeEventListener( 'click', this.onSlidesClicked, false );
+		}
+
+	}
+
+	createOverlay( className ) {
+
+		this.dom = document.createElement( 'div' );
+		this.dom.classList.add( 'r-overlay' );
+		this.dom.classList.add( className );
+
+		this.viewport = document.createElement( 'div' );
+		this.viewport.classList.add( 'r-overlay-viewport' );
+
+		this.dom.appendChild( this.viewport );
+		this.Reveal.getRevealElement().appendChild( this.dom );
+
+	}
+
+	/**
+	 * Opens a lightbox that previews the target URL.
+	 *
+	 * @param {string} url - url for lightbox iframe src
+	 */
+	previewIframe( url ) {
+
+		this.close();
+
+		this.state = { previewIframe: url };
+
+		this.createOverlay( 'r-overlay-preview' );
+		this.dom.dataset.state = 'loading';
+
+		this.viewport.innerHTML =
+			`<header class="r-overlay-header">
+				<a class="r-overlay-button r-overlay-external" href="${url}" target="_blank"><span class="icon"></span></a>
+				<button class="r-overlay-button r-overlay-close"><span class="icon"></span></button>
+			</header>
+			<div class="r-overlay-spinner"></div>
+			<div class="r-overlay-content">
+				<iframe src="${url}"></iframe>
+				<small class="r-overlay-content-inner">
+					<span class="r-overlay-error x-frame-error">Unable to load iframe. This is likely due to the site's policy (x-frame-options).</span>
+				</small>
+			</div>`;
+
+		this.dom.querySelector( 'iframe' ).addEventListener( 'load', event => {
+			this.dom.dataset.state = 'loaded';
+		}, false );
+
+		this.dom.querySelector( '.r-overlay-close' ).addEventListener( 'click', event => {
+			this.close();
+			event.preventDefault();
+		}, false );
+
+		this.dom.querySelector( '.r-overlay-external' ).addEventListener( 'click', event => {
+			this.close();
+		}, false );
+
+		this.Reveal.dispatchEvent({ type: 'previewiframe', data: { url } });
+
+	}
+
+	/**
+	 * Opens a lightbox window that provides a larger view of the
+	 * given image/video.
+	 *
+	 * @param {string} url - url to the image/video to preview
+	 * @param {image|video} mediaType
+	 * @param {string} [fitMode] - the fit mode to use for the preview
+	 */
+	previewMedia( url, mediaType, fitMode ) {
+
+		if( mediaType !== 'image' && mediaType !== 'video' ) {
+			console.warn( 'Please specify a valid media type to preview (image|video)' );
+			return;
+		}
+
+		this.close();
+
+		fitMode = fitMode || 'scale-down';
+
+		this.createOverlay( 'r-overlay-preview' );
+		this.dom.dataset.state = 'loading';
+		this.dom.dataset.previewFit = fitMode;
+
+		this.viewport.innerHTML =
+			`<header class="r-overlay-header">
+				<button class="r-overlay-button r-overlay-close">Esc <span class="icon"></span></button>
+			</header>
+			<div class="r-overlay-spinner"></div>
+			<div class="r-overlay-content"></div>`;
+
+		const contentElement = this.dom.querySelector( '.r-overlay-content' );
+
+		if( mediaType === 'image' ) {
+
+			this.state = { previewImage: url, previewFit: fitMode }
+
+			const img = document.createElement( 'img', {} );
+			img.src = url;
+			contentElement.appendChild( img );
+
+			img.addEventListener( 'load', () => {
+				this.dom.dataset.state = 'loaded';
+			}, false );
+
+			img.addEventListener( 'error', () => {
+				this.dom.dataset.state = 'error';
+				contentElement.innerHTML =
+						`<span class="r-overlay-error">Unable to load image.</span>`
+			}, false );
+
+			// Hide image overlays when clicking outside the overlay
+			this.dom.style.cursor = 'zoom-out';
+			this.dom.addEventListener( 'click', ( event ) => {
+				this.close();
+			}, false );
+
+			this.Reveal.dispatchEvent({ type: 'previewimage', data: { url } });
+
+		}
+		else if( mediaType === 'video' ) {
+
+			this.state = { previewVideo: url, previewFit: fitMode }
+
+			const video = document.createElement( 'video' );
+			video.autoplay = this.dom.dataset.previewAutoplay === 'false' ? false : true;
+			video.controls = this.dom.dataset.previewControls === 'false' ? false : true;
+			video.loop = this.dom.dataset.previewLoop === 'true' ? true : false;
+			video.muted = this.dom.dataset.previewMuted === 'true' ? true : false;
+			video.playsInline = true;
+			video.src = url;
+			contentElement.appendChild( video );
+
+			video.addEventListener( 'loadeddata', () => {
+				this.dom.dataset.state = 'loaded';
+			}, false );
+
+			video.addEventListener( 'error', () => {
+				this.dom.dataset.state = 'error';
+				contentElement.innerHTML =
+					`<span class="r-overlay-error">Unable to load video.</span>`;
+			}, false );
+
+			this.Reveal.dispatchEvent({ type: 'previewvideo', data: { url } });
+
+		}
+		else {
+			throw new Error( 'Please specify a valid media type to preview' );
+		}
+
+		this.dom.querySelector( '.r-overlay-close' ).addEventListener( 'click', ( event ) => {
+			this.close();
+			event.preventDefault();
+		}, false );
+
+	}
+
+	previewImage( url, fitMode ) {
+
+		this.previewMedia( url, 'image', fitMode );
+
+	}
+
+	previewVideo( url, fitMode ) {
+
+		this.previewMedia( url, 'video', fitMode );
+
+	}
+
+	/**
+	 * Open or close help overlay window.
+	 *
+	 * @param {Boolean} [override] Flag which overrides the
+	 * toggle logic and forcibly sets the desired state. True means
+	 * help is open, false means it's closed.
+	 */
+	toggleHelp( override ) {
+
+		if( typeof override === 'boolean' ) {
+			override ? this.showHelp() : this.close();
+		}
+		else {
+			if( this.dom ) {
+				this.close();
+			}
+			else {
+				this.showHelp();
+			}
+		}
+	}
+
+	/**
+	 * Opens an overlay window with help material.
+	 */
+	showHelp() {
+
+		if( this.Reveal.getConfig().help ) {
+
+			this.close();
+
+			this.createOverlay( 'r-overlay-help' );
+
+			let html = '<p class="title">Keyboard Shortcuts</p>';
+
+			let shortcuts = this.Reveal.keyboard.getShortcuts(),
+				bindings = this.Reveal.keyboard.getBindings();
+
+			html += '<table><th>KEY</th><th>ACTION</th>';
+			for( let key in shortcuts ) {
+				html += `<tr><td>${key}</td><td>${shortcuts[ key ]}</td></tr>`;
+			}
+
+			// Add custom key bindings that have associated descriptions
+			for( let binding in bindings ) {
+				if( bindings[binding].key && bindings[binding].description ) {
+					html += `<tr><td>${bindings[binding].key}</td><td>${bindings[binding].description}</td></tr>`;
+				}
+			}
+
+			html += '</table>';
+
+			this.viewport.innerHTML = `
+				<header class="r-overlay-header">
+					<button class="r-overlay-button r-overlay-close">Esc <span class="icon"></span></button>
+				</header>
+				<div class="r-overlay-content">
+					<div class="r-overlay-help-content">${html}</div>
+				</div>
+			`;
+
+			this.dom.querySelector( '.r-overlay-close' ).addEventListener( 'click', event => {
+				this.close();
+				event.preventDefault();
+			}, false );
+
+			this.Reveal.dispatchEvent({ type: 'showhelp' });
+
+		}
+
+	}
+
+	isOpen() {
+
+		return !!this.dom;
+
+	}
+
+	/**
+	 * Closes any currently open overlay.
+	 */
+	close() {
+
+		if( this.dom ) {
+			this.dom.remove();
+			this.dom = null;
+
+			this.state = {};
+
+			this.Reveal.dispatchEvent({ type: 'closeoverlay' });
+
+			return true;
+		}
+
+		return false;
+
+	}
+
+	getState() {
+
+		return this.state;
+
+	}
+
+	setState( state ) {
+
+		// Ignore the incoming state if none of the preview related
+		// props have changed
+		if( this.stateProps.every( key => this.state[ key ] === state[ key ] ) ) {
+			return;
+		}
+
+		if( state.previewIframe ) {
+			this.previewIframe( state.previewIframe );
+		}
+		else if( state.previewImage ) {
+			this.previewImage( state.previewImage, state.previewFit );
+		}
+		else if( state.previewVideo ) {
+			this.previewVideo( state.previewVideo, state.previewFit );
+		}
+		else {
+			this.close();
+		}
+
+	}
+
+	onSlidesClicked( event ) {
+
+		const target = event.target;
+
+		const linkTarget = target.closest( this.iframeTriggerSelector );
+		const mediaTarget = target.closest( this.mediaTriggerSelector );
+
+		// Was an iframe lightbox trigger clicked?
+		if( linkTarget ) {
+			if( event.metaKey || event.shiftKey || event.altKey ) {
+				// Let the browser handle meta keys naturally so users can cmd+click
+				return;
+			}
+			let url = linkTarget.getAttribute( 'href' ) || linkTarget.getAttribute( 'data-preview-link' );
+			if( url ) {
+				this.previewIframe( url );
+				event.preventDefault();
+			}
+		}
+		// Was a media lightbox trigger clicked?
+		else if( mediaTarget ) {
+			if( mediaTarget.hasAttribute( 'data-preview-image' ) ) {
+				let url = mediaTarget.dataset.previewImage || mediaTarget.getAttribute( 'src' );
+				if( url ) {
+					this.previewImage( url, mediaTarget.dataset.previewFit );
+					event.preventDefault();
+				}
+			}
+			else if( mediaTarget.hasAttribute( 'data-preview-video' ) ) {
+				let url = mediaTarget.dataset.previewVideo || mediaTarget.getAttribute( 'src' );
+				if( !url ) {
+					let source = mediaTarget.querySelector( 'source' );
+					if( source ) {
+						url = source.getAttribute( 'src' );
+					}
+				}
+				if( url ) {
+					this.previewVideo( url, mediaTarget.dataset.previewFit );
+					event.preventDefault();
+				}
+			}
+		}
+
+	}
+
+	destroy() {
+
+		this.close();
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/controllers/overview.js b/inst/reveal.js-5.2.1/js/controllers/overview.js
new file mode 100644
index 0000000..4e146b6
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/overview.js
@@ -0,0 +1,255 @@
+import { SLIDES_SELECTOR } from '../utils/constants.js'
+import { extend, queryAll, transformElement } from '../utils/util.js'
+
+/**
+ * Handles all logic related to the overview mode
+ * (birds-eye view of all slides).
+ */
+export default class Overview {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		this.active = false;
+
+		this.onSlideClicked = this.onSlideClicked.bind( this );
+
+	}
+
+	/**
+	 * Displays the overview of slides (quick nav) by scaling
+	 * down and arranging all slide elements.
+	 */
+	activate() {
+
+		// Only proceed if enabled in config
+		if( this.Reveal.getConfig().overview && !this.Reveal.isScrollView() && !this.isActive() ) {
+
+			this.active = true;
+
+			this.Reveal.getRevealElement().classList.add( 'overview' );
+
+			// Don't auto-slide while in overview mode
+			this.Reveal.cancelAutoSlide();
+
+			// Move the backgrounds element into the slide container to
+			// that the same scaling is applied
+			this.Reveal.getSlidesElement().appendChild( this.Reveal.getBackgroundsElement() );
+
+			// Clicking on an overview slide navigates to it
+			queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ).forEach( slide => {
+				if( !slide.classList.contains( 'stack' ) ) {
+					slide.addEventListener( 'click', this.onSlideClicked, true );
+				}
+			} );
+
+			// Calculate slide sizes
+			const margin = 70;
+			const slideSize = this.Reveal.getComputedSlideSize();
+			this.overviewSlideWidth = slideSize.width + margin;
+			this.overviewSlideHeight = slideSize.height + margin;
+
+			// Reverse in RTL mode
+			if( this.Reveal.getConfig().rtl ) {
+				this.overviewSlideWidth = -this.overviewSlideWidth;
+			}
+
+			this.Reveal.updateSlidesVisibility();
+
+			this.layout();
+			this.update();
+
+			this.Reveal.layout();
+
+			const indices = this.Reveal.getIndices();
+
+			// Notify observers of the overview showing
+			this.Reveal.dispatchEvent({
+				type: 'overviewshown',
+				data: {
+					'indexh': indices.h,
+					'indexv': indices.v,
+					'currentSlide': this.Reveal.getCurrentSlide()
+				}
+			});
+
+		}
+
+	}
+
+	/**
+	 * Uses CSS transforms to position all slides in a grid for
+	 * display inside of the overview mode.
+	 */
+	layout() {
+
+		// Layout slides
+		this.Reveal.getHorizontalSlides().forEach( ( hslide, h ) => {
+			hslide.setAttribute( 'data-index-h', h );
+			transformElement( hslide, 'translate3d(' + ( h * this.overviewSlideWidth ) + 'px, 0, 0)' );
+
+			if( hslide.classList.contains( 'stack' ) ) {
+
+				queryAll( hslide, 'section' ).forEach( ( vslide, v ) => {
+					vslide.setAttribute( 'data-index-h', h );
+					vslide.setAttribute( 'data-index-v', v );
+
+					transformElement( vslide, 'translate3d(0, ' + ( v * this.overviewSlideHeight ) + 'px, 0)' );
+				} );
+
+			}
+		} );
+
+		// Layout slide backgrounds
+		Array.from( this.Reveal.getBackgroundsElement().childNodes ).forEach( ( hbackground, h ) => {
+			transformElement( hbackground, 'translate3d(' + ( h * this.overviewSlideWidth ) + 'px, 0, 0)' );
+
+			queryAll( hbackground, '.slide-background' ).forEach( ( vbackground, v ) => {
+				transformElement( vbackground, 'translate3d(0, ' + ( v * this.overviewSlideHeight ) + 'px, 0)' );
+			} );
+		} );
+
+	}
+
+	/**
+	 * Moves the overview viewport to the current slides.
+	 * Called each time the current slide changes.
+	 */
+	update() {
+
+		const vmin = Math.min( window.innerWidth, window.innerHeight );
+		const scale = Math.max( vmin / 5, 150 ) / vmin;
+		const indices = this.Reveal.getIndices();
+
+		this.Reveal.transformSlides( {
+			overview: [
+				'scale('+ scale +')',
+				'translateX('+ ( -indices.h * this.overviewSlideWidth ) +'px)',
+				'translateY('+ ( -indices.v * this.overviewSlideHeight ) +'px)'
+			].join( ' ' )
+		} );
+
+	}
+
+	/**
+	 * Exits the slide overview and enters the currently
+	 * active slide.
+	 */
+	deactivate() {
+
+		// Only proceed if enabled in config
+		if( this.Reveal.getConfig().overview ) {
+
+			this.active = false;
+
+			this.Reveal.getRevealElement().classList.remove( 'overview' );
+
+			// Temporarily add a class so that transitions can do different things
+			// depending on whether they are exiting/entering overview, or just
+			// moving from slide to slide
+			this.Reveal.getRevealElement().classList.add( 'overview-deactivating' );
+
+			setTimeout( () => {
+				this.Reveal.getRevealElement().classList.remove( 'overview-deactivating' );
+			}, 1 );
+
+			// Move the background element back out
+			this.Reveal.getRevealElement().appendChild( this.Reveal.getBackgroundsElement() );
+
+			// Clean up changes made to slides
+			queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ).forEach( slide => {
+				transformElement( slide, '' );
+
+				slide.removeEventListener( 'click', this.onSlideClicked, true );
+			} );
+
+			// Clean up changes made to backgrounds
+			queryAll( this.Reveal.getBackgroundsElement(), '.slide-background' ).forEach( background => {
+				transformElement( background, '' );
+			} );
+
+			this.Reveal.transformSlides( { overview: '' } );
+
+			const indices = this.Reveal.getIndices();
+
+			this.Reveal.slide( indices.h, indices.v );
+			this.Reveal.layout();
+			this.Reveal.cueAutoSlide();
+
+			// Notify observers of the overview hiding
+			this.Reveal.dispatchEvent({
+				type: 'overviewhidden',
+				data: {
+					'indexh': indices.h,
+					'indexv': indices.v,
+					'currentSlide': this.Reveal.getCurrentSlide()
+				}
+			});
+
+		}
+	}
+
+	/**
+	 * Toggles the slide overview mode on and off.
+	 *
+	 * @param {Boolean} [override] Flag which overrides the
+	 * toggle logic and forcibly sets the desired state. True means
+	 * overview is open, false means it's closed.
+	 */
+	toggle( override ) {
+
+		if( typeof override === 'boolean' ) {
+			override ? this.activate() : this.deactivate();
+		}
+		else {
+			this.isActive() ? this.deactivate() : this.activate();
+		}
+
+	}
+
+	/**
+	 * Checks if the overview is currently active.
+	 *
+	 * @return {Boolean} true if the overview is active,
+	 * false otherwise
+	 */
+	isActive() {
+
+		return this.active;
+
+	}
+
+	/**
+	 * Invoked when a slide is and we're in the overview.
+	 *
+	 * @param {object} event
+	 */
+	onSlideClicked( event ) {
+
+		if( this.isActive() ) {
+			event.preventDefault();
+
+			let element = event.target;
+
+			while( element && !element.nodeName.match( /section/gi ) ) {
+				element = element.parentNode;
+			}
+
+			if( element && !element.classList.contains( 'disabled' ) ) {
+
+				this.deactivate();
+
+				if( element.nodeName.match( /section/gi ) ) {
+					let h = parseInt( element.getAttribute( 'data-index-h' ), 10 ),
+						v = parseInt( element.getAttribute( 'data-index-v' ), 10 );
+
+					this.Reveal.slide( h, v );
+				}
+
+			}
+		}
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/controllers/plugins.js b/inst/reveal.js-5.2.1/js/controllers/plugins.js
new file mode 100644
index 0000000..88f57bf
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/plugins.js
@@ -0,0 +1,254 @@
+import { loadScript } from '../utils/loader.js'
+
+/**
+ * Manages loading and registering of reveal.js plugins.
+ */
+export default class Plugins {
+
+	constructor( reveal ) {
+
+		this.Reveal = reveal;
+
+		// Flags our current state (idle -> loading -> loaded)
+		this.state = 'idle';
+
+		// An id:instance map of currently registered plugins
+		this.registeredPlugins = {};
+
+		this.asyncDependencies = [];
+
+	}
+
+	/**
+	 * Loads reveal.js dependencies, registers and
+	 * initializes plugins.
+	 *
+	 * Plugins are direct references to a reveal.js plugin
+	 * object that we register and initialize after any
+	 * synchronous dependencies have loaded.
+	 *
+	 * Dependencies are defined via the 'dependencies' config
+	 * option and will be loaded prior to starting reveal.js.
+	 * Some dependencies may have an 'async' flag, if so they
+	 * will load after reveal.js has been started up.
+	 */
+	load( plugins, dependencies ) {
+
+		this.state = 'loading';
+
+		plugins.forEach( this.registerPlugin.bind( this ) );
+
+		return new Promise( resolve => {
+
+			let scripts = [],
+				scriptsToLoad = 0;
+
+			dependencies.forEach( s => {
+				// Load if there's no condition or the condition is truthy
+				if( !s.condition || s.condition() ) {
+					if( s.async ) {
+						this.asyncDependencies.push( s );
+					}
+					else {
+						scripts.push( s );
+					}
+				}
+			} );
+
+			if( scripts.length ) {
+				scriptsToLoad = scripts.length;
+
+				const scriptLoadedCallback = (s) => {
+					if( s && typeof s.callback === 'function' ) s.callback();
+
+					if( --scriptsToLoad === 0 ) {
+						this.initPlugins().then( resolve );
+					}
+				};
+
+				// Load synchronous scripts
+				scripts.forEach( s => {
+					if( typeof s.id === 'string' ) {
+						this.registerPlugin( s );
+						scriptLoadedCallback( s );
+					}
+					else if( typeof s.src === 'string' ) {
+						loadScript( s.src, () => scriptLoadedCallback(s) );
+					}
+					else {
+						console.warn( 'Unrecognized plugin format', s );
+						scriptLoadedCallback();
+					}
+				} );
+			}
+			else {
+				this.initPlugins().then( resolve );
+			}
+
+		} );
+
+	}
+
+	/**
+	 * Initializes our plugins and waits for them to be ready
+	 * before proceeding.
+	 */
+	initPlugins() {
+
+		return new Promise( resolve => {
+
+			let pluginValues = Object.values( this.registeredPlugins );
+			let pluginsToInitialize = pluginValues.length;
+
+			// If there are no plugins, skip this step
+			if( pluginsToInitialize === 0 ) {
+				this.loadAsync().then( resolve );
+			}
+			// ... otherwise initialize plugins
+			else {
+
+				let initNextPlugin;
+
+				let afterPlugInitialized = () => {
+					if( --pluginsToInitialize === 0 ) {
+						this.loadAsync().then( resolve );
+					}
+					else {
+						initNextPlugin();
+					}
+				};
+
+				let i = 0;
+
+				// Initialize plugins serially
+				initNextPlugin = () => {
+
+					let plugin = pluginValues[i++];
+
+					// If the plugin has an 'init' method, invoke it
+					if( typeof plugin.init === 'function' ) {
+						let promise = plugin.init( this.Reveal );
+
+						// If the plugin returned a Promise, wait for it
+						if( promise && typeof promise.then === 'function' ) {
+							promise.then( afterPlugInitialized );
+						}
+						else {
+							afterPlugInitialized();
+						}
+					}
+					else {
+						afterPlugInitialized();
+					}
+
+				}
+
+				initNextPlugin();
+
+			}
+
+		} )
+
+	}
+
+	/**
+	 * Loads all async reveal.js dependencies.
+	 */
+	loadAsync() {
+
+		this.state = 'loaded';
+
+		if( this.asyncDependencies.length ) {
+			this.asyncDependencies.forEach( s => {
+				loadScript( s.src, s.callback );
+			} );
+		}
+
+		return Promise.resolve();
+
+	}
+
+	/**
+	 * Registers a new plugin with this reveal.js instance.
+	 *
+	 * reveal.js waits for all registered plugins to initialize
+	 * before considering itself ready, as long as the plugin
+	 * is registered before calling `Reveal.initialize()`.
+	 */
+	registerPlugin( plugin ) {
+
+		// Backwards compatibility to make reveal.js ~3.9.0
+		// plugins work with reveal.js 4.0.0
+		if( arguments.length === 2 && typeof arguments[0] === 'string' ) {
+			plugin = arguments[1];
+			plugin.id = arguments[0];
+		}
+		// Plugin can optionally be a function which we call
+		// to create an instance of the plugin
+		else if( typeof plugin === 'function' ) {
+			plugin = plugin();
+		}
+
+		let id = plugin.id;
+
+		if( typeof id !== 'string' ) {
+			console.warn( 'Unrecognized plugin format; can\'t find plugin.id', plugin );
+		}
+		else if( this.registeredPlugins[id] === undefined ) {
+			this.registeredPlugins[id] = plugin;
+
+			// If a plugin is registered after reveal.js is loaded,
+			// initialize it right away
+			if( this.state === 'loaded' && typeof plugin.init === 'function' ) {
+				plugin.init( this.Reveal );
+			}
+		}
+		else {
+			console.warn( 'reveal.js: "'+ id +'" plugin has already been registered' );
+		}
+
+	}
+
+	/**
+	 * Checks if a specific plugin has been registered.
+	 *
+	 * @param {String} id Unique plugin identifier
+	 */
+	hasPlugin( id ) {
+
+		return !!this.registeredPlugins[id];
+
+	}
+
+	/**
+	 * Returns the specific plugin instance, if a plugin
+	 * with the given ID has been registered.
+	 *
+	 * @param {String} id Unique plugin identifier
+	 */
+	getPlugin( id ) {
+
+		return this.registeredPlugins[id];
+
+	}
+
+	getRegisteredPlugins() {
+
+		return this.registeredPlugins;
+
+	}
+
+	destroy() {
+
+		Object.values( this.registeredPlugins ).forEach( plugin => {
+			if( typeof plugin.destroy === 'function' ) {
+				plugin.destroy();
+			}
+		} );
+
+		this.registeredPlugins = {};
+		this.asyncDependencies = [];
+
+	}
+
+}
diff --git a/inst/reveal.js-5.2.1/js/controllers/pointer.js b/inst/reveal.js-5.2.1/js/controllers/pointer.js
new file mode 100644
index 0000000..1a02762
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/pointer.js
@@ -0,0 +1,126 @@
+/**
+ * Handles hiding of the pointer/cursor when inactive.
+ */
+export default class Pointer {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		// Throttles mouse wheel navigation
+		this.lastMouseWheelStep = 0;
+
+		// Is the mouse pointer currently hidden from view
+		this.cursorHidden = false;
+
+		// Timeout used to determine when the cursor is inactive
+		this.cursorInactiveTimeout = 0;
+
+		this.onDocumentCursorActive = this.onDocumentCursorActive.bind( this );
+		this.onDocumentMouseScroll = this.onDocumentMouseScroll.bind( this );
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		if( config.mouseWheel ) {
+			document.addEventListener( 'wheel', this.onDocumentMouseScroll, false );
+		}
+		else {
+			document.removeEventListener( 'wheel', this.onDocumentMouseScroll, false );
+		}
+
+		// Auto-hide the mouse pointer when its inactive
+		if( config.hideInactiveCursor ) {
+			document.addEventListener( 'mousemove', this.onDocumentCursorActive, false );
+			document.addEventListener( 'mousedown', this.onDocumentCursorActive, false );
+		}
+		else {
+			this.showCursor();
+
+			document.removeEventListener( 'mousemove', this.onDocumentCursorActive, false );
+			document.removeEventListener( 'mousedown', this.onDocumentCursorActive, false );
+		}
+
+	}
+
+	/**
+	 * Shows the mouse pointer after it has been hidden with
+	 * #hideCursor.
+	 */
+	showCursor() {
+
+		if( this.cursorHidden ) {
+			this.cursorHidden = false;
+			this.Reveal.getRevealElement().style.cursor = '';
+		}
+
+	}
+
+	/**
+	 * Hides the mouse pointer when it's on top of the .reveal
+	 * container.
+	 */
+	hideCursor() {
+
+		if( this.cursorHidden === false ) {
+			this.cursorHidden = true;
+			this.Reveal.getRevealElement().style.cursor = 'none';
+		}
+
+	}
+
+	destroy() {
+
+		this.showCursor();
+
+		document.removeEventListener( 'wheel', this.onDocumentMouseScroll, false );
+		document.removeEventListener( 'mousemove', this.onDocumentCursorActive, false );
+		document.removeEventListener( 'mousedown', this.onDocumentCursorActive, false );
+
+	}
+
+	/**
+	 * Called whenever there is mouse input at the document level
+	 * to determine if the cursor is active or not.
+	 *
+	 * @param {object} event
+	 */
+	onDocumentCursorActive( event ) {
+
+		this.showCursor();
+
+		clearTimeout( this.cursorInactiveTimeout );
+
+		this.cursorInactiveTimeout = setTimeout( this.hideCursor.bind( this ), this.Reveal.getConfig().hideCursorTime );
+
+	}
+
+	/**
+	 * Handles mouse wheel scrolling, throttled to avoid skipping
+	 * multiple slides.
+	 *
+	 * @param {object} event
+	 */
+	onDocumentMouseScroll( event ) {
+
+		if( Date.now() - this.lastMouseWheelStep > 1000 ) {
+
+			this.lastMouseWheelStep = Date.now();
+
+			let delta = event.detail || -event.wheelDelta;
+			if( delta > 0 ) {
+				this.Reveal.next();
+			}
+			else if( delta < 0 ) {
+				this.Reveal.prev();
+			}
+
+		}
+
+	}
+
+}
diff --git a/inst/reveal.js-5.2.1/js/controllers/printview.js b/inst/reveal.js-5.2.1/js/controllers/printview.js
new file mode 100644
index 0000000..b335462
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/printview.js
@@ -0,0 +1,239 @@
+import { SLIDES_SELECTOR } from '../utils/constants.js'
+import { queryAll, createStyleSheet } from '../utils/util.js'
+
+/**
+ * Setups up our presentation for printing/exporting to PDF.
+ */
+export default class PrintView {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+	}
+
+	/**
+	 * Configures the presentation for printing to a static
+	 * PDF.
+	 */
+	async activate() {
+
+		const config = this.Reveal.getConfig();
+		const slides = queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR )
+
+		// Compute slide numbers now, before we start duplicating slides
+		const injectPageNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber );
+
+		const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
+
+		// Dimensions of the PDF pages
+		const pageWidth = Math.floor( slideSize.width * ( 1 + config.margin ) ),
+			pageHeight = Math.floor( slideSize.height * ( 1 + config.margin ) );
+
+		// Dimensions of slides within the pages
+		const slideWidth = slideSize.width,
+			slideHeight = slideSize.height;
+
+		await new Promise( requestAnimationFrame );
+
+		// Let the browser know what page size we want to print
+		createStyleSheet( '@page{size:'+ pageWidth +'px '+ pageHeight +'px; margin: 0px;}' );
+
+		// Limit the size of certain elements to the dimensions of the slide
+		createStyleSheet( '.reveal section>img, .reveal section>video, .reveal section>iframe{max-width: '+ slideWidth +'px; max-height:'+ slideHeight +'px}' );
+
+		document.documentElement.classList.add( 'reveal-print', 'print-pdf' );
+		document.body.style.width = pageWidth + 'px';
+		document.body.style.height = pageHeight + 'px';
+
+		const viewportElement = this.Reveal.getViewportElement();
+		let presentationBackground;
+		if( viewportElement ) {
+			const viewportStyles = window.getComputedStyle( viewportElement );
+			if( viewportStyles && viewportStyles.background ) {
+				presentationBackground = viewportStyles.background;
+			}
+		}
+
+		// Make sure stretch elements fit on slide
+		await new Promise( requestAnimationFrame );
+		this.Reveal.layoutSlideContents( slideWidth, slideHeight );
+
+		// Batch scrollHeight access to prevent layout thrashing
+		await new Promise( requestAnimationFrame );
+
+		const slideScrollHeights = slides.map( slide => slide.scrollHeight );
+
+		const pages = [];
+		const pageContainer = slides[0].parentNode;
+		let slideNumber = 1;
+
+		// Slide and slide background layout
+		slides.forEach( function( slide, index ) {
+
+			// Vertical stacks are not centred since their section
+			// children will be
+			if( slide.classList.contains( 'stack' ) === false ) {
+				// Center the slide inside of the page, giving the slide some margin
+				let left = ( pageWidth - slideWidth ) / 2;
+				let top = ( pageHeight - slideHeight ) / 2;
+
+				const contentHeight = slideScrollHeights[ index ];
+				let numberOfPages = Math.max( Math.ceil( contentHeight / pageHeight ), 1 );
+
+				// Adhere to configured pages per slide limit
+				numberOfPages = Math.min( numberOfPages, config.pdfMaxPagesPerSlide );
+
+				// Center slides vertically
+				if( numberOfPages === 1 && config.center || slide.classList.contains( 'center' ) ) {
+					top = Math.max( ( pageHeight - contentHeight ) / 2, 0 );
+				}
+
+				// Wrap the slide in a page element and hide its overflow
+				// so that no page ever flows onto another
+				const page = document.createElement( 'div' );
+				pages.push( page );
+
+				page.className = 'pdf-page';
+				page.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px';
+
+				// Copy the presentation-wide background to each individual
+				// page when printing
+				if( presentationBackground ) {
+					page.style.background = presentationBackground;
+				}
+
+				page.appendChild( slide );
+
+				// Position the slide inside of the page
+				slide.style.left = left + 'px';
+				slide.style.top = top + 'px';
+				slide.style.width = slideWidth + 'px';
+
+				this.Reveal.slideContent.layout( slide );
+
+				if( slide.slideBackgroundElement ) {
+					page.insertBefore( slide.slideBackgroundElement, slide );
+				}
+
+				// Inject notes if `showNotes` is enabled
+				if( config.showNotes ) {
+
+					// Are there notes for this slide?
+					const notes = this.Reveal.getSlideNotes( slide );
+					if( notes ) {
+
+						const notesSpacing = 8;
+						const notesLayout = typeof config.showNotes === 'string' ? config.showNotes : 'inline';
+						const notesElement = document.createElement( 'div' );
+						notesElement.classList.add( 'speaker-notes' );
+						notesElement.classList.add( 'speaker-notes-pdf' );
+						notesElement.setAttribute( 'data-layout', notesLayout );
+						notesElement.innerHTML = notes;
+
+						if( notesLayout === 'separate-page' ) {
+							pages.push( notesElement );
+						}
+						else {
+							notesElement.style.left = notesSpacing + 'px';
+							notesElement.style.bottom = notesSpacing + 'px';
+							notesElement.style.width = ( pageWidth - notesSpacing*2 ) + 'px';
+							page.appendChild( notesElement );
+						}
+
+					}
+
+				}
+
+				// Inject page numbers if `slideNumbers` are enabled
+				if( injectPageNumbers ) {
+					const numberElement = document.createElement( 'div' );
+					numberElement.classList.add( 'slide-number' );
+					numberElement.classList.add( 'slide-number-pdf' );
+					numberElement.innerHTML = slideNumber++;
+					page.appendChild( numberElement );
+				}
+
+				// Copy page and show fragments one after another
+				if( config.pdfSeparateFragments ) {
+
+					// Each fragment 'group' is an array containing one or more
+					// fragments. Multiple fragments that appear at the same time
+					// are part of the same group.
+					const fragmentGroups = this.Reveal.fragments.sort( page.querySelectorAll( '.fragment' ), true );
+
+					let previousFragmentStep;
+
+					fragmentGroups.forEach( function( fragments, index ) {
+
+						// Remove 'current-fragment' from the previous group
+						if( previousFragmentStep ) {
+							previousFragmentStep.forEach( function( fragment ) {
+								fragment.classList.remove( 'current-fragment' );
+							} );
+						}
+
+						// Show the fragments for the current index
+						fragments.forEach( function( fragment ) {
+							fragment.classList.add( 'visible', 'current-fragment' );
+						}, this );
+
+						// Create a separate page for the current fragment state
+						const clonedPage = page.cloneNode( true );
+
+						// Inject unique page numbers for fragments
+						if( injectPageNumbers ) {
+							const numberElement = clonedPage.querySelector( '.slide-number-pdf' );
+							const fragmentNumber = index + 1;
+							numberElement.innerHTML += '.' + fragmentNumber;
+						}
+
+						pages.push( clonedPage );
+
+						previousFragmentStep = fragments;
+
+					}, this );
+
+					// Reset the first/original page so that all fragments are hidden
+					fragmentGroups.forEach( function( fragments ) {
+						fragments.forEach( function( fragment ) {
+							fragment.classList.remove( 'visible', 'current-fragment' );
+						} );
+					} );
+
+				}
+				// Show all fragments
+				else {
+					queryAll( page, '.fragment:not(.fade-out)' ).forEach( function( fragment ) {
+						fragment.classList.add( 'visible' );
+					} );
+				}
+
+			}
+
+		}, this );
+
+		await new Promise( requestAnimationFrame );
+
+		pages.forEach( page => pageContainer.appendChild( page ) );
+
+		// Re-run JS-based content layout after the slide is added to page DOM
+		this.Reveal.slideContent.layout( this.Reveal.getSlidesElement() );
+
+		// Notify subscribers that the PDF layout is good to go
+		this.Reveal.dispatchEvent({ type: 'pdf-ready' });
+
+		viewportElement.classList.remove( 'loading-scroll-mode' );
+
+	}
+
+	/**
+	 * Checks if the print mode is/should be activated.
+	 */
+	isActive() {
+
+		return this.Reveal.getConfig().view === 'print';
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/controllers/progress.js b/inst/reveal.js-5.2.1/js/controllers/progress.js
new file mode 100644
index 0000000..87e2aaf
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/progress.js
@@ -0,0 +1,110 @@
+/**
+ * Creates a visual progress bar for the presentation.
+ */
+export default class Progress {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		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 );
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		this.element.style.display = config.progress ? 'block' : 'none';
+
+	}
+
+	bind() {
+
+		if( this.Reveal.getConfig().progress && this.element ) {
+			this.element.addEventListener( 'click', this.onProgressClicked, false );
+		}
+
+	}
+
+	unbind() {
+
+		if ( this.Reveal.getConfig().progress && this.element ) {
+			this.element.removeEventListener( 'click', this.onProgressClicked, false );
+		}
+
+	}
+
+	/**
+	 * Updates the progress bar to reflect the current slide.
+	 */
+	update() {
+
+		// Update progress if enabled
+		if( this.Reveal.getConfig().progress && this.bar ) {
+
+			let scale = this.Reveal.getProgress();
+
+			// Don't fill the progress bar if there's only one slide
+			if( this.Reveal.getTotalSlides() < 2 ) {
+				scale = 0;
+			}
+
+			this.bar.style.transform = 'scaleX('+ scale +')';
+
+		}
+
+	}
+
+	getMaxWidth() {
+
+		return this.Reveal.getRevealElement().offsetWidth;
+
+	}
+
+	/**
+	 * Clicking on the progress bar results in a navigation to the
+	 * closest approximate horizontal slide using this equation:
+	 *
+	 * ( clickX / presentationWidth ) * numberOfSlides
+	 *
+	 * @param {object} event
+	 */
+	onProgressClicked( event ) {
+
+		this.Reveal.onUserInput( event );
+
+		event.preventDefault();
+
+		let slides = this.Reveal.getSlides();
+		let slidesTotal = slides.length;
+		let slideIndex = Math.floor( ( event.clientX / this.getMaxWidth() ) * slidesTotal );
+
+		if( this.Reveal.getConfig().rtl ) {
+			slideIndex = slidesTotal - slideIndex;
+		}
+
+		let targetIndices = this.Reveal.getIndices(slides[slideIndex]);
+		this.Reveal.slide( targetIndices.h, targetIndices.v );
+
+	}
+
+	destroy() {
+
+		this.element.remove();
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/controllers/scrollview.js b/inst/reveal.js-5.2.1/js/controllers/scrollview.js
new file mode 100644
index 0000000..1181bb5
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/scrollview.js
@@ -0,0 +1,923 @@
+import { HORIZONTAL_SLIDES_SELECTOR, HORIZONTAL_BACKGROUNDS_SELECTOR } from '../utils/constants.js'
+import { queryAll } from '../utils/util.js'
+
+const HIDE_SCROLLBAR_TIMEOUT = 500;
+const MAX_PROGRESS_SPACING = 4;
+const MIN_PROGRESS_SEGMENT_HEIGHT = 6;
+const MIN_PLAYHEAD_HEIGHT = 8;
+
+/**
+ * The scroll view lets you read a reveal.js presentation
+ * as a linear scrollable page.
+ */
+export default class ScrollView {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		this.active = false;
+		this.activatedCallbacks = [];
+
+		this.onScroll = this.onScroll.bind( this );
+
+	}
+
+	/**
+	 * Activates the scroll view. This rearranges the presentation DOM
+	 * by—among other things—wrapping each slide in a page element.
+	 */
+	activate() {
+
+		if( this.active ) return;
+
+		const stateBeforeActivation = this.Reveal.getState();
+
+		this.active = true;
+
+		// Store the full presentation HTML so that we can restore it
+		// when/if the scroll view is deactivated
+		this.slideHTMLBeforeActivation = this.Reveal.getSlidesElement().innerHTML;
+
+		const horizontalSlides = queryAll( this.Reveal.getRevealElement(), HORIZONTAL_SLIDES_SELECTOR );
+		const horizontalBackgrounds = queryAll( this.Reveal.getRevealElement(), HORIZONTAL_BACKGROUNDS_SELECTOR );
+
+		this.viewportElement.classList.add( 'loading-scroll-mode', 'reveal-scroll' );
+
+		let presentationBackground;
+
+		const viewportStyles = window.getComputedStyle( this.viewportElement );
+		if( viewportStyles && viewportStyles.background ) {
+			presentationBackground = viewportStyles.background;
+		}
+
+		const pageElements = [];
+		const pageContainer = horizontalSlides[0].parentNode;
+
+		let previousSlide;
+
+		// Creates a new page element and appends the given slide/bg
+		// to it.
+		const createPageElement = ( slide, h, v, isVertical ) => {
+
+			let contentContainer;
+
+			// If this slide is part of an auto-animation sequence, we
+			// group it under the same page element as the previous slide
+			if( previousSlide && this.Reveal.shouldAutoAnimateBetween( previousSlide, slide ) ) {
+				contentContainer = document.createElement( 'div' );
+				contentContainer.className = 'scroll-page-content scroll-auto-animate-page';
+				contentContainer.style.display = 'none';
+				previousSlide.closest( '.scroll-page-content' ).parentNode.appendChild( contentContainer );
+			}
+			else {
+				// Wrap the slide in a page element and hide its overflow
+				// so that no page ever flows onto another
+				const page = document.createElement( 'div' );
+				page.className = 'scroll-page';
+				pageElements.push( page );
+
+				// This transfers over the background of the vertical stack containing
+				// the slide if it exists. Otherwise, it uses the presentation-wide
+				// background.
+				if( isVertical && horizontalBackgrounds.length > h ) {
+					const slideBackground = horizontalBackgrounds[h];
+					const pageBackground = window.getComputedStyle( slideBackground );
+
+					if( pageBackground && pageBackground.background ) {
+						page.style.background = pageBackground.background;
+					}
+					else if( presentationBackground ) {
+						page.style.background = presentationBackground;
+					}
+				} else if( presentationBackground ) {
+					page.style.background = presentationBackground;
+				}
+
+				const stickyContainer = document.createElement( 'div' );
+				stickyContainer.className = 'scroll-page-sticky';
+				page.appendChild( stickyContainer );
+
+				contentContainer = document.createElement( 'div' );
+				contentContainer.className = 'scroll-page-content';
+				stickyContainer.appendChild( contentContainer );
+			}
+
+			contentContainer.appendChild( slide );
+
+			slide.classList.remove( 'past', 'future' );
+			slide.setAttribute( 'data-index-h', h );
+			slide.setAttribute( 'data-index-v', v );
+
+			if( slide.slideBackgroundElement ) {
+				slide.slideBackgroundElement.remove( 'past', 'future' );
+				contentContainer.insertBefore( slide.slideBackgroundElement, slide );
+			}
+
+			previousSlide = slide;
+
+		}
+
+		// Slide and slide background layout
+		horizontalSlides.forEach( ( horizontalSlide, h ) => {
+
+			if( this.Reveal.isVerticalStack( horizontalSlide ) ) {
+				horizontalSlide.querySelectorAll( 'section' ).forEach( ( verticalSlide, v ) => {
+					createPageElement( verticalSlide, h, v, true );
+				});
+			}
+			else {
+				createPageElement( horizontalSlide, h, 0 );
+			}
+
+		}, this );
+
+		this.createProgressBar();
+
+		// Remove leftover stacks
+		queryAll( this.Reveal.getRevealElement(), '.stack' ).forEach( stack => stack.remove() );
+
+		// Add our newly created pages to the DOM
+		pageElements.forEach( page => pageContainer.appendChild( page ) );
+
+		// Re-run JS-based content layout after the slide is added to page DOM
+		this.Reveal.slideContent.layout( this.Reveal.getSlidesElement() );
+
+		this.Reveal.layout();
+		this.Reveal.setState( stateBeforeActivation );
+
+		this.activatedCallbacks.forEach( callback => callback() );
+		this.activatedCallbacks = [];
+
+		this.restoreScrollPosition();
+
+		this.viewportElement.classList.remove( 'loading-scroll-mode' );
+		this.viewportElement.addEventListener( 'scroll', this.onScroll, { passive: true } );
+
+	}
+
+	/**
+	 * Deactivates the scroll view and restores the standard slide-based
+	 * presentation.
+	 */
+	deactivate() {
+
+		if( !this.active ) return;
+
+		const stateBeforeDeactivation = this.Reveal.getState();
+
+		this.active = false;
+
+		this.viewportElement.removeEventListener( 'scroll', this.onScroll );
+		this.viewportElement.classList.remove( 'reveal-scroll' );
+
+		this.removeProgressBar();
+
+		this.Reveal.getSlidesElement().innerHTML = this.slideHTMLBeforeActivation;
+		this.Reveal.sync();
+		this.Reveal.setState( stateBeforeDeactivation );
+
+		this.slideHTMLBeforeActivation = null;
+
+	}
+
+	toggle( override ) {
+
+		if( typeof override === 'boolean' ) {
+			override ? this.activate() : this.deactivate();
+		}
+		else {
+			this.isActive() ? this.deactivate() : this.activate();
+		}
+
+	}
+
+	/**
+	 * Checks if the scroll view is currently active.
+	 */
+	isActive() {
+
+		return this.active;
+
+	}
+
+	/**
+	 * Renders the progress bar component.
+	 */
+	createProgressBar() {
+
+		this.progressBar = document.createElement( 'div' );
+		this.progressBar.className = 'scrollbar';
+
+		this.progressBarInner = document.createElement( 'div' );
+		this.progressBarInner.className = 'scrollbar-inner';
+		this.progressBar.appendChild( this.progressBarInner );
+
+		this.progressBarPlayhead = document.createElement( 'div' );
+		this.progressBarPlayhead.className = 'scrollbar-playhead';
+		this.progressBarInner.appendChild( this.progressBarPlayhead );
+
+		this.viewportElement.insertBefore( this.progressBar, this.viewportElement.firstChild );
+
+		const handleDocumentMouseMove	= ( event ) => {
+
+			let progress = ( event.clientY - this.progressBarInner.getBoundingClientRect().top ) / this.progressBarHeight;
+			progress = Math.max( Math.min( progress, 1 ), 0 );
+
+			this.viewportElement.scrollTop = progress * ( this.viewportElement.scrollHeight - this.viewportElement.offsetHeight );
+
+		};
+
+		const handleDocumentMouseUp = ( event ) => {
+
+			this.draggingProgressBar = false;
+			this.showProgressBar();
+
+			document.removeEventListener( 'mousemove', handleDocumentMouseMove );
+			document.removeEventListener( 'mouseup', handleDocumentMouseUp );
+
+		};
+
+		const handleMouseDown = ( event ) => {
+
+			event.preventDefault();
+
+			this.draggingProgressBar = true;
+
+			document.addEventListener( 'mousemove', handleDocumentMouseMove );
+			document.addEventListener( 'mouseup', handleDocumentMouseUp );
+
+			handleDocumentMouseMove( event );
+
+		};
+
+		this.progressBarInner.addEventListener( 'mousedown', handleMouseDown );
+
+	}
+
+	removeProgressBar() {
+
+		if( this.progressBar ) {
+			this.progressBar.remove();
+			this.progressBar = null;
+		}
+
+	}
+
+	layout() {
+
+		if( this.isActive() ) {
+			this.syncPages();
+			this.syncScrollPosition();
+		}
+
+	}
+
+	/**
+	 * Updates our pages to match the latest configuration and
+	 * presentation size.
+	 */
+	syncPages() {
+
+		const config = this.Reveal.getConfig();
+
+		const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
+		const scale = this.Reveal.getScale();
+		const useCompactLayout = config.scrollLayout === 'compact';
+
+		const viewportHeight = this.viewportElement.offsetHeight;
+		const compactHeight = slideSize.height * scale;
+		const pageHeight = useCompactLayout ? compactHeight : viewportHeight;
+
+		// The height that needs to be scrolled between scroll triggers
+		this.scrollTriggerHeight = useCompactLayout ? compactHeight : viewportHeight;
+
+		this.viewportElement.style.setProperty( '--page-height', pageHeight + 'px' );
+		this.viewportElement.style.scrollSnapType = typeof config.scrollSnap === 'string' ? `y ${config.scrollSnap}` : '';
+
+		// This will hold all scroll triggers used to show/hide slides
+		this.slideTriggers = [];
+
+		const pageElements = Array.from( this.Reveal.getRevealElement().querySelectorAll( '.scroll-page' ) );
+
+		this.pages = pageElements.map( pageElement => {
+			const page = this.createPage({
+				pageElement,
+				slideElement: pageElement.querySelector( 'section' ),
+				stickyElement: pageElement.querySelector( '.scroll-page-sticky' ),
+				contentElement: pageElement.querySelector( '.scroll-page-content' ),
+				backgroundElement: pageElement.querySelector( '.slide-background' ),
+				autoAnimateElements: pageElement.querySelectorAll( '.scroll-auto-animate-page' ),
+				autoAnimatePages: []
+			});
+
+			page.pageElement.style.setProperty( '--slide-height', config.center === true ? 'auto' : slideSize.height + 'px' );
+
+			this.slideTriggers.push({
+				page: page,
+				activate: () => this.activatePage( page ),
+				deactivate: () => this.deactivatePage( page )
+			});
+
+			// Create scroll triggers that show/hide fragments
+			this.createFragmentTriggersForPage( page );
+
+			// Create scroll triggers for triggering auto-animate steps
+			if( page.autoAnimateElements.length > 0 ) {
+				this.createAutoAnimateTriggersForPage( page );
+			}
+
+			let totalScrollTriggerCount = Math.max( page.scrollTriggers.length - 1, 0 );
+
+			// Each auto-animate step may include its own scroll triggers
+			// for fragments, ensure we count those as well
+			totalScrollTriggerCount += page.autoAnimatePages.reduce( ( total, page ) => {
+				return total + Math.max( page.scrollTriggers.length - 1, 0 );
+			}, page.autoAnimatePages.length );
+
+			// Clean up from previous renders
+			page.pageElement.querySelectorAll( '.scroll-snap-point' ).forEach( el => el.remove() );
+
+			// Create snap points for all scroll triggers
+			// - Can't be absolute in FF
+			// - Can't be 0-height in Safari
+			// - Can't use snap-align on parent in Safari because then
+			//   inner triggers won't work
+			for( let i = 0; i < totalScrollTriggerCount + 1; i++ ) {
+				const triggerStick = document.createElement( 'div' );
+				triggerStick.className = 'scroll-snap-point';
+				triggerStick.style.height = this.scrollTriggerHeight + 'px';
+				triggerStick.style.scrollSnapAlign = useCompactLayout ? 'center' : 'start';
+				page.pageElement.appendChild( triggerStick );
+
+				if( i === 0 ) {
+					triggerStick.style.marginTop = -this.scrollTriggerHeight + 'px';
+				}
+			}
+
+			// In the compact layout, only slides with scroll triggers cover the
+			// full viewport height. This helps avoid empty gaps before or after
+			// a sticky slide.
+			if( useCompactLayout && page.scrollTriggers.length > 0 ) {
+				page.pageHeight = viewportHeight;
+				page.pageElement.style.setProperty( '--page-height', viewportHeight + 'px' );
+			}
+			else {
+				page.pageHeight = pageHeight;
+				page.pageElement.style.removeProperty( '--page-height' );
+			}
+
+			// Add scroll padding based on how many scroll triggers we have
+			page.scrollPadding = this.scrollTriggerHeight * totalScrollTriggerCount;
+
+			// The total height including scrollable space
+			page.totalHeight = page.pageHeight + page.scrollPadding;
+
+			// This is used to pad the height of our page in CSS
+			page.pageElement.style.setProperty( '--page-scroll-padding', page.scrollPadding + 'px' );
+
+			// If this is a sticky page, stick it to the vertical center
+			if( totalScrollTriggerCount > 0 ) {
+				page.stickyElement.style.position = 'sticky';
+				page.stickyElement.style.top = Math.max( ( viewportHeight - page.pageHeight ) / 2, 0 ) + 'px';
+			}
+			else {
+				page.stickyElement.style.position = 'relative';
+				page.pageElement.style.scrollSnapAlign = page.pageHeight < viewportHeight ? 'center' : 'start';
+			}
+
+			return page;
+		} );
+
+		this.setTriggerRanges();
+
+		/*
+		console.log(this.slideTriggers.map( t => {
+			return {
+				range: `${t.range[0].toFixed(2)}-${t.range[1].toFixed(2)}`,
+				triggers: t.page.scrollTriggers.map( t => {
+					return `${t.range[0].toFixed(2)}-${t.range[1].toFixed(2)}`
+				}).join( ', ' ),
+			}
+		}))
+		*/
+
+		this.viewportElement.setAttribute( 'data-scrollbar', config.scrollProgress );
+
+		if( config.scrollProgress && this.totalScrollTriggerCount > 1 ) {
+			// Create the progress bar if it doesn't already exist
+			if( !this.progressBar ) this.createProgressBar();
+
+			this.syncProgressBar();
+		}
+		else {
+			this.removeProgressBar();
+		}
+
+	}
+
+	/**
+	 * Calculates and sets the scroll range for all of our scroll
+	 * triggers.
+	 */
+	setTriggerRanges() {
+
+		// Calculate the total number of scroll triggers
+		this.totalScrollTriggerCount = this.slideTriggers.reduce( ( total, trigger ) => {
+			return total + Math.max( trigger.page.scrollTriggers.length, 1 );
+		}, 0 );
+
+		let rangeStart = 0;
+
+		// Calculate the scroll range of each scroll trigger on a scale
+		// of 0-1
+		this.slideTriggers.forEach( ( trigger, i ) => {
+			trigger.range = [
+				rangeStart,
+				rangeStart + Math.max( trigger.page.scrollTriggers.length, 1 ) / this.totalScrollTriggerCount
+			];
+
+			const scrollTriggerSegmentSize = ( trigger.range[1] - trigger.range[0] ) / trigger.page.scrollTriggers.length;
+			// Set the range for each inner scroll trigger
+			trigger.page.scrollTriggers.forEach( ( scrollTrigger, i ) => {
+				scrollTrigger.range = [
+					rangeStart + i * scrollTriggerSegmentSize,
+					rangeStart + ( i + 1 ) * scrollTriggerSegmentSize
+				];
+			} );
+
+			rangeStart = trigger.range[1];
+		} );
+
+		// Ensure the last trigger extends to the end of the page, otherwise
+		// rounding errors can cause the last trigger to end at 0.999999...
+		this.slideTriggers[this.slideTriggers.length - 1].range[1] = 1;
+
+	}
+
+	/**
+	 * Creates one scroll trigger for each fragments in the given page.
+	 *
+	 * @param {*} page
+	 */
+	createFragmentTriggersForPage( page, slideElement ) {
+
+		slideElement = slideElement || page.slideElement;
+
+		// Each fragment 'group' is an array containing one or more
+		// fragments. Multiple fragments that appear at the same time
+		// are part of the same group.
+		const fragmentGroups = this.Reveal.fragments.sort( slideElement.querySelectorAll( '.fragment' ), true );
+
+		// Create scroll triggers that show/hide fragments
+		if( fragmentGroups.length ) {
+			page.fragments = this.Reveal.fragments.sort( slideElement.querySelectorAll( '.fragment:not(.disabled)' ) );
+			page.scrollTriggers.push(
+				// Trigger for the initial state with no fragments visible
+				{
+					activate: () => {
+						this.Reveal.fragments.update( -1, page.fragments, slideElement );
+					}
+				}
+			);
+
+			// Triggers for each fragment group
+			fragmentGroups.forEach( ( fragments, i ) => {
+				page.scrollTriggers.push({
+					activate: () => {
+						this.Reveal.fragments.update( i, page.fragments, slideElement );
+					}
+				});
+			} );
+		}
+
+
+		return page.scrollTriggers.length;
+
+	}
+
+	/**
+	 * Creates scroll triggers for the auto-animate steps in the
+	 * given page.
+	 *
+	 * @param {*} page
+	 */
+	createAutoAnimateTriggersForPage( page ) {
+
+		if( page.autoAnimateElements.length > 0 ) {
+
+			// Triggers for each subsequent auto-animate slide
+			this.slideTriggers.push( ...Array.from( page.autoAnimateElements ).map( ( autoAnimateElement, i ) => {
+				let autoAnimatePage = this.createPage({
+					slideElement: autoAnimateElement.querySelector( 'section' ),
+					contentElement: autoAnimateElement,
+					backgroundElement: autoAnimateElement.querySelector( '.slide-background' )
+				});
+
+				// Create fragment scroll triggers for the auto-animate slide
+				this.createFragmentTriggersForPage( autoAnimatePage, autoAnimatePage.slideElement );
+
+				page.autoAnimatePages.push( autoAnimatePage );
+
+				// Return our slide trigger
+				return {
+					page: autoAnimatePage,
+					activate: () => this.activatePage( autoAnimatePage ),
+					deactivate: () => this.deactivatePage( autoAnimatePage )
+				};
+			}));
+		}
+
+	}
+
+	/**
+	 * Helper method for creating a page definition and adding
+	 * required fields. A "page" is a slide or auto-animate step.
+	 */
+	createPage( page ) {
+
+		page.scrollTriggers = [];
+		page.indexh = parseInt( page.slideElement.getAttribute( 'data-index-h' ), 10 );
+		page.indexv = parseInt( page.slideElement.getAttribute( 'data-index-v' ), 10 );
+
+		return page;
+
+	}
+
+	/**
+	 * Rerenders progress bar segments so that they match the current
+	 * reveal.js config and size.
+	 */
+	syncProgressBar() {
+
+		this.progressBarInner.querySelectorAll( '.scrollbar-slide' ).forEach( slide => slide.remove() );
+
+		const scrollHeight = this.viewportElement.scrollHeight;
+		const viewportHeight = this.viewportElement.offsetHeight;
+		const viewportHeightFactor = viewportHeight / scrollHeight;
+
+		this.progressBarHeight = this.progressBarInner.offsetHeight;
+		this.playheadHeight = Math.max( viewportHeightFactor * this.progressBarHeight, MIN_PLAYHEAD_HEIGHT );
+		this.progressBarScrollableHeight = this.progressBarHeight - this.playheadHeight;
+
+		const progressSegmentHeight = viewportHeight / scrollHeight * this.progressBarHeight;
+		const spacing = Math.min( progressSegmentHeight / 8, MAX_PROGRESS_SPACING );
+
+		this.progressBarPlayhead.style.height = this.playheadHeight - spacing + 'px';
+
+		// Don't show individual segments if they're too small
+		if( progressSegmentHeight > MIN_PROGRESS_SEGMENT_HEIGHT ) {
+
+			this.slideTriggers.forEach( slideTrigger => {
+
+				const { page } = slideTrigger;
+
+				// Visual representation of a slide
+				page.progressBarSlide = document.createElement( 'div' );
+				page.progressBarSlide.className = 'scrollbar-slide';
+				page.progressBarSlide.style.top = slideTrigger.range[0] * this.progressBarHeight + 'px';
+				page.progressBarSlide.style.height = ( slideTrigger.range[1] - slideTrigger.range[0] ) * this.progressBarHeight - spacing + 'px';
+				page.progressBarSlide.classList.toggle( 'has-triggers', page.scrollTriggers.length > 0 );
+				this.progressBarInner.appendChild( page.progressBarSlide );
+
+				// Visual representations of each scroll trigger
+				page.scrollTriggerElements = page.scrollTriggers.map( ( trigger, i ) => {
+
+					const triggerElement = document.createElement( 'div' );
+					triggerElement.className = 'scrollbar-trigger';
+					triggerElement.style.top = ( trigger.range[0] - slideTrigger.range[0] ) * this.progressBarHeight + 'px';
+					triggerElement.style.height = ( trigger.range[1] - trigger.range[0] ) * this.progressBarHeight - spacing + 'px';
+					page.progressBarSlide.appendChild( triggerElement );
+
+					if( i === 0 ) triggerElement.style.display = 'none';
+
+					return triggerElement;
+
+				} );
+
+			} );
+
+		}
+		else {
+
+			this.pages.forEach( page => page.progressBarSlide = null );
+
+		}
+
+	}
+
+	/**
+	 * Reads the current scroll position and updates our active
+	 * trigger states accordingly.
+	 */
+	syncScrollPosition() {
+
+		const viewportHeight = this.viewportElement.offsetHeight;
+		const viewportHeightFactor = viewportHeight / this.viewportElement.scrollHeight;
+
+		const scrollTop = this.viewportElement.scrollTop;
+		const scrollHeight = this.viewportElement.scrollHeight - viewportHeight
+		const scrollProgress = Math.max( Math.min( scrollTop / scrollHeight, 1 ), 0 );
+		const scrollProgressMid = Math.max( Math.min( ( scrollTop + viewportHeight / 2 ) / this.viewportElement.scrollHeight, 1 ), 0 );
+
+		let activePage;
+
+		this.slideTriggers.forEach( ( trigger ) => {
+			const { page } = trigger;
+
+			const shouldPreload = scrollProgress >= trigger.range[0] - viewportHeightFactor*2 &&
+														scrollProgress <= trigger.range[1] + viewportHeightFactor*2;
+
+			// Load slides that are within the preload range
+			if( shouldPreload && !page.loaded ) {
+				page.loaded = true;
+				this.Reveal.slideContent.load( page.slideElement );
+			}
+			else if( page.loaded ) {
+				page.loaded = false;
+				this.Reveal.slideContent.unload( page.slideElement );
+			}
+
+			// If we're within this trigger range, activate it
+			if( scrollProgress >= trigger.range[0] && scrollProgress <= trigger.range[1] ) {
+				this.activateTrigger( trigger );
+				activePage = trigger.page;
+			}
+			// .. otherwise deactivate
+			else if( trigger.active ) {
+				this.deactivateTrigger( trigger );
+			}
+		} );
+
+		// Each page can have its own scroll triggers, check if any of those
+		// need to be activated/deactivated
+		if( activePage ) {
+			activePage.scrollTriggers.forEach( ( trigger ) => {
+				if( scrollProgressMid >= trigger.range[0] && scrollProgressMid <= trigger.range[1] ) {
+					this.activateTrigger( trigger );
+				}
+				else if( trigger.active ) {
+					this.deactivateTrigger( trigger );
+				}
+			} );
+		}
+
+		// Update our visual progress indication
+		this.setProgressBarValue( scrollTop / ( this.viewportElement.scrollHeight - viewportHeight ) );
+
+	}
+
+	/**
+	 * Moves the progress bar playhead to the specified position.
+	 *
+	 * @param {number} progress 0-1
+	 */
+	setProgressBarValue( progress ) {
+
+		if( this.progressBar ) {
+
+			this.progressBarPlayhead.style.transform = `translateY(${progress * this.progressBarScrollableHeight}px)`;
+
+			this.getAllPages()
+				.filter( page => page.progressBarSlide )
+				.forEach( ( page ) => {
+					page.progressBarSlide.classList.toggle( 'active', page.active === true );
+
+					page.scrollTriggers.forEach( ( trigger, i ) => {
+						page.scrollTriggerElements[i].classList.toggle( 'active', page.active === true && trigger.active === true );
+					} );
+				} );
+
+			this.showProgressBar();
+
+		}
+
+	}
+
+	/**
+	 * Show the progress bar and, if configured, automatically hide
+	 * it after a delay.
+	 */
+	showProgressBar() {
+
+		this.progressBar.classList.add( 'visible' );
+
+		clearTimeout( this.hideProgressBarTimeout );
+
+		if( this.Reveal.getConfig().scrollProgress === 'auto' && !this.draggingProgressBar ) {
+
+			this.hideProgressBarTimeout = setTimeout( () => {
+				if( this.progressBar ) {
+					this.progressBar.classList.remove( 'visible' );
+				}
+			}, HIDE_SCROLLBAR_TIMEOUT );
+
+		}
+
+	}
+
+	/**
+	 * Scroll to the previous page.
+	 */
+	prev() {
+
+		this.viewportElement.scrollTop -= this.scrollTriggerHeight;
+
+	}
+
+	/**
+	 * Scroll to the next page.
+	 */
+	next() {
+
+		this.viewportElement.scrollTop += this.scrollTriggerHeight;
+
+	}
+
+	/**
+	 * Scrolls the given slide element into view.
+	 *
+	 * @param {HTMLElement} slideElement
+	 */
+	scrollToSlide( slideElement ) {
+
+		// If the scroll view isn't active yet, queue this action
+		if( !this.active ) {
+			this.activatedCallbacks.push( () => this.scrollToSlide( slideElement ) );
+		}
+		else {
+			// Find the trigger for this slide
+			const trigger = this.getScrollTriggerBySlide( slideElement );
+
+			if( trigger ) {
+				// Use the trigger's range to calculate the scroll position
+				this.viewportElement.scrollTop = trigger.range[0] * ( this.viewportElement.scrollHeight - this.viewportElement.offsetHeight );
+			}
+		}
+
+	}
+
+	/**
+	 * Persists the current scroll position to session storage
+	 * so that it can be restored.
+	 */
+	storeScrollPosition() {
+
+		clearTimeout( this.storeScrollPositionTimeout );
+
+		this.storeScrollPositionTimeout = setTimeout( () => {
+			sessionStorage.setItem( 'reveal-scroll-top', this.viewportElement.scrollTop );
+			sessionStorage.setItem( 'reveal-scroll-origin', location.origin + location.pathname );
+
+			this.storeScrollPositionTimeout = null;
+		}, 50 );
+
+	}
+
+	/**
+	 * Restores the scroll position when a deck is reloader.
+	 */
+	restoreScrollPosition() {
+
+		const scrollPosition = sessionStorage.getItem( 'reveal-scroll-top' );
+		const scrollOrigin = sessionStorage.getItem( 'reveal-scroll-origin' );
+
+		if( scrollPosition && scrollOrigin === location.origin + location.pathname ) {
+			this.viewportElement.scrollTop = parseInt( scrollPosition, 10 );
+		}
+
+	}
+
+	/**
+	 * Activates the given page and starts its embedded content
+	 * if there is any.
+	 *
+	 * @param {object} page
+	 */
+	activatePage( page ) {
+
+		if( !page.active ) {
+
+			page.active = true;
+
+			const { slideElement, backgroundElement, contentElement, indexh, indexv } = page;
+
+			contentElement.style.display = 'block';
+
+			slideElement.classList.add( 'present' );
+
+			if( backgroundElement ) {
+				backgroundElement.classList.add( 'present' );
+			}
+
+			this.Reveal.setCurrentScrollPage( slideElement, indexh, indexv );
+			this.Reveal.backgrounds.bubbleSlideContrastClassToElement( slideElement, this.viewportElement );
+
+			// If this page is part of an auto-animation there will be one
+			// content element per auto-animated page. We need to show the
+			// current page and hide all others.
+			Array.from( contentElement.parentNode.querySelectorAll( '.scroll-page-content' ) ).forEach( sibling => {
+				if( sibling !== contentElement ) {
+					sibling.style.display = 'none';
+				}
+			});
+
+		}
+
+	}
+
+	/**
+	 * Deactivates the page after it has been visible.
+	 *
+	 * @param {object} page
+	 */
+	deactivatePage( page ) {
+
+		if( page.active ) {
+
+			page.active = false;
+			if( page.slideElement ) page.slideElement.classList.remove( 'present' );
+			if( page.backgroundElement ) page.backgroundElement.classList.remove( 'present' );
+
+		}
+
+	}
+
+	activateTrigger( trigger ) {
+
+		if( !trigger.active ) {
+			trigger.active = true;
+			trigger.activate();
+		}
+
+	}
+
+	deactivateTrigger( trigger ) {
+
+		if( trigger.active ) {
+			trigger.active = false;
+
+			if( trigger.deactivate ) {
+				trigger.deactivate();
+			}
+		}
+
+	}
+
+	/**
+	 * Retrieve a slide by its original h/v index (i.e. the indices the
+	 * slide had before being linearized).
+	 *
+	 * @param {number} h
+	 * @param {number} v
+	 * @returns {HTMLElement}
+	 */
+	getSlideByIndices( h, v ) {
+
+		const page = this.getAllPages().find( page => {
+			return page.indexh === h && page.indexv === v;
+		} );
+
+		return page ? page.slideElement : null;
+
+	}
+
+	/**
+	 * Retrieve a list of all scroll triggers for the given slide
+	 * DOM element.
+	 *
+	 * @param {HTMLElement} slide
+	 * @returns {Array}
+	 */
+	getScrollTriggerBySlide( slide ) {
+
+		return this.slideTriggers.find( trigger => trigger.page.slideElement === slide );
+
+	}
+
+	/**
+	 * Get a list of all pages in the scroll view. This includes
+	 * both top-level slides and auto-animate steps.
+	 *
+	 * @returns {Array}
+	 */
+	getAllPages() {
+
+		return this.pages.flatMap( page => [page, ...(page.autoAnimatePages || [])] );
+
+	}
+
+	onScroll() {
+
+		this.syncScrollPosition();
+		this.storeScrollPosition();
+
+	}
+
+	get viewportElement() {
+
+		return this.Reveal.getViewportElement();
+
+	}
+
+}
diff --git a/inst/reveal.js-5.2.1/js/controllers/slidecontent.js b/inst/reveal.js-5.2.1/js/controllers/slidecontent.js
new file mode 100644
index 0000000..ae2ffe8
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/slidecontent.js
@@ -0,0 +1,500 @@
+import { extend, queryAll, closest, getMimeTypeFromFile, encodeRFC3986URI } from '../utils/util.js'
+import { isMobile } from '../utils/device.js'
+
+import fitty from 'fitty';
+
+/**
+ * Handles loading, unloading and playback of slide
+ * content such as images, videos and iframes.
+ */
+export default class SlideContent {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		this.startEmbeddedIframe = this.startEmbeddedIframe.bind( this );
+
+	}
+
+	/**
+	 * Should the given element be preloaded?
+	 * Decides based on local element attributes and global config.
+	 *
+	 * @param {HTMLElement} element
+	 */
+	shouldPreload( element ) {
+
+		if( this.Reveal.isScrollView() ) {
+			return true;
+		}
+
+		// Prefer an explicit global preload setting
+		let preload = this.Reveal.getConfig().preloadIframes;
+
+		// If no global setting is available, fall back on the element's
+		// own preload setting
+		if( typeof preload !== 'boolean' ) {
+			preload = element.hasAttribute( 'data-preload' );
+		}
+
+		return preload;
+	}
+
+	/**
+	 * Called when the given slide is within the configured view
+	 * distance. Shows the slide element and loads any content
+	 * that is set to load lazily (data-src).
+	 *
+	 * @param {HTMLElement} slide Slide to show
+	 */
+	load( slide, options = {} ) {
+
+		// Show the slide element
+		slide.style.display = this.Reveal.getConfig().display;
+
+		// Media elements with data-src attributes
+		queryAll( slide, 'img[data-src], video[data-src], audio[data-src], iframe[data-src]' ).forEach( element => {
+			if( element.tagName !== 'IFRAME' || this.shouldPreload( element ) ) {
+				element.setAttribute( 'src', element.getAttribute( 'data-src' ) );
+				element.setAttribute( 'data-lazy-loaded', '' );
+				element.removeAttribute( 'data-src' );
+			}
+		} );
+
+		// Media elements with <source> children
+		queryAll( slide, 'video, audio' ).forEach( media => {
+			let sources = 0;
+
+			queryAll( media, 'source[data-src]' ).forEach( source => {
+				source.setAttribute( 'src', source.getAttribute( 'data-src' ) );
+				source.removeAttribute( 'data-src' );
+				source.setAttribute( 'data-lazy-loaded', '' );
+				sources += 1;
+			} );
+
+			// Enable inline video playback in mobile Safari
+			if( isMobile && media.tagName === 'VIDEO' ) {
+				media.setAttribute( 'playsinline', '' );
+			}
+
+			// If we rewrote sources for this video/audio element, we need
+			// to manually tell it to load from its new origin
+			if( sources > 0 ) {
+				media.load();
+			}
+		} );
+
+
+		// Show the corresponding background element
+		let background = slide.slideBackgroundElement;
+		if( background ) {
+			background.style.display = 'block';
+
+			let backgroundContent = slide.slideBackgroundContentElement;
+			let backgroundIframe = slide.getAttribute( 'data-background-iframe' );
+
+			// If the background contains media, load it
+			if( background.hasAttribute( 'data-loaded' ) === false ) {
+				background.setAttribute( 'data-loaded', 'true' );
+
+				let backgroundImage = slide.getAttribute( 'data-background-image' ),
+					backgroundVideo = slide.getAttribute( 'data-background-video' ),
+					backgroundVideoLoop = slide.hasAttribute( 'data-background-video-loop' ),
+					backgroundVideoMuted = slide.hasAttribute( 'data-background-video-muted' );
+
+				// Images
+				if( backgroundImage ) {
+					// base64
+					if(  /^data:/.test( backgroundImage.trim() ) ) {
+						backgroundContent.style.backgroundImage = `url(${backgroundImage.trim()})`;
+					}
+					// URL(s)
+					else {
+						backgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => {
+							// Decode URL(s) that are already encoded first
+							let decoded = decodeURI(background.trim());
+							return `url(${encodeRFC3986URI(decoded)})`;
+						}).join( ',' );
+					}
+				}
+				// Videos
+				else if ( backgroundVideo ) {
+					let video = document.createElement( 'video' );
+
+					if( backgroundVideoLoop ) {
+						video.setAttribute( 'loop', '' );
+					}
+
+					if( backgroundVideoMuted || this.Reveal.isSpeakerNotes() ) {
+						video.muted = true;
+					}
+
+					// Enable inline playback in mobile Safari
+					//
+					// Mute is required for video to play when using
+					// swipe gestures to navigate since they don't
+					// count as direct user actions :'(
+					if( isMobile ) {
+						video.muted = true;
+						video.setAttribute( 'playsinline', '' );
+					}
+
+					// Support comma separated lists of video sources
+					backgroundVideo.split( ',' ).forEach( source => {
+						const sourceElement = document.createElement( 'source' );
+						sourceElement.setAttribute( 'src', source );
+
+						let type = getMimeTypeFromFile( source );
+						if( type ) {
+							sourceElement.setAttribute( 'type', type );
+						}
+
+						video.appendChild( sourceElement );
+					} );
+
+					backgroundContent.appendChild( video );
+				}
+				// Iframes
+				else if( backgroundIframe && options.excludeIframes !== true ) {
+					let iframe = document.createElement( 'iframe' );
+					iframe.setAttribute( 'allowfullscreen', '' );
+					iframe.setAttribute( 'mozallowfullscreen', '' );
+					iframe.setAttribute( 'webkitallowfullscreen', '' );
+					iframe.setAttribute( 'allow', 'autoplay' );
+
+					iframe.setAttribute( 'data-src', backgroundIframe );
+
+					iframe.style.width  = '100%';
+					iframe.style.height = '100%';
+					iframe.style.maxHeight = '100%';
+					iframe.style.maxWidth = '100%';
+
+					backgroundContent.appendChild( iframe );
+				}
+			}
+
+			// Start loading preloadable iframes
+			let backgroundIframeElement = backgroundContent.querySelector( 'iframe[data-src]' );
+			if( backgroundIframeElement ) {
+
+				// Check if this iframe is eligible to be preloaded
+				if( this.shouldPreload( background ) && !/autoplay=(1|true|yes)/gi.test( backgroundIframe ) ) {
+					if( backgroundIframeElement.getAttribute( 'src' ) !== backgroundIframe ) {
+						backgroundIframeElement.setAttribute( 'src', backgroundIframe );
+					}
+				}
+
+			}
+
+		}
+
+		this.layout( slide );
+
+	}
+
+	/**
+	 * Applies JS-dependent layout helpers for the scope.
+	 */
+	layout( scopeElement ) {
+
+		// Autosize text with the r-fit-text class based on the
+		// size of its container. This needs to happen after the
+		// slide is visible in order to measure the text.
+		Array.from( scopeElement.querySelectorAll( '.r-fit-text' ) ).forEach( element => {
+			fitty( element, {
+				minSize: 24,
+				maxSize: this.Reveal.getConfig().height * 0.8,
+				observeMutations: false,
+				observeWindow: false
+			} );
+		} );
+
+	}
+
+	/**
+	 * Unloads and hides the given slide. This is called when the
+	 * slide is moved outside of the configured view distance.
+	 *
+	 * @param {HTMLElement} slide
+	 */
+	unload( slide ) {
+
+		// Hide the slide element
+		slide.style.display = 'none';
+
+		// Hide the corresponding background element
+		let background = this.Reveal.getSlideBackground( slide );
+		if( background ) {
+			background.style.display = 'none';
+
+			// Unload any background iframes
+			queryAll( background, 'iframe[src]' ).forEach( element => {
+				element.removeAttribute( 'src' );
+			} );
+		}
+
+		// Reset lazy-loaded media elements with src attributes
+		queryAll( slide, 'video[data-lazy-loaded][src], audio[data-lazy-loaded][src], iframe[data-lazy-loaded][src]' ).forEach( element => {
+			element.setAttribute( 'data-src', element.getAttribute( 'src' ) );
+			element.removeAttribute( 'src' );
+		} );
+
+		// Reset lazy-loaded media elements with <source> children
+		queryAll( slide, 'video[data-lazy-loaded] source[src], audio source[src]' ).forEach( source => {
+			source.setAttribute( 'data-src', source.getAttribute( 'src' ) );
+			source.removeAttribute( 'src' );
+		} );
+
+	}
+
+	/**
+	 * Enforces origin-specific format rules for embedded media.
+	 */
+	formatEmbeddedContent() {
+
+		let _appendParamToIframeSource = ( sourceAttribute, sourceURL, param ) => {
+			queryAll( this.Reveal.getSlidesElement(), 'iframe['+ sourceAttribute +'*="'+ sourceURL +'"]' ).forEach( el => {
+				let src = el.getAttribute( sourceAttribute );
+				if( src && src.indexOf( param ) === -1 ) {
+					el.setAttribute( sourceAttribute, src + ( !/\?/.test( src ) ? '?' : '&' ) + param );
+				}
+			});
+		};
+
+		// YouTube frames must include "?enablejsapi=1"
+		_appendParamToIframeSource( 'src', 'youtube.com/embed/', 'enablejsapi=1' );
+		_appendParamToIframeSource( 'data-src', 'youtube.com/embed/', 'enablejsapi=1' );
+
+		// Vimeo frames must include "?api=1"
+		_appendParamToIframeSource( 'src', 'player.vimeo.com/', 'api=1' );
+		_appendParamToIframeSource( 'data-src', 'player.vimeo.com/', 'api=1' );
+
+	}
+
+	/**
+	 * Start playback of any embedded content inside of
+	 * the given element.
+	 *
+	 * @param {HTMLElement} element
+	 */
+	startEmbeddedContent( element ) {
+
+		if( element ) {
+
+			const isSpeakerNotesWindow = this.Reveal.isSpeakerNotes();
+
+			// Restart GIFs
+			queryAll( element, 'img[src$=".gif"]' ).forEach( el => {
+				// Setting the same unchanged source like this was confirmed
+				// to work in Chrome, FF & Safari
+				el.setAttribute( 'src', el.getAttribute( 'src' ) );
+			} );
+
+			// HTML5 media elements
+			queryAll( element, 'video, audio' ).forEach( el => {
+				if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
+					return;
+				}
+
+				// Prefer an explicit global autoplay setting
+				let autoplay = this.Reveal.getConfig().autoPlayMedia;
+
+				// If no global setting is available, fall back on the element's
+				// own autoplay setting
+				if( typeof autoplay !== 'boolean' ) {
+					autoplay = el.hasAttribute( 'data-autoplay' ) || !!closest( el, '.slide-background' );
+				}
+
+				if( autoplay && typeof el.play === 'function' ) {
+
+					// In the speaker view we only auto-play muted media
+					if( isSpeakerNotesWindow && !el.muted ) return;
+
+					// If the media is ready, start playback
+					if( el.readyState > 1 ) {
+						this.startEmbeddedMedia( { target: el } );
+					}
+					// Mobile devices never fire a loaded event so instead
+					// of waiting, we initiate playback
+					else if( isMobile ) {
+						let promise = el.play();
+
+						// If autoplay does not work, ensure that the controls are visible so
+						// that the viewer can start the media on their own
+						if( promise && typeof promise.catch === 'function' && el.controls === false ) {
+							promise.catch( () => {
+								el.controls = true;
+
+								// Once the video does start playing, hide the controls again
+								el.addEventListener( 'play', () => {
+									el.controls = false;
+								} );
+							} );
+						}
+					}
+					// If the media isn't loaded, wait before playing
+					else {
+						el.removeEventListener( 'loadeddata', this.startEmbeddedMedia ); // remove first to avoid dupes
+						el.addEventListener( 'loadeddata', this.startEmbeddedMedia );
+					}
+
+				}
+			} );
+
+			// Don't play iframe content in the speaker view since we can't
+			// guarantee that it's muted
+			if( !isSpeakerNotesWindow ) {
+
+				// Normal iframes
+				queryAll( element, 'iframe[src]' ).forEach( el => {
+					if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
+						return;
+					}
+
+					this.startEmbeddedIframe( { target: el } );
+				} );
+
+				// Lazy loading iframes
+				queryAll( element, 'iframe[data-src]' ).forEach( el => {
+					if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
+						return;
+					}
+
+					if( el.getAttribute( 'src' ) !== el.getAttribute( 'data-src' ) ) {
+						el.removeEventListener( 'load', this.startEmbeddedIframe ); // remove first to avoid dupes
+						el.addEventListener( 'load', this.startEmbeddedIframe );
+						el.setAttribute( 'src', el.getAttribute( 'data-src' ) );
+					}
+				} );
+
+			}
+
+		}
+
+	}
+
+	/**
+	 * Starts playing an embedded video/audio element after
+	 * it has finished loading.
+	 *
+	 * @param {object} event
+	 */
+	startEmbeddedMedia( event ) {
+
+		let isAttachedToDOM = !!closest( event.target, 'html' ),
+			isVisible  		= !!closest( event.target, '.present' );
+
+		if( isAttachedToDOM && isVisible ) {
+			// Don't restart if media is already playing
+			if( event.target.paused || event.target.ended ) {
+				event.target.currentTime = 0;
+				event.target.play();
+			}
+		}
+
+		event.target.removeEventListener( 'loadeddata', this.startEmbeddedMedia );
+
+	}
+
+	/**
+	 * "Starts" the content of an embedded iframe using the
+	 * postMessage API.
+	 *
+	 * @param {object} event
+	 */
+	startEmbeddedIframe( event ) {
+
+		let iframe = event.target;
+
+		if( iframe && iframe.contentWindow ) {
+
+			let isAttachedToDOM = !!closest( event.target, 'html' ),
+				isVisible  		= !!closest( event.target, '.present' );
+
+			if( isAttachedToDOM && isVisible ) {
+
+				// Prefer an explicit global autoplay setting
+				let autoplay = this.Reveal.getConfig().autoPlayMedia;
+
+				// If no global setting is available, fall back on the element's
+				// own autoplay setting
+				if( typeof autoplay !== 'boolean' ) {
+					autoplay = iframe.hasAttribute( 'data-autoplay' ) || !!closest( iframe, '.slide-background' );
+				}
+
+				// YouTube postMessage API
+				if( /youtube\.com\/embed\//.test( iframe.getAttribute( 'src' ) ) && autoplay ) {
+					iframe.contentWindow.postMessage( '{"event":"command","func":"playVideo","args":""}', '*' );
+				}
+				// Vimeo postMessage API
+				else if( /player\.vimeo\.com\//.test( iframe.getAttribute( 'src' ) ) && autoplay ) {
+					iframe.contentWindow.postMessage( '{"method":"play"}', '*' );
+				}
+				// Generic postMessage API
+				else {
+					iframe.contentWindow.postMessage( 'slide:start', '*' );
+				}
+
+			}
+
+		}
+
+	}
+
+	/**
+	 * Stop playback of any embedded content inside of
+	 * the targeted slide.
+	 *
+	 * @param {HTMLElement} element
+	 */
+	stopEmbeddedContent( element, options = {} ) {
+
+		options = extend( {
+			// Defaults
+			unloadIframes: true
+		}, options );
+
+		if( element && element.parentNode ) {
+			// HTML5 media elements
+			queryAll( element, 'video, audio' ).forEach( el => {
+				if( !el.hasAttribute( 'data-ignore' ) && typeof el.pause === 'function' ) {
+					el.setAttribute('data-paused-by-reveal', '');
+					el.pause();
+				}
+			} );
+
+			// Generic postMessage API for non-lazy loaded iframes
+			queryAll( element, 'iframe' ).forEach( el => {
+				if( el.contentWindow ) el.contentWindow.postMessage( 'slide:stop', '*' );
+				el.removeEventListener( 'load', this.startEmbeddedIframe );
+			});
+
+			// YouTube postMessage API
+			queryAll( element, 'iframe[src*="youtube.com/embed/"]' ).forEach( el => {
+				if( !el.hasAttribute( 'data-ignore' ) && el.contentWindow && typeof el.contentWindow.postMessage === 'function' ) {
+					el.contentWindow.postMessage( '{"event":"command","func":"pauseVideo","args":""}', '*' );
+				}
+			});
+
+			// Vimeo postMessage API
+			queryAll( element, 'iframe[src*="player.vimeo.com/"]' ).forEach( el => {
+				if( !el.hasAttribute( 'data-ignore' ) && el.contentWindow && typeof el.contentWindow.postMessage === 'function' ) {
+					el.contentWindow.postMessage( '{"method":"pause"}', '*' );
+				}
+			});
+
+			if( options.unloadIframes === true ) {
+				// Unload lazy-loaded iframes
+				queryAll( element, 'iframe[data-src]' ).forEach( el => {
+					// Only removing the src doesn't actually unload the frame
+					// in all browsers (Firefox) so we set it to blank first
+					el.setAttribute( 'src', 'about:blank' );
+					el.removeAttribute( 'src' );
+				} );
+			}
+		}
+
+	}
+
+}
diff --git a/inst/reveal.js-5.2.1/js/controllers/slidenumber.js b/inst/reveal.js-5.2.1/js/controllers/slidenumber.js
new file mode 100644
index 0000000..e213e29
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/slidenumber.js
@@ -0,0 +1,139 @@
+import {
+	SLIDE_NUMBER_FORMAT_CURRENT,
+	SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL,
+	SLIDE_NUMBER_FORMAT_HORIZONTAL_DOT_VERTICAL,
+	SLIDE_NUMBER_FORMAT_HORIZONTAL_SLASH_VERTICAL
+} from "../utils/constants";
+
+/**
+ * Handles the display of reveal.js' optional slide number.
+ */
+export default class SlideNumber {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+	}
+
+	render() {
+
+		this.element = document.createElement( 'div' );
+		this.element.className = 'slide-number';
+		this.Reveal.getRevealElement().appendChild( this.element );
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		let slideNumberDisplay = 'none';
+		if( config.slideNumber && !this.Reveal.isPrintView() ) {
+			if( config.showSlideNumber === 'all' ) {
+				slideNumberDisplay = 'block';
+			}
+			else if( config.showSlideNumber === 'speaker' && this.Reveal.isSpeakerNotes() ) {
+				slideNumberDisplay = 'block';
+			}
+		}
+
+		this.element.style.display = slideNumberDisplay;
+
+	}
+
+	/**
+	 * Updates the slide number to match the current slide.
+	 */
+	update() {
+
+		// Update slide number if enabled
+		if( this.Reveal.getConfig().slideNumber && this.element ) {
+			this.element.innerHTML = this.getSlideNumber();
+		}
+
+	}
+
+	/**
+	 * Returns the HTML string corresponding to the current slide
+	 * number, including formatting.
+	 */
+	getSlideNumber( slide = this.Reveal.getCurrentSlide() ) {
+
+		let config = this.Reveal.getConfig();
+		let value;
+		let format = SLIDE_NUMBER_FORMAT_HORIZONTAL_DOT_VERTICAL;
+
+		if ( typeof config.slideNumber === 'function' ) {
+			value = config.slideNumber( slide );
+		} else {
+			// Check if a custom number format is available
+			if( typeof config.slideNumber === 'string' ) {
+				format = config.slideNumber;
+			}
+
+			// If there are ONLY vertical slides in this deck, always use
+			// a flattened slide number
+			if( !/c/.test( format ) && this.Reveal.getHorizontalSlides().length === 1 ) {
+				format = SLIDE_NUMBER_FORMAT_CURRENT;
+			}
+
+			// Offset the current slide number by 1 to make it 1-indexed
+			let horizontalOffset = slide && slide.dataset.visibility === 'uncounted' ? 0 : 1;
+
+			value = [];
+			switch( format ) {
+				case SLIDE_NUMBER_FORMAT_CURRENT:
+					value.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset );
+					break;
+				case SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL:
+					value.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset, '/', this.Reveal.getTotalSlides() );
+					break;
+				default:
+					let indices = this.Reveal.getIndices( slide );
+					value.push( indices.h + horizontalOffset );
+					let sep = format === SLIDE_NUMBER_FORMAT_HORIZONTAL_SLASH_VERTICAL ? '/' : '.';
+					if( this.Reveal.isVerticalSlide( slide ) ) value.push( sep, indices.v + 1 );
+			}
+		}
+
+		let url = '#' + this.Reveal.location.getHash( slide );
+		return this.formatNumber( value[0], value[1], value[2], url );
+
+	}
+
+	/**
+	 * Applies HTML formatting to a slide number before it's
+	 * written to the DOM.
+	 *
+	 * @param {number} a Current slide
+	 * @param {string} delimiter Character to separate slide numbers
+	 * @param {(number|*)} b Total slides
+	 * @param {HTMLElement} [url='#'+locationHash()] The url to link to
+	 * @return {string} HTML string fragment
+	 */
+	formatNumber( a, delimiter, b, url = '#' + this.Reveal.location.getHash() ) {
+
+		if( typeof b === 'number' && !isNaN( b ) ) {
+			return  `<a href="${url}">
+					<span class="slide-number-a">${a}</span>
+					<span class="slide-number-delimiter">${delimiter}</span>
+					<span class="slide-number-b">${b}</span>
+					</a>`;
+		}
+		else {
+			return `<a href="${url}">
+					<span class="slide-number-a">${a}</span>
+					</a>`;
+		}
+
+	}
+
+	destroy() {
+
+		this.element.remove();
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/controllers/touch.js b/inst/reveal.js-5.2.1/js/controllers/touch.js
new file mode 100644
index 0000000..7078cf2
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/touch.js
@@ -0,0 +1,265 @@
+import { isAndroid } from '../utils/device.js'
+import { matches } from '../utils/util.js'
+
+const SWIPE_THRESHOLD = 40;
+
+/**
+ * Controls all touch interactions and navigations for
+ * a presentation.
+ */
+export default class Touch {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		// Holds information about the currently ongoing touch interaction
+		this.touchStartX = 0;
+		this.touchStartY = 0;
+		this.touchStartCount = 0;
+		this.touchCaptured = false;
+
+		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 revealElement = this.Reveal.getRevealElement();
+
+		if( 'onpointerdown' in window ) {
+			// Use W3C pointer events
+			revealElement.addEventListener( 'pointerdown', this.onPointerDown, false );
+			revealElement.addEventListener( 'pointermove', this.onPointerMove, false );
+			revealElement.addEventListener( 'pointerup', this.onPointerUp, false );
+		}
+		else if( window.navigator.msPointerEnabled ) {
+			// IE 10 uses prefixed version of pointer events
+			revealElement.addEventListener( 'MSPointerDown', this.onPointerDown, false );
+			revealElement.addEventListener( 'MSPointerMove', this.onPointerMove, false );
+			revealElement.addEventListener( 'MSPointerUp', this.onPointerUp, false );
+		}
+		else {
+			// Fall back to touch events
+			revealElement.addEventListener( 'touchstart', this.onTouchStart, false );
+			revealElement.addEventListener( 'touchmove', this.onTouchMove, false );
+			revealElement.addEventListener( 'touchend', this.onTouchEnd, false );
+		}
+
+	}
+
+	/**
+	 *
+	 */
+	unbind() {
+
+		let revealElement = this.Reveal.getRevealElement();
+
+		revealElement.removeEventListener( 'pointerdown', this.onPointerDown, false );
+		revealElement.removeEventListener( 'pointermove', this.onPointerMove, false );
+		revealElement.removeEventListener( 'pointerup', this.onPointerUp, false );
+
+		revealElement.removeEventListener( 'MSPointerDown', this.onPointerDown, false );
+		revealElement.removeEventListener( 'MSPointerMove', this.onPointerMove, false );
+		revealElement.removeEventListener( 'MSPointerUp', this.onPointerUp, false );
+
+		revealElement.removeEventListener( 'touchstart', this.onTouchStart, false );
+		revealElement.removeEventListener( 'touchmove', this.onTouchMove, false );
+		revealElement.removeEventListener( 'touchend', this.onTouchEnd, false );
+
+	}
+
+	/**
+	 * Checks if the target element prevents the triggering of
+	 * swipe navigation.
+	 */
+	isSwipePrevented( target ) {
+
+		// Prevent accidental swipes when scrubbing timelines
+		if( matches( target, 'video[controls], audio[controls]' ) ) return true;
+
+		while( target && typeof target.hasAttribute === 'function' ) {
+			if( target.hasAttribute( 'data-prevent-swipe' ) ) return true;
+			target = target.parentNode;
+		}
+
+		return false;
+
+	}
+
+	/**
+	 * Handler for the 'touchstart' event, enables support for
+	 * swipe and pinch gestures.
+	 *
+	 * @param {object} event
+	 */
+	onTouchStart( event ) {
+
+		this.touchCaptured = false;
+
+		if( this.isSwipePrevented( event.target ) ) return true;
+
+		this.touchStartX = event.touches[0].clientX;
+		this.touchStartY = event.touches[0].clientY;
+		this.touchStartCount = event.touches.length;
+
+	}
+
+	/**
+	 * Handler for the 'touchmove' event.
+	 *
+	 * @param {object} event
+	 */
+	onTouchMove( event ) {
+
+		if( this.isSwipePrevented( event.target ) ) return true;
+
+		let config = this.Reveal.getConfig();
+
+		// Each touch should only trigger one action
+		if( !this.touchCaptured ) {
+			this.Reveal.onUserInput( event );
+
+			let currentX = event.touches[0].clientX;
+			let currentY = event.touches[0].clientY;
+
+			// There was only one touch point, look for a swipe
+			if( event.touches.length === 1 && this.touchStartCount !== 2 ) {
+
+				let availableRoutes = this.Reveal.availableRoutes({ includeFragments: true });
+
+				let deltaX = currentX - this.touchStartX,
+					deltaY = currentY - this.touchStartY;
+
+				if( deltaX > SWIPE_THRESHOLD && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
+					this.touchCaptured = true;
+					if( config.navigationMode === 'linear' ) {
+						if( config.rtl ) {
+							this.Reveal.next();
+						}
+						else {
+							this.Reveal.prev();
+						}
+					}
+					else {
+						this.Reveal.left();
+					}
+				}
+				else if( deltaX < -SWIPE_THRESHOLD && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
+					this.touchCaptured = true;
+					if( config.navigationMode === 'linear' ) {
+						if( config.rtl ) {
+							this.Reveal.prev();
+						}
+						else {
+							this.Reveal.next();
+						}
+					}
+					else {
+						this.Reveal.right();
+					}
+				}
+				else if( deltaY > SWIPE_THRESHOLD && availableRoutes.up ) {
+					this.touchCaptured = true;
+					if( config.navigationMode === 'linear' ) {
+						this.Reveal.prev();
+					}
+					else {
+						this.Reveal.up();
+					}
+				}
+				else if( deltaY < -SWIPE_THRESHOLD && availableRoutes.down ) {
+					this.touchCaptured = true;
+					if( config.navigationMode === 'linear' ) {
+						this.Reveal.next();
+					}
+					else {
+						this.Reveal.down();
+					}
+				}
+
+				// If we're embedded, only block touch events if they have
+				// triggered an action
+				if( config.embedded ) {
+					if( this.touchCaptured || this.Reveal.isVerticalSlide() ) {
+						event.preventDefault();
+					}
+				}
+				// Not embedded? Block them all to avoid needless tossing
+				// around of the viewport in iOS
+				else {
+					event.preventDefault();
+				}
+
+			}
+		}
+		// There's a bug with swiping on some Android devices unless
+		// the default action is always prevented
+		else if( isAndroid ) {
+			event.preventDefault();
+		}
+
+	}
+
+	/**
+	 * Handler for the 'touchend' event.
+	 *
+	 * @param {object} event
+	 */
+	onTouchEnd( event ) {
+
+		this.touchCaptured = false;
+
+	}
+
+	/**
+	 * Convert pointer down to touch start.
+	 *
+	 * @param {object} event
+	 */
+	onPointerDown( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" ) {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			this.onTouchStart( event );
+		}
+
+	}
+
+	/**
+	 * Convert pointer move to touch move.
+	 *
+	 * @param {object} event
+	 */
+	onPointerMove( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" )  {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			this.onTouchMove( event );
+		}
+
+	}
+
+	/**
+	 * Convert pointer up to touch end.
+	 *
+	 * @param {object} event
+	 */
+	onPointerUp( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" )  {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			this.onTouchEnd( event );
+		}
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/index.js b/inst/reveal.js-5.2.1/js/index.js
new file mode 100644
index 0000000..57be501
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/index.js
@@ -0,0 +1,58 @@
+import Deck, { VERSION } from './reveal.js'
+
+/**
+ * Expose the Reveal class to the window. To create a
+ * new instance:
+ * let deck = new Reveal( document.querySelector( '.reveal' ), {
+ *   controls: false
+ * } );
+ * deck.initialize().then(() => {
+ *   // reveal.js is ready
+ * });
+ */
+let Reveal = Deck;
+
+
+/**
+ * The below is a thin shell that mimics the pre 4.0
+ * reveal.js API and ensures backwards compatibility.
+ * This API only allows for one Reveal instance per
+ * page, whereas the new API above lets you run many
+ * presentations on the same page.
+ *
+ * Reveal.initialize( { controls: false } ).then(() => {
+ *   // reveal.js is ready
+ * });
+ */
+
+let enqueuedAPICalls = [];
+
+Reveal.initialize = options => {
+
+	// Create our singleton reveal.js instance
+	Object.assign( Reveal, new Deck( document.querySelector( '.reveal' ), options ) );
+
+	// Invoke any enqueued API calls
+	enqueuedAPICalls.map( method => method( Reveal ) );
+
+	return Reveal.initialize();
+
+}
+
+/**
+ * The pre 4.0 API let you add event listener before
+ * initializing. We maintain the same behavior by
+ * queuing up premature API calls and invoking all
+ * of them when Reveal.initialize is called.
+ */
+[ 'configure', 'on', 'off', 'addEventListener', 'removeEventListener', 'registerPlugin' ].forEach( method => {
+	Reveal[method] = ( ...args ) => {
+		enqueuedAPICalls.push( deck => deck[method].call( null, ...args ) );
+	}
+} );
+
+Reveal.isReady = () => false;
+
+Reveal.VERSION = VERSION;
+
+export default Reveal;
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/reveal.js b/inst/reveal.js-5.2.1/js/reveal.js
new file mode 100644
index 0000000..1585aff
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/reveal.js
@@ -0,0 +1,2906 @@
+import SlideContent from './controllers/slidecontent.js'
+import SlideNumber from './controllers/slidenumber.js'
+import JumpToSlide from './controllers/jumptoslide.js'
+import Backgrounds from './controllers/backgrounds.js'
+import AutoAnimate from './controllers/autoanimate.js'
+import ScrollView from './controllers/scrollview.js'
+import PrintView from './controllers/printview.js'
+import Fragments from './controllers/fragments.js'
+import Overview from './controllers/overview.js'
+import Keyboard from './controllers/keyboard.js'
+import Location from './controllers/location.js'
+import Controls from './controllers/controls.js'
+import Progress from './controllers/progress.js'
+import Pointer from './controllers/pointer.js'
+import Plugins from './controllers/plugins.js'
+import Overlay from './controllers/overlay.js'
+import Touch from './controllers/touch.js'
+import Focus from './controllers/focus.js'
+import Notes from './controllers/notes.js'
+import Playback from './components/playback.js'
+import defaultConfig from './config.js'
+import * as Util from './utils/util.js'
+import * as Device from './utils/device.js'
+import {
+	SLIDES_SELECTOR,
+	HORIZONTAL_SLIDES_SELECTOR,
+	VERTICAL_SLIDES_SELECTOR,
+	POST_MESSAGE_METHOD_BLACKLIST
+} from './utils/constants.js'
+
+// The reveal.js version
+export const VERSION = '5.2.1';
+
+/**
+ * reveal.js
+ * https://revealjs.com
+ * MIT licensed
+ *
+ * Copyright (C) 2011-2022 Hakim El Hattab, https://hakim.se
+ */
+export default function( revealElement, options ) {
+
+	// Support initialization with no args, one arg
+	// [options] or two args [revealElement, options]
+	if( arguments.length < 2 ) {
+		options = arguments[0];
+		revealElement = document.querySelector( '.reveal' );
+	}
+
+	const Reveal = {};
+
+	// Configuration defaults, can be overridden at initialization time
+	let config = {},
+
+		// Flags if initialize() has been invoked for this reveal instance
+		initialized = false,
+
+		// Flags if reveal.js is loaded (has dispatched the 'ready' event)
+		ready = false,
+
+		// The horizontal and vertical index of the currently active slide
+		indexh,
+		indexv,
+
+		// The previous and current slide HTML elements
+		previousSlide,
+		currentSlide,
+
+		// Remember which directions that the user has navigated towards
+		navigationHistory = {
+			hasNavigatedHorizontally: false,
+			hasNavigatedVertically: false
+		},
+
+		// Slides may have a data-state attribute which we pick up and apply
+		// as a class to the body. This list contains the combined state of
+		// all current slides.
+		state = [],
+
+		// The current scale of the presentation (see width/height config)
+		scale = 1,
+
+		// CSS transform that is currently applied to the slides container,
+		// split into two groups
+		slidesTransform = { layout: '', overview: '' },
+
+		// Cached references to DOM elements
+		dom = {},
+
+		// Flags if the interaction event listeners are bound
+		eventsAreBound = false,
+
+		// The current slide transition state; idle or running
+		transition = 'idle',
+
+		// The current auto-slide duration
+		autoSlide = 0,
+
+		// Auto slide properties
+		autoSlidePlayer,
+		autoSlideTimeout = 0,
+		autoSlideStartTime = -1,
+		autoSlidePaused = false,
+
+		// Controllers for different aspects of our presentation. They're
+		// all given direct references to this Reveal instance since there
+		// may be multiple presentations running in parallel.
+		slideContent = new SlideContent( Reveal ),
+		slideNumber = new SlideNumber( Reveal ),
+		jumpToSlide = new JumpToSlide( Reveal ),
+		autoAnimate = new AutoAnimate( Reveal ),
+		backgrounds = new Backgrounds( Reveal ),
+		scrollView = new ScrollView( Reveal ),
+		printView = new PrintView( Reveal ),
+		fragments = new Fragments( Reveal ),
+		overview = new Overview( Reveal ),
+		keyboard = new Keyboard( Reveal ),
+		location = new Location( Reveal ),
+		controls = new Controls( Reveal ),
+		progress = new Progress( Reveal ),
+		pointer = new Pointer( Reveal ),
+		plugins = new Plugins( Reveal ),
+		overlay = new Overlay( Reveal ),
+		focus = new Focus( Reveal ),
+		touch = new Touch( Reveal ),
+		notes = new Notes( Reveal );
+
+	/**
+	 * Starts up the presentation.
+	 */
+	function initialize( initOptions ) {
+
+		if( !revealElement ) throw 'Unable to find presentation root (<div class="reveal">).';
+
+		if( initialized ) throw 'Reveal.js has already been initialized.';
+
+		initialized = true;
+
+		// Cache references to key DOM elements
+		dom.wrapper = revealElement;
+		dom.slides = revealElement.querySelector( '.slides' );
+
+		if( !dom.slides ) throw 'Unable to find slides container (<div class="slides">).';
+
+		// Compose our config object in order of increasing precedence:
+		// 1. Default reveal.js options
+		// 2. Options provided via Reveal.configure() prior to
+		//    initialization
+		// 3. Options passed to the Reveal constructor
+		// 4. Options passed to Reveal.initialize
+		// 5. Query params
+		config = { ...defaultConfig, ...config, ...options, ...initOptions, ...Util.getQueryHash() };
+
+		// Legacy support for the ?print-pdf query
+		if( /print-pdf/gi.test( window.location.search ) ) {
+			config.view = 'print';
+		}
+
+		setViewport();
+
+		// Force a layout when the whole page, incl fonts, has loaded
+		window.addEventListener( 'load', layout, false );
+
+		// Register plugins and load dependencies, then move on to #start()
+		plugins.load( config.plugins, config.dependencies ).then( start );
+
+		return new Promise( resolve => Reveal.on( 'ready', resolve ) );
+
+	}
+
+	/**
+	 * Encase the presentation in a reveal.js viewport. The
+	 * extent of the viewport differs based on configuration.
+	 */
+	function setViewport() {
+
+		// Embedded decks use the reveal element as their viewport
+		if( config.embedded === true ) {
+			dom.viewport = Util.closest( revealElement, '.reveal-viewport' ) || revealElement;
+		}
+		// Full-page decks use the body as their viewport
+		else {
+			dom.viewport = document.body;
+			document.documentElement.classList.add( 'reveal-full-page' );
+		}
+
+		dom.viewport.classList.add( 'reveal-viewport' );
+
+	}
+
+	/**
+	 * Starts up reveal.js by binding input events and navigating
+	 * to the current URL deeplink if there is one.
+	 */
+	function start() {
+
+		// Don't proceed if this instance has been destroyed
+		if( initialized === false ) return;
+
+		ready = true;
+
+		// Remove slides hidden with data-visibility
+		removeHiddenSlides();
+
+		// Make sure we've got all the DOM elements we need
+		setupDOM();
+
+		// Listen to messages posted to this window
+		setupPostMessage();
+
+		// Prevent the slides from being scrolled out of view
+		setupScrollPrevention();
+
+		// Adds bindings for fullscreen mode
+		setupFullscreen();
+
+		// Resets all vertical slides so that only the first is visible
+		resetVerticalSlides();
+
+		// Updates the presentation to match the current configuration values
+		configure();
+
+		// Create slide backgrounds
+		backgrounds.update( true );
+
+		// Activate the print/scroll view if configured
+		activateInitialView();
+
+		// Read the initial hash
+		location.readURL();
+
+		// Notify listeners that the presentation is ready but use a 1ms
+		// timeout to ensure it's not fired synchronously after #initialize()
+		setTimeout( () => {
+			// Enable transitions now that we're loaded
+			dom.slides.classList.remove( 'no-transition' );
+
+			dom.wrapper.classList.add( 'ready' );
+
+			dispatchEvent({
+				type: 'ready',
+				data: {
+					indexh,
+					indexv,
+					currentSlide
+				}
+			});
+		}, 1 );
+
+	}
+
+	/**
+	 * Activates the correct reveal.js view based on our config.
+	 * This is only invoked once during initialization.
+	 */
+	function activateInitialView() {
+
+		const activatePrintView = config.view === 'print';
+		const activateScrollView = config.view === 'scroll' || config.view === 'reader';
+
+		if( activatePrintView || activateScrollView ) {
+
+			if( activatePrintView ) {
+				removeEventListeners();
+			}
+			else {
+				touch.unbind();
+			}
+
+			// Avoid content flickering during layout
+			dom.viewport.classList.add( 'loading-scroll-mode' );
+
+			if( activatePrintView ) {
+				// The document needs to have loaded for the PDF layout
+				// measurements to be accurate
+				if( document.readyState === 'complete' ) {
+					printView.activate();
+				}
+				else {
+					window.addEventListener( 'load', () => printView.activate() );
+				}
+			}
+			else {
+				scrollView.activate();
+			}
+		}
+
+	}
+
+	/**
+	 * Removes all slides with data-visibility="hidden". This
+	 * is done right before the rest of the presentation is
+	 * initialized.
+	 *
+	 * If you want to show all hidden slides, initialize
+	 * reveal.js with showHiddenSlides set to true.
+	 */
+	function removeHiddenSlides() {
+
+		if( !config.showHiddenSlides ) {
+			Util.queryAll( dom.wrapper, 'section[data-visibility="hidden"]' ).forEach( slide => {
+				const parent = slide.parentNode;
+
+				// If this slide is part of a stack and that stack will be
+				// empty after removing the hidden slide, remove the entire
+				// stack
+				if( parent.childElementCount === 1 && /section/i.test( parent.nodeName ) ) {
+					parent.remove();
+				}
+				else {
+					slide.remove();
+				}
+
+			} );
+		}
+
+	}
+
+	/**
+	 * Finds and stores references to DOM elements which are
+	 * required by the presentation. If a required element is
+	 * not found, it is created.
+	 */
+	function setupDOM() {
+
+		// Prevent transitions while we're loading
+		dom.slides.classList.add( 'no-transition' );
+
+		if( Device.isMobile ) {
+			dom.wrapper.classList.add( 'no-hover' );
+		}
+		else {
+			dom.wrapper.classList.remove( 'no-hover' );
+		}
+
+		backgrounds.render();
+		slideNumber.render();
+		jumpToSlide.render();
+		controls.render();
+		progress.render();
+		notes.render();
+
+		// Overlay graphic which is displayed during the paused mode
+		dom.pauseOverlay = Util.createSingletonNode( dom.wrapper, 'div', 'pause-overlay', config.controls ? '<button class="resume-button">Resume presentation</button>' : null );
+
+		dom.statusElement = createStatusElement();
+
+		dom.wrapper.setAttribute( 'role', 'application' );
+	}
+
+	/**
+	 * Creates a hidden div with role aria-live to announce the
+	 * current slide content. Hide the div off-screen to make it
+	 * available only to Assistive Technologies.
+	 *
+	 * @return {HTMLElement}
+	 */
+	function createStatusElement() {
+
+		let statusElement = dom.wrapper.querySelector( '.aria-status' );
+		if( !statusElement ) {
+			statusElement = document.createElement( 'div' );
+			statusElement.style.position = 'absolute';
+			statusElement.style.height = '1px';
+			statusElement.style.width = '1px';
+			statusElement.style.overflow = 'hidden';
+			statusElement.style.clip = 'rect( 1px, 1px, 1px, 1px )';
+			statusElement.classList.add( 'aria-status' );
+			statusElement.setAttribute( 'aria-live', 'polite' );
+			statusElement.setAttribute( 'aria-atomic','true' );
+			dom.wrapper.appendChild( statusElement );
+		}
+		return statusElement;
+
+	}
+
+	/**
+	 * Announces the given text to screen readers.
+	 */
+	function announceStatus( value ) {
+
+		dom.statusElement.textContent = value;
+
+	}
+
+	/**
+	 * Converts the given HTML element into a string of text
+	 * that can be announced to a screen reader. Hidden
+	 * elements are excluded.
+	 */
+	function getStatusText( node ) {
+
+		let text = '';
+
+		// Text node
+		if( node.nodeType === 3 ) {
+			text += node.textContent;
+		}
+		// Element node
+		else if( node.nodeType === 1 ) {
+
+			let isAriaHidden = node.getAttribute( 'aria-hidden' );
+			let isDisplayHidden = window.getComputedStyle( node )['display'] === 'none';
+			if( isAriaHidden !== 'true' && !isDisplayHidden ) {
+
+				Array.from( node.childNodes ).forEach( child => {
+					text += getStatusText( child );
+				} );
+
+			}
+
+		}
+
+		text = text.trim();
+
+		return text === '' ? '' : text + ' ';
+
+	}
+
+	/**
+	 * This is an unfortunate necessity. Some actions – such as
+	 * an input field being focused in an iframe or using the
+	 * keyboard to expand text selection beyond the bounds of
+	 * a slide – can trigger our content to be pushed out of view.
+	 * This scrolling can not be prevented by hiding overflow in
+	 * CSS (we already do) so we have to resort to repeatedly
+	 * checking if the slides have been offset :(
+	 */
+	function setupScrollPrevention() {
+
+		setInterval( () => {
+			if( !scrollView.isActive() && dom.wrapper.scrollTop !== 0 || dom.wrapper.scrollLeft !== 0 ) {
+				dom.wrapper.scrollTop = 0;
+				dom.wrapper.scrollLeft = 0;
+			}
+		}, 1000 );
+
+	}
+
+	/**
+	 * After entering fullscreen we need to force a layout to
+	 * get our presentations to scale correctly. This behavior
+	 * is inconsistent across browsers but a force layout seems
+	 * to normalize it.
+	 */
+	function setupFullscreen() {
+
+		document.addEventListener( 'fullscreenchange', onFullscreenChange );
+		document.addEventListener( 'webkitfullscreenchange', onFullscreenChange );
+
+	}
+
+	/**
+	 * Registers a listener to postMessage events, this makes it
+	 * possible to call all reveal.js API methods from another
+	 * window. For example:
+	 *
+	 * revealWindow.postMessage( JSON.stringify({
+	 *   method: 'slide',
+	 *   args: [ 2 ]
+	 * }), '*' );
+	 */
+	function setupPostMessage() {
+
+		if( config.postMessage ) {
+			window.addEventListener( 'message', onPostMessage, false );
+		}
+
+	}
+
+	/**
+	 * Applies the configuration settings from the config
+	 * object. May be called multiple times.
+	 *
+	 * @param {object} options
+	 */
+	function configure( options ) {
+
+		const oldConfig = { ...config }
+
+		// New config options may be passed when this method
+		// is invoked through the API after initialization
+		if( typeof options === 'object' ) Util.extend( config, options );
+
+		// Abort if reveal.js hasn't finished loading, config
+		// changes will be applied automatically once ready
+		if( Reveal.isReady() ===  false ) return;
+
+		const numberOfSlides = dom.wrapper.querySelectorAll( SLIDES_SELECTOR ).length;
+
+		// The transition is added as a class on the .reveal element
+		dom.wrapper.classList.remove( oldConfig.transition );
+		dom.wrapper.classList.add( config.transition );
+
+		dom.wrapper.setAttribute( 'data-transition-speed', config.transitionSpeed );
+		dom.wrapper.setAttribute( 'data-background-transition', config.backgroundTransition );
+
+		// Expose our configured slide dimensions as custom props
+		dom.viewport.style.setProperty( '--slide-width', typeof config.width === 'string' ? config.width :  config.width + 'px' );
+		dom.viewport.style.setProperty( '--slide-height', typeof config.height === 'string' ? config.height :  config.height + 'px' );
+
+		if( config.shuffle ) {
+			shuffle();
+		}
+
+		Util.toggleClass( dom.wrapper, 'embedded', config.embedded );
+		Util.toggleClass( dom.wrapper, 'rtl', config.rtl );
+		Util.toggleClass( dom.wrapper, 'center', config.center );
+
+		// Exit the paused mode if it was configured off
+		if( config.pause === false ) {
+			resume();
+		}
+
+		// Reset all changes made by auto-animations
+		autoAnimate.reset();
+
+		// Remove existing auto-slide controls
+		if( autoSlidePlayer ) {
+			autoSlidePlayer.destroy();
+			autoSlidePlayer = null;
+		}
+
+		// Generate auto-slide controls if needed
+		if( numberOfSlides > 1 && config.autoSlide && config.autoSlideStoppable ) {
+			autoSlidePlayer = new Playback( dom.wrapper, () => {
+				return Math.min( Math.max( ( Date.now() - autoSlideStartTime ) / autoSlide, 0 ), 1 );
+			} );
+
+			autoSlidePlayer.on( 'click', onAutoSlidePlayerClick );
+			autoSlidePaused = false;
+		}
+
+		// Add the navigation mode to the DOM so we can adjust styling
+		if( config.navigationMode !== 'default' ) {
+			dom.wrapper.setAttribute( 'data-navigation-mode', config.navigationMode );
+		}
+		else {
+			dom.wrapper.removeAttribute( 'data-navigation-mode' );
+		}
+
+		notes.configure( config, oldConfig );
+		focus.configure( config, oldConfig );
+		pointer.configure( config, oldConfig );
+		controls.configure( config, oldConfig );
+		progress.configure( config, oldConfig );
+		keyboard.configure( config, oldConfig );
+		fragments.configure( config, oldConfig );
+		slideNumber.configure( config, oldConfig );
+
+		sync();
+
+	}
+
+	/**
+	 * Binds all event listeners.
+	 */
+	function addEventListeners() {
+
+		eventsAreBound = true;
+
+		window.addEventListener( 'resize', onWindowResize, false );
+
+		if( config.touch ) touch.bind();
+		if( config.keyboard ) keyboard.bind();
+		if( config.progress ) progress.bind();
+		if( config.respondToHashChanges ) location.bind();
+		controls.bind();
+		focus.bind();
+
+		dom.slides.addEventListener( 'click', onSlidesClicked, false );
+		dom.slides.addEventListener( 'transitionend', onTransitionEnd, false );
+		dom.pauseOverlay.addEventListener( 'click', resume, false );
+
+		if( config.focusBodyOnPageVisibilityChange ) {
+			document.addEventListener( 'visibilitychange', onPageVisibilityChange, false );
+		}
+
+	}
+
+	/**
+	 * Unbinds all event listeners.
+	 */
+	function removeEventListeners() {
+
+		eventsAreBound = false;
+
+		touch.unbind();
+		focus.unbind();
+		keyboard.unbind();
+		controls.unbind();
+		progress.unbind();
+		location.unbind();
+
+		window.removeEventListener( 'resize', onWindowResize, false );
+
+		dom.slides.removeEventListener( 'click', onSlidesClicked, false );
+		dom.slides.removeEventListener( 'transitionend', onTransitionEnd, false );
+		dom.pauseOverlay.removeEventListener( 'click', resume, false );
+
+	}
+
+	/**
+	 * Uninitializes reveal.js by undoing changes made to the
+	 * DOM and removing all event listeners.
+	 */
+	function destroy() {
+
+		initialized = false;
+
+		// There's nothing to destroy if this instance hasn't finished
+		// initializing
+		if( ready === false ) return;
+
+		removeEventListeners();
+		cancelAutoSlide();
+
+		// Destroy controllers
+		notes.destroy();
+		focus.destroy();
+		overlay.destroy();
+		plugins.destroy();
+		pointer.destroy();
+		controls.destroy();
+		progress.destroy();
+		backgrounds.destroy();
+		slideNumber.destroy();
+		jumpToSlide.destroy();
+
+		// Remove event listeners
+		document.removeEventListener( 'fullscreenchange', onFullscreenChange );
+		document.removeEventListener( 'webkitfullscreenchange', onFullscreenChange );
+		document.removeEventListener( 'visibilitychange', onPageVisibilityChange, false );
+		window.removeEventListener( 'message', onPostMessage, false );
+		window.removeEventListener( 'load', layout, false );
+
+		// Undo DOM changes
+		if( dom.pauseOverlay ) dom.pauseOverlay.remove();
+		if( dom.statusElement ) dom.statusElement.remove();
+
+		document.documentElement.classList.remove( 'reveal-full-page' );
+
+		dom.wrapper.classList.remove( 'ready', 'center', 'has-horizontal-slides', 'has-vertical-slides' );
+		dom.wrapper.removeAttribute( 'data-transition-speed' );
+		dom.wrapper.removeAttribute( 'data-background-transition' );
+
+		dom.viewport.classList.remove( 'reveal-viewport' );
+		dom.viewport.style.removeProperty( '--slide-width' );
+		dom.viewport.style.removeProperty( '--slide-height' );
+
+		dom.slides.style.removeProperty( 'width' );
+		dom.slides.style.removeProperty( 'height' );
+		dom.slides.style.removeProperty( 'zoom' );
+		dom.slides.style.removeProperty( 'left' );
+		dom.slides.style.removeProperty( 'top' );
+		dom.slides.style.removeProperty( 'bottom' );
+		dom.slides.style.removeProperty( 'right' );
+		dom.slides.style.removeProperty( 'transform' );
+
+		Array.from( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( slide => {
+			slide.style.removeProperty( 'display' );
+			slide.style.removeProperty( 'top' );
+			slide.removeAttribute( 'hidden' );
+			slide.removeAttribute( 'aria-hidden' );
+		} );
+
+	}
+
+	/**
+	 * Adds a listener to one of our custom reveal.js events,
+	 * like slidechanged.
+	 */
+	function on( type, listener, useCapture ) {
+
+		revealElement.addEventListener( type, listener, useCapture );
+
+	}
+
+	/**
+	 * Unsubscribes from a reveal.js event.
+	 */
+	function off( type, listener, useCapture ) {
+
+		revealElement.removeEventListener( type, listener, useCapture );
+
+	}
+
+	/**
+	 * Applies CSS transforms to the slides container. The container
+	 * is transformed from two separate sources: layout and the overview
+	 * mode.
+	 *
+	 * @param {object} transforms
+	 */
+	function transformSlides( transforms ) {
+
+		// Pick up new transforms from arguments
+		if( typeof transforms.layout === 'string' ) slidesTransform.layout = transforms.layout;
+		if( typeof transforms.overview === 'string' ) slidesTransform.overview = transforms.overview;
+
+		// Apply the transforms to the slides container
+		if( slidesTransform.layout ) {
+			Util.transformElement( dom.slides, slidesTransform.layout + ' ' + slidesTransform.overview );
+		}
+		else {
+			Util.transformElement( dom.slides, slidesTransform.overview );
+		}
+
+	}
+
+	/**
+	 * Dispatches an event of the specified type from the
+	 * reveal DOM element.
+	 */
+	function dispatchEvent({ target=dom.wrapper, type, data, bubbles=true }) {
+
+		let event = document.createEvent( 'HTMLEvents', 1, 2 );
+		event.initEvent( type, bubbles, true );
+		Util.extend( event, data );
+		target.dispatchEvent( event );
+
+		if( target === dom.wrapper ) {
+			// If we're in an iframe, post each reveal.js event to the
+			// parent window. Used by the notes plugin
+			dispatchPostMessage( type );
+		}
+
+		return event;
+
+	}
+
+	/**
+	 * Dispatches a slidechanged event.
+	 *
+	 * @param {string} origin Used to identify multiplex clients
+	 */
+	function dispatchSlideChanged( origin ) {
+
+		dispatchEvent({
+			type: 'slidechanged',
+			data: {
+				indexh,
+				indexv,
+				previousSlide,
+				currentSlide,
+				origin
+			}
+		});
+
+	}
+
+	/**
+	 * Dispatched a postMessage of the given type from our window.
+	 */
+	function dispatchPostMessage( type, data ) {
+
+		if( config.postMessageEvents && window.parent !== window.self ) {
+			let message = {
+				namespace: 'reveal',
+				eventName: type,
+				state: getState()
+			};
+
+			Util.extend( message, data );
+
+			window.parent.postMessage( JSON.stringify( message ), '*' );
+		}
+
+	}
+
+	/**
+	 * Applies JavaScript-controlled layout rules to the
+	 * presentation.
+	 */
+	function layout() {
+
+		if( dom.wrapper && !printView.isActive() ) {
+
+			const viewportWidth = dom.viewport.offsetWidth;
+			const viewportHeight = dom.viewport.offsetHeight;
+
+			if( !config.disableLayout ) {
+
+				// On some mobile devices '100vh' is taller than the visible
+				// viewport which leads to part of the presentation being
+				// cut off. To work around this we define our own '--vh' custom
+				// property where 100x adds up to the correct height.
+				//
+				// https://css-tricks.com/the-trick-to-viewport-units-on-mobile/
+				if( Device.isMobile && !config.embedded ) {
+					document.documentElement.style.setProperty( '--vh', ( window.innerHeight * 0.01 ) + 'px' );
+				}
+
+				const size = scrollView.isActive() ?
+							 getComputedSlideSize( viewportWidth, viewportHeight ) :
+							 getComputedSlideSize();
+
+				const oldScale = scale;
+
+				// Layout the contents of the slides
+				layoutSlideContents( config.width, config.height );
+
+				dom.slides.style.width = size.width + 'px';
+				dom.slides.style.height = size.height + 'px';
+
+				// Determine scale of content to fit within available space
+				scale = Math.min( size.presentationWidth / size.width, size.presentationHeight / size.height );
+
+				// Respect max/min scale settings
+				scale = Math.max( scale, config.minScale );
+				scale = Math.min( scale, config.maxScale );
+
+				// Don't apply any scaling styles if scale is 1 or we're
+				// in the scroll view
+				if( scale === 1 || scrollView.isActive() ) {
+					dom.slides.style.zoom = '';
+					dom.slides.style.left = '';
+					dom.slides.style.top = '';
+					dom.slides.style.bottom = '';
+					dom.slides.style.right = '';
+					transformSlides( { layout: '' } );
+				}
+				else {
+					dom.slides.style.zoom = '';
+					dom.slides.style.left = '50%';
+					dom.slides.style.top = '50%';
+					dom.slides.style.bottom = 'auto';
+					dom.slides.style.right = 'auto';
+					transformSlides( { layout: 'translate(-50%, -50%) scale('+ scale +')' } );
+				}
+
+				// Select all slides, vertical and horizontal
+				const slides = Array.from( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) );
+
+				for( let i = 0, len = slides.length; i < len; i++ ) {
+					const slide = slides[ i ];
+
+					// Don't bother updating invisible slides
+					if( slide.style.display === 'none' ) {
+						continue;
+					}
+
+					if( ( config.center || slide.classList.contains( 'center' ) ) ) {
+						// Vertical stacks are not centred since their section
+						// children will be
+						if( slide.classList.contains( 'stack' ) ) {
+							slide.style.top = 0;
+						}
+						else {
+							slide.style.top = Math.max( ( size.height - slide.scrollHeight ) / 2, 0 ) + 'px';
+						}
+					}
+					else {
+						slide.style.top = '';
+					}
+
+				}
+
+				if( oldScale !== scale ) {
+					dispatchEvent({
+						type: 'resize',
+						data: {
+							oldScale,
+							scale,
+							size
+						}
+					});
+				}
+			}
+
+			checkResponsiveScrollView();
+
+			dom.viewport.style.setProperty( '--slide-scale', scale );
+			dom.viewport.style.setProperty( '--viewport-width', viewportWidth + 'px' );
+			dom.viewport.style.setProperty( '--viewport-height', viewportHeight + 'px' );
+
+			scrollView.layout();
+
+			progress.update();
+			backgrounds.updateParallax();
+
+			if( overview.isActive() ) {
+				overview.update();
+			}
+
+		}
+
+	}
+
+	/**
+	 * Applies layout logic to the contents of all slides in
+	 * the presentation.
+	 *
+	 * @param {string|number} width
+	 * @param {string|number} height
+	 */
+	function layoutSlideContents( width, height ) {
+		// Handle sizing of elements with the 'r-stretch' class
+		Util.queryAll( dom.slides, 'section > .stretch, section > .r-stretch' ).forEach( element => {
+
+			// Determine how much vertical space we can use
+			let remainingHeight = Util.getRemainingHeight( element, height );
+
+			// Consider the aspect ratio of media elements
+			if( /(img|video)/gi.test( element.nodeName ) ) {
+				const nw = element.naturalWidth || element.videoWidth,
+					  nh = element.naturalHeight || element.videoHeight;
+
+				const es = Math.min( width / nw, remainingHeight / nh );
+
+				element.style.width = ( nw * es ) + 'px';
+				element.style.height = ( nh * es ) + 'px';
+
+			}
+			else {
+				element.style.width = width + 'px';
+				element.style.height = remainingHeight + 'px';
+			}
+
+		} );
+
+	}
+
+	/**
+	 * Responsively activates the scroll mode when we reach the configured
+	 * activation width.
+	 */
+	function checkResponsiveScrollView() {
+
+		// Only proceed if...
+		// 1. The DOM is ready
+		// 2. Layouts aren't disabled via config
+		// 3. We're not currently printing
+		// 4. There is a scrollActivationWidth set
+		// 5. The deck isn't configured to always use the scroll view
+		if(
+			dom.wrapper &&
+			!config.disableLayout &&
+			!printView.isActive() &&
+			typeof config.scrollActivationWidth === 'number' &&
+			config.view !== 'scroll'
+		) {
+			const size = getComputedSlideSize();
+
+			if( size.presentationWidth > 0 && size.presentationWidth <= config.scrollActivationWidth ) {
+				if( !scrollView.isActive() ) {
+					backgrounds.create();
+					scrollView.activate()
+				};
+			}
+			else {
+				if( scrollView.isActive() ) scrollView.deactivate();
+			}
+		}
+
+	}
+
+	/**
+	 * Calculates the computed pixel size of our slides. These
+	 * values are based on the width and height configuration
+	 * options.
+	 *
+	 * @param {number} [presentationWidth=dom.wrapper.offsetWidth]
+	 * @param {number} [presentationHeight=dom.wrapper.offsetHeight]
+	 */
+	function getComputedSlideSize( presentationWidth, presentationHeight ) {
+
+		let width = config.width;
+		let height = config.height;
+
+		if( config.disableLayout ) {
+			width = dom.slides.offsetWidth;
+			height = dom.slides.offsetHeight;
+		}
+
+		const size = {
+			// Slide size
+			width: width,
+			height: height,
+
+			// Presentation size
+			presentationWidth: presentationWidth || dom.wrapper.offsetWidth,
+			presentationHeight: presentationHeight || dom.wrapper.offsetHeight
+		};
+
+		// Reduce available space by margin
+		size.presentationWidth -= ( size.presentationWidth * config.margin );
+		size.presentationHeight -= ( size.presentationHeight * config.margin );
+
+		// Slide width may be a percentage of available width
+		if( typeof size.width === 'string' && /%$/.test( size.width ) ) {
+			size.width = parseInt( size.width, 10 ) / 100 * size.presentationWidth;
+		}
+
+		// Slide height may be a percentage of available height
+		if( typeof size.height === 'string' && /%$/.test( size.height ) ) {
+			size.height = parseInt( size.height, 10 ) / 100 * size.presentationHeight;
+		}
+
+		return size;
+
+	}
+
+	/**
+	 * Stores the vertical index of a stack so that the same
+	 * vertical slide can be selected when navigating to and
+	 * from the stack.
+	 *
+	 * @param {HTMLElement} stack The vertical stack element
+	 * @param {string|number} [v=0] Index to memorize
+	 */
+	function setPreviousVerticalIndex( stack, v ) {
+
+		if( typeof stack === 'object' && typeof stack.setAttribute === 'function' ) {
+			stack.setAttribute( 'data-previous-indexv', v || 0 );
+		}
+
+	}
+
+	/**
+	 * Retrieves the vertical index which was stored using
+	 * #setPreviousVerticalIndex() or 0 if no previous index
+	 * exists.
+	 *
+	 * @param {HTMLElement} stack The vertical stack element
+	 */
+	function getPreviousVerticalIndex( stack ) {
+
+		if( typeof stack === 'object' && typeof stack.setAttribute === 'function' && stack.classList.contains( 'stack' ) ) {
+			// Prefer manually defined start-indexv
+			const attributeName = stack.hasAttribute( 'data-start-indexv' ) ? 'data-start-indexv' : 'data-previous-indexv';
+
+			return parseInt( stack.getAttribute( attributeName ) || 0, 10 );
+		}
+
+		return 0;
+
+	}
+
+	/**
+	 * Checks if the current or specified slide is vertical
+	 * (nested within another slide).
+	 *
+	 * @param {HTMLElement} [slide=currentSlide] The slide to check
+	 * orientation of
+	 * @return {Boolean}
+	 */
+	function isVerticalSlide( slide = currentSlide ) {
+
+		return slide && slide.parentNode && !!slide.parentNode.nodeName.match( /section/i );
+
+	}
+
+	/**
+	 * Checks if the current or specified slide is a stack containing
+	 * vertical slides.
+	 *
+	 * @param {HTMLElement} [slide=currentSlide]
+	 * @return {Boolean}
+	 */
+	function isVerticalStack( slide = currentSlide ) {
+
+		return slide.classList.contains( '.stack' ) || slide.querySelector( 'section' ) !== null;
+
+	}
+
+	/**
+	 * Returns true if we're on the last slide in the current
+	 * vertical stack.
+	 */
+	function isLastVerticalSlide() {
+
+		if( currentSlide && isVerticalSlide( currentSlide ) ) {
+			// Does this slide have a next sibling?
+			if( currentSlide.nextElementSibling ) return false;
+
+			return true;
+		}
+
+		return false;
+
+	}
+
+	/**
+	 * Returns true if we're currently on the first slide in
+	 * the presentation.
+	 */
+	function isFirstSlide() {
+
+		return indexh === 0 && indexv === 0;
+
+	}
+
+	/**
+	 * Returns true if we're currently on the last slide in
+	 * the presentation. If the last slide is a stack, we only
+	 * consider this the last slide if it's at the end of the
+	 * stack.
+	 */
+	function isLastSlide() {
+
+		if( currentSlide ) {
+			// Does this slide have a next sibling?
+			if( currentSlide.nextElementSibling ) return false;
+
+			// If it's vertical, does its parent have a next sibling?
+			if( isVerticalSlide( currentSlide ) && currentSlide.parentNode.nextElementSibling ) return false;
+
+			return true;
+		}
+
+		return false;
+
+	}
+
+	/**
+	 * Enters the paused mode which fades everything on screen to
+	 * black.
+	 */
+	function pause() {
+
+		if( config.pause ) {
+			const wasPaused = dom.wrapper.classList.contains( 'paused' );
+
+			cancelAutoSlide();
+			dom.wrapper.classList.add( 'paused' );
+
+			if( wasPaused === false ) {
+				dispatchEvent({ type: 'paused' });
+			}
+		}
+
+	}
+
+	/**
+	 * Exits from the paused mode.
+	 */
+	function resume() {
+
+		const wasPaused = dom.wrapper.classList.contains( 'paused' );
+		dom.wrapper.classList.remove( 'paused' );
+
+		cueAutoSlide();
+
+		if( wasPaused ) {
+			dispatchEvent({ type: 'resumed' });
+		}
+
+	}
+
+	/**
+	 * Toggles the paused mode on and off.
+	 */
+	function togglePause( override ) {
+
+		if( typeof override === 'boolean' ) {
+			override ? pause() : resume();
+		}
+		else {
+			isPaused() ? resume() : pause();
+		}
+
+	}
+
+	/**
+	 * Checks if we are currently in the paused mode.
+	 *
+	 * @return {Boolean}
+	 */
+	function isPaused() {
+
+		return dom.wrapper.classList.contains( 'paused' );
+
+	}
+
+	/**
+	 * Toggles visibility of the jump-to-slide UI.
+	 */
+	function toggleJumpToSlide( override ) {
+
+		if( typeof override === 'boolean' ) {
+			override ? jumpToSlide.show() : jumpToSlide.hide();
+		}
+		else {
+			jumpToSlide.isVisible() ? jumpToSlide.hide() : jumpToSlide.show();
+		}
+
+	}
+
+	/**
+	 * Toggles the auto slide mode on and off.
+	 *
+	 * @param {Boolean} [override] Flag which sets the desired state.
+	 * True means autoplay starts, false means it stops.
+	 */
+
+	function toggleAutoSlide( override ) {
+
+		if( typeof override === 'boolean' ) {
+			override ? resumeAutoSlide() : pauseAutoSlide();
+		}
+
+		else {
+			autoSlidePaused ? resumeAutoSlide() : pauseAutoSlide();
+		}
+
+	}
+
+	/**
+	 * Checks if the auto slide mode is currently on.
+	 *
+	 * @return {Boolean}
+	 */
+	function isAutoSliding() {
+
+		return !!( autoSlide && !autoSlidePaused );
+
+	}
+
+	/**
+	 * Steps from the current point in the presentation to the
+	 * slide which matches the specified horizontal and vertical
+	 * indices.
+	 *
+	 * @param {number} [h=indexh] Horizontal index of the target slide
+	 * @param {number} [v=indexv] Vertical index of the target slide
+	 * @param {number} [f] Index of a fragment within the
+	 * target slide to activate
+	 * @param {number} [origin] Origin for use in multimaster environments
+	 */
+	function slide( h, v, f, origin ) {
+
+		// Dispatch an event before the slide
+		const slidechange = dispatchEvent({
+			type: 'beforeslidechange',
+			data: {
+				indexh: h === undefined ? indexh : h,
+				indexv: v === undefined ? indexv : v,
+				origin
+			}
+		});
+
+		// Abort if this slide change was prevented by an event listener
+		if( slidechange.defaultPrevented ) return;
+
+		// Remember where we were at before
+		previousSlide = currentSlide;
+
+		// Query all horizontal slides in the deck
+		const horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
+
+		// If we're in scroll mode, we scroll the target slide into view
+		// instead of running our standard slide transition
+		if( scrollView.isActive() ) {
+			const scrollToSlide = scrollView.getSlideByIndices( h, v );
+			if( scrollToSlide ) scrollView.scrollToSlide( scrollToSlide );
+			return;
+		}
+
+		// Abort if there are no slides
+		if( horizontalSlides.length === 0 ) return;
+
+		// If no vertical index is specified and the upcoming slide is a
+		// stack, resume at its previous vertical index
+		if( v === undefined && !overview.isActive() ) {
+			v = getPreviousVerticalIndex( horizontalSlides[ h ] );
+		}
+
+		// If we were on a vertical stack, remember what vertical index
+		// it was on so we can resume at the same position when returning
+		if( previousSlide && previousSlide.parentNode && previousSlide.parentNode.classList.contains( 'stack' ) ) {
+			setPreviousVerticalIndex( previousSlide.parentNode, indexv );
+		}
+
+		// Remember the state before this slide
+		const stateBefore = state.concat();
+
+		// Reset the state array
+		state.length = 0;
+
+		let indexhBefore = indexh || 0,
+			indexvBefore = indexv || 0;
+
+		// Activate and transition to the new slide
+		indexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h );
+		indexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v );
+
+		// Dispatch an event if the slide changed
+		let slideChanged = ( indexh !== indexhBefore || indexv !== indexvBefore );
+
+		// Ensure that the previous slide is never the same as the current
+		if( !slideChanged ) previousSlide = null;
+
+		// Find the current horizontal slide and any possible vertical slides
+		// within it
+		let currentHorizontalSlide = horizontalSlides[ indexh ],
+			currentVerticalSlides = currentHorizontalSlide.querySelectorAll( 'section' );
+
+		// Indicate when we're on a vertical slide
+		revealElement.classList.toggle( 'is-vertical-slide', currentVerticalSlides.length > 1 );
+
+		// Store references to the previous and current slides
+		currentSlide = currentVerticalSlides[ indexv ] || currentHorizontalSlide;
+
+		let autoAnimateTransition = false;
+
+		// Detect if we're moving between two auto-animated slides
+		if( slideChanged && previousSlide && currentSlide && !overview.isActive() ) {
+			transition = 'running';
+
+			autoAnimateTransition = shouldAutoAnimateBetween( previousSlide, currentSlide, indexhBefore, indexvBefore );
+
+			// If this is an auto-animated transition, we disable the
+			// regular slide transition
+			//
+			// Note 20-03-2020:
+			// This needs to happen before we update slide visibility,
+			// otherwise transitions will still run in Safari.
+			if( autoAnimateTransition ) {
+				dom.slides.classList.add( 'disable-slide-transitions' )
+			}
+		}
+
+		// Update the visibility of slides now that the indices have changed
+		updateSlidesVisibility();
+
+		layout();
+
+		// Update the overview if it's currently active
+		if( overview.isActive() ) {
+			overview.update();
+		}
+
+		// Show fragment, if specified
+		if( typeof f !== 'undefined' ) {
+			fragments.goto( f );
+		}
+
+		// Solves an edge case where the previous slide maintains the
+		// 'present' class when navigating between adjacent vertical
+		// stacks
+		if( previousSlide && previousSlide !== currentSlide ) {
+			previousSlide.classList.remove( 'present' );
+			previousSlide.setAttribute( 'aria-hidden', 'true' );
+
+			// Reset all slides upon navigate to home
+			if( isFirstSlide() ) {
+				// Launch async task
+				setTimeout( () => {
+					getVerticalStacks().forEach( slide => {
+						setPreviousVerticalIndex( slide, 0 );
+					} );
+				}, 0 );
+			}
+		}
+
+		// Apply the new state
+		stateLoop: for( let i = 0, len = state.length; i < len; i++ ) {
+			// Check if this state existed on the previous slide. If it
+			// did, we will avoid adding it repeatedly
+			for( let j = 0; j < stateBefore.length; j++ ) {
+				if( stateBefore[j] === state[i] ) {
+					stateBefore.splice( j, 1 );
+					continue stateLoop;
+				}
+			}
+
+			dom.viewport.classList.add( state[i] );
+
+			// Dispatch custom event matching the state's name
+			dispatchEvent({ type: state[i] });
+		}
+
+		// Clean up the remains of the previous state
+		while( stateBefore.length ) {
+			dom.viewport.classList.remove( stateBefore.pop() );
+		}
+
+		if( slideChanged ) {
+			dispatchSlideChanged( origin );
+		}
+
+		// Handle embedded content
+		if( slideChanged || !previousSlide ) {
+			slideContent.stopEmbeddedContent( previousSlide );
+			slideContent.startEmbeddedContent( currentSlide );
+		}
+
+		// Announce the current slide contents to screen readers
+		// Use animation frame to prevent getComputedStyle in getStatusText
+		// from triggering layout mid-frame
+		requestAnimationFrame( () => {
+			announceStatus( getStatusText( currentSlide ) );
+		});
+
+		progress.update();
+		controls.update();
+		notes.update();
+		backgrounds.update();
+		backgrounds.updateParallax();
+		slideNumber.update();
+		fragments.update();
+
+		// Update the URL hash
+		location.writeURL();
+
+		cueAutoSlide();
+
+		// Auto-animation
+		if( autoAnimateTransition ) {
+
+			setTimeout( () => {
+				dom.slides.classList.remove( 'disable-slide-transitions' );
+			}, 0 );
+
+			if( config.autoAnimate ) {
+				// Run the auto-animation between our slides
+				autoAnimate.run( previousSlide, currentSlide );
+			}
+
+		}
+
+	}
+
+	/**
+	 * Checks whether or not an auto-animation should take place between
+	 * the two given slides.
+	 *
+	 * @param {HTMLElement} fromSlide
+	 * @param {HTMLElement} toSlide
+	 * @param {number} indexhBefore
+	 * @param {number} indexvBefore
+	 *
+	 * @returns {boolean}
+	 */
+	function shouldAutoAnimateBetween( fromSlide, toSlide, indexhBefore, indexvBefore ) {
+
+		return 	fromSlide.hasAttribute( 'data-auto-animate' ) && toSlide.hasAttribute( 'data-auto-animate' ) &&
+				fromSlide.getAttribute( 'data-auto-animate-id' ) === toSlide.getAttribute( 'data-auto-animate-id' ) &&
+				!( ( indexh > indexhBefore || indexv > indexvBefore ) ? toSlide : fromSlide ).hasAttribute( 'data-auto-animate-restart' );
+
+	}
+
+	/**
+	 * Called anytime a new slide should be activated while in the scroll
+	 * view. The active slide is the page that occupies the most space in
+	 * the scrollable viewport.
+	 *
+	 * @param {number} pageIndex
+	 * @param {HTMLElement} slideElement
+	 */
+	function setCurrentScrollPage( slideElement, h, v ) {
+
+		let indexhBefore = indexh || 0;
+
+		indexh = h;
+		indexv = v;
+
+		const slideChanged = currentSlide !== slideElement;
+
+		previousSlide = currentSlide;
+		currentSlide = slideElement;
+
+		if( currentSlide && previousSlide ) {
+			if( config.autoAnimate && shouldAutoAnimateBetween( previousSlide, currentSlide, indexhBefore, indexv ) ) {
+				// Run the auto-animation between our slides
+				autoAnimate.run( previousSlide, currentSlide );
+			}
+		}
+
+		// Start or stop embedded content like videos and iframes
+		if( slideChanged ) {
+			if( previousSlide ) {
+				slideContent.stopEmbeddedContent( previousSlide );
+				slideContent.stopEmbeddedContent( previousSlide.slideBackgroundElement );
+			}
+
+			slideContent.startEmbeddedContent( currentSlide );
+			slideContent.startEmbeddedContent( currentSlide.slideBackgroundElement );
+		}
+
+		requestAnimationFrame( () => {
+			announceStatus( getStatusText( currentSlide ) );
+		});
+
+		dispatchSlideChanged();
+
+	}
+
+	/**
+	 * Syncs the presentation with the current DOM. Useful
+	 * when new slides or control elements are added or when
+	 * the configuration has changed.
+	 */
+	function sync() {
+
+		// Subscribe to input
+		removeEventListeners();
+		addEventListeners();
+
+		// Force a layout to make sure the current config is accounted for
+		layout();
+
+		// Reflect the current autoSlide value
+		autoSlide = config.autoSlide;
+
+		// Start auto-sliding if it's enabled
+		cueAutoSlide();
+
+		// Re-create all slide backgrounds
+		backgrounds.create();
+
+		// Write the current hash to the URL
+		location.writeURL();
+
+		if( config.sortFragmentsOnSync === true ) {
+			fragments.sortAll();
+		}
+
+		controls.update();
+		progress.update();
+
+		updateSlidesVisibility();
+
+		notes.update();
+		notes.updateVisibility();
+		overlay.update();
+		backgrounds.update( true );
+		slideNumber.update();
+		slideContent.formatEmbeddedContent();
+
+		// Start or stop embedded content depending on global config
+		if( config.autoPlayMedia === false ) {
+			slideContent.stopEmbeddedContent( currentSlide, { unloadIframes: false } );
+		}
+		else {
+			slideContent.startEmbeddedContent( currentSlide );
+		}
+
+		if( overview.isActive() ) {
+			overview.layout();
+		}
+
+	}
+
+	/**
+	 * Updates reveal.js to keep in sync with new slide attributes. For
+	 * example, if you add a new `data-background-image` you can call
+	 * this to have reveal.js render the new background image.
+	 *
+	 * Similar to #sync() but more efficient when you only need to
+	 * refresh a specific slide.
+	 *
+	 * @param {HTMLElement} slide
+	 */
+	function syncSlide( slide = currentSlide ) {
+
+		backgrounds.sync( slide );
+		fragments.sync( slide );
+
+		slideContent.load( slide );
+
+		backgrounds.update();
+		notes.update();
+
+	}
+
+	/**
+	 * Resets all vertical slides so that only the first
+	 * is visible.
+	 */
+	function resetVerticalSlides() {
+
+		getHorizontalSlides().forEach( horizontalSlide => {
+
+			Util.queryAll( horizontalSlide, 'section' ).forEach( ( verticalSlide, y ) => {
+
+				if( y > 0 ) {
+					verticalSlide.classList.remove( 'present' );
+					verticalSlide.classList.remove( 'past' );
+					verticalSlide.classList.add( 'future' );
+					verticalSlide.setAttribute( 'aria-hidden', 'true' );
+				}
+
+			} );
+
+		} );
+
+	}
+
+	/**
+	 * Randomly shuffles all slides in the deck.
+	 */
+	function shuffle( slides = getHorizontalSlides() ) {
+
+		slides.forEach( ( slide, i ) => {
+
+			// Insert the slide next to a randomly picked sibling slide
+			// slide. This may cause the slide to insert before itself,
+			// but that's not an issue.
+			let beforeSlide = slides[ Math.floor( Math.random() * slides.length ) ];
+			if( beforeSlide.parentNode === slide.parentNode ) {
+				slide.parentNode.insertBefore( slide, beforeSlide );
+			}
+
+			// Randomize the order of vertical slides (if there are any)
+			let verticalSlides = slide.querySelectorAll( 'section' );
+			if( verticalSlides.length ) {
+				shuffle( verticalSlides );
+			}
+
+		} );
+
+	}
+
+	/**
+	 * Updates one dimension of slides by showing the slide
+	 * with the specified index.
+	 *
+	 * @param {string} selector A CSS selector that will fetch
+	 * the group of slides we are working with
+	 * @param {number} index The index of the slide that should be
+	 * shown
+	 *
+	 * @return {number} The index of the slide that is now shown,
+	 * might differ from the passed in index if it was out of
+	 * bounds.
+	 */
+	function updateSlides( selector, index ) {
+
+		// Select all slides and convert the NodeList result to
+		// an array
+		let slides = Util.queryAll( dom.wrapper, selector ),
+			slidesLength = slides.length;
+
+		let printMode = scrollView.isActive() || printView.isActive();
+		let loopedForwards = false;
+		let loopedBackwards = false;
+
+		if( slidesLength ) {
+
+			// Should the index loop?
+			if( config.loop ) {
+				if( index >= slidesLength ) loopedForwards = true;
+
+				index %= slidesLength;
+
+				if( index < 0 ) {
+					index = slidesLength + index;
+					loopedBackwards = true;
+				}
+			}
+
+			// Enforce max and minimum index bounds
+			index = Math.max( Math.min( index, slidesLength - 1 ), 0 );
+
+			for( let i = 0; i < slidesLength; i++ ) {
+				let element = slides[i];
+
+				let reverse = config.rtl && !isVerticalSlide( element );
+
+				// Avoid .remove() with multiple args for IE11 support
+				element.classList.remove( 'past' );
+				element.classList.remove( 'present' );
+				element.classList.remove( 'future' );
+
+				// http://www.w3.org/html/wg/drafts/html/master/editing.html#the-hidden-attribute
+				element.setAttribute( 'hidden', '' );
+				element.setAttribute( 'aria-hidden', 'true' );
+
+				// If this element contains vertical slides
+				if( element.querySelector( 'section' ) ) {
+					element.classList.add( 'stack' );
+				}
+
+				// If we're printing static slides, all slides are "present"
+				if( printMode ) {
+					element.classList.add( 'present' );
+					continue;
+				}
+
+				if( i < index ) {
+					// Any element previous to index is given the 'past' class
+					element.classList.add( reverse ? 'future' : 'past' );
+
+					if( config.fragments ) {
+						// Show all fragments in prior slides
+						showFragmentsIn( element );
+					}
+				}
+				else if( i > index ) {
+					// Any element subsequent to index is given the 'future' class
+					element.classList.add( reverse ? 'past' : 'future' );
+
+					if( config.fragments ) {
+						// Hide all fragments in future slides
+						hideFragmentsIn( element );
+					}
+				}
+				// Update the visibility of fragments when a presentation loops
+				// in either direction
+				else if( i === index && config.fragments ) {
+					if( loopedForwards ) {
+						hideFragmentsIn( element );
+					}
+					else if( loopedBackwards ) {
+						showFragmentsIn( element );
+					}
+				}
+			}
+
+			let slide = slides[index];
+			let wasPresent = slide.classList.contains( 'present' );
+
+			// Mark the current slide as present
+			slide.classList.add( 'present' );
+			slide.removeAttribute( 'hidden' );
+			slide.removeAttribute( 'aria-hidden' );
+
+			if( !wasPresent ) {
+				// Dispatch an event indicating the slide is now visible
+				dispatchEvent({
+					target: slide,
+					type: 'visible',
+					bubbles: false
+				});
+			}
+
+			// If this slide has a state associated with it, add it
+			// onto the current state of the deck
+			let slideState = slide.getAttribute( 'data-state' );
+			if( slideState ) {
+				state = state.concat( slideState.split( ' ' ) );
+			}
+
+		}
+		else {
+			// Since there are no slides we can't be anywhere beyond the
+			// zeroth index
+			index = 0;
+		}
+
+		return index;
+
+	}
+
+	/**
+	 * Shows all fragment elements within the given container.
+	 */
+	function showFragmentsIn( container ) {
+
+		Util.queryAll( container, '.fragment' ).forEach( fragment => {
+			fragment.classList.add( 'visible' );
+			fragment.classList.remove( 'current-fragment' );
+		} );
+
+	}
+
+	/**
+	 * Hides all fragment elements within the given container.
+	 */
+	function hideFragmentsIn( container ) {
+
+		Util.queryAll( container, '.fragment.visible' ).forEach( fragment => {
+			fragment.classList.remove( 'visible', 'current-fragment' );
+		} );
+
+	}
+
+	/**
+	 * Optimization method; hide all slides that are far away
+	 * from the present slide.
+	 */
+	function updateSlidesVisibility() {
+
+		// Select all slides and convert the NodeList result to
+		// an array
+		let horizontalSlides = getHorizontalSlides(),
+			horizontalSlidesLength = horizontalSlides.length,
+			distanceX,
+			distanceY;
+
+		if( horizontalSlidesLength && typeof indexh !== 'undefined' ) {
+
+			// The number of steps away from the present slide that will
+			// be visible
+			let viewDistance = overview.isActive() ? 10 : config.viewDistance;
+
+			// Shorten the view distance on devices that typically have
+			// less resources
+			if( Device.isMobile ) {
+				viewDistance = overview.isActive() ? 6 : config.mobileViewDistance;
+			}
+
+			// All slides need to be visible when exporting to PDF
+			if( printView.isActive() ) {
+				viewDistance = Number.MAX_VALUE;
+			}
+
+			for( let x = 0; x < horizontalSlidesLength; x++ ) {
+				let horizontalSlide = horizontalSlides[x];
+
+				let verticalSlides = Util.queryAll( horizontalSlide, 'section' ),
+					verticalSlidesLength = verticalSlides.length;
+
+				// Determine how far away this slide is from the present
+				distanceX = Math.abs( ( indexh || 0 ) - x ) || 0;
+
+				// If the presentation is looped, distance should measure
+				// 1 between the first and last slides
+				if( config.loop ) {
+					distanceX = Math.abs( ( ( indexh || 0 ) - x ) % ( horizontalSlidesLength - viewDistance ) ) || 0;
+				}
+
+				// Show the horizontal slide if it's within the view distance
+				if( distanceX < viewDistance ) {
+					slideContent.load( horizontalSlide );
+				}
+				else {
+					slideContent.unload( horizontalSlide );
+				}
+
+				if( verticalSlidesLength ) {
+
+					let oy = getPreviousVerticalIndex( horizontalSlide );
+
+					for( let y = 0; y < verticalSlidesLength; y++ ) {
+						let verticalSlide = verticalSlides[y];
+
+						distanceY = x === ( indexh || 0 ) ? Math.abs( ( indexv || 0 ) - y ) : Math.abs( y - oy );
+
+						if( distanceX + distanceY < viewDistance ) {
+							slideContent.load( verticalSlide );
+						}
+						else {
+							slideContent.unload( verticalSlide );
+						}
+					}
+
+				}
+			}
+
+			// Flag if there are ANY vertical slides, anywhere in the deck
+			if( hasVerticalSlides() ) {
+				dom.wrapper.classList.add( 'has-vertical-slides' );
+			}
+			else {
+				dom.wrapper.classList.remove( 'has-vertical-slides' );
+			}
+
+			// Flag if there are ANY horizontal slides, anywhere in the deck
+			if( hasHorizontalSlides() ) {
+				dom.wrapper.classList.add( 'has-horizontal-slides' );
+			}
+			else {
+				dom.wrapper.classList.remove( 'has-horizontal-slides' );
+			}
+
+		}
+
+	}
+
+	/**
+	 * Determine what available routes there are for navigation.
+	 *
+	 * @return {{left: boolean, right: boolean, up: boolean, down: boolean}}
+	 */
+	function availableRoutes({ includeFragments = false } = {}) {
+
+		let horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ),
+			verticalSlides = dom.wrapper.querySelectorAll( VERTICAL_SLIDES_SELECTOR );
+
+		let routes = {
+			left: indexh > 0,
+			right: indexh < horizontalSlides.length - 1,
+			up: indexv > 0,
+			down: indexv < verticalSlides.length - 1
+		};
+
+		// Looped presentations can always be navigated as long as
+		// there are slides available
+		if( config.loop ) {
+			if( horizontalSlides.length > 1 ) {
+				routes.left = true;
+				routes.right = true;
+			}
+
+			if( verticalSlides.length > 1 ) {
+				routes.up = true;
+				routes.down = true;
+			}
+		}
+
+		if ( horizontalSlides.length > 1 && config.navigationMode === 'linear' ) {
+			routes.right = routes.right || routes.down;
+			routes.left = routes.left || routes.up;
+		}
+
+		// If includeFragments is set, a route will be considered
+		// available if either a slid OR fragment is available in
+		// the given direction
+		if( includeFragments === true ) {
+			let fragmentRoutes = fragments.availableRoutes();
+			routes.left = routes.left || fragmentRoutes.prev;
+			routes.up = routes.up || fragmentRoutes.prev;
+			routes.down = routes.down || fragmentRoutes.next;
+			routes.right = routes.right || fragmentRoutes.next;
+		}
+
+		// Reverse horizontal controls for rtl
+		if( config.rtl ) {
+			let left = routes.left;
+			routes.left = routes.right;
+			routes.right = left;
+		}
+
+		return routes;
+
+	}
+
+	/**
+	 * Returns the number of past slides. This can be used as a global
+	 * flattened index for slides.
+	 *
+	 * @param {HTMLElement} [slide=currentSlide] The slide we're counting before
+	 *
+	 * @return {number} Past slide count
+	 */
+	function getSlidePastCount( slide = currentSlide ) {
+
+		let horizontalSlides = getHorizontalSlides();
+
+		// The number of past slides
+		let pastCount = 0;
+
+		// Step through all slides and count the past ones
+		mainLoop: for( let i = 0; i < horizontalSlides.length; i++ ) {
+
+			let horizontalSlide = horizontalSlides[i];
+			let verticalSlides = horizontalSlide.querySelectorAll( 'section' );
+
+			for( let j = 0; j < verticalSlides.length; j++ ) {
+
+				// Stop as soon as we arrive at the present
+				if( verticalSlides[j] === slide ) {
+					break mainLoop;
+				}
+
+				// Don't count slides with the "uncounted" class
+				if( verticalSlides[j].dataset.visibility !== 'uncounted' ) {
+					pastCount++;
+				}
+
+			}
+
+			// Stop as soon as we arrive at the present
+			if( horizontalSlide === slide ) {
+				break;
+			}
+
+			// Don't count the wrapping section for vertical slides and
+			// slides marked as uncounted
+			if( horizontalSlide.classList.contains( 'stack' ) === false && horizontalSlide.dataset.visibility !== 'uncounted' ) {
+				pastCount++;
+			}
+
+		}
+
+		return pastCount;
+
+	}
+
+	/**
+	 * Returns a value ranging from 0-1 that represents
+	 * how far into the presentation we have navigated.
+	 *
+	 * @return {number}
+	 */
+	function getProgress() {
+
+		// The number of past and total slides
+		let totalCount = getTotalSlides();
+		let pastCount = getSlidePastCount();
+
+		if( currentSlide ) {
+
+			let allFragments = currentSlide.querySelectorAll( '.fragment' );
+
+			// If there are fragments in the current slide those should be
+			// accounted for in the progress.
+			if( allFragments.length > 0 ) {
+				let visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' );
+
+				// This value represents how big a portion of the slide progress
+				// that is made up by its fragments (0-1)
+				let fragmentWeight = 0.9;
+
+				// Add fragment progress to the past slide count
+				pastCount += ( visibleFragments.length / allFragments.length ) * fragmentWeight;
+			}
+
+		}
+
+		return Math.min( pastCount / ( totalCount - 1 ), 1 );
+
+	}
+
+	/**
+	 * Retrieves the h/v location and fragment of the current,
+	 * or specified, slide.
+	 *
+	 * @param {HTMLElement} [slide] If specified, the returned
+	 * index will be for this slide rather than the currently
+	 * active one
+	 *
+	 * @return {{h: number, v: number, f: number}}
+	 */
+	function getIndices( slide ) {
+
+		// By default, return the current indices
+		let h = indexh,
+			v = indexv,
+			f;
+
+		// If a slide is specified, return the indices of that slide
+		if( slide ) {
+			// In scroll mode the original h/x index is stored on the slide
+			if( scrollView.isActive() ) {
+				h = parseInt( slide.getAttribute( 'data-index-h' ), 10 );
+
+				if( slide.getAttribute( 'data-index-v' ) ) {
+					v = parseInt( slide.getAttribute( 'data-index-v' ), 10 );
+				}
+			}
+			else {
+				let isVertical = isVerticalSlide( slide );
+				let slideh = isVertical ? slide.parentNode : slide;
+
+				// Select all horizontal slides
+				let horizontalSlides = getHorizontalSlides();
+
+				// Now that we know which the horizontal slide is, get its index
+				h = Math.max( horizontalSlides.indexOf( slideh ), 0 );
+
+				// Assume we're not vertical
+				v = undefined;
+
+				// If this is a vertical slide, grab the vertical index
+				if( isVertical ) {
+					v = Math.max( Util.queryAll( slide.parentNode, 'section' ).indexOf( slide ), 0 );
+				}
+			}
+		}
+
+		if( !slide && currentSlide ) {
+			let hasFragments = currentSlide.querySelectorAll( '.fragment' ).length > 0;
+			if( hasFragments ) {
+				let currentFragment = currentSlide.querySelector( '.current-fragment' );
+				if( currentFragment && currentFragment.hasAttribute( 'data-fragment-index' ) ) {
+					f = parseInt( currentFragment.getAttribute( 'data-fragment-index' ), 10 );
+				}
+				else {
+					f = currentSlide.querySelectorAll( '.fragment.visible' ).length - 1;
+				}
+			}
+		}
+
+		return { h, v, f };
+
+	}
+
+	/**
+	 * Retrieves all slides in this presentation.
+	 */
+	function getSlides() {
+
+		return Util.queryAll( dom.wrapper, SLIDES_SELECTOR + ':not(.stack):not([data-visibility="uncounted"])' );
+
+	}
+
+	/**
+	 * Returns a list of all horizontal slides in the deck. Each
+	 * vertical stack is included as one horizontal slide in the
+	 * resulting array.
+	 */
+	function getHorizontalSlides() {
+
+		return Util.queryAll( dom.wrapper, HORIZONTAL_SLIDES_SELECTOR );
+
+	}
+
+	/**
+	 * Returns all vertical slides that exist within this deck.
+	 */
+	function getVerticalSlides() {
+
+		return Util.queryAll( dom.wrapper, '.slides>section>section' );
+
+	}
+
+	/**
+	 * Returns all vertical stacks (each stack can contain multiple slides).
+	 */
+	function getVerticalStacks() {
+
+		return Util.queryAll( dom.wrapper, HORIZONTAL_SLIDES_SELECTOR + '.stack');
+
+	}
+
+	/**
+	 * Returns true if there are at least two horizontal slides.
+	 */
+	function hasHorizontalSlides() {
+
+		return getHorizontalSlides().length > 1;
+	}
+
+	/**
+	 * Returns true if there are at least two vertical slides.
+	 */
+	function hasVerticalSlides() {
+
+		return getVerticalSlides().length > 1;
+
+	}
+
+	/**
+	 * Returns an array of objects where each object represents the
+	 * attributes on its respective slide.
+	 */
+	function getSlidesAttributes() {
+
+		return getSlides().map( slide => {
+
+			let attributes = {};
+			for( let i = 0; i < slide.attributes.length; i++ ) {
+				let attribute = slide.attributes[ i ];
+				attributes[ attribute.name ] = attribute.value;
+			}
+			return attributes;
+
+		} );
+
+	}
+
+	/**
+	 * Retrieves the total number of slides in this presentation.
+	 *
+	 * @return {number}
+	 */
+	function getTotalSlides() {
+
+		return getSlides().length;
+
+	}
+
+	/**
+	 * Returns the slide element matching the specified index.
+	 *
+	 * @return {HTMLElement}
+	 */
+	function getSlide( x, y ) {
+
+		let horizontalSlide = getHorizontalSlides()[ x ];
+		let verticalSlides = horizontalSlide && horizontalSlide.querySelectorAll( 'section' );
+
+		if( verticalSlides && verticalSlides.length && typeof y === 'number' ) {
+			return verticalSlides ? verticalSlides[ y ] : undefined;
+		}
+
+		return horizontalSlide;
+
+	}
+
+	/**
+	 * Returns the background element for the given slide.
+	 * All slides, even the ones with no background properties
+	 * defined, have a background element so as long as the
+	 * index is valid an element will be returned.
+	 *
+	 * @param {mixed} x Horizontal background index OR a slide
+	 * HTML element
+	 * @param {number} y Vertical background index
+	 * @return {(HTMLElement[]|*)}
+	 */
+	function getSlideBackground( x, y ) {
+
+		let slide = typeof x === 'number' ? getSlide( x, y ) : x;
+		if( slide ) {
+			return slide.slideBackgroundElement;
+		}
+
+		return undefined;
+
+	}
+
+	/**
+	 * Retrieves the current state of the presentation as
+	 * an object. This state can then be restored at any
+	 * time.
+	 *
+	 * @return {{indexh: number, indexv: number, indexf: number, paused: boolean, overview: boolean}}
+	 */
+	function getState() {
+
+		let indices = getIndices();
+
+		return {
+			indexh: indices.h,
+			indexv: indices.v,
+			indexf: indices.f,
+			paused: isPaused(),
+			overview: overview.isActive(),
+			...overlay.getState()
+		};
+
+	}
+
+	/**
+	 * Restores the presentation to the given state.
+	 *
+	 * @param {object} state As generated by getState()
+	 * @see {@link getState} generates the parameter `state`
+	 */
+	function setState( state ) {
+
+		if( typeof state === 'object' ) {
+			slide( Util.deserialize( state.indexh ), Util.deserialize( state.indexv ), Util.deserialize( state.indexf ) );
+
+			let pausedFlag = Util.deserialize( state.paused ),
+				overviewFlag = Util.deserialize( state.overview );
+
+			if( typeof pausedFlag === 'boolean' && pausedFlag !== isPaused() ) {
+				togglePause( pausedFlag );
+			}
+
+			if( typeof overviewFlag === 'boolean' && overviewFlag !== overview.isActive() ) {
+				overview.toggle( overviewFlag );
+			}
+
+			overlay.setState( state );
+		}
+
+	}
+
+	/**
+	 * Cues a new automated slide if enabled in the config.
+	 */
+	function cueAutoSlide() {
+
+		cancelAutoSlide();
+
+		if( currentSlide && config.autoSlide !== false ) {
+
+			let fragment = currentSlide.querySelector( '.current-fragment[data-autoslide]' );
+
+			let fragmentAutoSlide = fragment ? fragment.getAttribute( 'data-autoslide' ) : null;
+			let parentAutoSlide = currentSlide.parentNode ? currentSlide.parentNode.getAttribute( 'data-autoslide' ) : null;
+			let slideAutoSlide = currentSlide.getAttribute( 'data-autoslide' );
+
+			// Pick value in the following priority order:
+			// 1. Current fragment's data-autoslide
+			// 2. Current slide's data-autoslide
+			// 3. Parent slide's data-autoslide
+			// 4. Global autoSlide setting
+			if( fragmentAutoSlide ) {
+				autoSlide = parseInt( fragmentAutoSlide, 10 );
+			}
+			else if( slideAutoSlide ) {
+				autoSlide = parseInt( slideAutoSlide, 10 );
+			}
+			else if( parentAutoSlide ) {
+				autoSlide = parseInt( parentAutoSlide, 10 );
+			}
+			else {
+				autoSlide = config.autoSlide;
+
+				// If there are media elements with data-autoplay,
+				// automatically set the autoSlide duration to the
+				// length of that media. Not applicable if the slide
+				// is divided up into fragments.
+				// playbackRate is accounted for in the duration.
+				if( currentSlide.querySelectorAll( '.fragment' ).length === 0 ) {
+					Util.queryAll( currentSlide, 'video, audio' ).forEach( el => {
+						if( el.hasAttribute( 'data-autoplay' ) ) {
+							if( autoSlide && (el.duration * 1000 / el.playbackRate ) > autoSlide ) {
+								autoSlide = ( el.duration * 1000 / el.playbackRate ) + 1000;
+							}
+						}
+					} );
+				}
+			}
+
+			// Cue the next auto-slide if:
+			// - There is an autoSlide value
+			// - Auto-sliding isn't paused by the user
+			// - The presentation isn't paused
+			// - The overview isn't active
+			// - The presentation isn't over
+			if( autoSlide && !autoSlidePaused && !isPaused() && !overview.isActive() && ( !isLastSlide() || fragments.availableRoutes().next || config.loop === true ) ) {
+				autoSlideTimeout = setTimeout( () => {
+					if( typeof config.autoSlideMethod === 'function' ) {
+						config.autoSlideMethod()
+					}
+					else {
+						navigateNext();
+					}
+					cueAutoSlide();
+				}, autoSlide );
+				autoSlideStartTime = Date.now();
+			}
+
+			if( autoSlidePlayer ) {
+				autoSlidePlayer.setPlaying( autoSlideTimeout !== -1 );
+			}
+
+		}
+
+	}
+
+	/**
+	 * Cancels any ongoing request to auto-slide.
+	 */
+	function cancelAutoSlide() {
+
+		clearTimeout( autoSlideTimeout );
+		autoSlideTimeout = -1;
+
+	}
+
+	function pauseAutoSlide() {
+
+		if( autoSlide && !autoSlidePaused ) {
+			autoSlidePaused = true;
+			dispatchEvent({ type: 'autoslidepaused' });
+			clearTimeout( autoSlideTimeout );
+
+			if( autoSlidePlayer ) {
+				autoSlidePlayer.setPlaying( false );
+			}
+		}
+
+	}
+
+	function resumeAutoSlide() {
+
+		if( autoSlide && autoSlidePaused ) {
+			autoSlidePaused = false;
+			dispatchEvent({ type: 'autoslideresumed' });
+			cueAutoSlide();
+		}
+
+	}
+
+	function navigateLeft({skipFragments=false}={}) {
+
+		navigationHistory.hasNavigatedHorizontally = true;
+
+		// Scroll view navigation is handled independently
+		if( scrollView.isActive() ) return scrollView.prev();
+
+		// Reverse for RTL
+		if( config.rtl ) {
+			if( ( overview.isActive() || skipFragments || fragments.next() === false ) && availableRoutes().left ) {
+				slide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined );
+			}
+		}
+		// Normal navigation
+		else if( ( overview.isActive() || skipFragments || fragments.prev() === false ) && availableRoutes().left ) {
+			slide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined );
+		}
+
+	}
+
+	function navigateRight({skipFragments=false}={}) {
+
+		navigationHistory.hasNavigatedHorizontally = true;
+
+		// Scroll view navigation is handled independently
+		if( scrollView.isActive() ) return scrollView.next();
+
+		// Reverse for RTL
+		if( config.rtl ) {
+			if( ( overview.isActive() || skipFragments || fragments.prev() === false ) && availableRoutes().right ) {
+				slide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined );
+			}
+		}
+		// Normal navigation
+		else if( ( overview.isActive() || skipFragments || fragments.next() === false ) && availableRoutes().right ) {
+			slide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined );
+		}
+
+	}
+
+	function navigateUp({skipFragments=false}={}) {
+
+		// Scroll view navigation is handled independently
+		if( scrollView.isActive() ) return scrollView.prev();
+
+		// Prioritize hiding fragments
+		if( ( overview.isActive() || skipFragments || fragments.prev() === false ) && availableRoutes().up ) {
+			slide( indexh, indexv - 1 );
+		}
+
+	}
+
+	function navigateDown({skipFragments=false}={}) {
+
+		navigationHistory.hasNavigatedVertically = true;
+
+		// Scroll view navigation is handled independently
+		if( scrollView.isActive() ) return scrollView.next();
+
+		// Prioritize revealing fragments
+		if( ( overview.isActive() || skipFragments || fragments.next() === false ) && availableRoutes().down ) {
+			slide( indexh, indexv + 1 );
+		}
+
+	}
+
+	/**
+	 * Navigates backwards, prioritized in the following order:
+	 * 1) Previous fragment
+	 * 2) Previous vertical slide
+	 * 3) Previous horizontal slide
+	 */
+	function navigatePrev({skipFragments=false}={}) {
+
+		// Scroll view navigation is handled independently
+		if( scrollView.isActive() ) return scrollView.prev();
+
+		// Prioritize revealing fragments
+		if( skipFragments || fragments.prev() === false ) {
+			if( availableRoutes().up ) {
+				navigateUp({skipFragments});
+			}
+			else {
+				// Fetch the previous horizontal slide, if there is one
+				let previousSlide;
+
+				if( config.rtl ) {
+					previousSlide = Util.queryAll( dom.wrapper, HORIZONTAL_SLIDES_SELECTOR + '.future' ).pop();
+				}
+				else {
+					previousSlide = Util.queryAll( dom.wrapper, HORIZONTAL_SLIDES_SELECTOR + '.past' ).pop();
+				}
+
+				// When going backwards and arriving on a stack we start
+				// at the bottom of the stack
+				if( previousSlide && previousSlide.classList.contains( 'stack' ) ) {
+					let v = ( previousSlide.querySelectorAll( 'section' ).length - 1 ) || undefined;
+					let h = indexh - 1;
+					slide( h, v );
+				}
+				else if( config.rtl ) {
+					navigateRight({skipFragments});
+				}
+				else {
+					navigateLeft({skipFragments});
+				}
+			}
+		}
+
+	}
+
+	/**
+	 * The reverse of #navigatePrev().
+	 */
+	function navigateNext({skipFragments=false}={}) {
+
+		navigationHistory.hasNavigatedHorizontally = true;
+		navigationHistory.hasNavigatedVertically = true;
+
+		// Scroll view navigation is handled independently
+		if( scrollView.isActive() ) return scrollView.next();
+
+		// Prioritize revealing fragments
+		if( skipFragments || fragments.next() === false ) {
+
+			let routes = availableRoutes();
+
+			// When looping is enabled `routes.down` is always available
+			// so we need a separate check for when we've reached the
+			// end of a stack and should move horizontally
+			if( routes.down && routes.right && config.loop && isLastVerticalSlide() ) {
+				routes.down = false;
+			}
+
+			if( routes.down ) {
+				navigateDown({skipFragments});
+			}
+			else if( config.rtl ) {
+				navigateLeft({skipFragments});
+			}
+			else {
+				navigateRight({skipFragments});
+			}
+		}
+
+	}
+
+
+	// --------------------------------------------------------------------//
+	// ----------------------------- EVENTS -------------------------------//
+	// --------------------------------------------------------------------//
+
+	/**
+	 * Called by all event handlers that are based on user
+	 * input.
+	 *
+	 * @param {object} [event]
+	 */
+	function onUserInput( event ) {
+
+		if( config.autoSlideStoppable ) {
+			pauseAutoSlide();
+		}
+
+	}
+
+	/**
+	* Listener for post message events posted to this window.
+	*/
+	function onPostMessage( event ) {
+
+		let data = event.data;
+
+		// Make sure we're dealing with JSON
+		if( typeof data === 'string' && data.charAt( 0 ) === '{' && data.charAt( data.length - 1 ) === '}' ) {
+			data = JSON.parse( data );
+
+			// Check if the requested method can be found
+			if( data.method && typeof Reveal[data.method] === 'function' ) {
+
+				if( POST_MESSAGE_METHOD_BLACKLIST.test( data.method ) === false ) {
+
+					const result = Reveal[data.method].apply( Reveal, data.args );
+
+					// Dispatch a postMessage event with the returned value from
+					// our method invocation for getter functions
+					dispatchPostMessage( 'callback', { method: data.method, result: result } );
+
+				}
+				else {
+					console.warn( 'reveal.js: "'+ data.method +'" is is blacklisted from the postMessage API' );
+				}
+
+			}
+		}
+
+	}
+
+	/**
+	 * Event listener for transition end on the current slide.
+	 *
+	 * @param {object} [event]
+	 */
+	function onTransitionEnd( event ) {
+
+		if( transition === 'running' && /section/gi.test( event.target.nodeName ) ) {
+			transition = 'idle';
+			dispatchEvent({
+				type: 'slidetransitionend',
+				data: { indexh, indexv, previousSlide, currentSlide }
+			});
+		}
+
+	}
+
+	/**
+	 * A global listener for all click events inside of the
+	 * .slides container.
+	 *
+	 * @param {object} [event]
+	 */
+	function onSlidesClicked( event ) {
+
+		const anchor = Util.closest( event.target, 'a[href^="#"]' );
+
+		// If a hash link is clicked, we find the target slide
+		// and navigate to it. We previously relied on 'hashchange'
+		// for links like these but that prevented media with
+		// audio tracks from playing in mobile browsers since it
+		// wasn't considered a direct interaction with the document.
+		if( anchor ) {
+			const hash = anchor.getAttribute( 'href' );
+			const indices = location.getIndicesFromHash( hash );
+
+			if( indices ) {
+				Reveal.slide( indices.h, indices.v, indices.f );
+				event.preventDefault();
+			}
+		}
+
+	}
+
+	/**
+	 * Handler for the window level 'resize' event.
+	 *
+	 * @param {object} [event]
+	 */
+	function onWindowResize( event ) {
+
+		layout();
+	}
+
+	/**
+	 * Handle for the window level 'visibilitychange' event.
+	 *
+	 * @param {object} [event]
+	 */
+	function onPageVisibilityChange( event ) {
+
+		// If, after clicking a link or similar and we're coming back,
+		// focus the document.body to ensure we can use keyboard shortcuts
+		if( document.hidden === false && document.activeElement !== document.body ) {
+			// Not all elements support .blur() - SVGs among them.
+			if( typeof document.activeElement.blur === 'function' ) {
+				document.activeElement.blur();
+			}
+			document.body.focus();
+		}
+
+	}
+
+	/**
+	 * Handler for the document level 'fullscreenchange' event.
+	 *
+	 * @param {object} [event]
+	 */
+	function onFullscreenChange( event ) {
+
+		let element = document.fullscreenElement || document.webkitFullscreenElement;
+		if( element === dom.wrapper ) {
+			event.stopImmediatePropagation();
+
+			// Timeout to avoid layout shift in Safari
+			setTimeout( () => {
+				Reveal.layout();
+				Reveal.focus.focus(); // focus.focus :'(
+			}, 1 );
+		}
+
+	}
+
+	/**
+	 * Handles click on the auto-sliding controls element.
+	 *
+	 * @param {object} [event]
+	 */
+	function onAutoSlidePlayerClick( event ) {
+
+		// Replay
+		if( isLastSlide() && config.loop === false ) {
+			slide( 0, 0 );
+			resumeAutoSlide();
+		}
+		// Resume
+		else if( autoSlidePaused ) {
+			resumeAutoSlide();
+		}
+		// Pause
+		else {
+			pauseAutoSlide();
+		}
+
+	}
+
+
+	// --------------------------------------------------------------------//
+	// ------------------------------- API --------------------------------//
+	// --------------------------------------------------------------------//
+
+	// The public reveal.js API
+	const API = {
+		VERSION,
+
+		initialize,
+		configure,
+		destroy,
+
+		sync,
+		syncSlide,
+		syncFragments: fragments.sync.bind( fragments ),
+
+		// Navigation methods
+		slide,
+		left: navigateLeft,
+		right: navigateRight,
+		up: navigateUp,
+		down: navigateDown,
+		prev: navigatePrev,
+		next: navigateNext,
+
+		// Navigation aliases
+		navigateLeft, navigateRight, navigateUp, navigateDown, navigatePrev, navigateNext,
+
+		// Fragment methods
+		navigateFragment: fragments.goto.bind( fragments ),
+		prevFragment: fragments.prev.bind( fragments ),
+		nextFragment: fragments.next.bind( fragments ),
+
+		// Event binding
+		on,
+		off,
+
+		// Legacy event binding methods left in for backwards compatibility
+		addEventListener: on,
+		removeEventListener: off,
+
+		// Forces an update in slide layout
+		layout,
+
+		// Randomizes the order of slides
+		shuffle,
+
+		// Returns an object with the available routes as booleans (left/right/top/bottom)
+		availableRoutes,
+
+		// Returns an object with the available fragments as booleans (prev/next)
+		availableFragments: fragments.availableRoutes.bind( fragments ),
+
+		// Toggles a help overlay with keyboard shortcuts
+		toggleHelp: overlay.toggleHelp.bind( overlay ),
+
+		// Toggles the overview mode on/off
+		toggleOverview: overview.toggle.bind( overview ),
+
+		// Toggles the scroll view on/off
+		toggleScrollView: scrollView.toggle.bind( scrollView ),
+
+		// Toggles the "black screen" mode on/off
+		togglePause,
+
+		// Toggles the auto slide mode on/off
+		toggleAutoSlide,
+
+		// Toggles visibility of the jump-to-slide UI
+		toggleJumpToSlide,
+
+		// Slide navigation checks
+		isFirstSlide,
+		isLastSlide,
+		isLastVerticalSlide,
+		isVerticalSlide,
+		isVerticalStack,
+
+		// State checks
+		isPaused,
+		isAutoSliding,
+		isSpeakerNotes: notes.isSpeakerNotesWindow.bind( notes ),
+		isOverview: overview.isActive.bind( overview ),
+		isFocused: focus.isFocused.bind( focus ),
+		isOverlayOpen: overlay.isOpen.bind( overlay ),
+		isScrollView: scrollView.isActive.bind( scrollView ),
+		isPrintView: printView.isActive.bind( printView ),
+
+		// Checks if reveal.js has been loaded and is ready for use
+		isReady: () => ready,
+
+		// Slide preloading
+		loadSlide: slideContent.load.bind( slideContent ),
+		unloadSlide: slideContent.unload.bind( slideContent ),
+
+		// Start/stop all media inside of the current slide
+		startEmbeddedContent: () => slideContent.startEmbeddedContent( currentSlide ),
+		stopEmbeddedContent: () => slideContent.stopEmbeddedContent( currentSlide, { unloadIframes: false } ),
+
+		// Lightbox previews
+		previewIframe: overlay.previewIframe.bind( overlay ),
+		previewImage: overlay.previewImage.bind( overlay ),
+		previewVideo: overlay.previewVideo.bind( overlay ),
+
+		showPreview: overlay.previewIframe.bind( overlay ), // deprecated in favor of showIframeLightbox
+		hidePreview: overlay.close.bind( overlay ),
+
+		// Adds or removes all internal event listeners
+		addEventListeners,
+		removeEventListeners,
+		dispatchEvent,
+
+		// Facility for persisting and restoring the presentation state
+		getState,
+		setState,
+
+		// Presentation progress on range of 0-1
+		getProgress,
+
+		// Returns the indices of the current, or specified, slide
+		getIndices,
+
+		// Returns an Array of key:value maps of the attributes of each
+		// slide in the deck
+		getSlidesAttributes,
+
+		// Returns the number of slides that we have passed
+		getSlidePastCount,
+
+		// Returns the total number of slides
+		getTotalSlides,
+
+		// Returns the slide element at the specified index
+		getSlide,
+
+		// Returns the previous slide element, may be null
+		getPreviousSlide: () => previousSlide,
+
+		// Returns the current slide element
+		getCurrentSlide: () => currentSlide,
+
+		// Returns the slide background element at the specified index
+		getSlideBackground,
+
+		// Returns the speaker notes string for a slide, or null
+		getSlideNotes: notes.getSlideNotes.bind( notes ),
+
+		// Returns an Array of all slides
+		getSlides,
+
+		// Returns an array with all horizontal/vertical slides in the deck
+		getHorizontalSlides,
+		getVerticalSlides,
+
+		// Checks if the presentation contains two or more horizontal
+		// and vertical slides
+		hasHorizontalSlides,
+		hasVerticalSlides,
+
+		// Checks if the deck has navigated on either axis at least once
+		hasNavigatedHorizontally: () => navigationHistory.hasNavigatedHorizontally,
+		hasNavigatedVertically: () => navigationHistory.hasNavigatedVertically,
+
+		shouldAutoAnimateBetween,
+
+		// Adds/removes a custom key binding
+		addKeyBinding: keyboard.addKeyBinding.bind( keyboard ),
+		removeKeyBinding: keyboard.removeKeyBinding.bind( keyboard ),
+
+		// Programmatically triggers a keyboard event
+		triggerKey: keyboard.triggerKey.bind( keyboard ),
+
+		// Registers a new shortcut to include in the help overlay
+		registerKeyboardShortcut: keyboard.registerKeyboardShortcut.bind( keyboard ),
+
+		getComputedSlideSize,
+		setCurrentScrollPage,
+
+		// Returns the current scale of the presentation content
+		getScale: () => scale,
+
+		// Returns the current configuration object
+		getConfig: () => config,
+
+		// Helper method, retrieves query string as a key:value map
+		getQueryHash: Util.getQueryHash,
+
+		// Returns the path to the current slide as represented in the URL
+		getSlidePath: location.getHash.bind( location ),
+
+		// Returns reveal.js DOM elements
+		getRevealElement: () => revealElement,
+		getSlidesElement: () => dom.slides,
+		getViewportElement: () => dom.viewport,
+		getBackgroundsElement: () => backgrounds.element,
+
+		// API for registering and retrieving plugins
+		registerPlugin: plugins.registerPlugin.bind( plugins ),
+		hasPlugin: plugins.hasPlugin.bind( plugins ),
+		getPlugin: plugins.getPlugin.bind( plugins ),
+		getPlugins: plugins.getRegisteredPlugins.bind( plugins )
+
+	};
+
+	// Our internal API which controllers have access to
+	Util.extend( Reveal, {
+		...API,
+
+		// Methods for announcing content to screen readers
+		announceStatus,
+		getStatusText,
+
+		// Controllers
+		focus,
+		scroll: scrollView,
+		progress,
+		controls,
+		location,
+		overview,
+		keyboard,
+		fragments,
+		backgrounds,
+		slideContent,
+		slideNumber,
+
+		onUserInput,
+		closeOverlay: overlay.close.bind( overlay ),
+		updateSlidesVisibility,
+		layoutSlideContents,
+		transformSlides,
+		cueAutoSlide,
+		cancelAutoSlide
+	} );
+
+	return API;
+
+};
diff --git a/inst/reveal.js-5.2.1/js/utils/color.js b/inst/reveal.js-5.2.1/js/utils/color.js
new file mode 100644
index 0000000..e28a2b1
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/utils/color.js
@@ -0,0 +1,77 @@
+/**
+ * Converts various color input formats to an {r:0,g:0,b:0} object.
+ *
+ * @param {string} color The string representation of a color
+ * @example
+ * colorToRgb('#000');
+ * @example
+ * colorToRgb('#000000');
+ * @example
+ * colorToRgb('rgb(0,0,0)');
+ * @example
+ * colorToRgb('rgba(0,0,0)');
+ *
+ * @return {{r: number, g: number, b: number, [a]: number}|null}
+ */
+export const colorToRgb = ( color ) => {
+
+	let hex3 = color.match( /^#([0-9a-f]{3})$/i );
+	if( hex3 && hex3[1] ) {
+		hex3 = hex3[1];
+		return {
+			r: parseInt( hex3.charAt( 0 ), 16 ) * 0x11,
+			g: parseInt( hex3.charAt( 1 ), 16 ) * 0x11,
+			b: parseInt( hex3.charAt( 2 ), 16 ) * 0x11
+		};
+	}
+
+	let hex6 = color.match( /^#([0-9a-f]{6})$/i );
+	if( hex6 && hex6[1] ) {
+		hex6 = hex6[1];
+		return {
+			r: parseInt( hex6.slice( 0, 2 ), 16 ),
+			g: parseInt( hex6.slice( 2, 4 ), 16 ),
+			b: parseInt( hex6.slice( 4, 6 ), 16 )
+		};
+	}
+
+	let rgb = color.match( /^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i );
+	if( rgb ) {
+		return {
+			r: parseInt( rgb[1], 10 ),
+			g: parseInt( rgb[2], 10 ),
+			b: parseInt( rgb[3], 10 )
+		};
+	}
+
+	let rgba = color.match( /^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d]+|[\d]*.[\d]+)\s*\)$/i );
+	if( rgba ) {
+		return {
+			r: parseInt( rgba[1], 10 ),
+			g: parseInt( rgba[2], 10 ),
+			b: parseInt( rgba[3], 10 ),
+			a: parseFloat( rgba[4] )
+		};
+	}
+
+	return null;
+
+}
+
+/**
+ * Calculates brightness on a scale of 0-255.
+ *
+ * @param {string} color See colorToRgb for supported formats.
+ * @see {@link colorToRgb}
+ */
+export const colorBrightness = ( color ) => {
+
+	if( typeof color === 'string' ) color = colorToRgb( color );
+
+	if( color ) {
+		return ( color.r * 299 + color.g * 587 + color.b * 114 ) / 1000;
+	}
+
+	return null;
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/utils/constants.js b/inst/reveal.js-5.2.1/js/utils/constants.js
new file mode 100644
index 0000000..91a9f22
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/utils/constants.js
@@ -0,0 +1,17 @@
+
+export const SLIDES_SELECTOR = '.slides section';
+export const HORIZONTAL_SLIDES_SELECTOR = '.slides>section';
+export const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section';
+export const HORIZONTAL_BACKGROUNDS_SELECTOR = '.backgrounds>.slide-background';
+
+// Methods that may not be invoked via the postMessage API
+export const POST_MESSAGE_METHOD_BLACKLIST = /registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener|showPreview/;
+
+// Regex for retrieving the fragment style from a class attribute
+export const FRAGMENT_STYLE_REGEX = /fade-(down|up|right|left|out|in-then-out|in-then-semi-out)|semi-fade-out|current-visible|shrink|grow/;
+
+// Slide number formats
+export const SLIDE_NUMBER_FORMAT_HORIZONTAL_DOT_VERTICAL = 'h.v';
+export const SLIDE_NUMBER_FORMAT_HORIZONTAL_SLASH_VERTICAL = 'h/v';
+export const SLIDE_NUMBER_FORMAT_CURRENT = 'c';
+export const SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL = 'c/t';
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/utils/device.js b/inst/reveal.js-5.2.1/js/utils/device.js
new file mode 100644
index 0000000..f2bce20
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/utils/device.js
@@ -0,0 +1,8 @@
+const UA = navigator.userAgent;
+
+export const isMobile = /(iphone|ipod|ipad|android)/gi.test( UA ) ||
+						( navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 ); // iPadOS
+
+export const isChrome = /chrome/i.test( UA ) && !/edge/i.test( UA );
+
+export const isAndroid = /android/gi.test( UA );
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/utils/loader.js b/inst/reveal.js-5.2.1/js/utils/loader.js
new file mode 100644
index 0000000..58d39ac
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/utils/loader.js
@@ -0,0 +1,46 @@
+/**
+ * Loads a JavaScript file from the given URL and executes it.
+ *
+ * @param {string} url Address of the .js file to load
+ * @param {function} callback Method to invoke when the script
+ * has loaded and executed
+ */
+export const loadScript = ( url, callback ) => {
+
+	const script = document.createElement( 'script' );
+	script.type = 'text/javascript';
+	script.async = false;
+	script.defer = false;
+	script.src = url;
+
+	if( typeof callback === 'function' ) {
+
+		// Success callback
+		script.onload = script.onreadystatechange = event => {
+			if( event.type === 'load' || /loaded|complete/.test( script.readyState ) ) {
+
+				// Kill event listeners
+				script.onload = script.onreadystatechange = script.onerror = null;
+
+				callback();
+
+			}
+		};
+
+		// Error callback
+		script.onerror = err => {
+
+			// Kill event listeners
+			script.onload = script.onreadystatechange = script.onerror = null;
+
+			callback( new Error( 'Failed loading script: ' + script.src + '\n' + err ) );
+
+		};
+
+	}
+
+	// Append the script at the end of <head>
+	const head = document.querySelector( 'head' );
+	head.insertBefore( script, head.lastChild );
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-5.2.1/js/utils/util.js b/inst/reveal.js-5.2.1/js/utils/util.js
new file mode 100644
index 0000000..a5515e8
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/utils/util.js
@@ -0,0 +1,313 @@
+/**
+ * Extend object a with the properties of object b.
+ * If there's a conflict, object b takes precedence.
+ *
+ * @param {object} a
+ * @param {object} b
+ */
+export const extend = ( a, b ) => {
+
+	for( let i in b ) {
+		a[ i ] = b[ i ];
+	}
+
+	return a;
+
+}
+
+/**
+ * querySelectorAll but returns an Array.
+ */
+export const queryAll = ( el, selector ) => {
+
+	return Array.from( el.querySelectorAll( selector ) );
+
+}
+
+/**
+ * classList.toggle() with cross browser support
+ */
+export const toggleClass = ( el, className, value ) => {
+	if( value ) {
+		el.classList.add( className );
+	}
+	else {
+		el.classList.remove( className );
+	}
+}
+
+/**
+ * Utility for deserializing a value.
+ *
+ * @param {*} value
+ * @return {*}
+ */
+export const deserialize = ( value ) => {
+
+	if( typeof value === 'string' ) {
+		if( value === 'null' ) return null;
+		else if( value === 'true' ) return true;
+		else if( value === 'false' ) return false;
+		else if( value.match( /^-?[\d\.]+$/ ) ) return parseFloat( value );
+	}
+
+	return value;
+
+}
+
+/**
+ * Measures the distance in pixels between point a
+ * and point b.
+ *
+ * @param {object} a point with x/y properties
+ * @param {object} b point with x/y properties
+ *
+ * @return {number}
+ */
+export const distanceBetween = ( a, b ) => {
+
+	let dx = a.x - b.x,
+		dy = a.y - b.y;
+
+	return Math.sqrt( dx*dx + dy*dy );
+
+}
+
+/**
+ * Applies a CSS transform to the target element.
+ *
+ * @param {HTMLElement} element
+ * @param {string} transform
+ */
+export const transformElement = ( element, transform ) => {
+
+	element.style.transform = transform;
+
+}
+
+/**
+ * Element.matches with IE support.
+ *
+ * @param {HTMLElement} target The element to match
+ * @param {String} selector The CSS selector to match
+ * the element against
+ *
+ * @return {Boolean}
+ */
+export const matches = ( target, selector ) => {
+
+	let matchesMethod = target.matches || target.matchesSelector || target.msMatchesSelector;
+
+	return !!( matchesMethod && matchesMethod.call( target, selector ) );
+
+}
+
+/**
+ * Find the closest parent that matches the given
+ * selector.
+ *
+ * @param {HTMLElement} target The child element
+ * @param {String} selector The CSS selector to match
+ * the parents against
+ *
+ * @return {HTMLElement} The matched parent or null
+ * if no matching parent was found
+ */
+export const closest = ( target, selector ) => {
+
+	// Native Element.closest
+	if( typeof target.closest === 'function' ) {
+		return target.closest( selector );
+	}
+
+	// Polyfill
+	while( target ) {
+		if( matches( target, selector ) ) {
+			return target;
+		}
+
+		// Keep searching
+		target = target.parentNode;
+	}
+
+	return null;
+
+}
+
+/**
+ * Handling the fullscreen functionality via the fullscreen API
+ *
+ * @see http://fullscreen.spec.whatwg.org/
+ * @see https://developer.mozilla.org/en-US/docs/DOM/Using_fullscreen_mode
+ */
+export const enterFullscreen = element => {
+
+	element = element || document.documentElement;
+
+	// Check which implementation is available
+	let requestMethod = element.requestFullscreen ||
+						element.webkitRequestFullscreen ||
+						element.webkitRequestFullScreen ||
+						element.mozRequestFullScreen ||
+						element.msRequestFullscreen;
+
+	if( requestMethod ) {
+		requestMethod.apply( element );
+	}
+
+}
+
+/**
+ * Creates an HTML element and returns a reference to it.
+ * If the element already exists the existing instance will
+ * be returned.
+ *
+ * @param {HTMLElement} container
+ * @param {string} tagname
+ * @param {string} classname
+ * @param {string} innerHTML
+ *
+ * @return {HTMLElement}
+ */
+export const createSingletonNode = ( container, tagname, classname, innerHTML='' ) => {
+
+	// Find all nodes matching the description
+	let nodes = container.querySelectorAll( '.' + classname );
+
+	// Check all matches to find one which is a direct child of
+	// the specified container
+	for( let i = 0; i < nodes.length; i++ ) {
+		let testNode = nodes[i];
+		if( testNode.parentNode === container ) {
+			return testNode;
+		}
+	}
+
+	// If no node was found, create it now
+	let node = document.createElement( tagname );
+	node.className = classname;
+	node.innerHTML = innerHTML;
+	container.appendChild( node );
+
+	return node;
+
+}
+
+/**
+ * Injects the given CSS styles into the DOM.
+ *
+ * @param {string} value
+ */
+export const createStyleSheet = ( value ) => {
+
+	let tag = document.createElement( 'style' );
+	tag.type = 'text/css';
+
+	if( value && value.length > 0 ) {
+		if( tag.styleSheet ) {
+			tag.styleSheet.cssText = value;
+		}
+		else {
+			tag.appendChild( document.createTextNode( value ) );
+		}
+	}
+
+	document.head.appendChild( tag );
+
+	return tag;
+
+}
+
+/**
+ * Returns a key:value hash of all query params.
+ */
+export const getQueryHash = () => {
+
+	let query = {};
+
+	location.search.replace( /[A-Z0-9]+?=([\w\.%-]*)/gi, a => {
+		query[ a.split( '=' ).shift() ] = a.split( '=' ).pop();
+	} );
+
+	// Basic deserialization
+	for( let i in query ) {
+		let value = query[ i ];
+
+		query[ i ] = deserialize( unescape( value ) );
+	}
+
+	// Do not accept new dependencies via query config to avoid
+	// the potential of malicious script injection
+	if( typeof query['dependencies'] !== 'undefined' ) delete query['dependencies'];
+
+	return query;
+
+}
+
+/**
+ * Returns the remaining height within the parent of the
+ * target element.
+ *
+ * remaining height = [ configured parent height ] - [ current parent height ]
+ *
+ * @param {HTMLElement} element
+ * @param {number} [height]
+ */
+export const getRemainingHeight = ( element, height = 0 ) => {
+
+	if( element ) {
+		let newHeight, oldHeight = element.style.height;
+
+		// Change the .stretch element height to 0 in order find the height of all
+		// the other elements
+		element.style.height = '0px';
+
+		// In Overview mode, the parent (.slide) height is set of 700px.
+		// Restore it temporarily to its natural height.
+		element.parentNode.style.height = 'auto';
+
+		newHeight = height - element.parentNode.offsetHeight;
+
+		// Restore the old height, just in case
+		element.style.height = oldHeight + 'px';
+
+		// Clear the parent (.slide) height. .removeProperty works in IE9+
+		element.parentNode.style.removeProperty('height');
+
+		return newHeight;
+	}
+
+	return height;
+
+}
+
+const fileExtensionToMimeMap = {
+	'mp4': 'video/mp4',
+	'm4a': 'video/mp4',
+	'ogv': 'video/ogg',
+	'mpeg': 'video/mpeg',
+	'webm': 'video/webm'
+}
+
+/**
+ * Guess the MIME type for common file formats.
+ */
+export const getMimeTypeFromFile = ( filename='' ) => {
+	return fileExtensionToMimeMap[filename.split('.').pop()]
+}
+
+/**
+ * Encodes a string for RFC3986-compliant URL format.
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI#encoding_for_rfc3986
+ *
+ * @param {string} url
+ */
+export const encodeRFC3986URI = ( url='' ) => {
+	return encodeURI(url)
+	  .replace(/%5B/g, "[")
+	  .replace(/%5D/g, "]")
+	  .replace(
+		/[!'()*]/g,
+		(c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`
+	  );
+}
\ No newline at end of file
