diff --git a/static/js/graveyard/common.js b/static/js/graveyard/common.js
new file mode 100644
index 0000000..621a626
--- /dev/null
+++ b/static/js/graveyard/common.js
@@ -0,0 +1,709 @@
+/* Copyright 2016 The Chromium Authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://developers.google.com/open-source/licenses/bsd
+ */
+
+// ------------------------------------------------------------------------
+// This file contains common utilities and basic javascript infrastructure.
+//
+// Notes:
+// * Press 'D' to toggle debug mode.
+//
+// Functions:
+//
+// - Assertions
+// DEPRECATED: Use assert.js
+// AssertTrue(): assert an expression. Throws an exception if false.
+// Fail(): Throws an exception. (Mark block of code that should be unreachable)
+// AssertEquals(): assert that two values are equal.
+// AssertType(): assert that a value has a particular type
+//
+// - Cookies
+// SetCookie(): Sets a cookie.
+// ExpireCookie(): Expires a cookie.
+// GetCookie(): Gets a cookie value.
+//
+// - Dynamic HTML/DOM utilities
+// MaybeGetElement(): get an element by its id
+// GetElement(): get an element by its id
+// GetParentNode(): Get the parent of an element
+// GetAttribute(): Get attribute value of a DOM node
+// GetInnerHTML(): get the inner HTML of a node
+// SetCssStyle(): Sets a CSS property of a node.
+// GetStyleProperty(): Get CSS property from a style attribute string
+// GetCellIndex(): Get the index of a table cell in a table row
+// ShowElement(): Show/hide element by setting the "display" css property.
+// ShowBlockElement(): Show/hide block element
+// SetButtonText(): Set the text of a button element.
+// AppendNewElement(): Create and append a html element to a parent node.
+// CreateDIV(): Create a DIV element and append to the document.
+// HasClass(): check if element has a given class
+// AddClass(): add a class to an element
+// RemoveClass(): remove a class from an element
+//
+// - Window/Screen utiltiies
+// GetPageOffsetLeft(): get the X page offset of an element
+// GetPageOffsetTop(): get the Y page offset of an element
+// GetPageOffset(): get the X and Y page offsets of an element
+// GetPageOffsetRight() : get X page offset of the right side of an element
+// GetPageOffsetRight() : get Y page offset of the bottom of an element
+// GetScrollTop(): get the vertical scrolling pos of a window.
+// GetScrollLeft(): get the horizontal scrolling pos of a window
+// IsScrollAtEnd():  check if window scrollbar has reached its maximum offset
+// ScrollTo(): scroll window to a position
+// ScrollIntoView(): scroll window so that an element is in view.
+// GetWindowWidth(): get width of a window.
+// GetWindowHeight(): get height of a window
+// GetAvailScreenWidth(): get available screen width
+// GetAvailScreenHeight(): get available screen height
+// GetNiceWindowHeight(): get a nice height for a new browser window.
+// Open{External/Internal}Window(): open a separate window
+// CloseWindow(): close a window
+//
+// - DOM walking utilities
+// AnnotateTerms(): find terms in a node and decorate them with some tag
+// AnnotateText(): find terms in a text node and decorate them with some tag
+//
+// - String utilties
+// HtmlEscape(): html escapes a string
+// HtmlUnescape(): remove html-escaping.
+// QuoteEscape(): escape " quotes.
+// CollapseWhitespace(): collapse multiple whitespace into one whitespace.
+// Trim(): trim whitespace on ends of string
+// IsEmpty(): check if CollapseWhiteSpace(String) == ""
+// IsLetterOrDigit(): check if a character is a letter or a digit
+// ConvertEOLToLF(): normalize the new-lines of a string.
+// HtmlEscapeInsertWbrs(): HtmlEscapes and inserts <wbr>s (word break tags)
+//   after every n non-space chars and/or after or before certain special chars
+//
+// - TextArea utilities
+// GetCursorPos(): finds the cursor position of a textfield
+// SetCursorPos(): sets the cursor position in a textfield
+//
+// - Array utilities
+// FindInArray(): do a linear search to find an element value.
+// DeleteArrayElement(): return a new array with a specific value removed.
+// CloneObject(): clone an object, copying its values recursively.
+// CloneEvent(): clone an event; cannot use CloneObject because it
+//               suffers from infinite recursion
+//
+// - Formatting utilities
+// PrintArray(): used to print/generate HTML by combining static text
+// and dynamic strings.
+// ImageHtml(): create html for an img tag
+// FormatJSLink(): formats a link that invokes js code when clicked.
+// MakeId3(): formats an id that has two id numbers, eg, foo_3_7
+//
+// - Timeouts
+// SafeTimeout(): sets a timeout with protection against ugly JS-errors
+// CancelTimeout(): cancels a timeout with a given ID
+// CancelAllTimeouts(): cancels all timeouts on a given window
+//
+// - Miscellaneous
+// IsDefined(): returns true if argument is not undefined
+// ------------------------------------------------------------------------
+
+// browser detection
+function BR_AgentContains_(str) {
+  if (str in BR_AgentContains_cache_) {
+    return BR_AgentContains_cache_[str];
+  }
+
+  return BR_AgentContains_cache_[str] =
+    (navigator.userAgent.toLowerCase().indexOf(str) != -1);
+}
+// We cache the results of the indexOf operation. This gets us a 10x benefit in
+// Gecko, 8x in Safari and 4x in MSIE for all of the browser checks
+var BR_AgentContains_cache_ = {};
+
+function BR_IsIE() {
+  return (BR_AgentContains_('msie') || BR_AgentContains_('trident')) &&
+         !window.opera;
+}
+
+function BR_IsKonqueror() {
+  return BR_AgentContains_('konqueror');
+}
+
+function BR_IsSafari() {
+  return BR_AgentContains_('safari') || BR_IsKonqueror();
+}
+
+function BR_IsNav() {
+  return !BR_IsIE() &&
+         !BR_IsSafari() &&
+         BR_AgentContains_('mozilla');
+}
+
+var BACKSPACE_KEYNAME = 'Backspace';
+var COMMA_KEYNAME = ',';
+var DELETE_KEYNAME = 'Delete';
+var UP_KEYNAME = 'ArrowUp';
+var DOWN_KEYNAME = 'ArrowDown';
+var LEFT_KEYNAME = 'ArrowLeft';
+var RIGHT_KEYNAME = 'ArrowRight';
+var ENTER_KEYNAME = 'Enter';
+var ESC_KEYNAME = 'Escape';
+var SPACE_KEYNAME = ' ';
+var TAB_KEYNAME = 'Tab';
+var SHIFT_KEYNAME = 'Shift';
+var PAGE_DOWN_KEYNAME = 'PageDown';
+var PAGE_UP_KEYNAME = 'PageUp';
+
+var MAX_EMAIL_ADDRESS_LENGTH = 320; // 64 + '@' + 255
+var MAX_SIGNATURE_LENGTH = 1000; // 1000 chars of maximum signature
+
+// ------------------------------------------------------------------------
+// Assertions
+// DEPRECATED: Use assert.js
+// ------------------------------------------------------------------------
+/**
+ * DEPRECATED: Use assert.js
+ */
+function raise(msg) {
+  if (typeof Error != 'undefined') {
+    throw new Error(msg || 'Assertion Failed');
+  } else {
+    throw (msg);
+  }
+}
+
+/**
+ * DEPRECATED: Use assert.js
+ *
+ * Fail() is useful for marking logic paths that should
+ * not be reached. For example, if you have a class that uses
+ * ints for enums:
+ *
+ * MyClass.ENUM_FOO = 1;
+ * MyClass.ENUM_BAR = 2;
+ * MyClass.ENUM_BAZ = 3;
+ *
+ * And a switch statement elsewhere in your code that
+ * has cases for each of these enums, then you can
+ * "protect" your code as follows:
+ *
+ * switch(type) {
+ *   case MyClass.ENUM_FOO: doFooThing(); break;
+ *   case MyClass.ENUM_BAR: doBarThing(); break;
+ *   case MyClass.ENUM_BAZ: doBazThing(); break;
+ *   default:
+ *     Fail("No enum in MyClass with value: " + type);
+ * }
+ *
+ * This way, if someone introduces a new value for this enum
+ * without noticing this switch statement, then the code will
+ * fail if the logic allows it to reach the switch with the
+ * new value, alerting the developer that they should add a
+ * case to the switch to handle the new value they have introduced.
+ *
+ * @param {string} opt_msg to display for failure
+ *                 DEFAULT: "Assertion failed"
+ */
+function Fail(opt_msg) {
+  opt_msg = opt_msg || 'Assertion failed';
+  if (IsDefined(DumpError)) DumpError(opt_msg + '\n');
+  raise(opt_msg);
+}
+
+/**
+ * DEPRECATED: Use assert.js
+ *
+ * Asserts that an expression is true (non-zero and non-null).
+ *
+ * Note that it is critical not to pass logic
+ * with side-effects as the expression for AssertTrue
+ * because if the assertions are removed by the
+ * JSCompiler, then the expression will be removed
+ * as well, in which case the side-effects will
+ * be lost. So instead of this:
+ *
+ *  AssertTrue( criticalComputation() );
+ *
+ * Do this:
+ *
+ *  var result = criticalComputation();
+ *  AssertTrue(result);
+ *
+ * @param expression to evaluate
+ * @param {string} opt_msg to display if the assertion fails
+ *
+ */
+function AssertTrue(expression, opt_msg) {
+  if (!expression) {
+    opt_msg = opt_msg || 'Assertion failed';
+    Fail(opt_msg);
+  }
+}
+
+/**
+ * DEPRECATED: Use assert.js
+ *
+ * Asserts that a value is of the provided type.
+ *
+ *   AssertType(6, Number);
+ *   AssertType("ijk", String);
+ *   AssertType([], Array);
+ *   AssertType({}, Object);
+ *   AssertType(ICAL_Date.now(), ICAL_Date);
+ *
+ * @param value
+ * @param type A constructor function
+ * @param {string} opt_msg to display if the assertion fails
+ */
+function AssertType(value, type, opt_msg) {
+  // for backwards compatability only
+  if (typeof value == type) return;
+
+  if (value || value == '') {
+    try {
+      if (type == AssertTypeMap[typeof value] || value instanceof type) return;
+    } catch (e) {/* failure, type was an illegal argument to instanceof */}
+  }
+  let makeMsg = opt_msg === undefined;
+  if (makeMsg) {
+    if (typeof type == 'function') {
+      let match = type.toString().match(/^\s*function\s+([^\s\{]+)/);
+      if (match) type = match[1];
+    }
+    opt_msg = 'AssertType failed: <' + value + '> not typeof '+ type;
+  }
+  Fail(opt_msg);
+}
+
+var AssertTypeMap = {
+  'string': String,
+  'number': Number,
+  'boolean': Boolean,
+};
+
+var EXPIRED_COOKIE_VALUE = 'EXPIRED';
+
+
+// ------------------------------------------------------------------------
+// Window/screen utilities
+// TODO: these should be renamed (e.g. GetWindowWidth to GetWindowInnerWidth
+// and moved to geom.js)
+// ------------------------------------------------------------------------
+// Get page offset of an element
+function GetPageOffsetLeft(el) {
+  let x = el.offsetLeft;
+  if (el.offsetParent != null) {
+    x += GetPageOffsetLeft(el.offsetParent);
+  }
+  return x;
+}
+
+// Get page offset of an element
+function GetPageOffsetTop(el) {
+  let y = el.offsetTop;
+  if (el.offsetParent != null) {
+    y += GetPageOffsetTop(el.offsetParent);
+  }
+  return y;
+}
+
+// Get page offset of an element
+function GetPageOffset(el) {
+  let x = el.offsetLeft;
+  let y = el.offsetTop;
+  if (el.offsetParent != null) {
+    let pos = GetPageOffset(el.offsetParent);
+    x += pos.x;
+    y += pos.y;
+  }
+  return {x: x, y: y};
+}
+
+// Get the y position scroll offset.
+function GetScrollTop(win) {
+  return GetWindowPropertyByBrowser_(win, getScrollTopGetters_);
+}
+
+var getScrollTopGetters_ = {
+  ieQuirks_: function(win) {
+    return win.document.body.scrollTop;
+  },
+  ieStandards_: function(win) {
+    return win.document.documentElement.scrollTop;
+  },
+  dom_: function(win) {
+    return win.pageYOffset;
+  },
+};
+
+// Get the x position scroll offset.
+function GetScrollLeft(win) {
+  return GetWindowPropertyByBrowser_(win, getScrollLeftGetters_);
+}
+
+var getScrollLeftGetters_ = {
+  ieQuirks_: function(win) {
+    return win.document.body.scrollLeft;
+  },
+  ieStandards_: function(win) {
+    return win.document.documentElement.scrollLeft;
+  },
+  dom_: function(win) {
+    return win.pageXOffset;
+  },
+};
+
+// Scroll so that as far as possible the entire element is in view.
+var ALIGN_BOTTOM = 'b';
+var ALIGN_MIDDLE = 'm';
+var ALIGN_TOP = 't';
+
+var getWindowWidthGetters_ = {
+  ieQuirks_: function(win) {
+    return win.document.body.clientWidth;
+  },
+  ieStandards_: function(win) {
+    return win.document.documentElement.clientWidth;
+  },
+  dom_: function(win) {
+    return win.innerWidth;
+  },
+};
+
+function GetWindowHeight(win) {
+  return GetWindowPropertyByBrowser_(win, getWindowHeightGetters_);
+}
+
+var getWindowHeightGetters_ = {
+  ieQuirks_: function(win) {
+    return win.document.body.clientHeight;
+  },
+  ieStandards_: function(win) {
+    return win.document.documentElement.clientHeight;
+  },
+  dom_: function(win) {
+    return win.innerHeight;
+  },
+};
+
+/**
+ * Allows the easy use of different getters for IE quirks mode, IE standards
+ * mode and fully DOM-compliant browers.
+ *
+ * @param win window to get the property for
+ * @param getters object with various getters. Invoked with the passed window.
+ * There are three properties:
+ * - ieStandards_: IE 6.0 standards mode
+ * - ieQuirks_: IE 6.0 quirks mode and IE 5.5 and older
+ * - dom_: Mozilla, Safari and other fully DOM compliant browsers
+ *
+ * @private
+ */
+function GetWindowPropertyByBrowser_(win, getters) {
+  try {
+    if (BR_IsSafari()) {
+      return getters.dom_(win);
+    } else if (!window.opera &&
+               'compatMode' in win.document &&
+               win.document.compatMode == 'CSS1Compat') {
+      return getters.ieStandards_(win);
+    } else if (BR_IsIE()) {
+      return getters.ieQuirks_(win);
+    }
+  } catch (e) {
+    // Ignore for now and fall back to DOM method
+  }
+
+  return getters.dom_(win);
+}
+
+function GetAvailScreenWidth(win) {
+  return win.screen.availWidth;
+}
+
+// Used for horizontally centering a new window of the given width in the
+// available screen. Set the new window's distance from the left of the screen
+// equal to this function's return value.
+// Params: width: the width of the new window
+// Returns: the distance from the left edge of the screen for the new window to
+//   be horizontally centered
+function GetCenteringLeft(win, width) {
+  return (win.screen.availWidth - width) >> 1;
+}
+
+// Used for vertically centering a new window of the given height in the
+// available screen. Set the new window's distance from the top of the screen
+// equal to this function's return value.
+// Params: height: the height of the new window
+// Returns: the distance from the top edge of the screen for the new window to
+//   be vertically aligned.
+function GetCenteringTop(win, height) {
+  return (win.screen.availHeight - height) >> 1;
+}
+
+/**
+ * Opens a child popup window that has no browser toolbar/decorations.
+ * (Copied from caribou's common.js library with small modifications.)
+ *
+ * @param url the URL for the new window (Note: this will be unique-ified)
+ * @param opt_name the name of the new window
+ * @param opt_width the width of the new window
+ * @param opt_height the height of the new window
+ * @param opt_center if true, the new window is centered in the available screen
+ * @param opt_hide_scrollbars if true, the window hides the scrollbars
+ * @param opt_noresize if true, makes window unresizable
+ * @param opt_blocked_msg message warning that the popup has been blocked
+ * @return {Window} a reference to the new child window
+ */
+function Popup(url, opt_name, opt_width, opt_height, opt_center,
+  opt_hide_scrollbars, opt_noresize, opt_blocked_msg) {
+  if (!opt_height) {
+    opt_height = Math.floor(GetWindowHeight(window.top) * 0.8);
+  }
+  if (!opt_width) {
+    opt_width = Math.min(GetAvailScreenWidth(window), opt_height);
+  }
+
+  let features = 'resizable=' + (opt_noresize ? 'no' : 'yes') + ',' +
+                 'scrollbars=' + (opt_hide_scrollbars ? 'no' : 'yes') + ',' +
+                 'width=' + opt_width + ',height=' + opt_height;
+  if (opt_center) {
+    features += ',left=' + GetCenteringLeft(window, opt_width) + ',' +
+                'top=' + GetCenteringTop(window, opt_height);
+  }
+  return OpenWindow(window, url, opt_name, features, opt_blocked_msg);
+}
+
+/**
+ * Opens a new window. Returns the new window handle. Tries to open the new
+ * window using top.open() first. If that doesn't work, then tries win.open().
+ * If that still doesn't work, prints an alert.
+ * (Copied from caribou's common.js library with small modifications.)
+ *
+ * @param win the parent window from which to open the new child window
+ * @param url the URL for the new window (Note: this will be unique-ified)
+ * @param opt_name the name of the new window
+ * @param opt_features the properties of the new window
+ * @param opt_blocked_msg message warning that the popup has been blocked
+ * @return {Window} a reference to the new child window
+ */
+function OpenWindow(win, url, opt_name, opt_features, opt_blocked_msg) {
+  let newwin = OpenWindowHelper(top, url, opt_name, opt_features);
+  if (!newwin || newwin.closed || !newwin.focus) {
+    newwin = OpenWindowHelper(win, url, opt_name, opt_features);
+  }
+  if (!newwin || newwin.closed || !newwin.focus) {
+    if (opt_blocked_msg) alert(opt_blocked_msg);
+  } else {
+    // Make sure that the window has the focus
+    newwin.focus();
+  }
+  return newwin;
+}
+
+/*
+ * Helper for OpenWindow().
+ * (Copied from caribou's common.js library with small modifications.)
+ */
+function OpenWindowHelper(win, url, name, features) {
+  let newwin;
+  if (features) {
+    newwin = win.open(url, name, features);
+  } else if (name) {
+    newwin = win.open(url, name);
+  } else {
+    newwin = win.open(url);
+  }
+  return newwin;
+}
+
+// ------------------------------------------------------------------------
+// String utilities
+// ------------------------------------------------------------------------
+// Do html escaping
+var amp_re_ = /&/g;
+var lt_re_ = /</g;
+var gt_re_ = />/g;
+
+// converts multiple ws chars to a single space, and strips
+// leading and trailing ws
+var spc_re_ = /\s+/g;
+var beg_spc_re_ = /^ /;
+var end_spc_re_ = / $/;
+
+var newline_re_ = /\r?\n/g;
+var spctab_re_ = /[ \t]+/g;
+var nbsp_re_ = /\xa0/g;
+
+// URL-decodes the string. We need to specially handle '+'s because
+// the javascript library doesn't properly convert them to spaces
+var plus_re_ = /\+/g;
+
+// Converts any instances of "\r" or "\r\n" style EOLs into "\n" (Line Feed),
+// and also trim the extra newlines and whitespaces at the end.
+var eol_re_ = /\r\n?/g;
+var trailingspc_re_ = /[\n\t ]+$/;
+
+// Converts a string to its canonicalized label form.
+var illegal_chars_re_ = /[ \/(){}&|\\\"\000]/g;
+
+// ------------------------------------------------------------------------
+// TextArea utilities
+// ------------------------------------------------------------------------
+
+// Gets the cursor pos in a text area. Returns -1 if the cursor pos cannot
+// be determined or if the cursor out of the textfield.
+function GetCursorPos(win, textfield) {
+  try {
+    if (IsDefined(textfield.selectionEnd)) {
+      // Mozilla directly supports this
+      return textfield.selectionEnd;
+    } else if (win.document.selection && win.document.selection.createRange) {
+      // IE doesn't export an accessor for the endpoints of a selection.
+      // Instead, it uses the TextRange object, which has an extremely obtuse
+      // API. Here's what seems to work:
+
+      // (1) Obtain a textfield from the current selection (cursor)
+      let tr = win.document.selection.createRange();
+
+      // Check if the current selection is in the textfield
+      if (tr.parentElement() != textfield) {
+        return -1;
+      }
+
+      // (2) Make a text range encompassing the textfield
+      let tr2 = tr.duplicate();
+      tr2.moveToElementText(textfield);
+
+      // (3) Move the end of the copy to the beginning of the selection
+      tr2.setEndPoint('EndToStart', tr);
+
+      // (4) The span of the textrange copy is equivalent to the cursor pos
+      let cursor = tr2.text.length;
+
+      // Finally, perform a sanity check to make sure the cursor is in the
+      // textfield. IE sometimes screws this up when the window is activated
+      if (cursor > textfield.value.length) {
+        return -1;
+      }
+      return cursor;
+    } else {
+      Debug('Unable to get cursor position for: ' + navigator.userAgent);
+
+      // Just return the size of the textfield
+      // TODO: Investigate how to get cursor pos in Safari!
+      return textfield.value.length;
+    }
+  } catch (e) {
+    DumpException(e, 'Cannot get cursor pos');
+  }
+
+  return -1;
+}
+
+function SetCursorPos(win, textfield, pos) {
+  if (IsDefined(textfield.selectionEnd) &&
+      IsDefined(textfield.selectionStart)) {
+    // Mozilla directly supports this
+    textfield.selectionStart = pos;
+    textfield.selectionEnd = pos;
+  } else if (win.document.selection && textfield.createTextRange) {
+    // IE has textranges. A textfield's textrange encompasses the
+    // entire textfield's text by default
+    let sel = textfield.createTextRange();
+
+    sel.collapse(true);
+    sel.move('character', pos);
+    sel.select();
+  }
+}
+
+// ------------------------------------------------------------------------
+// Array utilities
+// ------------------------------------------------------------------------
+// Find an item in an array, returns the key, or -1 if not found
+function FindInArray(array, x) {
+  for (let i = 0; i < array.length; i++) {
+    if (array[i] == x) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+// Delete an element from an array
+function DeleteArrayElement(array, x) {
+  let i = 0;
+  while (i < array.length && array[i] != x) {
+    i++;
+  }
+  array.splice(i, 1);
+}
+
+// Clean up email address:
+// - remove extra spaces
+// - Surround name with quotes if it contains special characters
+// to check if we need " quotes
+// Note: do not use /g in the regular expression, otherwise the
+// regular expression cannot be reusable.
+var specialchars_re_ = /[()<>@,;:\\\".\[\]]/;
+
+// ------------------------------------------------------------------------
+// Timeouts
+//
+// It is easy to forget to put a try/catch block around a timeout function,
+// and the result is an ugly user visible javascript error.
+// Also, it would be nice if a timeout associated with a window is
+// automatically cancelled when the user navigates away from that window.
+//
+// When storing timeouts in a window, we can't let that variable be renamed
+// since the window could be top.js, and renaming such a property could
+// clash with any of the variables/functions defined in top.js.
+// ------------------------------------------------------------------------
+/**
+ * Sets a timeout safely.
+ * @param win the window object. If null is passed in, then a timeout if set
+ *   on the js frame. If the window is closed, or freed, the timeout is
+ *   automaticaaly cancelled
+ * @param fn the callback function: fn(win) will be called.
+ * @param ms number of ms the callback should be called later
+ */
+function SafeTimeout(win, fn, ms) {
+  if (!win) win = window;
+  if (!win._tm) {
+    win._tm = [];
+  }
+  let timeoutfn = SafeTimeoutFunction_(win, fn);
+  let id = win.setTimeout(timeoutfn, ms);
+
+  // Save the id so that it can be removed from the _tm array
+  timeoutfn.id = id;
+
+  // Safe the timeout in the _tm array
+  win._tm[id] = 1;
+
+  return id;
+}
+
+/** Creates a callback function for a timeout*/
+function SafeTimeoutFunction_(win, fn) {
+  var timeoutfn = function() {
+    try {
+      fn(win);
+
+      let t = win._tm;
+      if (t) {
+        delete t[timeoutfn.id];
+      }
+    } catch (e) {
+      DumpException(e);
+    }
+  };
+  return timeoutfn;
+}
+
+// ------------------------------------------------------------------------
+// Misc
+// ------------------------------------------------------------------------
+// Check if a value is defined
+function IsDefined(value) {
+  return (typeof value) != 'undefined';
+}
diff --git a/static/js/graveyard/geom.js b/static/js/graveyard/geom.js
new file mode 100644
index 0000000..3eaffb7
--- /dev/null
+++ b/static/js/graveyard/geom.js
@@ -0,0 +1,94 @@
+/* Copyright 2016 The Chromium Authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://developers.google.com/open-source/licenses/bsd
+ */
+
+// functions for dealing with layout and geometry of page elements.
+// Requires shapes.js
+
+/** returns the bounding box of the given DOM node in document space.
+  *
+  * @param {Element?} obj a DOM node.
+  * @return {Rect?}
+  */
+function nodeBounds(obj) {
+  if (!obj) return null;
+
+  function fixRectForScrolling(r) {
+    // Need to take into account scrolling offset of ancestors (IE already does
+    // this)
+    for (let o = obj.offsetParent;
+      o && o.offsetParent;
+      o = o.offsetParent) {
+      if (o.scrollLeft) {
+        r.x -= o.scrollLeft;
+      }
+      if (o.scrollTop) {
+        r.y -= o.scrollTop;
+      }
+    }
+  }
+
+  let refWindow;
+  if (obj.ownerDocument && obj.ownerDocument.parentWindow) {
+    refWindow = obj.ownerDocument.parentWindow;
+  } else if (obj.ownerDocument && obj.ownerDocument.defaultView) {
+    refWindow = obj.ownerDocument.defaultView;
+  } else {
+    refWindow = window;
+  }
+
+  // IE, Mozilla 3+
+  if (obj.getBoundingClientRect) {
+    let rect = obj.getBoundingClientRect();
+
+    return new Rect(rect.left + GetScrollLeft(refWindow),
+      rect.top + GetScrollTop(refWindow),
+      rect.right - rect.left,
+      rect.bottom - rect.top,
+      refWindow);
+  }
+
+  // Mozilla < 3
+  if (obj.ownerDocument && obj.ownerDocument.getBoxObjectFor) {
+    let box = obj.ownerDocument.getBoxObjectFor(obj);
+    var r = new Rect(box.x, box.y, box.width, box.height, refWindow);
+    fixRectForScrolling(r);
+    return r;
+  }
+
+  // Fallback to recursively computing this
+  let left = 0;
+  let top = 0;
+  for (let o = obj; o.offsetParent; o = o.offsetParent) {
+    left += o.offsetLeft;
+    top += o.offsetTop;
+  }
+
+  var r = new Rect(left, top, obj.offsetWidth, obj.offsetHeight, refWindow);
+  fixRectForScrolling(r);
+  return r;
+}
+
+function GetMousePosition(e) {
+  // copied from http://www.quirksmode.org/js/events_compinfo.html
+  let posx = 0;
+  let posy = 0;
+  if (e.pageX || e.pageY) {
+    posx = e.pageX;
+    posy = e.pageY;
+  } else if (e.clientX || e.clientY) {
+    let obj = (e.target ? e.target : e.srcElement);
+    let refWindow;
+    if (obj.ownerDocument && obj.ownerDocument.parentWindow) {
+      refWindow = obj.ownerDocument.parentWindow;
+    } else {
+      refWindow = window;
+    }
+    posx = e.clientX + GetScrollLeft(refWindow);
+    posy = e.clientY + GetScrollTop(refWindow);
+  }
+  return new Point(posx, posy, window);
+}
diff --git a/static/js/graveyard/listen.js b/static/js/graveyard/listen.js
new file mode 100644
index 0000000..953d674
--- /dev/null
+++ b/static/js/graveyard/listen.js
@@ -0,0 +1,145 @@
+/* Copyright 2016 The Chromium Authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://developers.google.com/open-source/licenses/bsd
+ */
+
+var listen;
+var unlisten;
+var unlistenByKey;
+
+(function() {
+  let listeners = {};
+  let nextId = 0;
+
+  function getHashCode_(obj) {
+    if (obj.listen_hc_ == null) {
+      obj.listen_hc_ = ++nextId;
+    }
+    return obj.listen_hc_;
+  }
+
+  /**
+   * Takes a node, event, listener, and capture flag to create a key
+   * to identify the tuple in the listeners hash.
+   *
+   * @param {Element} node The node to listen to events on.
+   * @param {string} event The name of the event without the "on" prefix.
+   * @param {Function} listener A function to call when the event occurs.
+   * @param {boolean} opt_useCapture In DOM-compliant browsers, this determines
+   *                                 whether the listener is fired during the
+   *                                 capture or bubble phase of the event.
+   * @return {string} key to identify this tuple in the listeners hash.
+   */
+  function createKey_(node, event, listener, opt_useCapture) {
+    let nodeHc = getHashCode_(node);
+    let listenerHc = getHashCode_(listener);
+    opt_useCapture = !!opt_useCapture;
+    let key = nodeHc + '_' + event + '_' + listenerHc + '_' + opt_useCapture;
+    return key;
+  }
+
+  /**
+   * Adds an event listener to a DOM node for a specific event.
+   *
+   * Listen() and unlisten() use an indirect lookup of listener functions
+   * to avoid circular references between DOM (in IE) or XPCOM (in Mozilla)
+   * objects which leak memory. This makes it easier to write OO
+   * Javascript/DOM code.
+   *
+   * Examples:
+   * listen(myButton, 'click', myHandler, true);
+   * listen(myButton, 'click', this.myHandler.bind(this), true);
+   *
+   * @param {Element} node The node to listen to events on.
+   * @param {string} event The name of the event without the "on" prefix.
+   * @param {Function} listener A function to call when the event occurs.
+   * @param {boolean} opt_useCapture In DOM-compliant browsers, this determines
+   *                                 whether the listener is fired during the
+   *                                 capture or bubble phase of the event.
+   * @return {string} a unique key to indentify this listener.
+   */
+  listen = function(node, event, listener, opt_useCapture) {
+    let key = createKey_(node, event, listener, opt_useCapture);
+
+    // addEventListener does not allow multiple listeners
+    if (key in listeners) {
+      return key;
+    }
+
+    let proxy = handleEvent.bind(null, key);
+    listeners[key] = {
+      listener: listener,
+      proxy: proxy,
+      event: event,
+      node: node,
+      useCapture: opt_useCapture,
+    };
+
+    if (node.addEventListener) {
+      node.addEventListener(event, proxy, opt_useCapture);
+    } else if (node.attachEvent) {
+      node.attachEvent('on' + event, proxy);
+    } else {
+      throw new Error('Node {' + node + '} does not support event listeners.');
+    }
+
+    return key;
+  };
+
+  /**
+   * Removes an event listener which was added with listen().
+   *
+   * @param {Element} node The node to stop listening to events on.
+   * @param {string} event The name of the event without the "on" prefix.
+   * @param {Function} listener The listener function to remove.
+   * @param {boolean} opt_useCapture In DOM-compliant browsers, this determines
+   *                                 whether the listener is fired during the
+   *                                 capture or bubble phase of the event.
+   * @return {boolean} indicating whether the listener was there to remove.
+   */
+  unlisten = function(node, event, listener, opt_useCapture) {
+    let key = createKey_(node, event, listener, opt_useCapture);
+
+    return unlistenByKey(key);
+  };
+
+  /**
+   * Variant of {@link unlisten} that takes a key that was returned by
+   * {@link listen} and removes that listener.
+   *
+   * @param {string} key Key of event to be unlistened.
+   * @return {boolean} indicating whether it was there to be removed.
+   */
+  unlistenByKey = function(key) {
+    if (!(key in listeners)) {
+      return false;
+    }
+    let listener = listeners[key];
+    let proxy = listener.proxy;
+    let event = listener.event;
+    let node = listener.node;
+    let useCapture = listener.useCapture;
+
+    if (node.removeEventListener) {
+      node.removeEventListener(event, proxy, useCapture);
+    } else if (node.detachEvent) {
+      node.detachEvent('on' + event, proxy);
+    }
+
+    delete listeners[key];
+    return true;
+  };
+
+  /**
+   * The function which is actually called when the DOM event occurs. This
+   * function is a proxy for the real listener the user specified.
+   */
+  function handleEvent(key) {
+    // pass all arguments which were sent to this function except listenerID
+    // on to the actual listener.
+    let args = Array.prototype.splice.call(arguments, 1, arguments.length);
+    return listeners[key].listener.apply(null, args);
+  }
+})();
diff --git a/static/js/graveyard/popup_controller.js b/static/js/graveyard/popup_controller.js
new file mode 100644
index 0000000..41c2956
--- /dev/null
+++ b/static/js/graveyard/popup_controller.js
@@ -0,0 +1,145 @@
+/* Copyright 2016 The Chromium Authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://developers.google.com/open-source/licenses/bsd
+ */
+
+/**
+ * It is common to make a DIV temporarily visible to simulate
+ * a popup window. Often, this is done by adding an onClick
+ * handler to the element that can be clicked on to show the
+ * popup.
+ *
+ * Unfortunately, closing the popup is not as simple.
+ * The popup creator often wants to let the user close
+ * the popup by clicking elsewhere on the window; however,
+ * the popup only receives mouse events that occur
+ * on the popup itself. Thus, popups need a mechanism
+ * that notifies them that the user has clicked elsewhere
+ * to try to get rid of them.
+ *
+ * PopupController is such a mechanism --
+ * it monitors all mousedown events that
+ * occur in the window so that it can notify registered
+ * popups of the mousedown, and the popups can choose
+ * to deactivate themselves.
+ *
+ * For an object to qualify as a popup, it must have a
+ * function called "deactivate" that takes a mousedown event
+ * and returns a boolean indicating that it has deactivated
+ * itself as a result of that event.
+ *
+ * EXAMPLE:
+ *
+ * // popup that attaches itself to the supplied div
+ * function MyPopup(div) {
+ *   this._div = div;
+ *   this._isVisible = false;
+ *   this._innerHTML = ...
+ * }
+ *
+ * MyPopup.prototype.show = function() {
+ *   this._div.display = '';
+ *   this._isVisible = true;
+ *   PC_addPopup(this);
+ * }
+ *
+ * MyPopup.prototype.hide = function() {
+ *   this._div.display = 'none';
+ *   this._isVisible = false;
+ * }
+ *
+ * MyPopup.prototype.deactivate = function(e) {
+ *   if (this._isVisible) {
+ *     var p = GetMousePosition(e);
+ *     if (nodeBounds(this._div).contains(p)) {
+ *       return false; // use clicked on popup, remain visible
+ *     } else {
+ *       this.hide();
+ *       return true; // clicked outside popup, make invisible
+ *     }
+ *   } else {
+ *     return true; // already deactivated, not visible
+ *   }
+ * }
+ *
+ * DEPENDENCIES (from this directory):
+ *   bind.js
+ *   listen.js
+ *   common.js
+ *   shapes.js
+ *   geom.js
+ *
+ * USAGE:
+ *  _PC_Install() must be called after the body is loaded
+ */
+
+/**
+ * PopupController constructor.
+ * @constructor
+ */
+function PopupController() {
+  this.activePopups_ = [];
+}
+
+/**
+ * @param {Document} opt_doc document to add PopupController to
+ *                   DEFAULT: "document" variable that is currently in scope
+ * @return {boolean} indicating if PopupController installed for the document;
+ *                   returns false if document already had PopupController
+ */
+function _PC_Install(opt_doc) {
+  if (gPopupControllerInstalled) return false;
+  gPopupControllerInstalled = true;
+  let doc = (opt_doc) ? opt_doc : document;
+
+  // insert _notifyPopups in BODY's onmousedown chain
+  listen(doc.body, 'mousedown', PC_notifyPopups);
+  return true;
+}
+
+/**
+ * Notifies each popup of a mousedown event, giving
+ * each popup the chance to deactivate itself.
+ *
+ * @throws Error if a popup does not have a deactivate function
+ *
+ * @private
+ */
+function PC_notifyPopups(e) {
+  if (gPopupController.activePopups_.length == 0) return false;
+  e = e || window.event;
+  for (let i = gPopupController.activePopups_.length - 1; i >= 0; --i) {
+    let popup = gPopupController.activePopups_[i];
+    PC_assertIsPopup(popup);
+    if (popup.deactivate(e)) {
+      gPopupController.activePopups_.splice(i, 1);
+    }
+  }
+  return true;
+}
+
+/**
+ * Adds the popup to the list of popups to be
+ * notified of a mousedown event.
+ *
+ * @return boolean indicating if added popup; false if already contained
+ * @throws Error if popup does not have a deactivate function
+ */
+function PC_addPopup(popup) {
+  PC_assertIsPopup(popup);
+  for (let i = 0; i < gPopupController.activePopups_.length; ++i) {
+    if (popup === gPopupController.activePopups_[i]) return false;
+  }
+  gPopupController.activePopups_.push(popup);
+  return true;
+}
+
+/** asserts that popup has a deactivate function */
+function PC_assertIsPopup(popup) {
+  AssertType(popup.deactivate, Function, 'popup missing deactivate function');
+}
+
+var gPopupController = new PopupController();
+var gPopupControllerInstalled = false;
diff --git a/static/js/graveyard/shapes.js b/static/js/graveyard/shapes.js
new file mode 100644
index 0000000..27cd7f1
--- /dev/null
+++ b/static/js/graveyard/shapes.js
@@ -0,0 +1,126 @@
+/* Copyright 2016 The Chromium Authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://developers.google.com/open-source/licenses/bsd
+ */
+
+// shape related classes
+
+/** a point in 2 cartesian dimensions.
+  * @constructor
+  * @param x x-coord.
+  * @param y y-coord.
+  * @param opt_coordinateFrame a key that can be passed to a translation function to
+  *   convert from one coordinate frame to another.
+  *   Coordinate frames might correspond to things like windows, iframes, or
+  *   any element with a position style attribute.
+  */
+function Point(x, y, opt_coordinateFrame) {
+  /** a numeric x coordinate. */
+  this.x = x;
+  /** a numeric y coordinate. */
+  this.y = y;
+  /** a key that can be passed to a translation function to
+    * convert from one coordinate frame to another.
+    * Coordinate frames might correspond to things like windows, iframes, or
+    * any element with a position style attribute.
+    */
+  this.coordinateFrame = opt_coordinateFrame || null;
+}
+Point.prototype.toString = function() {
+  return '[P ' + this.x + ',' + this.y + ']';
+};
+Point.prototype.clone = function() {
+  return new Point(this.x, this.y, this.coordinateFrame);
+};
+
+/** a distance between two points in 2-space in cartesian form.
+  * A delta doesn't have a coordinate frame associated since all the coordinate
+  * frames used in the HTML dom are convertible without rotation/scaling.
+  * If a delta is not being used in pixel-space then it may be annotated with
+  * a coordinate frame, and the undefined coordinate frame can be assumed
+  * to represent pixel space.
+  * @constructor
+  * @param dx distance along x axis
+  * @param dy distance along y axis
+  */
+function Delta(dx, dy) {
+  /** a numeric distance along the x dimension. */
+  this.dx = dx;
+  /** a numeric distance along the y dimension. */
+  this.dy = dy;
+}
+Delta.prototype.toString = function() {
+  return '[D ' + this.dx + ',' + this.dy + ']';
+};
+
+/** a rectangle or bounding region.
+  * @constructor
+  * @param x x-coord of the left edge.
+  * @param y y-coord of the top edge.
+  * @param w width.
+  * @param h height.
+  * @param opt_coordinateFrame a key that can be passed to a translation function to
+  *   convert from one coordinate frame to another.
+  *   Coordinate frames might correspond to things like windows, iframes, or
+  *   any element with a position style attribute.
+  */
+function Rect(x, y, w, h, opt_coordinateFrame) {
+  /** the numeric x coordinate of the left edge. */
+  this.x = x;
+  /** the numeric y coordinate of the top edge. */
+  this.y = y;
+  /** the numeric distance between the right edge and the left. */
+  this.w = w;
+  /** the numeric distance between the top edge and the bottom. */
+  this.h = h;
+  /** a key that can be passed to a translation function to
+    * convert from one coordinate frame to another.
+    * Coordinate frames might correspond to things like windows, iframes, or
+    * any element with a position style attribute.
+    */
+  this.coordinateFrame = opt_coordinateFrame || null;
+}
+
+/**
+ * Determines whether the Rectangle contains the Point.
+ * The Point is considered "contained" if it lies
+ * on the boundary of, or in the interior of, the Rectangle.
+ *
+ * @param {Point} p
+ * @return boolean indicating if this Rect contains p
+ */
+Rect.prototype.contains = function(p) {
+  return this.x <= p.x && p.x < (this.x + this.w) &&
+             this.y <= p.y && p.y < (this.y + this.h);
+};
+
+/**
+ * Determines whether the given rectangle intersects this rectangle.
+ *
+ * @param {Rect} r
+ * @return boolean indicating if this the two rectangles intersect
+ */
+Rect.prototype.intersects = function(r) {
+  let p = function(x, y) {
+    return new Point(x, y, null);
+  };
+
+  return this.contains(p(r.x, r.y)) ||
+         this.contains(p(r.x + r.w, r.y)) ||
+         this.contains(p(r.x + r.w, r.y + r.h)) ||
+         this.contains(p(r.x, r.y + r.h)) ||
+         r.contains(p(this.x, this.y)) ||
+         r.contains(p(this.x + this.w, this.y)) ||
+         r.contains(p(this.x + this.w, this.y + this.h)) ||
+         r.contains(p(this.x, this.y + this.h));
+};
+
+Rect.prototype.toString = function() {
+  return '[R ' + this.w + 'x' + this.h + '+' + this.x + '+' + this.y + ']';
+};
+
+Rect.prototype.clone = function() {
+  return new Rect(this.x, this.y, this.w, this.h, this.coordinateFrame);
+};
diff --git a/static/js/graveyard/xmlhttp.js b/static/js/graveyard/xmlhttp.js
new file mode 100644
index 0000000..eaf1f36
--- /dev/null
+++ b/static/js/graveyard/xmlhttp.js
@@ -0,0 +1,141 @@
+/* Copyright 2016 The Chromium Authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://developers.google.com/open-source/licenses/bsd
+ */
+
+/**
+ * @fileoverview A bunch of XML HTTP recipes used to do RPC from JavaScript
+ */
+
+
+/**
+ * The active x identifier used for ie.
+ * @type String
+ * @private
+ */
+var XH_ieProgId_;
+
+
+// Domain for XMLHttpRequest readyState
+var XML_READY_STATE_UNINITIALIZED = 0;
+var XML_READY_STATE_LOADING = 1;
+var XML_READY_STATE_LOADED = 2;
+var XML_READY_STATE_INTERACTIVE = 3;
+var XML_READY_STATE_COMPLETED = 4;
+
+
+/**
+ * Initialize the private state used by other functions.
+ * @private
+ */
+function XH_XmlHttpInit_() {
+  // The following blog post describes what PROG IDs to use to create the
+  // XMLHTTP object in Internet Explorer:
+  // http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
+  // However we do not (yet) fully trust that this will be OK for old versions
+  // of IE on Win9x so we therefore keep the last 2.
+  // Versions 4 and 5 have been removed because 3.0 is the preferred "fallback"
+  // per the article above.
+  // - Version 5 was built for Office applications and is not recommended for
+  //   web applications.
+  // - Version 4 has been superseded by 6 and is only intended for legacy apps.
+  // - Version 3 has a wide install base and is serviced regularly with the OS.
+
+  /**
+   * Candidate Active X types.
+   * @type Array.<String>
+   * @private
+   */
+  let XH_ACTIVE_X_IDENTS = ['MSXML2.XMLHTTP.6.0', 'MSXML2.XMLHTTP.3.0',
+    'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
+
+  if (typeof XMLHttpRequest == 'undefined' &&
+      typeof ActiveXObject != 'undefined') {
+    for (let i = 0; i < XH_ACTIVE_X_IDENTS.length; i++) {
+      let candidate = XH_ACTIVE_X_IDENTS[i];
+
+      try {
+        new ActiveXObject(candidate);
+        XH_ieProgId_ = candidate;
+        break;
+      } catch (e) {
+        // do nothing; try next choice
+      }
+    }
+
+    // couldn't find any matches
+    if (!XH_ieProgId_) {
+      throw Error('Could not create ActiveXObject. ActiveX might be disabled,' +
+                  ' or MSXML might not be installed.');
+    }
+  }
+}
+
+
+XH_XmlHttpInit_();
+
+
+/**
+ * Create and return an xml http request object that can be passed to
+ * {@link #XH_XmlHttpGET} or {@link #XH_XmlHttpPOST}.
+ */
+function XH_XmlHttpCreate() {
+  if (XH_ieProgId_) {
+    return new ActiveXObject(XH_ieProgId_);
+  } else {
+    return new XMLHttpRequest();
+  }
+}
+
+
+/**
+ * Send a get request.
+ * @param {XMLHttpRequest} xmlHttp as from {@link XH_XmlHttpCreate}.
+ * @param {string} url the service to contact
+ * @param {Function} handler function called when the response is received.
+ */
+function XH_XmlHttpGET(xmlHttp, url, handler) {
+  xmlHttp.open('GET', url, true);
+  xmlHttp.onreadystatechange = handler;
+  XH_XmlHttpSend(xmlHttp, null);
+}
+
+/**
+ * Send a post request.
+ * @param {XMLHttpRequest} xmlHttp as from {@link XH_XmlHttpCreate}.
+ * @param {string} url the service to contact
+ * @param {string} data the request content.
+ * @param {Function} handler function called when the response is received.
+ */
+function XH_XmlHttpPOST(xmlHttp, url, data, handler) {
+  xmlHttp.open('POST', url, true);
+  xmlHttp.onreadystatechange = handler;
+  xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+  XH_XmlHttpSend(xmlHttp, data);
+}
+
+/**
+ * Calls 'send' on the XMLHttpRequest object and calls a function called 'log'
+ * if any error occured.
+ *
+ * @deprecated This dependes on a function called 'log'. You are better off
+ * handling your errors on application level.
+ *
+ * @param {XMLHttpRequest} xmlHttp as from {@link XH_XmlHttpCreate}.
+ * @param {string|null} data the request content.
+ */
+function XH_XmlHttpSend(xmlHttp, data) {
+  try {
+    xmlHttp.send(data);
+  } catch (e) {
+    // You may want to log/debug this error one that you should be aware of is
+    // e.number == -2146697208, which occurs when the 'Languages...' setting in
+    // IE is empty.
+    // This is not entirely true. The same error code is used when the user is
+    // off line.
+    console.log('XMLHttpSend failed ' + e.toString() + '<br>' + e.stack);
+    throw e;
+  }
+}
