diff --git a/static/js/tracker/ac.js b/static/js/tracker/ac.js
new file mode 100644
index 0000000..4c0bf2b
--- /dev/null
+++ b/static/js/tracker/ac.js
@@ -0,0 +1,1010 @@
+/* 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
+ */
+
+/**
+ * An autocomplete library for javascript.
+ * Public API
+ * - _ac_install() install global handlers required for everything else to
+ *   function.
+ * - _ac_register(SC) register a store constructor (see below)
+ * - _ac_isCompleting() true iff focus is in an auto complete box and the user
+ *   has triggered completion with a keystroke, and completion has not been
+ *   cancelled (programatically or otherwise).
+ * - _ac_isCompleteListShowing() true if _as_isCompleting and the complete list
+ *   is visible to the user.
+ * - _ac_cancel() if completing, stop it, otherwise a no-op.
+ *
+ *
+ * A quick example
+ *     // an auto complete store
+ *     var myFavoritestAutoCompleteStore = new _AC_SimpleStore(
+ *       ['some', 'strings', 'to', 'complete']);
+ *
+ *     // a store constructor
+ *     _ac_register(function (inputNode, keyEvent) {
+ *         if (inputNode.id == 'my-auto-completing-check-box') {
+ *           return myFavoritestAutoCompleteStore;
+ *         }
+ *         return null;
+ *       });
+ *
+ *     <html>
+ *       <head>
+ *         <script type=text/javascript src=ac.js></script>
+ *       </head>
+ *       <body onload=_ac_install()>
+ *         <!-- the constructor above looks at the id.  It could as easily
+ *            - look at the class, name, or value.
+ *            - The autocomplete=off stops browser autocomplete from
+ *            - interfering with our autocomplete
+ *           -->
+ *         <input type=text id="my-auto-completing-check-box"
+ *          autocomplete=off>
+ *       </body>
+ *     </html>
+ *
+ *
+ * Concepts
+ * - Store Constructor function
+ *   A store constructor is a policy function with the signature
+ *     _AC_Store myStoreConstructor(
+ *       HtmlInputElement|HtmlTextAreaElement inputNode, Event keyEvent)
+ *   When a key event is received on a text input or text area, the autocomplete
+ *   library will try each of the store constructors in turn until it finds one
+ *   that returns an AC_Store which will be used for auto-completion of that
+ *   text box until focus is lost.
+ *
+ * - interface _AC_Store
+ *   An autocomplete store encapsulates all operations that affect how a
+ *   particular text node is autocompleted.  It has the following operations:
+ *   - String completable(String inputValue, int caret)
+ *     This method returns null if not completable or the section of inputValue
+ *     that is subject to completion.  If autocomplete works on items in a
+ *     comma separated list, then the input value "foo, ba" might yield "ba"
+ *     as the completable chunk since it is separated from its predecessor by
+ *     a comma.
+ *     caret is the position of the text cursor (caret) in the text input.
+ *   - _AC_Completion[] completions(String completable,
+ *                                  _AC_Completion[] toFilter)
+ *     This method returns null if there are no completions.  If toFilter is
+ *     not null or undefined, then this method may assume that toFilter was
+ *     returned as a set of completions that contain completable.
+ *   - String substitute(String inputValue, int caret,
+ *                       String completable, _AC_Completion completion)
+ *     returns the inputValue with the given completion substituted for the
+ *     given completable.  caret has the same meaning as in the
+ *     completable operation.
+ *   - String oncomplete(boolean completed, String key,
+ *                       HTMLElement element, String text)
+ *     This method is called when the user hits a completion key. The default
+ *     value is to do nothing, but you can override it if you want. Note that
+ *     key will be null if the user clicked on it to select
+ *   - Boolean autoselectFirstRow()
+ *     This method returns True by default, but subclasses can override it
+ *     to make autocomplete fields that require the user to press the down
+ *     arrow or do a mouseover once before any completion option is considered
+ *     to be selected.
+ *
+ * - class _AC_SimpleStore
+ *   An implementation of _AC_Store that completes a set of strings given at
+ *   construct time in a text field with a comma separated value.
+ *
+ * - struct _AC_Completion
+ *   a struct with two fields
+ *   - String value : the plain text completion value
+ *   - String html : the value, as html, with the completable in bold.
+ *
+ * Key Handling
+ * Several keys affect completion in an autocompleted input.
+ * ESC - the escape key cancels autocompleting.  The autocompletion will have
+ *   no effect on the focused textbox until it loses focus, regains it, and
+ *   a key is pressed.
+ * ENTER - completes using the currently selected completion, or if there is
+ *   only one, uses that completion.
+ * UP ARROW - selects the completion above the current selection.
+ * DOWN ARROW - selects the completion below the current selection.
+ *
+ *
+ * CSS styles
+ * The following CSS selector rules can be used to change the completion list
+ * look:
+ * #ac-list               style of the auto-complete list
+ * #ac-list .selected     style of the selected item
+ * #ac-list b             style of the matching text in a candidate completion
+ *
+ * Dependencies
+ * The library depends on the following libraries:
+ * javascript:base for definition of key constants and SetCursorPos
+ * javascript:shapes for nodeBounds()
+ */
+
+/**
+ * install global handlers required for the rest of the module to function.
+ */
+function _ac_install() {
+  ac_addHandler_(document.body, 'onkeydown', ac_keyevent_);
+  ac_addHandler_(document.body, 'onkeypress', ac_keyevent_);
+}
+
+/**
+ * register a store constructor
+ * @param storeConstructor a function like
+ *   _AC_Store myStoreConstructor(HtmlInputElement|HtmlTextArea, Event)
+ */
+function _ac_register(storeConstructor) {
+  // check that not already registered
+  for (let i = ac_storeConstructors.length; --i >= 0;) {
+    if (ac_storeConstructors[i] === storeConstructor) {
+      return;
+    }
+  }
+  ac_storeConstructors.push(storeConstructor);
+}
+
+/**
+ * may be attached as an onfocus handler to a text input to popup autocomplete
+ * immediately on the box gaining focus.
+ */
+function _ac_onfocus(event) {
+  ac_keyevent_(event);
+}
+
+/**
+ * true iff the autocomplete widget is currently active.
+ */
+function _ac_isCompleting() {
+  return !!ac_store && !ac_suppressCompletions;
+}
+
+/**
+ * true iff the completion list is displayed.
+ */
+function _ac_isCompleteListShowing() {
+  return !!ac_store && !ac_suppressCompletions && ac_completions &&
+    ac_completions.length;
+}
+
+/**
+ * cancel any autocomplete in progress.
+ */
+function _ac_cancel() {
+  ac_suppressCompletions = true;
+  ac_updateCompletionList(false);
+}
+
+/** add a handler without whacking any existing handler. @private */
+function ac_addHandler_(node, handlerName, handler) {
+  const oldHandler = node[handlerName];
+  if (!oldHandler) {
+    node[handlerName] = handler;
+  } else {
+    node[handlerName] = ac_fnchain_(node[handlerName], handler);
+  }
+  return oldHandler;
+}
+
+/** cancel the event. @private */
+function ac_cancelEvent_(event) {
+  if ('stopPropagation' in event) {
+    event.stopPropagation();
+  } else {
+    event.cancelBubble = true;
+  }
+
+  // This is handled in IE by returning false from the handler
+  if ('preventDefault' in event) {
+    event.preventDefault();
+  }
+}
+
+/** Call two functions, a and b, and return false if either one returns
+    false.  This is used as a primitive way to attach multiple event
+    handlers to an element without using addEventListener().   This
+    library predates the availablity of addEventListener().
+    @private
+*/
+function ac_fnchain_(a, b) {
+  return function() {
+    const ar = a.apply(this, arguments);
+    const br = b.apply(this, arguments);
+
+    // NOTE 1: (undefined && false) -> undefined
+    // NOTE 2: returning FALSE from a onkeypressed cancels it,
+    //         returning UNDEFINED does not.
+    // As such, we specifically look for falses here
+    if (ar === false || br === false) {
+      return false;
+    } else {
+      return true;
+    }
+  };
+}
+
+/** key press handler.  @private */
+function ac_keyevent_(event) {
+  event = event || window.event;
+
+  const source = getTargetFromEvent(event);
+  const isInput = 'INPUT' == source.tagName &&
+    source.type.match(/^text|email$/i);
+  const isTextarea = 'TEXTAREA' == source.tagName;
+  if (!isInput && !isTextarea) return true;
+
+  const key = event.key;
+  const isDown = event.type == 'keydown';
+  const isShiftKey = event.shiftKey;
+  let storeFound = true;
+
+  if ((source !== ac_focusedInput) || (ac_store === null)) {
+    ac_focusedInput = source;
+    storeFound = false;
+    if (ENTER_KEYNAME !== key && ESC_KEYNAME !== key) {
+      for (let i = 0; i < ac_storeConstructors.length; ++i) {
+        const store = (ac_storeConstructors[i])(source, event);
+        if (store) {
+          ac_store = store;
+          ac_store.setAvoid(event);
+          ac_oldBlurHandler = ac_addHandler_(
+              ac_focusedInput, 'onblur', _ac_ob);
+          storeFound = true;
+          break;
+        }
+      }
+
+      // There exists an odd condition where an edit box with autocomplete
+      // attached can be removed from the DOM without blur being called
+      // In which case we are left with a store around that will try to
+      // autocomplete the next edit box to receive focus. We need to clean
+      // this up
+
+      // If we can't find a store, force a blur
+      if (!storeFound) {
+        _ac_ob(null);
+      }
+    }
+    // ac-table rows need to be removed when switching to another input.
+    ac_updateCompletionList(false);
+  }
+  // If the user typed Esc when the auto-complete menu was not shown,
+  // then blur the input text field so that the user can use keyboard
+  // shortcuts.
+  const acList = document.getElementById('ac-list');
+  if (ESC_KEYNAME == key &&
+      (!acList || acList.style.display == 'none')) {
+    ac_focusedInput.blur();
+  }
+
+  if (!storeFound) return true;
+
+  const isCompletion = ac_store.isCompletionKey(key, isDown, isShiftKey);
+  const hasResults = ac_completions && (ac_completions.length > 0);
+  let cancelEvent = false;
+
+  if (isCompletion && hasResults) {
+    // Cancel any enter keystrokes if something is selected so that the
+    // browser doesn't go submitting the form.
+    cancelEvent = (!ac_suppressCompletions && !!ac_completions &&
+                      (ac_selected != -1));
+    window.setTimeout(function() {
+      if (ac_store) {
+        ac_handleKey_(key, isDown, isShiftKey);
+      }
+    }, 0);
+  } else if (!isCompletion) {
+    // Don't want to also blur the field. Up and down move the cursor (in
+    // Firefox) to the start/end of the field. We also don't want that while
+    // the list is showing.
+    cancelEvent = (key == ESC_KEYNAME ||
+                  key == DOWN_KEYNAME ||
+                  key == UP_KEYNAME);
+
+    window.setTimeout(function() {
+      if (ac_store) {
+        ac_handleKey_(key, isDown, isShiftKey);
+      }
+    }, 0);
+  } else { // implicit if (isCompletion && !hasResults)
+    if (ac_store.oncomplete) {
+      ac_store.oncomplete(false, key, ac_focusedInput, undefined);
+    }
+  }
+
+  if (cancelEvent) {
+    ac_cancelEvent_(event);
+  }
+
+  return !cancelEvent;
+}
+
+/** Autocomplete onblur handler. */
+function _ac_ob(event) {
+  if (ac_focusedInput) {
+    ac_focusedInput.onblur = ac_oldBlurHandler;
+  }
+  ac_store = null;
+  ac_focusedInput = null;
+  ac_everTyped = false;
+  ac_oldBlurHandler = null;
+  ac_suppressCompletions = false;
+  ac_updateCompletionList(false);
+}
+
+/** @constructor */
+function _AC_Store() {
+}
+/** returns the chunk of the input to treat as completable. */
+_AC_Store.prototype.completable = function(inputValue, caret) {
+  console.log('UNIMPLEMENTED completable');
+};
+/** returns the chunk of the input to treat as completable. */
+_AC_Store.prototype.completions = function(prefix, tofilter) {
+  console.log('UNIMPLEMENTED completions');
+};
+/** returns the chunk of the input to treat as completable. */
+_AC_Store.prototype.oncomplete = function(completed, key, element, text) {
+  // Call the onkeyup handler so that choosing an autocomplete option has
+  // the same side-effect as typing.  E.g., exposing the next row of input
+  // fields.
+  element.dispatchEvent(new Event('keyup'));
+  _ac_ob();
+};
+/** substitutes a completion for a completable in a text input's value. */
+_AC_Store.prototype.substitute =
+  function(inputValue, caret, completable, completion) {
+    console.log('UNIMPLEMENTED substitute');
+  };
+/** true iff hitting a comma key should complete. */
+_AC_Store.prototype.commaCompletes = true;
+/**
+ * true iff the given keystroke should cause a completion (and be consumed in
+ * the process.
+ */
+_AC_Store.prototype.isCompletionKey = function(key, isDown, isShiftKey) {
+  if (!isDown && (ENTER_KEYNAME === key ||
+                  (COMMA_KEYNAME == key && this.commaCompletes))) {
+    return true;
+  }
+  if (TAB_KEYNAME === key && !isShiftKey) {
+    // IE doesn't fire an event for tab on click in a text field, and firefox
+    // requires that the onkeypress event for tab be consumed or it navigates
+    // to next field.
+    return false;
+    // JER: return isDown == BR_IsIE();
+  }
+  return false;
+};
+
+_AC_Store.prototype.setAvoid = function(event) {
+  if (event && event.avoidValues) {
+    ac_avoidValues = event.avoidValues;
+  } else {
+    ac_avoidValues = this.computeAvoid();
+  }
+  ac_avoidValues = ac_avoidValues.map((val) => val.toLowerCase());
+};
+
+/* Subclasses may implement this to compute values to avoid
+   offering in the current input field, i.e., because those
+   values are already used. */
+_AC_Store.prototype.computeAvoid = function() {
+  return [];
+};
+
+
+function _AC_AddItemToFirstCharMap(firstCharMap, ch, s) {
+  let l = firstCharMap[ch];
+  if (!l) {
+    l = firstCharMap[ch] = [];
+  } else if (l[l.length - 1].value == s) {
+    return;
+  }
+  l.push(new _AC_Completion(s, null, ''));
+}
+
+/**
+ * an _AC_Store implementation suitable for completing lists of email
+ * addresses.
+ * @constructor
+ */
+function _AC_SimpleStore(strings, opt_docStrings) {
+  this.firstCharMap_ = {};
+
+  for (let i = 0; i < strings.length; ++i) {
+    let s = strings[i];
+    if (!s) {
+      continue;
+    }
+    if (opt_docStrings && opt_docStrings[s]) {
+      s = s + ' ' + opt_docStrings[s];
+    }
+
+    const parts = s.split(/\W+/);
+    for (let j = 0; j < parts.length; ++j) {
+      if (parts[j]) {
+        _AC_AddItemToFirstCharMap(
+            this.firstCharMap_, parts[j].charAt(0).toLowerCase(), strings[i]);
+      }
+    }
+  }
+
+  // The maximimum number of results that we are willing to show
+  this.countThreshold = 2500;
+  this.docstrings = opt_docStrings || {};
+}
+_AC_SimpleStore.prototype = new _AC_Store();
+_AC_SimpleStore.prototype.constructor = _AC_SimpleStore;
+
+_AC_SimpleStore.prototype.completable =
+  function(inputValue, caret) {
+  // complete after the last comma not inside ""s
+    let start = 0;
+    let state = 0;
+    for (let i = 0; i < caret; ++i) {
+      const ch = inputValue.charAt(i);
+      switch (state) {
+        case 0:
+          if ('"' == ch) {
+            state = 1;
+          } else if (',' == ch || ' ' == ch) {
+            start = i + 1;
+          }
+          break;
+        case 1:
+          if ('"' == ch) {
+            state = 0;
+          }
+          break;
+      }
+    }
+    while (start < caret &&
+         ' \t\r\n'.indexOf(inputValue.charAt(start)) >= 0) {
+      ++start;
+    }
+    return inputValue.substring(start, caret);
+  };
+
+
+/** Simple function to create a <span> with matching text in bold.
+ */
+function _AC_CreateSpanWithMatchHighlighted(match) {
+  const span = document.createElement('span');
+  span.appendChild(document.createTextNode(match[1] || ''));
+  const bold = document.createElement('b');
+  span.appendChild(bold);
+  bold.appendChild(document.createTextNode(match[2]));
+  span.appendChild(document.createTextNode(match[3] || ''));
+  return span;
+};
+
+
+/**
+ * Get all completions matching the given prefix.
+ * @param {string} prefix The prefix of the text to autocomplete on.
+ * @param {List.<string>?} toFilter Optional list to filter on. Otherwise will
+ *     use this.firstCharMap_ using the prefix's first character.
+ * @return {List.<_AC_Completion>} The computed list of completions.
+ */
+_AC_SimpleStore.prototype.completions = function(prefix) {
+  if (!prefix) {
+    return [];
+  }
+  toFilter = this.firstCharMap_[prefix.charAt(0).toLowerCase()];
+
+  // Since we use prefix to build a regular expression, we need to escape RE
+  // characters. We match '-', '{', '$' and others in the prefix and convert
+  // them into "\-", "\{", "\$".
+  const regexForRegexCharacters = /([\^*+\-\$\\\{\}\(\)\[\]\#?\.])/g;
+  const modifiedPrefix = prefix.replace(regexForRegexCharacters, '\\$1');
+
+  // Match the modifiedPrefix anywhere as long as it is either at the very
+  // beginning "Th" -> "The Hobbit", or comes immediately after a word separator
+  // such as "Ga" -> "The-Great-Gatsby".
+  const patternRegex = '^(.*\\W)?(' + modifiedPrefix + ')(.*)';
+  const pattern = new RegExp(patternRegex, 'i' /* ignore case */);
+
+  // We keep separate lists of possible completions that were generated
+  // by matching a value or generated by matching a docstring.  We return
+  // a concatenated list so that value matches all come before docstring
+  // matches.
+  const completions = [];
+  const docCompletions = [];
+
+  if (toFilter) {
+    const toFilterLength = toFilter.length;
+    for (let i = 0; i < toFilterLength; ++i) {
+      const docStr = this.docstrings[toFilter[i].value];
+      let compSpan = null;
+      let docSpan = null;
+      const matches = toFilter[i].value.match(pattern);
+      const docMatches = docStr && docStr.match(pattern);
+      if (matches) {
+        compSpan = _AC_CreateSpanWithMatchHighlighted(matches);
+        if (docStr) docSpan = document.createTextNode(docStr);
+      } else if (docMatches) {
+        compSpan = document.createTextNode(toFilter[i].value);
+        docSpan = _AC_CreateSpanWithMatchHighlighted(docMatches);
+      }
+
+      if (compSpan) {
+        const newCompletion = new _AC_Completion(
+            toFilter[i].value, compSpan, docSpan);
+
+        if (matches) {
+          completions.push(newCompletion);
+        } else {
+          docCompletions.push(newCompletion);
+        }
+        if (completions.length + docCompletions.length > this.countThreshold) {
+          break;
+        }
+      }
+    }
+  }
+
+  return completions.concat(docCompletions);
+};
+
+// Normally, when the user types a few characters, we aggressively
+// select the first possible completion (if any).  When the user
+// hits ENTER, that first completion is substituted.  When that
+// behavior is not desired, override this to return false.
+_AC_SimpleStore.prototype.autoselectFirstRow = function() {
+  return true;
+};
+
+// Comparison function for _AC_Completion
+function _AC_CompareACCompletion(a, b) {
+  // convert it to lower case and remove all leading junk
+  const aval = a.value.toLowerCase().replace(/^\W*/, '');
+  const bval = b.value.toLowerCase().replace(/^\W*/, '');
+
+  if (a.value === b.value) {
+    return 0;
+  } else if (aval < bval) {
+    return -1;
+  } else {
+    return 1;
+  }
+}
+
+_AC_SimpleStore.prototype.substitute =
+function(inputValue, caret, completable, completion) {
+  return inputValue.substring(0, caret - completable.length) +
+    completion.value + ', ' + inputValue.substring(caret);
+};
+
+/**
+ * a possible completion.
+ * @constructor
+ */
+function _AC_Completion(value, compSpan, docSpan) {
+  /** plain text. */
+  this.value = value;
+  if (typeof compSpan == 'string') compSpan = document.createTextNode(compSpan);
+  this.compSpan = compSpan;
+  if (typeof docSpan == 'string') docSpan = document.createTextNode(docSpan);
+  this.docSpan = docSpan;
+}
+_AC_Completion.prototype.toString = function() {
+  return '(AC_Completion: ' + this.value + ')';
+};
+
+/** registered store constructors.  @private */
+var ac_storeConstructors = [];
+/**
+ * the focused text input or textarea whether store is null or not.
+ * A text input may have focus and this may be null iff no key has been typed in
+ * the text input.
+ */
+var ac_focusedInput = null;
+/**
+ * null or the autocomplete store used to complete ac_focusedInput.
+ * @private
+ */
+var ac_store = null;
+/** store handler from ac_focusedInput. @private */
+var ac_oldBlurHandler = null;
+/**
+ * true iff user has indicated completions are unwanted (via ESC key)
+ * @private
+ */
+var ac_suppressCompletions = false;
+/**
+ * chunk of completable text seen last keystroke.
+ * Used to generate ac_completions.
+ * @private
+ */
+let ac_lastCompletable = null;
+/** an array of _AC_Completions.  @private */
+var ac_completions = null;
+/** -1 or in [0, _AC_Completions.length).  @private */
+var ac_selected = -1;
+
+/** Maximum number of options displayed in menu. @private */
+const ac_max_options = 100;
+
+/** Don't offer these values because they are already used. @private */
+let ac_avoidValues = [];
+
+/**
+ * handles all the key strokes, updating the completion list, tracking selected
+ * element, performing substitutions, etc.
+ * @private
+ */
+function ac_handleKey_(key, isDown, isShiftKey) {
+  // check completions
+  ac_checkCompletions();
+  let show = true;
+  const numCompletions = ac_completions ? ac_completions.length : 0;
+  // handle enter and tab on key press and the rest on key down
+  if (ac_store.isCompletionKey(key, isDown, isShiftKey)) {
+    if (ac_selected < 0 && numCompletions >= 1 &&
+        ac_store.autoselectFirstRow()) {
+      ac_selected = 0;
+    }
+    if (ac_selected >= 0) {
+      const backupInput = ac_focusedInput;
+      const completeValue = ac_completions[ac_selected].value;
+      ac_complete();
+      if (ac_store.oncomplete) {
+        ac_store.oncomplete(true, key, backupInput, completeValue);
+      }
+    }
+  } else {
+    switch (key) {
+      case ESC_KEYNAME: // escape
+      // JER?? ac_suppressCompletions = true;
+        ac_selected = -1;
+        show = false;
+        break;
+      case UP_KEYNAME: // up
+        if (isDown) {
+        // firefox fires arrow events on both down and press, but IE only fires
+        // then on press.
+          ac_selected = Math.max(numCompletions >= 0 ? 0 : -1, ac_selected - 1);
+        }
+        break;
+      case DOWN_KEYNAME: // down
+        if (isDown) {
+          ac_selected = Math.min(
+              ac_max_options - 1, Math.min(numCompletions - 1, ac_selected + 1));
+        }
+        break;
+    }
+
+    if (isDown) {
+      switch (key) {
+        case ESC_KEYNAME:
+        case ENTER_KEYNAME:
+        case UP_KEYNAME:
+        case DOWN_KEYNAME:
+        case RIGHT_KEYNAME:
+        case LEFT_KEYNAME:
+        case TAB_KEYNAME:
+        case SHIFT_KEYNAME:
+        case BACKSPACE_KEYNAME:
+        case DELETE_KEYNAME:
+          break;
+        default: // User typed some new characters.
+          ac_everTyped = true;
+      }
+    }
+  }
+
+  if (ac_focusedInput) {
+    ac_updateCompletionList(show);
+  }
+}
+
+/**
+ * called when an option is clicked on to select that option.
+ */
+function _ac_select(optionIndex) {
+  ac_selected = optionIndex;
+  ac_complete();
+  if (ac_store.oncomplete) {
+    ac_store.oncomplete(true, null, ac_focusedInput, ac_focusedInput.value);
+  }
+
+  // check completions
+  ac_checkCompletions();
+  ac_updateCompletionList(true);
+}
+
+function _ac_mouseover(optionIndex) {
+  ac_selected = optionIndex;
+  ac_updateCompletionList(true);
+}
+
+/** perform the substitution of the currently selected item. */
+function ac_complete() {
+  const caret = ac_getCaretPosition_(ac_focusedInput);
+  const completion = ac_completions[ac_selected];
+
+  ac_focusedInput.value = ac_store.substitute(
+      ac_focusedInput.value, caret,
+      ac_lastCompletable, completion);
+  // When the prefix starts with '*' we want to return the complete set of all
+  // possible completions. We treat the ac_lastCompletable value as empty so
+  // that the caret is correctly calculated (i.e. the caret should not consider
+  // placeholder values like '*member').
+  let new_caret = caret + completion.value.length;
+  if (!ac_lastCompletable.startsWith('*')) {
+    // Only consider the ac_lastCompletable length if it does not start with '*'
+    new_caret = new_caret - ac_lastCompletable.length;
+  }
+  // If we inserted something ending in two quotation marks, position
+  // the cursor between the quotation marks. If we inserted a complete term,
+  // skip over the trailing space so that the user is ready to enter the next
+  // term.  If we inserted just a search operator, leave the cursor immediately
+  // after the colon or equals and don't skip over the space.
+  if (completion.value.substring(completion.value.length - 2) == '""') {
+    new_caret--;
+  } else if (completion.value.substring(completion.value.length - 1) != ':' &&
+             completion.value.substring(completion.value.length - 1) != '=') {
+    new_caret++; // To account for the comma.
+    new_caret++; // To account for the space after the comma.
+  }
+  ac_selected = -1;
+  ac_completions = null;
+  ac_lastCompletable = null;
+  ac_everTyped = false;
+  SetCursorPos(window, ac_focusedInput, new_caret);
+}
+
+/**
+ * True if the user has ever typed any actual characters in the currently
+ * focused text field.  False if they have only clicked, backspaced, and
+ * used the arrow keys.
+ */
+var ac_everTyped = false;
+
+/**
+ * maintains ac_completions, ac_selected, ac_lastCompletable.
+ * @private
+ */
+function ac_checkCompletions() {
+  if (ac_focusedInput && !ac_suppressCompletions) {
+    const caret = ac_getCaretPosition_(ac_focusedInput);
+    const completable = ac_store.completable(ac_focusedInput.value, caret);
+
+    // If we already have completed, then our work here is done.
+    if (completable == ac_lastCompletable) {
+      return;
+    }
+
+    ac_completions = null;
+    ac_selected = -1;
+
+    const oldSelected =
+      ((ac_selected >= 0 && ac_selected < ac_completions.length) ?
+        ac_completions[ac_selected].value : null);
+    ac_completions = ac_store.completions(completable);
+    // Don't offer options for values that the user has already used
+    // in another part of the current form.
+    ac_completions = ac_completions.filter((comp) =>
+      FindInArray(ac_avoidValues, comp.value.toLowerCase()) === -1);
+
+    ac_selected = oldSelected ? 0 : -1;
+    ac_lastCompletable = completable;
+    return;
+  }
+  ac_lastCompletable = null;
+  ac_completions = null;
+  ac_selected = -1;
+}
+
+/**
+ * maintains the completion list GUI.
+ * @private
+ */
+function ac_updateCompletionList(show) {
+  let clist = document.getElementById('ac-list');
+  const input = ac_focusedInput;
+  if (input) {
+    input.setAttribute('aria-activedescendant', 'ac-status-row-none');
+  }
+  let tableEl;
+  let tableBody;
+  if (show && ac_completions && ac_completions.length) {
+    if (!clist) {
+      clist = document.createElement('DIV');
+      clist.id = 'ac-list';
+      clist.style.position = 'absolute';
+      clist.style.display = 'none';
+      // with 'listbox' and 'option' roles, screenreader narrates total
+      // number of options eg. 'New = issue has not .... 1 of 9'
+      document.body.appendChild(clist);
+      tableEl = document.createElement('table');
+      tableEl.setAttribute('cellpadding', 0);
+      tableEl.setAttribute('cellspacing', 0);
+      tableEl.id = 'ac-table';
+      tableEl.setAttribute('role', 'presentation');
+      tableBody = document.createElement('tbody');
+      tableBody.id = 'ac-table-body';
+      tableEl.appendChild(tableBody);
+      tableBody.setAttribute('role', 'listbox');
+      clist.appendChild(tableEl);
+      input.setAttribute('aria-controls', 'ac-table');
+      input.setAttribute('aria-haspopup', 'grid');
+    } else {
+      tableEl = document.getElementById('ac-table');
+      tableBody = document.getElementById('ac-table-body');
+      while (tableBody.childNodes.length) {
+        tableBody.removeChild(tableBody.childNodes[0]);
+      }
+    }
+
+    // If no choice is selected, then select the first item, if desired.
+    if (ac_selected < 0 && ac_store && ac_store.autoselectFirstRow()) {
+      ac_selected = 0;
+    }
+
+    let headerCount= 0;
+    for (let i = 0; i < Math.min(ac_max_options, ac_completions.length); ++i) {
+      if (ac_completions[i].heading) {
+        var rowEl = document.createElement('tr');
+        tableBody.appendChild(rowEl);
+        const cellEl = document.createElement('th');
+        rowEl.appendChild(cellEl);
+        cellEl.setAttribute('colspan', 2);
+        if (headerCount) {
+          cellEl.appendChild(document.createElement('br'));
+        }
+        cellEl.appendChild(
+            document.createTextNode(ac_completions[i].heading));
+        headerCount++;
+      } else {
+        var rowEl = document.createElement('tr');
+        tableBody.appendChild(rowEl);
+        if (i == ac_selected) {
+          rowEl.className = 'selected';
+        }
+        rowEl.id = `ac-status-row-${i}`;
+        rowEl.setAttribute('data-index', i);
+        rowEl.setAttribute('role', 'option');
+        rowEl.addEventListener('mousedown', function(event) {
+          event.preventDefault();
+        });
+        rowEl.addEventListener('mouseup', function(event) {
+          let target = event.target;
+          while (target && target.tagName != 'TR') {
+            target = target.parentNode;
+          }
+          const idx = Number(target.getAttribute('data-index'));
+          try {
+            _ac_select(idx);
+          } finally {
+            return false;
+          }
+        });
+        rowEl.addEventListener('mouseover', function(event) {
+          let target = event.target;
+          while (target && target.tagName != 'TR') {
+            target = target.parentNode;
+          }
+          const idx = Number(target.getAttribute('data-index'));
+          _ac_mouseover(idx);
+        });
+        const valCellEl = document.createElement('td');
+        rowEl.appendChild(valCellEl);
+        if (ac_completions[i].compSpan) {
+          valCellEl.appendChild(ac_completions[i].compSpan);
+        }
+        const docCellEl = document.createElement('td');
+        rowEl.appendChild(docCellEl);
+        if (ac_completions[i].docSpan &&
+            ac_completions[i].docSpan.textContent) {
+          docCellEl.appendChild(document.createTextNode(' = '));
+          docCellEl.appendChild(ac_completions[i].docSpan);
+        }
+      }
+    }
+
+    // position
+    const inputBounds = nodeBounds(ac_focusedInput);
+    clist.style.left = inputBounds.x + 'px';
+    clist.style.top = (inputBounds.y + inputBounds.h) + 'px';
+
+    window.setTimeout(ac_autoscroll, 100);
+    input.setAttribute('aria-activedescendant', `ac-status-row-${ac_selected}`);
+    // Note - we use '' instead of 'block', since 'block' has odd effects on
+    // the screen in IE, and causes scrollbars to resize
+    clist.style.display = '';
+  } else {
+    tableBody = document.getElementById('ac-table-body');
+    if (clist && tableBody) {
+      clist.style.display = 'none';
+      while (tableBody.childNodes.length) {
+        tableBody.removeChild(tableBody.childNodes[0]);
+      }
+    }
+  }
+}
+
+// TODO(jrobbins): make arrow keys and mouse not conflict if they are
+// used at the same time.
+
+
+/** Scroll the autocomplete menu to show the currently selected row. */
+function ac_autoscroll() {
+  const acList = document.getElementById('ac-list');
+  const acSelRow = acList.getElementsByClassName('selected')[0];
+  const acSelRowTop = acSelRow ? acSelRow.offsetTop : 0;
+  const acSelRowHeight = acSelRow ? acSelRow.offsetHeight : 0;
+
+
+  const EXTRA = 8; // Go an extra few pixels so the next row is partly exposed.
+
+  if (!acList || !acSelRow) return;
+
+  // Autoscroll upward if the selected item is above the visible area,
+  // else autoscroll downward if the selected item is below the visible area.
+  if (acSelRowTop < acList.scrollTop) {
+    acList.scrollTop = acSelRowTop - EXTRA;
+  } else if (acSelRowTop + acSelRowHeight + EXTRA >
+             acList.scrollTop + acList.offsetHeight) {
+    acList.scrollTop = (acSelRowTop + acSelRowHeight -
+                        acList.offsetHeight + EXTRA);
+  }
+}
+
+
+/** the position of the text caret in the given text field.
+ *
+ * @param textField an INPUT node with type=text or a TEXTAREA node
+ * @return an index in [0, textField.value.length]
+ */
+function ac_getCaretPosition_(textField) {
+  if ('INPUT' == textField.tagName) {
+    let caret = textField.value.length;
+
+    // chrome/firefox
+    if (undefined != textField.selectionStart) {
+      caret = textField.selectionEnd;
+
+      // JER: Special treatment for issue status field that makes all
+      // options show up more often
+      if (textField.id.startsWith('status')) {
+        caret = textField.selectionStart;
+      }
+      // ie
+    } else if (document.selection) {
+      // get an empty selection range
+      const range = document.selection.createRange();
+      const origSelectionLength = range.text.length;
+      // Force selection start to 0 position
+      range.moveStart('character', -caret);
+      // the caret end position is the new selection length
+      caret = range.text.length;
+
+      // JER: Special treatment for issue status field that makes all
+      // options show up more often
+      if (textField.id.startsWith('status')) {
+        // The amount that the selection grew when we forced start to
+        // position 0 is == the original start position.
+        caret = range.text.length - origSelectionLength;
+      }
+    }
+
+    return caret;
+  } else {
+    // a textarea
+
+    return GetCursorPos(window, textField);
+  }
+}
+
+function getTargetFromEvent(event) {
+  let targ = event.target || event.srcElement;
+  if (targ.shadowRoot) {
+    // Find the element within the shadowDOM.
+    const path = event.path || event.composedPath();
+    targ = path[0];
+  }
+  return targ;
+}
