diff --git a/static/third_party/js/keys.js b/static/third_party/js/keys.js
new file mode 100644
index 0000000..1f2a7ff
--- /dev/null
+++ b/static/third_party/js/keys.js
@@ -0,0 +1,192 @@
+/**
+ * Copyright 2008 Steve McKay.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Kibbles.Keys is a Javascript library providing simple cross browser
+ * keyboard event support.
+ */
+(function(){
+
+var _listening = false;
+
+// code to handler list map.
+// Wildcard listeners use magic code wildcards "before" and "after".
+var _listeners = {
+	before: [],
+	after: []
+};
+
+/*
+ * Map of key names to char code. This map is consulted before
+ * charCodeAt(0) is used to determine the character code.
+ *
+ * This map also serves as a definitive list of supported "special" keys.
+ * See _codeForEvent for details.
+ */
+var _CODE_MAP = {
+	ESC: 27,
+	ENTER: 13
+};
+
+/**
+ * Register a keypress listener.
+ */
+function _listen() {
+	if (_listening) return;
+
+	var d = document;
+	if (d.addEventListener) {
+		d.addEventListener('keypress', _handleKeyboardEvent, false);
+		d.addEventListener('keydown', _handleKeyDownEvent, false);
+	} else if (d.attachEvent) {
+		d.documentElement.attachEvent('onkeypress', _handleKeyboardEvent);
+		d.documentElement.attachEvent('onkeydown', _handleKeyDownEvent);
+	}
+	_listening = true;
+}
+
+/**
+ * Register a keypress listener for the supplied skip code.
+ */
+function _addKeyPressListener(spec, handler) {
+	var code = spec.toLowerCase();
+	if (code == "before" || code == "after") {
+		_listeners[code].push(handler);
+		return;
+	}
+
+	// try to find the character or key code.
+	code = _CODE_MAP[spec.toUpperCase()];
+	if (!code) {
+		code = spec.charCodeAt(0);
+	}
+	if (!_listeners[code]) {
+		_listeners[code] = [];
+	}
+	_listeners[code].push(handler);
+}
+
+/**
+ * Our handler for keypress events.
+ */
+function _handleKeyboardEvent(e) {
+
+	// If event is null, this is probably IE.
+	if (!e) e = window.event;
+
+	var source = _getSourceElement(e);
+	if (_isInputElement(source)) {
+		return;
+	}
+
+        if (_hasFlakeyModifier(e)) return;
+
+	var code = _codeForEvent(e);
+
+	if (code == undefined) return;
+
+	var payload = {
+		code: code
+	};
+
+	for (var i = 0; i < _listeners.before.length; i++) {
+		_listeners.before[i](payload);
+	}
+
+	var listeners = _listeners[code];
+	if (listeners) {
+		for (var i = 0; i < listeners.length; i++) {
+			listeners[i]({
+				code: code
+			});
+		}
+	}
+
+	for (var i = 0; i < _listeners.after.length; i++) {
+		_listeners.after[i](payload);
+	}
+}
+
+function _handleKeyDownEvent(e) {
+  if (!e) e = window.event;
+  var code = _codeForEvent(e);
+  if (code == _CODE_MAP['ESC'] || code == _CODE_MAP['ENTER']) {
+    _handleKeyboardEvent(e);
+  }
+}
+
+/**
+ * Returns the keycode associated with the event.
+ */
+function _codeForEvent(e) {
+  return e.keyCode ? e.keyCode : e.which;
+}
+
+/**
+ * Returns true if the supplied event has an associated modifier key
+ * that we have had trouble with in certain browsers.
+ */
+function _hasFlakeyModifier(e) {
+	return e.altKey || e.ctrlKey || e.metaKey;
+}
+
+/**
+ * Returns the source element for the supplied event.
+ */
+function _getSourceElement(e) {
+	var element = e.target;
+	if (!element) {
+		element = e.srcElement;
+	}
+
+	if (element.shadowRoot) {
+	  // Find the element within the shadowDOM.
+		const path = e.path || e.composedPath();
+	  element = path[0];
+	}
+
+	// If the source element is a text node, the parent is the object
+	// we're interested in.
+	if (element.nodeType == 3) {
+		element = element.parentNode;
+	}
+
+	return element;
+}
+
+/**
+ * Returns true if the element is a known form input element.
+ */
+function _isInputElement(element) {
+	return element.tagName == 'INPUT' || element.tagName == 'TEXTAREA';
+}
+
+/*
+ * A nice little namespace to call our own.
+ *
+ * Formalizing Kibbles.Keys as a traditional javascript class caused headaches
+ * with respect to capturing the context (what is "this" at any point in time).
+ * So we use a simple script exported via the "kibbles.keys" namespace.
+ */
+if (!window.kibbles)
+	window.kibbles = {}
+
+window.kibbles.keys = {
+	listen: _listen,
+	addKeyPressListener: _addKeyPressListener
+};
+
+})();
diff --git a/static/third_party/js/skipper.js b/static/third_party/js/skipper.js
new file mode 100644
index 0000000..4c131b1
--- /dev/null
+++ b/static/third_party/js/skipper.js
@@ -0,0 +1,335 @@
+/**
+ * Copyright 2008 Steve McKay.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Kibbles.Skipper is a Javascript library providing support for keyboard
+ * navigation among DOM object on a page.
+ */
+(function(){
+
+var _stops = new Array();  // list of stop objects
+var _lastStop;  // id of the last stop we visited to.
+
+// Named options. The value can be a literal value, or a function to call.
+var _options = {
+	padding_top: 0, // window offset when scrolling
+  padding_bottom: 0,
+  scroll_window: true
+};
+
+/*
+ * Constants identifying listener types. Used with the method that
+ * enables registration of listeners.
+ */
+var _LISTENER_TYPE = {
+  PRE: 'pre',
+  POST: 'post'
+};
+
+// map of stop listeners by type. pre listeners are called before navigation
+// post listeners are called after navigation.
+var _stopListener = {
+	pre: [],
+	post: []
+};
+
+/**
+ * Remove all stop previously identified stop elements.
+ */
+function _reset() {
+	_stops = new Array();
+}
+
+function _get(i) {
+	return _stops[i];
+}
+
+function _set(i, element) {
+	_stops[i] = element;
+}
+
+function _insert(i, element) {
+  if (i < 0 || i > _stops.length - 1) {
+    throw "Index out of bounds.";
+  }
+	_stops.splice(i, 0, element);
+  if (i <= _lastStop) {
+    _lastStop++;
+  }
+}
+
+function _append(element) {
+	_stops.push(element);
+}
+
+function _del(i) {
+  if (i < 0 || i > _stops.length - 1) {
+    throw "Index out of bounds.";
+  }
+	_stops.splice(i, 1);
+  if (_lastStop >= i) {
+    _lastStop--;
+  }
+}
+
+function _length() {
+	return _stops.length;
+}
+
+/**
+ * Sets the named option to the specified value.
+ */
+function _setOption(name, value) {
+	_options[name] = value;
+}
+
+/**
+ * Register a key to move forward one stop.
+ */
+function _addFwdKey(character) {
+	kibbles.keys.addKeyPressListener(character, _gotoNextStop);
+}
+
+/**
+ * Register a key to move back one stop.
+ */
+function _addRevKey(character) {
+	kibbles.keys.addKeyPressListener(character, _gotoPreviousStop);
+}
+
+/**
+ * Adds a stop listener.
+ */
+function _addStopListener(type, handler) {
+	if (type == _LISTENER_TYPE.PRE) {
+		_stopListener.pre.push(handler);
+	} else if (type == _LISTENER_TYPE.POST) {
+		_stopListener.post.push(handler);
+	}
+}
+
+/**
+ * Scroll to next stop if any.
+ */
+function _gotoNextStop() {
+	_setCurrentStop(_getNextStop());
+}
+
+/**
+ * Scroll to previous stop if any.
+ */
+function _gotoPreviousStop() {
+	_setCurrentStop(_getPreviousStop());
+}
+
+/**
+ * Update the current and previous stops, scrolling window to the location
+ * of the specified stop, and notifying listeners in the process.
+ */
+function _setCurrentStop(i) {
+	if (i >= 0) {
+		var prevStop = _lastStop;
+		_lastStop = i;
+
+    var next = new Stop(i);
+    var prev = (prevStop >= 0) ? new Stop(prevStop) : undefined;
+
+		_notifyListeners(next, prev, _stopListener.pre);
+
+		// If the y coord of the stop was not previously determined
+		// it may have been hidden. Since "PRE" listeners may reveal
+		// hidden stops, we try again if "y" is not know.
+		if (!next.y) next.y = _findObjectPosition(next.element);
+
+		// if we can't id the y coords at this point, we throw an exception.
+		if (!next.y && !(next.y >= 0)) {
+			throw "Next stop does not y coords. Aborting.";
+		}
+		_notifyListeners(next, prev, _stopListener.post);
+	}
+}
+
+/**
+ * Called by a listener, not directly.
+ */
+function _scrollOpportunityListener(next, prev) {
+  if (!_getOptionValue('scroll_window')) return;
+
+  if (next && next.element) {
+
+    var viewTop = _windowScrollTop();
+    var viewBottom = viewTop + document.documentElement.clientHeight;
+
+    var padTop = _getOptionValue('padding_top');
+
+    var bottom = viewBottom - padTop;
+
+    // if we skipped below the bottom padding
+    if (next.y > bottom) {
+      window.scrollTo(0, next.y - padTop);
+      return;
+    }
+
+    var padBottom = _getOptionValue('padding_bottom');
+    // if we skipped above the top offset
+    var top = viewTop + padBottom;
+    if (next.y < top) {
+      window.scrollTo(0, (next.y - document.documentElement.clientHeight) + padBottom);
+      return;
+    }
+  }
+}
+
+function _windowScrollTop() {
+  if (window.document.body.scrollTop) {
+    return window.document.body.scrollTop;
+  } else if (window.document.documentElement.scrollTop) {
+    return window.document.documentElement.scrollTop;
+  } else if (window.pageYOffset) {
+    return window.pageYOffset;
+  }
+  return 0;
+}
+
+
+/**
+ * Returns an option value or if the value is a function,
+ * the value returned by the function.
+ */
+function _getOptionValue(name) {
+	var opt = _options[name];
+	if (typeof opt == "function") {
+		return opt();
+	}
+	return opt;
+}
+
+/**
+ * Notify all supplied stop listeners.
+ */
+function _notifyListeners(stop, previousStop, listeners) {
+	if (stop && listeners) {
+		try {
+			for (var i = 0; i < listeners.length; i++) {
+				listeners[i](stop, previousStop);
+			}
+		} catch(err) {
+			// don't let a grumpy listener bring us down.
+		}
+	}
+}
+
+/**
+ * Returns the next stop or null if none stop available.
+ */
+function _getNextStop() {
+	var i = 0;
+
+	// if we've already visited a stop, use that as the base for the next stop.
+	if (_lastStop >= 0) {
+		i = _lastStop + 1;
+	}
+
+	// if the presumed next stop is out of bounds, return null.
+	if (i > _stops.length - 1) {
+		return;
+	}
+  return i;
+}
+
+/**
+ * Returns the previous stop or null if none available.
+ */
+function _getPreviousStop() {
+	var i = _stops.length - 1;
+
+	// if we've already visited a stop, use that as the base for the next stop.
+	if (_lastStop >= 0) {
+		i = _lastStop - 1;
+	}
+
+	// if the presumed next stop is out of bounds, return null.
+	if (i < 0) {
+		return;
+	}
+  return i;
+}
+
+/**
+ * Convenience wrapper for "stop" related information.
+ */
+function Stop(i, y) {
+	this.index = i;
+	this.element = _stops[i];
+	this.y = _findObjectPosition(this.element);
+}
+
+/**
+ * Returns the vertical coordinate of the top of specified object
+ * relative to the top of the entire page.
+ */
+function _findObjectPosition(obj) {
+	if (obj) {
+		var curtop = 0;
+		if (obj.offsetParent) {
+			while (obj.offsetParent) {
+				curtop += obj.offsetTop;
+				obj = obj.offsetParent;
+			}
+		} else if (obj.y) {
+			curtop += obj.y;
+		}
+		return curtop;
+	}
+	return null;
+}
+
+if (!window.kibbles.keys) {
+  throw "Kibbles.Skipper requires Kibbles.Keys which is not loaded."
+      + " Can't continue.";
+}
+
+/**
+ * A nice little namespace to call our own.
+ *
+ * Formalizing Kibbles.Skipper as a traditional javascript class caused
+ * headaches with respect to capturing the context (what is "this"
+ * at any point in time). So we use a simple script exported via the
+ * "kibbles.skipper" namespace.
+ */
+window.kibbles.skipper = {
+	setOption: _setOption,
+	addFwdKey: _addFwdKey,
+	addRevKey: _addRevKey,
+	LISTENER_TYPE: _LISTENER_TYPE,
+	addStopListener: _addStopListener,
+  setCurrentStop: _setCurrentStop,
+	// array like methods for stop manipulation
+	get: _get,
+	set: _set,
+	append: _append,
+	insert: _insert,
+	del: _del,
+	length: _length,
+	reset: _reset
+}
+
+_addStopListener(kibbles.skipper.LISTENER_TYPE.POST, _scrollOpportunityListener)
+
+// we depend on kibbles.keys.
+kibbles.keys.listen();
+
+})();
