diff --git a/inst/reveal.js-4.6.1/js/utils/color.js b/inst/reveal.js-4.6.1/js/utils/color.js
new file mode 100644
index 0000000..edf67c4
--- /dev/null
+++ b/inst/reveal.js-4.6.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-4.6.1/js/utils/constants.js b/inst/reveal.js-4.6.1/js/utils/constants.js
new file mode 100644
index 0000000..43fcb84
--- /dev/null
+++ b/inst/reveal.js-4.6.1/js/utils/constants.js
@@ -0,0 +1,10 @@
+
+export const SLIDES_SELECTOR = '.slides section';
+export const HORIZONTAL_SLIDES_SELECTOR = '.slides>section';
+export const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section';
+
+// 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/;
\ No newline at end of file
diff --git a/inst/reveal.js-4.6.1/js/utils/device.js b/inst/reveal.js-4.6.1/js/utils/device.js
new file mode 100644
index 0000000..f2bce20
--- /dev/null
+++ b/inst/reveal.js-4.6.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-4.6.1/js/utils/loader.js b/inst/reveal.js-4.6.1/js/utils/loader.js
new file mode 100644
index 0000000..58d39ac
--- /dev/null
+++ b/inst/reveal.js-4.6.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-4.6.1/js/utils/util.js b/inst/reveal.js-4.6.1/js/utils/util.js
new file mode 100644
index 0000000..a5515e8
--- /dev/null
+++ b/inst/reveal.js-4.6.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
