diff --git a/htdocs/dist/1.85/hterm_all.js b/htdocs/dist/1.85/hterm_all.js
new file mode 100644
index 0000000..4696da7
--- /dev/null
+++ b/htdocs/dist/1.85/hterm_all.js
@@ -0,0 +1,20243 @@
+// This file was generated by libdot/bin/concat.sh.
+// It has been marked read-only for your safety.  Rather than
+// edit it directly, please modify one of these source files.
+//
+// libdot/js/lib.js
+// libdot/js/lib_polyfill.js
+// libdot/js/lib_array.js
+// libdot/js/lib_codec.js
+// libdot/js/lib_colors.js
+// libdot/js/lib_f.js
+// libdot/js/lib_i18n.js
+// libdot/js/lib_message_manager.js
+// libdot/js/lib_preference_manager.js
+// libdot/js/lib_resource.js
+// libdot/js/lib_storage.js
+// libdot/js/lib_storage_chrome.js
+// libdot/js/lib_storage_local.js
+// libdot/js/lib_storage_memory.js
+// libdot/third_party/fast-text-encoding/text.js
+// libdot/third_party/intl-segmenter/intl-segmenter.js
+// libdot/third_party/wcwidth/lib_wc.js
+
+'use strict';
+
+// SOURCE FILE: libdot/js/lib.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+const lib = {};
+
+// Export for node environments.
+if (typeof exports !== 'undefined') {
+  module.exports = lib;
+}
+
+/**
+ * List of functions that need to be invoked during library initialization.
+ *
+ * Each element in the initCallbacks_ array is itself a two-element array.
+ * Element 0 is a short string describing the owner of the init routine, useful
+ * for debugging.  Element 1 is the callback function.
+ */
+lib.initCallbacks_ = [];
+
+/**
+ * Register an initialization function.
+ *
+ * The initialization functions are invoked in registration order when
+ * lib.init() is invoked.  Each function will receive a single parameter, which
+ * is a function to be invoked when it completes its part of the initialization.
+ *
+ * @param {string} name A short descriptive name of the init routine useful for
+ *     debugging.
+ * @param {function(function)} callback The initialization function to register.
+ * @return {function} The callback parameter.
+ */
+lib.registerInit = function(name, callback) {
+  lib.initCallbacks_.push([name, callback]);
+  return callback;
+};
+
+/**
+ * Initialize the library.
+ *
+ * This will ensure that all registered runtime dependencies are met, and
+ * invoke any registered initialization functions.
+ *
+ * Initialization is asynchronous.  The library is not ready for use until
+ * the onInit function is invoked.
+ *
+ * @param {function()} onInit The function to invoke when initialization is
+ *     complete.
+ * @param {function(*)} opt_logFunction An optional function to send
+ *     initialization related log messages to.
+ */
+lib.init = function(onInit, opt_logFunction) {
+  var ary = lib.initCallbacks_;
+
+  var initNext = function() {
+    if (ary.length) {
+      var rec = ary.shift();
+      if (opt_logFunction)
+        opt_logFunction('init: ' + rec[0]);
+      rec[1](initNext);
+    } else {
+      onInit();
+    }
+  };
+
+  if (typeof onInit != 'function')
+    throw new Error('Missing or invalid argument: onInit');
+
+  setTimeout(initNext, 0);
+};
+// SOURCE FILE: libdot/js/lib_polyfill.js
+// Copyright 2017 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Polyfills for ES2016+ features we want to use.
+ */
+
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
+if (!String.prototype.padStart) {
+  String.prototype.padStart = function(targetLength, padString) {
+    // If the string is already long enough, nothing to do!
+    targetLength -= this.length;
+    if (targetLength <= 0)
+      return String(this);
+
+    if (padString === undefined)
+      padString = ' ';
+
+    // In case the pad is multiple chars long.
+    if (targetLength > padString.length)
+      padString = padString.repeat((targetLength / padString.length) + 1);
+
+    return padString.slice(0, targetLength) + String(this);
+  };
+}
+
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
+if (!String.prototype.padEnd) {
+  String.prototype.padEnd = function(targetLength, padString) {
+    // If the string is already long enough, nothing to do!
+    targetLength -= this.length;
+    if (targetLength <= 0)
+      return String(this);
+
+    if (padString === undefined)
+      padString = ' ';
+
+    // In case the pad is multiple chars long.
+    if (targetLength > padString.length)
+      padString = padString.repeat((targetLength / padString.length) + 1);
+
+    return String(this) + padString.slice(0, targetLength);
+  };
+}
+
+// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Object/values
+// https://github.com/tc39/proposal-object-values-entries/blob/master/polyfill.js
+if (!Object.values || !Object.entries) {
+  const reduce = Function.bind.call(Function.call, Array.prototype.reduce);
+  const isEnumerable = Function.bind.call(Function.call,
+      Object.prototype.propertyIsEnumerable);
+  const concat = Function.bind.call(Function.call, Array.prototype.concat);
+
+  if (!Object.values) {
+    Object.values = function values(O) {
+      return reduce(Reflect.ownKeys(O), (v, k) => concat(v,
+          typeof k === 'string' && isEnumerable(O, k) ? [O[k]] : []), []);
+    };
+  }
+
+  if (!Object.entries) {
+    Object.entries = function entries(O) {
+      return reduce(Reflect.ownKeys(O), (e, k) => concat(e,
+          typeof k === 'string' && isEnumerable(O, k) ? [[k, O[k]]] : []), []);
+    };
+  }
+}
+
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally
+// https://github.com/tc39/proposal-promise-finally/blob/master/polyfill.js
+if (typeof Promise.prototype.finally !== 'function') {
+  const speciesConstructor = function(O, defaultConstructor) {
+    if (!O || (typeof O !== 'object' && typeof O !== 'function')) {
+      throw new TypeError('Assertion failed: Type(O) is not Object');
+    }
+    const C = O.constructor;
+    if (typeof C === 'undefined') {
+      return defaultConstructor;
+    }
+    if (!C || (typeof C !== 'object' && typeof C !== 'function')) {
+      throw new TypeError('O.constructor is not an Object');
+    }
+    const S =
+        typeof Symbol === 'function' && typeof Symbol.species === 'symbol' ?
+        C[Symbol.species] : undefined;
+    if (S == null) {
+      return defaultConstructor;
+    }
+    if (typeof S === 'function' && S.prototype) {
+      return S;
+    }
+    throw new TypeError('no constructor found');
+  };
+
+  const shim = {
+    finally(onFinally) {
+      const promise = this;
+      if (typeof promise !== 'object' || promise === null) {
+        throw new TypeError('"this" value is not an Object');
+      }
+      const C = speciesConstructor(promise, Promise);
+      if (typeof onFinally !== 'function') {
+        return Promise.prototype.then.call(promise, onFinally, onFinally);
+      }
+      return Promise.prototype.then.call(
+        promise,
+        x => new C(resolve => resolve(onFinally())).then(() => x),
+        e => new C(resolve => resolve(onFinally())).then(() => { throw e; })
+      );
+    }
+  };
+  Object.defineProperty(Promise.prototype, 'finally', {
+    configurable: true, writable: true, value: shim.finally,
+  });
+}
+// SOURCE FILE: libdot/js/lib_array.js
+// Copyright 2017 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Helper functions for (typed) arrays.
+ */
+
+lib.array = {};
+
+/**
+ * Concatenate an arbitrary number of typed arrays of the same type into a new
+ * typed array of this type.
+ *
+ * @template TYPED_ARRAY
+ * @param {...!TYPED_ARRAY} arrays
+ * @returns {!TYPED_ARRAY}
+ */
+lib.array.concatTyped = function(...arrays) {
+  let resultLength = 0;
+  for (const array of arrays) {
+    resultLength += array.length;
+  }
+  const result = new arrays[0].constructor(resultLength);
+  let pos = 0;
+  for (const array of arrays) {
+    result.set(array, pos);
+    pos += array.length;
+  }
+  return result;
+};
+
+/**
+ * Compare two array-like objects entrywise.
+ *
+ * @template ARRAY_LIKE
+ * @param {?ARRAY_LIKE} a
+ * @param {?ARRAY_LIKE} b
+ * @returns {!boolean} true if both arrays are null or they agree entrywise;
+ *     false otherwise.
+ */
+lib.array.compare = function(a, b) {
+  if (a === null || b === null) {
+    return a === null && b === null;
+  }
+
+  if (a.length !== b.length) {
+    return false;
+  }
+
+  for (let i = 0; i < a.length; i++) {
+    if (a[i] !== b[i]) {
+      return false;
+    }
+  }
+  return true;
+};
+// SOURCE FILE: libdot/js/lib_codec.js
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+lib.codec = {};
+
+/**
+ * Join an array of code units to a string.
+ *
+ * The code units must not be larger than 65535.  The individual code units may
+ * be for UTF-8 or UTF-16 -- it doesn't matter since UTF-16 can handle all UTF-8
+ * code units.
+ *
+ * The input array type may be an Array or a typed Array (e.g. Uint8Array).
+ *
+ * @param {Array<number>} array The code units to generate for the string.
+ * @return {string} A UTF-16 encoded string.
+ */
+lib.codec.codeUnitArrayToString = function(array) {
+  // String concat is faster than Array.join.
+  //
+  // String.fromCharCode.apply is faster than this if called less frequently
+  // and with smaller array sizes (like <32K).  But it's a recursive call so
+  // larger arrays will blow the stack and fail.  We also seem to be faster
+  // (or at least more constant time) when called frequently.
+  let ret = '';
+  for (let i = 0; i < array.length; ++i) {
+    ret += String.fromCharCode(array[i]);
+  }
+  return ret;
+};
+
+/**
+ * Create an array of code units from a UTF-16 encoded string.
+ *
+ * @param {string} str The string to extract code units from.
+ * @param {type=} type The type of the return value.
+ * @return {Array<number>} The array of code units.
+ */
+lib.codec.stringToCodeUnitArray = function(str, type=Array) {
+  // Indexing string directly is faster than Array.map.
+  const ret = new type(str.length);
+  for (let i = 0; i < str.length; ++i) {
+    ret[i] = str.charCodeAt(i);
+  }
+  return ret;
+};
+// SOURCE FILE: libdot/js/lib_colors.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Namespace for color utilities.
+ */
+lib.colors = {};
+
+/**
+ * First, some canned regular expressions we're going to use in this file.
+ *
+ *
+ *                              BRACE YOURSELF
+ *
+ *                                 ,~~~~.
+ *                                 |>_< ~~
+ *                                3`---'-/.
+ *                                3:::::\v\
+ *                               =o=:::::\,\
+ *                                | :::::\,,\
+ *
+ *                        THE REGULAR EXPRESSIONS
+ *                               ARE COMING.
+ *
+ * There's no way to break long RE literals in JavaScript.  Fix that why don't
+ * you?  Oh, and also there's no way to write a string that doesn't interpret
+ * escapes.
+ *
+ * Instead, we stoop to this .replace() trick.
+ */
+lib.colors.re_ = {
+  // CSS hex color, #RGB.
+  hex16: /#([a-f0-9])([a-f0-9])([a-f0-9])/i,
+
+  // CSS hex color, #RRGGBB.
+  hex24: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/i,
+
+  // CSS rgb color, rgb(rrr,ggg,bbb).
+  rgb: new RegExp(
+      ('^/s*rgb/s*/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*,' +
+       '/s*(/d{1,3})/s*/)/s*$'
+       ).replace(/\//g, '\\'), 'i'),
+
+  // CSS rgb color, rgb(rrr,ggg,bbb,aaa).
+  rgba: new RegExp(
+      ('^/s*rgba/s*' +
+       '/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*,/s*(/d{1,3})/s*' +
+       '(?:,/s*(/d+(?:/./d+)?)/s*)/)/s*$'
+       ).replace(/\//g, '\\'), 'i'),
+
+  // Either RGB or RGBA.
+  rgbx: new RegExp(
+      ('^/s*rgba?/s*' +
+       '/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*,/s*(/d{1,3})/s*' +
+       '(?:,/s*(/d+(?:/./d+)?)/s*)?/)/s*$'
+       ).replace(/\//g, '\\'), 'i'),
+
+  // An X11 "rgb:dddd/dddd/dddd" value.
+  x11rgb: /^\s*rgb:([a-f0-9]{1,4})\/([a-f0-9]{1,4})\/([a-f0-9]{1,4})\s*$/i,
+
+  // English color name.
+  name: /[a-z][a-z0-9\s]+/,
+};
+
+/**
+ * Convert a CSS rgb(ddd,ddd,ddd) color value into an X11 color value.
+ *
+ * Other CSS color values are ignored to ensure sanitary data handling.
+ *
+ * Each 'ddd' component is a one byte value specified in decimal.
+ *
+ * @param {string} value The CSS color value to convert.
+ * @return {string} The X11 color value or null if the value could not be
+ *     converted.
+ */
+lib.colors.rgbToX11 = function(value) {
+  function scale(v) {
+    v = (Math.min(v, 255) * 257).toString(16);
+    return lib.f.zpad(v, 4);
+  }
+
+  var ary = value.match(lib.colors.re_.rgbx);
+  if (!ary)
+    return null;
+
+  return 'rgb:' + scale(ary[1]) + '/' + scale(ary[2]) + '/' + scale(ary[3]);
+};
+
+/**
+ * Convert a legacy X11 colover value into an CSS rgb(...) color value.
+ *
+ * They take the form:
+ * 12 bit: #RGB          -> #R000G000B000
+ * 24 bit: #RRGGBB       -> #RR00GG00BB00
+ * 36 bit: #RRRGGGBBB    -> #RRR0GGG0BBB0
+ * 48 bit: #RRRRGGGGBBBB
+ * These are the most significant bits.
+ *
+ * Truncate values back down to 24 bit since that's all CSS supports.
+ */
+lib.colors.x11HexToCSS = function(v) {
+  if (!v.startsWith('#'))
+    return null;
+  // Strip the leading # off.
+  v = v.substr(1);
+
+  // Reject unknown sizes.
+  if ([3, 6, 9, 12].indexOf(v.length) == -1)
+    return null;
+
+  // Reject non-hex values.
+  if (v.match(/[^a-f0-9]/i))
+    return null;
+
+  // Split the colors out.
+  var size = v.length / 3;
+  var r = v.substr(0, size);
+  var g = v.substr(size, size);
+  var b = v.substr(size + size, size);
+
+  // Normalize to 16 bits.
+  function norm16(v) {
+    v = parseInt(v, 16);
+    return size == 2 ? v :         // 16 bit
+           size == 1 ? v << 4 :    // 8 bit
+           v >> (4 * (size - 2));  // 24 or 32 bit
+  }
+  return lib.colors.arrayToRGBA([r, g, b].map(norm16));
+};
+
+/**
+ * Convert an X11 color value into an CSS rgb(...) color value.
+ *
+ * The X11 value may be an X11 color name, or an RGB value of the form
+ * rgb:hhhh/hhhh/hhhh.  If a component value is less than 4 digits it is
+ * padded out to 4, then scaled down to fit in a single byte.
+ *
+ * @param {string} value The X11 color value to convert.
+ * @return {string} The CSS color value or null if the value could not be
+ *     converted.
+ */
+lib.colors.x11ToCSS = function(v) {
+  function scale(v) {
+    // Pad out values with less than four digits.  This padding (probably)
+    // matches xterm.  It's difficult to say for sure since xterm seems to
+    // arrive at a padded value and then perform some combination of
+    // gamma correction, color space transformation, and quantization.
+
+    if (v.length == 1) {
+      // Single digits pad out to four by repeating the character.  "f" becomes
+      // "ffff".  Scaling down a hex value of this pattern by 257 is the same
+      // as cutting off one byte.  We skip the middle step and just double
+      // the character.
+      return parseInt(v + v, 16);
+    }
+
+    if (v.length == 2) {
+      // Similar deal here.  X11 pads two digit values by repeating the
+      // byte (or scale up by 257).  Since we're going to scale it back
+      // down anyway, we can just return the original value.
+      return parseInt(v, 16);
+    }
+
+    if (v.length == 3) {
+      // Three digit values seem to be padded by repeating the final digit.
+      // e.g. 10f becomes 10ff.
+      v = v + v.substr(2);
+    }
+
+    // Scale down the 2 byte value.
+    return Math.round(parseInt(v, 16) / 257);
+  }
+
+  var ary = v.match(lib.colors.re_.x11rgb);
+  if (!ary) {
+    // Handle the legacy format.
+    if (v.startsWith('#'))
+      return lib.colors.x11HexToCSS(v);
+    else
+      return lib.colors.nameToRGB(v);
+  }
+
+  ary.splice(0, 1);
+  return lib.colors.arrayToRGBA(ary.map(scale));
+};
+
+/**
+ * Converts one or more CSS '#RRGGBB' color values into their rgb(...)
+ * form.
+ *
+ * Arrays are converted in place. If a value cannot be converted, it is
+ * replaced with null.
+ *
+ * @param {string|Array.<string>} A single RGB value or array of RGB values to
+ *     convert.
+ * @return {string|Array.<string>} The converted value or values.
+ */
+lib.colors.hexToRGB = function(arg) {
+  var hex16 = lib.colors.re_.hex16;
+  var hex24 = lib.colors.re_.hex24;
+
+  function convert(hex) {
+    if (hex.length == 4) {
+      hex = hex.replace(hex16, function(h, r, g, b) {
+        return "#" + r + r + g + g + b + b;
+      });
+    }
+    var ary = hex.match(hex24);
+    if (!ary)
+      return null;
+
+    return 'rgb(' + parseInt(ary[1], 16) + ', ' +
+        parseInt(ary[2], 16) + ', ' +
+        parseInt(ary[3], 16) + ')';
+  }
+
+  if (arg instanceof Array) {
+    for (var i = 0; i < arg.length; i++) {
+      arg[i] = convert(arg[i]);
+    }
+  } else {
+    arg = convert(arg);
+  }
+
+  return arg;
+};
+
+/**
+ * Converts one or more CSS rgb(...) forms into their '#RRGGBB' color values.
+ *
+ * If given an rgba(...) form, the alpha field is thrown away.
+ *
+ * Arrays are converted in place. If a value cannot be converted, it is
+ * replaced with null.
+ *
+ * @param {string|Array.<string>} A single rgb(...) value or array of rgb(...)
+ *     values to convert.
+ * @return {string|Array.<string>} The converted value or values.
+ */
+lib.colors.rgbToHex = function(arg) {
+  function convert(rgb) {
+    var ary = lib.colors.crackRGB(rgb);
+    if (!ary)
+      return null;
+    return '#' + lib.f.zpad(((parseInt(ary[0]) << 16) |
+                             (parseInt(ary[1]) <<  8) |
+                             (parseInt(ary[2]) <<  0)).toString(16), 6);
+  }
+
+  if (arg instanceof Array) {
+    for (var i = 0; i < arg.length; i++) {
+      arg[i] = convert(arg[i]);
+    }
+  } else {
+    arg = convert(arg);
+  }
+
+  return arg;
+};
+
+/**
+ * Take any valid css color definition and turn it into an rgb or rgba value.
+ *
+ * Returns null if the value could not be normalized.
+ */
+lib.colors.normalizeCSS = function(def) {
+  if (def.startsWith('#'))
+    return lib.colors.hexToRGB(def);
+
+  if (lib.colors.re_.rgbx.test(def))
+    return def;
+
+  return lib.colors.nameToRGB(def);
+};
+
+/**
+ * Convert a 3 or 4 element array into an rgba(...) string.
+ */
+lib.colors.arrayToRGBA = function(ary) {
+  var alpha = (ary.length > 3) ? ary[3] : 1;
+  return 'rgba(' + ary[0] + ', ' + ary[1] + ', ' + ary[2] + ', ' + alpha + ')';
+};
+
+/**
+ * Overwrite the alpha channel of an rgb/rgba color.
+ */
+lib.colors.setAlpha = function(rgb, alpha) {
+  var ary = lib.colors.crackRGB(rgb);
+  ary[3] = alpha;
+  return lib.colors.arrayToRGBA(ary);
+};
+
+/**
+ * Mix a percentage of a tint color into a base color.
+ */
+lib.colors.mix = function(base, tint, percent) {
+  var ary1 = lib.colors.crackRGB(base);
+  var ary2 = lib.colors.crackRGB(tint);
+
+  for (var i = 0; i < 4; ++i) {
+    var diff = ary2[i] - ary1[i];
+    ary1[i] = Math.round(parseInt(ary1[i]) + diff * percent);
+  }
+
+  return lib.colors.arrayToRGBA(ary1);
+};
+
+/**
+ * Split an rgb/rgba color into an array of its components.
+ *
+ * On success, a 4 element array will be returned.  For rgb values, the alpha
+ * will be set to 1.
+ */
+lib.colors.crackRGB = function(color) {
+  if (color.startsWith('rgba')) {
+    var ary = color.match(lib.colors.re_.rgba);
+    if (ary) {
+      ary.shift();
+      return Array.from(ary);
+    }
+  } else {
+    var ary = color.match(lib.colors.re_.rgb);
+    if (ary) {
+      ary.shift();
+      ary.push('1');
+      return Array.from(ary);
+    }
+  }
+
+  console.error('Couldn\'t crack: ' + color);
+  return null;
+};
+
+/**
+ * Convert an X11 color name into a CSS rgb(...) value.
+ *
+ * Names are stripped of spaces and converted to lowercase.  If the name is
+ * unknown, null is returned.
+ *
+ * This list of color name to RGB mapping is derived from the stock X11
+ * rgb.txt file.
+ *
+ * @param {string} name The color name to convert.
+ * @return {string} The corresponding CSS rgb(...) value.
+ */
+lib.colors.nameToRGB = function(name) {
+  if (name in lib.colors.colorNames)
+    return lib.colors.colorNames[name];
+
+  name = name.toLowerCase();
+  if (name in lib.colors.colorNames)
+    return lib.colors.colorNames[name];
+
+  name = name.replace(/\s+/g, '');
+  if (name in lib.colors.colorNames)
+    return lib.colors.colorNames[name];
+
+  return null;
+};
+
+/**
+ * The stock color palette.
+ */
+lib.colors.stockColorPalette = lib.colors.hexToRGB
+  ([// The "ANSI 16"...
+    '#000000', '#CC0000', '#4E9A06', '#C4A000',
+    '#3465A4', '#75507B', '#06989A', '#D3D7CF',
+    '#555753', '#EF2929', '#00BA13', '#FCE94F',
+    '#729FCF', '#F200CB', '#00B5BD', '#EEEEEC',
+
+    // The 6x6 color cubes...
+    '#000000', '#00005F', '#000087', '#0000AF', '#0000D7', '#0000FF',
+    '#005F00', '#005F5F', '#005F87', '#005FAF', '#005FD7', '#005FFF',
+    '#008700', '#00875F', '#008787', '#0087AF', '#0087D7', '#0087FF',
+    '#00AF00', '#00AF5F', '#00AF87', '#00AFAF', '#00AFD7', '#00AFFF',
+    '#00D700', '#00D75F', '#00D787', '#00D7AF', '#00D7D7', '#00D7FF',
+    '#00FF00', '#00FF5F', '#00FF87', '#00FFAF', '#00FFD7', '#00FFFF',
+
+    '#5F0000', '#5F005F', '#5F0087', '#5F00AF', '#5F00D7', '#5F00FF',
+    '#5F5F00', '#5F5F5F', '#5F5F87', '#5F5FAF', '#5F5FD7', '#5F5FFF',
+    '#5F8700', '#5F875F', '#5F8787', '#5F87AF', '#5F87D7', '#5F87FF',
+    '#5FAF00', '#5FAF5F', '#5FAF87', '#5FAFAF', '#5FAFD7', '#5FAFFF',
+    '#5FD700', '#5FD75F', '#5FD787', '#5FD7AF', '#5FD7D7', '#5FD7FF',
+    '#5FFF00', '#5FFF5F', '#5FFF87', '#5FFFAF', '#5FFFD7', '#5FFFFF',
+
+    '#870000', '#87005F', '#870087', '#8700AF', '#8700D7', '#8700FF',
+    '#875F00', '#875F5F', '#875F87', '#875FAF', '#875FD7', '#875FFF',
+    '#878700', '#87875F', '#878787', '#8787AF', '#8787D7', '#8787FF',
+    '#87AF00', '#87AF5F', '#87AF87', '#87AFAF', '#87AFD7', '#87AFFF',
+    '#87D700', '#87D75F', '#87D787', '#87D7AF', '#87D7D7', '#87D7FF',
+    '#87FF00', '#87FF5F', '#87FF87', '#87FFAF', '#87FFD7', '#87FFFF',
+
+    '#AF0000', '#AF005F', '#AF0087', '#AF00AF', '#AF00D7', '#AF00FF',
+    '#AF5F00', '#AF5F5F', '#AF5F87', '#AF5FAF', '#AF5FD7', '#AF5FFF',
+    '#AF8700', '#AF875F', '#AF8787', '#AF87AF', '#AF87D7', '#AF87FF',
+    '#AFAF00', '#AFAF5F', '#AFAF87', '#AFAFAF', '#AFAFD7', '#AFAFFF',
+    '#AFD700', '#AFD75F', '#AFD787', '#AFD7AF', '#AFD7D7', '#AFD7FF',
+    '#AFFF00', '#AFFF5F', '#AFFF87', '#AFFFAF', '#AFFFD7', '#AFFFFF',
+
+    '#D70000', '#D7005F', '#D70087', '#D700AF', '#D700D7', '#D700FF',
+    '#D75F00', '#D75F5F', '#D75F87', '#D75FAF', '#D75FD7', '#D75FFF',
+    '#D78700', '#D7875F', '#D78787', '#D787AF', '#D787D7', '#D787FF',
+    '#D7AF00', '#D7AF5F', '#D7AF87', '#D7AFAF', '#D7AFD7', '#D7AFFF',
+    '#D7D700', '#D7D75F', '#D7D787', '#D7D7AF', '#D7D7D7', '#D7D7FF',
+    '#D7FF00', '#D7FF5F', '#D7FF87', '#D7FFAF', '#D7FFD7', '#D7FFFF',
+
+    '#FF0000', '#FF005F', '#FF0087', '#FF00AF', '#FF00D7', '#FF00FF',
+    '#FF5F00', '#FF5F5F', '#FF5F87', '#FF5FAF', '#FF5FD7', '#FF5FFF',
+    '#FF8700', '#FF875F', '#FF8787', '#FF87AF', '#FF87D7', '#FF87FF',
+    '#FFAF00', '#FFAF5F', '#FFAF87', '#FFAFAF', '#FFAFD7', '#FFAFFF',
+    '#FFD700', '#FFD75F', '#FFD787', '#FFD7AF', '#FFD7D7', '#FFD7FF',
+    '#FFFF00', '#FFFF5F', '#FFFF87', '#FFFFAF', '#FFFFD7', '#FFFFFF',
+
+    // The greyscale ramp...
+    '#080808', '#121212', '#1C1C1C', '#262626', '#303030', '#3A3A3A',
+    '#444444', '#4E4E4E', '#585858', '#626262', '#6C6C6C', '#767676',
+    '#808080', '#8A8A8A', '#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2',
+    '#BCBCBC', '#C6C6C6', '#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE'
+   ]);
+
+/**
+ * The current color palette, possibly with user changes.
+ */
+lib.colors.colorPalette = lib.colors.stockColorPalette;
+
+/**
+ * Named colors according to the stock X11 rgb.txt file.
+ */
+lib.colors.colorNames = {
+  "aliceblue": "rgb(240, 248, 255)",
+  "antiquewhite": "rgb(250, 235, 215)",
+  "antiquewhite1": "rgb(255, 239, 219)",
+  "antiquewhite2": "rgb(238, 223, 204)",
+  "antiquewhite3": "rgb(205, 192, 176)",
+  "antiquewhite4": "rgb(139, 131, 120)",
+  "aquamarine": "rgb(127, 255, 212)",
+  "aquamarine1": "rgb(127, 255, 212)",
+  "aquamarine2": "rgb(118, 238, 198)",
+  "aquamarine3": "rgb(102, 205, 170)",
+  "aquamarine4": "rgb(69, 139, 116)",
+  "azure": "rgb(240, 255, 255)",
+  "azure1": "rgb(240, 255, 255)",
+  "azure2": "rgb(224, 238, 238)",
+  "azure3": "rgb(193, 205, 205)",
+  "azure4": "rgb(131, 139, 139)",
+  "beige": "rgb(245, 245, 220)",
+  "bisque": "rgb(255, 228, 196)",
+  "bisque1": "rgb(255, 228, 196)",
+  "bisque2": "rgb(238, 213, 183)",
+  "bisque3": "rgb(205, 183, 158)",
+  "bisque4": "rgb(139, 125, 107)",
+  "black": "rgb(0, 0, 0)",
+  "blanchedalmond": "rgb(255, 235, 205)",
+  "blue": "rgb(0, 0, 255)",
+  "blue1": "rgb(0, 0, 255)",
+  "blue2": "rgb(0, 0, 238)",
+  "blue3": "rgb(0, 0, 205)",
+  "blue4": "rgb(0, 0, 139)",
+  "blueviolet": "rgb(138, 43, 226)",
+  "brown": "rgb(165, 42, 42)",
+  "brown1": "rgb(255, 64, 64)",
+  "brown2": "rgb(238, 59, 59)",
+  "brown3": "rgb(205, 51, 51)",
+  "brown4": "rgb(139, 35, 35)",
+  "burlywood": "rgb(222, 184, 135)",
+  "burlywood1": "rgb(255, 211, 155)",
+  "burlywood2": "rgb(238, 197, 145)",
+  "burlywood3": "rgb(205, 170, 125)",
+  "burlywood4": "rgb(139, 115, 85)",
+  "cadetblue": "rgb(95, 158, 160)",
+  "cadetblue1": "rgb(152, 245, 255)",
+  "cadetblue2": "rgb(142, 229, 238)",
+  "cadetblue3": "rgb(122, 197, 205)",
+  "cadetblue4": "rgb(83, 134, 139)",
+  "chartreuse": "rgb(127, 255, 0)",
+  "chartreuse1": "rgb(127, 255, 0)",
+  "chartreuse2": "rgb(118, 238, 0)",
+  "chartreuse3": "rgb(102, 205, 0)",
+  "chartreuse4": "rgb(69, 139, 0)",
+  "chocolate": "rgb(210, 105, 30)",
+  "chocolate1": "rgb(255, 127, 36)",
+  "chocolate2": "rgb(238, 118, 33)",
+  "chocolate3": "rgb(205, 102, 29)",
+  "chocolate4": "rgb(139, 69, 19)",
+  "coral": "rgb(255, 127, 80)",
+  "coral1": "rgb(255, 114, 86)",
+  "coral2": "rgb(238, 106, 80)",
+  "coral3": "rgb(205, 91, 69)",
+  "coral4": "rgb(139, 62, 47)",
+  "cornflowerblue": "rgb(100, 149, 237)",
+  "cornsilk": "rgb(255, 248, 220)",
+  "cornsilk1": "rgb(255, 248, 220)",
+  "cornsilk2": "rgb(238, 232, 205)",
+  "cornsilk3": "rgb(205, 200, 177)",
+  "cornsilk4": "rgb(139, 136, 120)",
+  "cyan": "rgb(0, 255, 255)",
+  "cyan1": "rgb(0, 255, 255)",
+  "cyan2": "rgb(0, 238, 238)",
+  "cyan3": "rgb(0, 205, 205)",
+  "cyan4": "rgb(0, 139, 139)",
+  "darkblue": "rgb(0, 0, 139)",
+  "darkcyan": "rgb(0, 139, 139)",
+  "darkgoldenrod": "rgb(184, 134, 11)",
+  "darkgoldenrod1": "rgb(255, 185, 15)",
+  "darkgoldenrod2": "rgb(238, 173, 14)",
+  "darkgoldenrod3": "rgb(205, 149, 12)",
+  "darkgoldenrod4": "rgb(139, 101, 8)",
+  "darkgray": "rgb(169, 169, 169)",
+  "darkgreen": "rgb(0, 100, 0)",
+  "darkgrey": "rgb(169, 169, 169)",
+  "darkkhaki": "rgb(189, 183, 107)",
+  "darkmagenta": "rgb(139, 0, 139)",
+  "darkolivegreen": "rgb(85, 107, 47)",
+  "darkolivegreen1": "rgb(202, 255, 112)",
+  "darkolivegreen2": "rgb(188, 238, 104)",
+  "darkolivegreen3": "rgb(162, 205, 90)",
+  "darkolivegreen4": "rgb(110, 139, 61)",
+  "darkorange": "rgb(255, 140, 0)",
+  "darkorange1": "rgb(255, 127, 0)",
+  "darkorange2": "rgb(238, 118, 0)",
+  "darkorange3": "rgb(205, 102, 0)",
+  "darkorange4": "rgb(139, 69, 0)",
+  "darkorchid": "rgb(153, 50, 204)",
+  "darkorchid1": "rgb(191, 62, 255)",
+  "darkorchid2": "rgb(178, 58, 238)",
+  "darkorchid3": "rgb(154, 50, 205)",
+  "darkorchid4": "rgb(104, 34, 139)",
+  "darkred": "rgb(139, 0, 0)",
+  "darksalmon": "rgb(233, 150, 122)",
+  "darkseagreen": "rgb(143, 188, 143)",
+  "darkseagreen1": "rgb(193, 255, 193)",
+  "darkseagreen2": "rgb(180, 238, 180)",
+  "darkseagreen3": "rgb(155, 205, 155)",
+  "darkseagreen4": "rgb(105, 139, 105)",
+  "darkslateblue": "rgb(72, 61, 139)",
+  "darkslategray": "rgb(47, 79, 79)",
+  "darkslategray1": "rgb(151, 255, 255)",
+  "darkslategray2": "rgb(141, 238, 238)",
+  "darkslategray3": "rgb(121, 205, 205)",
+  "darkslategray4": "rgb(82, 139, 139)",
+  "darkslategrey": "rgb(47, 79, 79)",
+  "darkturquoise": "rgb(0, 206, 209)",
+  "darkviolet": "rgb(148, 0, 211)",
+  "debianred": "rgb(215, 7, 81)",
+  "deeppink": "rgb(255, 20, 147)",
+  "deeppink1": "rgb(255, 20, 147)",
+  "deeppink2": "rgb(238, 18, 137)",
+  "deeppink3": "rgb(205, 16, 118)",
+  "deeppink4": "rgb(139, 10, 80)",
+  "deepskyblue": "rgb(0, 191, 255)",
+  "deepskyblue1": "rgb(0, 191, 255)",
+  "deepskyblue2": "rgb(0, 178, 238)",
+  "deepskyblue3": "rgb(0, 154, 205)",
+  "deepskyblue4": "rgb(0, 104, 139)",
+  "dimgray": "rgb(105, 105, 105)",
+  "dimgrey": "rgb(105, 105, 105)",
+  "dodgerblue": "rgb(30, 144, 255)",
+  "dodgerblue1": "rgb(30, 144, 255)",
+  "dodgerblue2": "rgb(28, 134, 238)",
+  "dodgerblue3": "rgb(24, 116, 205)",
+  "dodgerblue4": "rgb(16, 78, 139)",
+  "firebrick": "rgb(178, 34, 34)",
+  "firebrick1": "rgb(255, 48, 48)",
+  "firebrick2": "rgb(238, 44, 44)",
+  "firebrick3": "rgb(205, 38, 38)",
+  "firebrick4": "rgb(139, 26, 26)",
+  "floralwhite": "rgb(255, 250, 240)",
+  "forestgreen": "rgb(34, 139, 34)",
+  "gainsboro": "rgb(220, 220, 220)",
+  "ghostwhite": "rgb(248, 248, 255)",
+  "gold": "rgb(255, 215, 0)",
+  "gold1": "rgb(255, 215, 0)",
+  "gold2": "rgb(238, 201, 0)",
+  "gold3": "rgb(205, 173, 0)",
+  "gold4": "rgb(139, 117, 0)",
+  "goldenrod": "rgb(218, 165, 32)",
+  "goldenrod1": "rgb(255, 193, 37)",
+  "goldenrod2": "rgb(238, 180, 34)",
+  "goldenrod3": "rgb(205, 155, 29)",
+  "goldenrod4": "rgb(139, 105, 20)",
+  "gray": "rgb(190, 190, 190)",
+  "gray0": "rgb(0, 0, 0)",
+  "gray1": "rgb(3, 3, 3)",
+  "gray10": "rgb(26, 26, 26)",
+  "gray100": "rgb(255, 255, 255)",
+  "gray11": "rgb(28, 28, 28)",
+  "gray12": "rgb(31, 31, 31)",
+  "gray13": "rgb(33, 33, 33)",
+  "gray14": "rgb(36, 36, 36)",
+  "gray15": "rgb(38, 38, 38)",
+  "gray16": "rgb(41, 41, 41)",
+  "gray17": "rgb(43, 43, 43)",
+  "gray18": "rgb(46, 46, 46)",
+  "gray19": "rgb(48, 48, 48)",
+  "gray2": "rgb(5, 5, 5)",
+  "gray20": "rgb(51, 51, 51)",
+  "gray21": "rgb(54, 54, 54)",
+  "gray22": "rgb(56, 56, 56)",
+  "gray23": "rgb(59, 59, 59)",
+  "gray24": "rgb(61, 61, 61)",
+  "gray25": "rgb(64, 64, 64)",
+  "gray26": "rgb(66, 66, 66)",
+  "gray27": "rgb(69, 69, 69)",
+  "gray28": "rgb(71, 71, 71)",
+  "gray29": "rgb(74, 74, 74)",
+  "gray3": "rgb(8, 8, 8)",
+  "gray30": "rgb(77, 77, 77)",
+  "gray31": "rgb(79, 79, 79)",
+  "gray32": "rgb(82, 82, 82)",
+  "gray33": "rgb(84, 84, 84)",
+  "gray34": "rgb(87, 87, 87)",
+  "gray35": "rgb(89, 89, 89)",
+  "gray36": "rgb(92, 92, 92)",
+  "gray37": "rgb(94, 94, 94)",
+  "gray38": "rgb(97, 97, 97)",
+  "gray39": "rgb(99, 99, 99)",
+  "gray4": "rgb(10, 10, 10)",
+  "gray40": "rgb(102, 102, 102)",
+  "gray41": "rgb(105, 105, 105)",
+  "gray42": "rgb(107, 107, 107)",
+  "gray43": "rgb(110, 110, 110)",
+  "gray44": "rgb(112, 112, 112)",
+  "gray45": "rgb(115, 115, 115)",
+  "gray46": "rgb(117, 117, 117)",
+  "gray47": "rgb(120, 120, 120)",
+  "gray48": "rgb(122, 122, 122)",
+  "gray49": "rgb(125, 125, 125)",
+  "gray5": "rgb(13, 13, 13)",
+  "gray50": "rgb(127, 127, 127)",
+  "gray51": "rgb(130, 130, 130)",
+  "gray52": "rgb(133, 133, 133)",
+  "gray53": "rgb(135, 135, 135)",
+  "gray54": "rgb(138, 138, 138)",
+  "gray55": "rgb(140, 140, 140)",
+  "gray56": "rgb(143, 143, 143)",
+  "gray57": "rgb(145, 145, 145)",
+  "gray58": "rgb(148, 148, 148)",
+  "gray59": "rgb(150, 150, 150)",
+  "gray6": "rgb(15, 15, 15)",
+  "gray60": "rgb(153, 153, 153)",
+  "gray61": "rgb(156, 156, 156)",
+  "gray62": "rgb(158, 158, 158)",
+  "gray63": "rgb(161, 161, 161)",
+  "gray64": "rgb(163, 163, 163)",
+  "gray65": "rgb(166, 166, 166)",
+  "gray66": "rgb(168, 168, 168)",
+  "gray67": "rgb(171, 171, 171)",
+  "gray68": "rgb(173, 173, 173)",
+  "gray69": "rgb(176, 176, 176)",
+  "gray7": "rgb(18, 18, 18)",
+  "gray70": "rgb(179, 179, 179)",
+  "gray71": "rgb(181, 181, 181)",
+  "gray72": "rgb(184, 184, 184)",
+  "gray73": "rgb(186, 186, 186)",
+  "gray74": "rgb(189, 189, 189)",
+  "gray75": "rgb(191, 191, 191)",
+  "gray76": "rgb(194, 194, 194)",
+  "gray77": "rgb(196, 196, 196)",
+  "gray78": "rgb(199, 199, 199)",
+  "gray79": "rgb(201, 201, 201)",
+  "gray8": "rgb(20, 20, 20)",
+  "gray80": "rgb(204, 204, 204)",
+  "gray81": "rgb(207, 207, 207)",
+  "gray82": "rgb(209, 209, 209)",
+  "gray83": "rgb(212, 212, 212)",
+  "gray84": "rgb(214, 214, 214)",
+  "gray85": "rgb(217, 217, 217)",
+  "gray86": "rgb(219, 219, 219)",
+  "gray87": "rgb(222, 222, 222)",
+  "gray88": "rgb(224, 224, 224)",
+  "gray89": "rgb(227, 227, 227)",
+  "gray9": "rgb(23, 23, 23)",
+  "gray90": "rgb(229, 229, 229)",
+  "gray91": "rgb(232, 232, 232)",
+  "gray92": "rgb(235, 235, 235)",
+  "gray93": "rgb(237, 237, 237)",
+  "gray94": "rgb(240, 240, 240)",
+  "gray95": "rgb(242, 242, 242)",
+  "gray96": "rgb(245, 245, 245)",
+  "gray97": "rgb(247, 247, 247)",
+  "gray98": "rgb(250, 250, 250)",
+  "gray99": "rgb(252, 252, 252)",
+  "green": "rgb(0, 255, 0)",
+  "green1": "rgb(0, 255, 0)",
+  "green2": "rgb(0, 238, 0)",
+  "green3": "rgb(0, 205, 0)",
+  "green4": "rgb(0, 139, 0)",
+  "greenyellow": "rgb(173, 255, 47)",
+  "grey": "rgb(190, 190, 190)",
+  "grey0": "rgb(0, 0, 0)",
+  "grey1": "rgb(3, 3, 3)",
+  "grey10": "rgb(26, 26, 26)",
+  "grey100": "rgb(255, 255, 255)",
+  "grey11": "rgb(28, 28, 28)",
+  "grey12": "rgb(31, 31, 31)",
+  "grey13": "rgb(33, 33, 33)",
+  "grey14": "rgb(36, 36, 36)",
+  "grey15": "rgb(38, 38, 38)",
+  "grey16": "rgb(41, 41, 41)",
+  "grey17": "rgb(43, 43, 43)",
+  "grey18": "rgb(46, 46, 46)",
+  "grey19": "rgb(48, 48, 48)",
+  "grey2": "rgb(5, 5, 5)",
+  "grey20": "rgb(51, 51, 51)",
+  "grey21": "rgb(54, 54, 54)",
+  "grey22": "rgb(56, 56, 56)",
+  "grey23": "rgb(59, 59, 59)",
+  "grey24": "rgb(61, 61, 61)",
+  "grey25": "rgb(64, 64, 64)",
+  "grey26": "rgb(66, 66, 66)",
+  "grey27": "rgb(69, 69, 69)",
+  "grey28": "rgb(71, 71, 71)",
+  "grey29": "rgb(74, 74, 74)",
+  "grey3": "rgb(8, 8, 8)",
+  "grey30": "rgb(77, 77, 77)",
+  "grey31": "rgb(79, 79, 79)",
+  "grey32": "rgb(82, 82, 82)",
+  "grey33": "rgb(84, 84, 84)",
+  "grey34": "rgb(87, 87, 87)",
+  "grey35": "rgb(89, 89, 89)",
+  "grey36": "rgb(92, 92, 92)",
+  "grey37": "rgb(94, 94, 94)",
+  "grey38": "rgb(97, 97, 97)",
+  "grey39": "rgb(99, 99, 99)",
+  "grey4": "rgb(10, 10, 10)",
+  "grey40": "rgb(102, 102, 102)",
+  "grey41": "rgb(105, 105, 105)",
+  "grey42": "rgb(107, 107, 107)",
+  "grey43": "rgb(110, 110, 110)",
+  "grey44": "rgb(112, 112, 112)",
+  "grey45": "rgb(115, 115, 115)",
+  "grey46": "rgb(117, 117, 117)",
+  "grey47": "rgb(120, 120, 120)",
+  "grey48": "rgb(122, 122, 122)",
+  "grey49": "rgb(125, 125, 125)",
+  "grey5": "rgb(13, 13, 13)",
+  "grey50": "rgb(127, 127, 127)",
+  "grey51": "rgb(130, 130, 130)",
+  "grey52": "rgb(133, 133, 133)",
+  "grey53": "rgb(135, 135, 135)",
+  "grey54": "rgb(138, 138, 138)",
+  "grey55": "rgb(140, 140, 140)",
+  "grey56": "rgb(143, 143, 143)",
+  "grey57": "rgb(145, 145, 145)",
+  "grey58": "rgb(148, 148, 148)",
+  "grey59": "rgb(150, 150, 150)",
+  "grey6": "rgb(15, 15, 15)",
+  "grey60": "rgb(153, 153, 153)",
+  "grey61": "rgb(156, 156, 156)",
+  "grey62": "rgb(158, 158, 158)",
+  "grey63": "rgb(161, 161, 161)",
+  "grey64": "rgb(163, 163, 163)",
+  "grey65": "rgb(166, 166, 166)",
+  "grey66": "rgb(168, 168, 168)",
+  "grey67": "rgb(171, 171, 171)",
+  "grey68": "rgb(173, 173, 173)",
+  "grey69": "rgb(176, 176, 176)",
+  "grey7": "rgb(18, 18, 18)",
+  "grey70": "rgb(179, 179, 179)",
+  "grey71": "rgb(181, 181, 181)",
+  "grey72": "rgb(184, 184, 184)",
+  "grey73": "rgb(186, 186, 186)",
+  "grey74": "rgb(189, 189, 189)",
+  "grey75": "rgb(191, 191, 191)",
+  "grey76": "rgb(194, 194, 194)",
+  "grey77": "rgb(196, 196, 196)",
+  "grey78": "rgb(199, 199, 199)",
+  "grey79": "rgb(201, 201, 201)",
+  "grey8": "rgb(20, 20, 20)",
+  "grey80": "rgb(204, 204, 204)",
+  "grey81": "rgb(207, 207, 207)",
+  "grey82": "rgb(209, 209, 209)",
+  "grey83": "rgb(212, 212, 212)",
+  "grey84": "rgb(214, 214, 214)",
+  "grey85": "rgb(217, 217, 217)",
+  "grey86": "rgb(219, 219, 219)",
+  "grey87": "rgb(222, 222, 222)",
+  "grey88": "rgb(224, 224, 224)",
+  "grey89": "rgb(227, 227, 227)",
+  "grey9": "rgb(23, 23, 23)",
+  "grey90": "rgb(229, 229, 229)",
+  "grey91": "rgb(232, 232, 232)",
+  "grey92": "rgb(235, 235, 235)",
+  "grey93": "rgb(237, 237, 237)",
+  "grey94": "rgb(240, 240, 240)",
+  "grey95": "rgb(242, 242, 242)",
+  "grey96": "rgb(245, 245, 245)",
+  "grey97": "rgb(247, 247, 247)",
+  "grey98": "rgb(250, 250, 250)",
+  "grey99": "rgb(252, 252, 252)",
+  "honeydew": "rgb(240, 255, 240)",
+  "honeydew1": "rgb(240, 255, 240)",
+  "honeydew2": "rgb(224, 238, 224)",
+  "honeydew3": "rgb(193, 205, 193)",
+  "honeydew4": "rgb(131, 139, 131)",
+  "hotpink": "rgb(255, 105, 180)",
+  "hotpink1": "rgb(255, 110, 180)",
+  "hotpink2": "rgb(238, 106, 167)",
+  "hotpink3": "rgb(205, 96, 144)",
+  "hotpink4": "rgb(139, 58, 98)",
+  "indianred": "rgb(205, 92, 92)",
+  "indianred1": "rgb(255, 106, 106)",
+  "indianred2": "rgb(238, 99, 99)",
+  "indianred3": "rgb(205, 85, 85)",
+  "indianred4": "rgb(139, 58, 58)",
+  "ivory": "rgb(255, 255, 240)",
+  "ivory1": "rgb(255, 255, 240)",
+  "ivory2": "rgb(238, 238, 224)",
+  "ivory3": "rgb(205, 205, 193)",
+  "ivory4": "rgb(139, 139, 131)",
+  "khaki": "rgb(240, 230, 140)",
+  "khaki1": "rgb(255, 246, 143)",
+  "khaki2": "rgb(238, 230, 133)",
+  "khaki3": "rgb(205, 198, 115)",
+  "khaki4": "rgb(139, 134, 78)",
+  "lavender": "rgb(230, 230, 250)",
+  "lavenderblush": "rgb(255, 240, 245)",
+  "lavenderblush1": "rgb(255, 240, 245)",
+  "lavenderblush2": "rgb(238, 224, 229)",
+  "lavenderblush3": "rgb(205, 193, 197)",
+  "lavenderblush4": "rgb(139, 131, 134)",
+  "lawngreen": "rgb(124, 252, 0)",
+  "lemonchiffon": "rgb(255, 250, 205)",
+  "lemonchiffon1": "rgb(255, 250, 205)",
+  "lemonchiffon2": "rgb(238, 233, 191)",
+  "lemonchiffon3": "rgb(205, 201, 165)",
+  "lemonchiffon4": "rgb(139, 137, 112)",
+  "lightblue": "rgb(173, 216, 230)",
+  "lightblue1": "rgb(191, 239, 255)",
+  "lightblue2": "rgb(178, 223, 238)",
+  "lightblue3": "rgb(154, 192, 205)",
+  "lightblue4": "rgb(104, 131, 139)",
+  "lightcoral": "rgb(240, 128, 128)",
+  "lightcyan": "rgb(224, 255, 255)",
+  "lightcyan1": "rgb(224, 255, 255)",
+  "lightcyan2": "rgb(209, 238, 238)",
+  "lightcyan3": "rgb(180, 205, 205)",
+  "lightcyan4": "rgb(122, 139, 139)",
+  "lightgoldenrod": "rgb(238, 221, 130)",
+  "lightgoldenrod1": "rgb(255, 236, 139)",
+  "lightgoldenrod2": "rgb(238, 220, 130)",
+  "lightgoldenrod3": "rgb(205, 190, 112)",
+  "lightgoldenrod4": "rgb(139, 129, 76)",
+  "lightgoldenrodyellow": "rgb(250, 250, 210)",
+  "lightgray": "rgb(211, 211, 211)",
+  "lightgreen": "rgb(144, 238, 144)",
+  "lightgrey": "rgb(211, 211, 211)",
+  "lightpink": "rgb(255, 182, 193)",
+  "lightpink1": "rgb(255, 174, 185)",
+  "lightpink2": "rgb(238, 162, 173)",
+  "lightpink3": "rgb(205, 140, 149)",
+  "lightpink4": "rgb(139, 95, 101)",
+  "lightsalmon": "rgb(255, 160, 122)",
+  "lightsalmon1": "rgb(255, 160, 122)",
+  "lightsalmon2": "rgb(238, 149, 114)",
+  "lightsalmon3": "rgb(205, 129, 98)",
+  "lightsalmon4": "rgb(139, 87, 66)",
+  "lightseagreen": "rgb(32, 178, 170)",
+  "lightskyblue": "rgb(135, 206, 250)",
+  "lightskyblue1": "rgb(176, 226, 255)",
+  "lightskyblue2": "rgb(164, 211, 238)",
+  "lightskyblue3": "rgb(141, 182, 205)",
+  "lightskyblue4": "rgb(96, 123, 139)",
+  "lightslateblue": "rgb(132, 112, 255)",
+  "lightslategray": "rgb(119, 136, 153)",
+  "lightslategrey": "rgb(119, 136, 153)",
+  "lightsteelblue": "rgb(176, 196, 222)",
+  "lightsteelblue1": "rgb(202, 225, 255)",
+  "lightsteelblue2": "rgb(188, 210, 238)",
+  "lightsteelblue3": "rgb(162, 181, 205)",
+  "lightsteelblue4": "rgb(110, 123, 139)",
+  "lightyellow": "rgb(255, 255, 224)",
+  "lightyellow1": "rgb(255, 255, 224)",
+  "lightyellow2": "rgb(238, 238, 209)",
+  "lightyellow3": "rgb(205, 205, 180)",
+  "lightyellow4": "rgb(139, 139, 122)",
+  "limegreen": "rgb(50, 205, 50)",
+  "linen": "rgb(250, 240, 230)",
+  "magenta": "rgb(255, 0, 255)",
+  "magenta1": "rgb(255, 0, 255)",
+  "magenta2": "rgb(238, 0, 238)",
+  "magenta3": "rgb(205, 0, 205)",
+  "magenta4": "rgb(139, 0, 139)",
+  "maroon": "rgb(176, 48, 96)",
+  "maroon1": "rgb(255, 52, 179)",
+  "maroon2": "rgb(238, 48, 167)",
+  "maroon3": "rgb(205, 41, 144)",
+  "maroon4": "rgb(139, 28, 98)",
+  "mediumaquamarine": "rgb(102, 205, 170)",
+  "mediumblue": "rgb(0, 0, 205)",
+  "mediumorchid": "rgb(186, 85, 211)",
+  "mediumorchid1": "rgb(224, 102, 255)",
+  "mediumorchid2": "rgb(209, 95, 238)",
+  "mediumorchid3": "rgb(180, 82, 205)",
+  "mediumorchid4": "rgb(122, 55, 139)",
+  "mediumpurple": "rgb(147, 112, 219)",
+  "mediumpurple1": "rgb(171, 130, 255)",
+  "mediumpurple2": "rgb(159, 121, 238)",
+  "mediumpurple3": "rgb(137, 104, 205)",
+  "mediumpurple4": "rgb(93, 71, 139)",
+  "mediumseagreen": "rgb(60, 179, 113)",
+  "mediumslateblue": "rgb(123, 104, 238)",
+  "mediumspringgreen": "rgb(0, 250, 154)",
+  "mediumturquoise": "rgb(72, 209, 204)",
+  "mediumvioletred": "rgb(199, 21, 133)",
+  "midnightblue": "rgb(25, 25, 112)",
+  "mintcream": "rgb(245, 255, 250)",
+  "mistyrose": "rgb(255, 228, 225)",
+  "mistyrose1": "rgb(255, 228, 225)",
+  "mistyrose2": "rgb(238, 213, 210)",
+  "mistyrose3": "rgb(205, 183, 181)",
+  "mistyrose4": "rgb(139, 125, 123)",
+  "moccasin": "rgb(255, 228, 181)",
+  "navajowhite": "rgb(255, 222, 173)",
+  "navajowhite1": "rgb(255, 222, 173)",
+  "navajowhite2": "rgb(238, 207, 161)",
+  "navajowhite3": "rgb(205, 179, 139)",
+  "navajowhite4": "rgb(139, 121, 94)",
+  "navy": "rgb(0, 0, 128)",
+  "navyblue": "rgb(0, 0, 128)",
+  "oldlace": "rgb(253, 245, 230)",
+  "olivedrab": "rgb(107, 142, 35)",
+  "olivedrab1": "rgb(192, 255, 62)",
+  "olivedrab2": "rgb(179, 238, 58)",
+  "olivedrab3": "rgb(154, 205, 50)",
+  "olivedrab4": "rgb(105, 139, 34)",
+  "orange": "rgb(255, 165, 0)",
+  "orange1": "rgb(255, 165, 0)",
+  "orange2": "rgb(238, 154, 0)",
+  "orange3": "rgb(205, 133, 0)",
+  "orange4": "rgb(139, 90, 0)",
+  "orangered": "rgb(255, 69, 0)",
+  "orangered1": "rgb(255, 69, 0)",
+  "orangered2": "rgb(238, 64, 0)",
+  "orangered3": "rgb(205, 55, 0)",
+  "orangered4": "rgb(139, 37, 0)",
+  "orchid": "rgb(218, 112, 214)",
+  "orchid1": "rgb(255, 131, 250)",
+  "orchid2": "rgb(238, 122, 233)",
+  "orchid3": "rgb(205, 105, 201)",
+  "orchid4": "rgb(139, 71, 137)",
+  "palegoldenrod": "rgb(238, 232, 170)",
+  "palegreen": "rgb(152, 251, 152)",
+  "palegreen1": "rgb(154, 255, 154)",
+  "palegreen2": "rgb(144, 238, 144)",
+  "palegreen3": "rgb(124, 205, 124)",
+  "palegreen4": "rgb(84, 139, 84)",
+  "paleturquoise": "rgb(175, 238, 238)",
+  "paleturquoise1": "rgb(187, 255, 255)",
+  "paleturquoise2": "rgb(174, 238, 238)",
+  "paleturquoise3": "rgb(150, 205, 205)",
+  "paleturquoise4": "rgb(102, 139, 139)",
+  "palevioletred": "rgb(219, 112, 147)",
+  "palevioletred1": "rgb(255, 130, 171)",
+  "palevioletred2": "rgb(238, 121, 159)",
+  "palevioletred3": "rgb(205, 104, 137)",
+  "palevioletred4": "rgb(139, 71, 93)",
+  "papayawhip": "rgb(255, 239, 213)",
+  "peachpuff": "rgb(255, 218, 185)",
+  "peachpuff1": "rgb(255, 218, 185)",
+  "peachpuff2": "rgb(238, 203, 173)",
+  "peachpuff3": "rgb(205, 175, 149)",
+  "peachpuff4": "rgb(139, 119, 101)",
+  "peru": "rgb(205, 133, 63)",
+  "pink": "rgb(255, 192, 203)",
+  "pink1": "rgb(255, 181, 197)",
+  "pink2": "rgb(238, 169, 184)",
+  "pink3": "rgb(205, 145, 158)",
+  "pink4": "rgb(139, 99, 108)",
+  "plum": "rgb(221, 160, 221)",
+  "plum1": "rgb(255, 187, 255)",
+  "plum2": "rgb(238, 174, 238)",
+  "plum3": "rgb(205, 150, 205)",
+  "plum4": "rgb(139, 102, 139)",
+  "powderblue": "rgb(176, 224, 230)",
+  "purple": "rgb(160, 32, 240)",
+  "purple1": "rgb(155, 48, 255)",
+  "purple2": "rgb(145, 44, 238)",
+  "purple3": "rgb(125, 38, 205)",
+  "purple4": "rgb(85, 26, 139)",
+  "red": "rgb(255, 0, 0)",
+  "red1": "rgb(255, 0, 0)",
+  "red2": "rgb(238, 0, 0)",
+  "red3": "rgb(205, 0, 0)",
+  "red4": "rgb(139, 0, 0)",
+  "rosybrown": "rgb(188, 143, 143)",
+  "rosybrown1": "rgb(255, 193, 193)",
+  "rosybrown2": "rgb(238, 180, 180)",
+  "rosybrown3": "rgb(205, 155, 155)",
+  "rosybrown4": "rgb(139, 105, 105)",
+  "royalblue": "rgb(65, 105, 225)",
+  "royalblue1": "rgb(72, 118, 255)",
+  "royalblue2": "rgb(67, 110, 238)",
+  "royalblue3": "rgb(58, 95, 205)",
+  "royalblue4": "rgb(39, 64, 139)",
+  "saddlebrown": "rgb(139, 69, 19)",
+  "salmon": "rgb(250, 128, 114)",
+  "salmon1": "rgb(255, 140, 105)",
+  "salmon2": "rgb(238, 130, 98)",
+  "salmon3": "rgb(205, 112, 84)",
+  "salmon4": "rgb(139, 76, 57)",
+  "sandybrown": "rgb(244, 164, 96)",
+  "seagreen": "rgb(46, 139, 87)",
+  "seagreen1": "rgb(84, 255, 159)",
+  "seagreen2": "rgb(78, 238, 148)",
+  "seagreen3": "rgb(67, 205, 128)",
+  "seagreen4": "rgb(46, 139, 87)",
+  "seashell": "rgb(255, 245, 238)",
+  "seashell1": "rgb(255, 245, 238)",
+  "seashell2": "rgb(238, 229, 222)",
+  "seashell3": "rgb(205, 197, 191)",
+  "seashell4": "rgb(139, 134, 130)",
+  "sienna": "rgb(160, 82, 45)",
+  "sienna1": "rgb(255, 130, 71)",
+  "sienna2": "rgb(238, 121, 66)",
+  "sienna3": "rgb(205, 104, 57)",
+  "sienna4": "rgb(139, 71, 38)",
+  "skyblue": "rgb(135, 206, 235)",
+  "skyblue1": "rgb(135, 206, 255)",
+  "skyblue2": "rgb(126, 192, 238)",
+  "skyblue3": "rgb(108, 166, 205)",
+  "skyblue4": "rgb(74, 112, 139)",
+  "slateblue": "rgb(106, 90, 205)",
+  "slateblue1": "rgb(131, 111, 255)",
+  "slateblue2": "rgb(122, 103, 238)",
+  "slateblue3": "rgb(105, 89, 205)",
+  "slateblue4": "rgb(71, 60, 139)",
+  "slategray": "rgb(112, 128, 144)",
+  "slategray1": "rgb(198, 226, 255)",
+  "slategray2": "rgb(185, 211, 238)",
+  "slategray3": "rgb(159, 182, 205)",
+  "slategray4": "rgb(108, 123, 139)",
+  "slategrey": "rgb(112, 128, 144)",
+  "snow": "rgb(255, 250, 250)",
+  "snow1": "rgb(255, 250, 250)",
+  "snow2": "rgb(238, 233, 233)",
+  "snow3": "rgb(205, 201, 201)",
+  "snow4": "rgb(139, 137, 137)",
+  "springgreen": "rgb(0, 255, 127)",
+  "springgreen1": "rgb(0, 255, 127)",
+  "springgreen2": "rgb(0, 238, 118)",
+  "springgreen3": "rgb(0, 205, 102)",
+  "springgreen4": "rgb(0, 139, 69)",
+  "steelblue": "rgb(70, 130, 180)",
+  "steelblue1": "rgb(99, 184, 255)",
+  "steelblue2": "rgb(92, 172, 238)",
+  "steelblue3": "rgb(79, 148, 205)",
+  "steelblue4": "rgb(54, 100, 139)",
+  "tan": "rgb(210, 180, 140)",
+  "tan1": "rgb(255, 165, 79)",
+  "tan2": "rgb(238, 154, 73)",
+  "tan3": "rgb(205, 133, 63)",
+  "tan4": "rgb(139, 90, 43)",
+  "thistle": "rgb(216, 191, 216)",
+  "thistle1": "rgb(255, 225, 255)",
+  "thistle2": "rgb(238, 210, 238)",
+  "thistle3": "rgb(205, 181, 205)",
+  "thistle4": "rgb(139, 123, 139)",
+  "tomato": "rgb(255, 99, 71)",
+  "tomato1": "rgb(255, 99, 71)",
+  "tomato2": "rgb(238, 92, 66)",
+  "tomato3": "rgb(205, 79, 57)",
+  "tomato4": "rgb(139, 54, 38)",
+  "turquoise": "rgb(64, 224, 208)",
+  "turquoise1": "rgb(0, 245, 255)",
+  "turquoise2": "rgb(0, 229, 238)",
+  "turquoise3": "rgb(0, 197, 205)",
+  "turquoise4": "rgb(0, 134, 139)",
+  "violet": "rgb(238, 130, 238)",
+  "violetred": "rgb(208, 32, 144)",
+  "violetred1": "rgb(255, 62, 150)",
+  "violetred2": "rgb(238, 58, 140)",
+  "violetred3": "rgb(205, 50, 120)",
+  "violetred4": "rgb(139, 34, 82)",
+  "wheat": "rgb(245, 222, 179)",
+  "wheat1": "rgb(255, 231, 186)",
+  "wheat2": "rgb(238, 216, 174)",
+  "wheat3": "rgb(205, 186, 150)",
+  "wheat4": "rgb(139, 126, 102)",
+  "white": "rgb(255, 255, 255)",
+  "whitesmoke": "rgb(245, 245, 245)",
+  "yellow": "rgb(255, 255, 0)",
+  "yellow1": "rgb(255, 255, 0)",
+  "yellow2": "rgb(238, 238, 0)",
+  "yellow3": "rgb(205, 205, 0)",
+  "yellow4": "rgb(139, 139, 0)",
+  "yellowgreen": "rgb(154, 205, 50)"
+};
+// SOURCE FILE: libdot/js/lib_f.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Grab bag of utility functions.
+ */
+lib.f = {};
+
+/**
+ * Replace variable references in a string.
+ *
+ * Variables are of the form %FUNCTION(VARNAME).  FUNCTION is an optional
+ * escape function to apply to the value.
+ *
+ * For example
+ *   lib.f.replaceVars("%(greeting), %encodeURIComponent(name)",
+ *                     { greeting: "Hello",
+ *                       name: "Google+" });
+ *
+ * Will result in "Hello, Google%2B".
+ */
+lib.f.replaceVars = function(str, vars) {
+  return str.replace(/%([a-z]*)\(([^\)]+)\)/gi, function(match, fn, varname) {
+      if (typeof vars[varname] == 'undefined')
+        throw 'Unknown variable: ' + varname;
+
+      var rv = vars[varname];
+
+      if (fn in lib.f.replaceVars.functions) {
+        rv = lib.f.replaceVars.functions[fn](rv);
+      } else if (fn) {
+        throw 'Unknown escape function: ' + fn;
+      }
+
+      return rv;
+    });
+};
+
+/**
+ * Functions that can be used with replaceVars.
+ *
+ * Clients can add to this list to extend lib.f.replaceVars().
+ */
+lib.f.replaceVars.functions = {
+  encodeURI: encodeURI,
+  encodeURIComponent: encodeURIComponent,
+  escapeHTML: function(str) {
+    var map = {
+      '<': '&lt;',
+      '>': '&gt;',
+      '&': '&amp;',
+      '"': '&quot;',
+      "'": '&#39;'
+    };
+
+    return str.replace(/[<>&\"\']/g, (m) => map[m]);
+  }
+};
+
+lib.f.getURL = function(path) {
+  if (lib.f.getURL.chromeSupported())
+    return chrome.runtime.getURL(path);
+
+  return path;
+};
+
+lib.f.getURL.chromeSupported = function() {
+  return window.chrome && chrome.runtime && chrome.runtime.getURL;
+};
+
+/**
+ * Clamp a given integer to a specified range.
+ *
+ * @param {integer} v The value to be clamped.
+ * @param {integer} min The minimum acceptable value.
+ * @param {integer} max The maximum acceptable value.
+ */
+lib.f.clamp = function(v, min, max) {
+  if (v < min)
+    return min;
+  if (v > max)
+    return max;
+  return v;
+};
+
+/**
+ * Left pad a number to a given length with leading zeros.
+ *
+ * @param {string|integer} number The number to pad.
+ * @param {integer} length The desired length.
+ * @return {string} The padded number as a string.
+ */
+lib.f.zpad = function(number, length) {
+  return String(number).padStart(length, '0');
+};
+
+/**
+ * Return a string containing a given number of space characters.
+ *
+ * This method maintains a static cache of the largest amount of whitespace
+ * ever requested.  It shouldn't be used to generate an insanely huge amount of
+ * whitespace.
+ *
+ * @param {integer} length The desired amount of whitespace.
+ * @param {string} A string of spaces of the requested length.
+ */
+lib.f.getWhitespace = function(length) {
+  if (length <= 0)
+    return '';
+
+  var f = this.getWhitespace;
+  if (!f.whitespace)
+    f.whitespace = '          ';
+
+  while (length > f.whitespace.length) {
+    f.whitespace += f.whitespace;
+  }
+
+  return f.whitespace.substr(0, length);
+};
+
+/**
+ * Return the current call stack after skipping a given number of frames.
+ *
+ * This method is intended to be used for debugging only.  It returns an
+ * Object instead of an Array, because the console stringifies arrays by
+ * default and that's not what we want.
+ *
+ * A typical call might look like...
+ *
+ *    console.log('Something wicked this way came', lib.f.getStack());
+ *    //                         Notice the comma ^
+ *
+ * This would print the message to the js console, followed by an object
+ * which can be clicked to reveal the stack.
+ *
+ * @param {number=} ignoreFrames How many inner stack frames to ignore.  The
+ *     innermost 'getStack' call is always ignored.
+ * @param {number=} count How many frames to return.
+ */
+lib.f.getStack = function(ignoreFrames = 0, count = undefined) {
+  const stackArray = (new Error()).stack.split('\n');
+
+  // Always ignore the Error() object and getStack call itself.
+  // [0] = 'Error'
+  // [1] = '    at Object.lib.f.getStack (file:///.../lib_f.js:267:23)'
+  ignoreFrames += 2;
+
+  const max = stackArray.length - ignoreFrames;
+  if (count === undefined)
+    count = max;
+  else
+    count = lib.f.clamp(count, 0, max);
+
+  // Remove the leading spaces and "at" from each line:
+  // '    at window.onload (file:///.../lib_test.js:11:18)'
+  const stackObject = new Array();
+  for (let i = ignoreFrames; i < count + ignoreFrames; ++i)
+    stackObject.push(stackArray[i].replace(/^\s*at\s+/, ''));
+
+  return stackObject;
+};
+
+/**
+ * Divides the two numbers and floors the results, unless the remainder is less
+ * than an incredibly small value, in which case it returns the ceiling.
+ * This is useful when the number are truncated approximations of longer
+ * values, and so doing division with these numbers yields a result incredibly
+ * close to a whole number.
+ *
+ * @param {number} numerator
+ * @param {number} denominator
+ * @return {number}
+ */
+lib.f.smartFloorDivide = function(numerator,  denominator) {
+  var val = numerator / denominator;
+  var ceiling = Math.ceil(val);
+  if (ceiling - val < .0001) {
+    return ceiling;
+  } else {
+    return Math.floor(val);
+  }
+};
+
+/**
+ * Get a random integer in a range (inclusive).
+ *
+ * @param {number} min The lowest integer in the range.
+ * @param {number} max The highest integer in the range.
+ * @return {number} A random number between min & max.
+ */
+lib.f.randomInt = function(min, max) {
+  return Math.floor(Math.random() * (max - min + 1)) + min;
+};
+
+/**
+ * Get the current OS.
+ *
+ * @return {Promise<string>} A promise that resolves to a constant in
+ *     runtime.PlatformOs.
+ */
+lib.f.getOs = function() {
+  // Try the brower extensions API.
+  if (window.browser && browser.runtime && browser.runtime.getPlatformInfo)
+    return browser.runtime.getPlatformInfo().then((info) => info.os);
+
+  // Use the native Chrome API if available.
+  if (window.chrome && chrome.runtime && chrome.runtime.getPlatformInfo) {
+    return new Promise((resolve, reject) =>
+        chrome.runtime.getPlatformInfo((info) => resolve(info.os)));
+  }
+
+  // Fallback logic.  Capture the major OS's.  The rest should support the
+  // browser API above.
+  if (window.navigator && navigator.userAgent) {
+    const ua = navigator.userAgent;
+    if (ua.includes('Mac OS X'))
+      return Promise.resolve('mac');
+    else if (ua.includes('CrOS'))
+      return Promise.resolve('cros');
+    else if (ua.includes('Linux'))
+      return Promise.resolve('linux');
+    else if (ua.includes('Android'))
+      return Promise.resolve('android');
+    else if (ua.includes('Windows'))
+      return Promise.resolve('windows');
+  }
+
+  // Probe node environment.
+  if (typeof process != 'undefined') {
+    return Promise.resolve('node');
+  }
+
+  // Still here?  No idea.
+  return Promise.reject(null);
+};
+
+/**
+ * Get the current Chrome milestone version.
+ *
+ * @return {number} The milestone number if we're running on Chrome, else NaN.
+ */
+lib.f.getChromeMilestone = function() {
+  if (window.navigator && navigator.userAgent) {
+    const ary = navigator.userAgent.match(/\sChrome\/(\d+)/);
+    if (ary)
+      return parseInt(ary[1]);
+  }
+
+  // Returning NaN will make all number comparisons fail.
+  return NaN;
+};
+
+/**
+ * Return the lastError string in the browser.
+ *
+ * This object might live in different locations, and it isn't always defined
+ * (if there hasn't been a "last error").  Wrap all that ugliness here.
+ *
+ * @param {string=} defaultMsg The default message if no error is found.
+ * @return {string} The last error message from the browser.
+ */
+lib.f.lastError = function(defaultMsg = null) {
+  let lastError;
+  if (window.browser && browser.runtime)
+    lastError = browser.runtime.lastError;
+  else if (window.chrome && chrome.runtime)
+    lastError = chrome.runtime.lastError;
+
+  if (lastError && lastError.message)
+    return lastError.message;
+  else
+    return defaultMsg;
+};
+
+/**
+ * Just like window.open, but enforce noopener.
+ *
+ * If we're not careful, the website we open will have access to use via its
+ * window.opener field.  Newer browser support putting 'noopener' into the
+ * features argument, but there are many which still don't.  So hack it.
+ *
+ * @param {string=} url The URL to point the new window to.
+ * @param {string=} name The name of the new window.
+ * @param {string=} features The window features to enable.
+ * @return {Window} The newly opened window.
+ */
+lib.f.openWindow = function(url, name=undefined, features=undefined) {
+  // We create the window first without the URL loaded.
+  const win = window.open(undefined, name, features);
+
+  // If the system is blocking window.open, don't crash.
+  if (win !== null) {
+    // Clear the opener setting before redirecting.
+    win.opener = null;
+
+    // Now it's safe to redirect.  Skip this step if the url is not set so we
+    // mimic the window.open behavior more precisely.
+    if (url) {
+      win.location = url;
+    }
+  }
+
+  return win;
+};
+// SOURCE FILE: libdot/js/lib_i18n.js
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Wrappers over the browser i18n helpers.
+ *
+ * Arguably some of these functions should be l10n, but oh well.
+ */
+lib.i18n = {};
+
+/**
+ * Convenience shortcut to the browser i18n object.
+ */
+lib.i18n.browser_ =
+    window.browser && browser.i18n ? browser.i18n :
+    window.chrome && chrome.i18n ? chrome.i18n :
+    null;
+
+/**
+ * Get the list of accepted UI languages.
+ *
+ * https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/i18n/getAcceptLanguages
+ *
+ * @param {function(Array)} callback Function to invoke with the results.  The
+ *     parameter is a list of locale names.
+ */
+lib.i18n.getAcceptLanguages = function(callback) {
+  if (lib.i18n.browser_) {
+    lib.i18n.browser_.getAcceptLanguages(callback);
+  } else {
+    setTimeout(function() {
+        callback([navigator.language.replace(/-/g, '_')]);
+      }, 0);
+  }
+};
+
+/**
+ * Get a message by name, optionally replacing arguments too.
+ *
+ * https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/i18n/getMessage
+ *
+ * @param {string} msgname The id for this localized string.
+ * @param {string[]=} substitutions Any replacements in the string.
+ * @param {string=} fallback Translation if the message wasn't found.
+ * @return {string} The translated message.
+ */
+lib.i18n.getMessage = function(msgname, substitutions = [], fallback = '') {
+  // First let the native browser APIs handle everything for us.
+  if (lib.i18n.browser_) {
+    const message = lib.i18n.browser_.getMessage(msgname, substitutions);
+    if (message)
+      return message;
+  }
+
+  // Do our best to get something reasonable.
+  return lib.i18n.replaceReferences(fallback, substitutions);
+};
+
+/**
+ * Replace $1...$n references with the elements of the args array.
+ *
+ * This largely behaves like Chrome's getMessage helper.  The $# references are
+ * always replaced/removed regardless of the specified substitutions.
+ *
+ * @param {string} msg String containing the message and argument references.
+ * @param {string[]=} args Array containing the argument values.
+ * @return {string} The message with replacements expanded.
+ */
+lib.i18n.replaceReferences = function(msg, args = []) {
+  // The Chrome API allows a single substitution as a string rather than array.
+  if (args === null) {
+    args = [];
+  }
+  if (!(args instanceof Array)) {
+    args = [args];
+  }
+
+  return msg.replace(/\$(\d+)/g, (m, index) => {
+    return index <= args.length ? args[index - 1] : '';
+  });
+};
+// SOURCE FILE: libdot/js/lib_message_manager.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * MessageManager class handles internationalized strings.
+ *
+ * Note: chrome.i18n isn't sufficient because...
+ *     1. There's a bug in chrome that makes it unavailable in iframes:
+ *        https://crbug.com/130200
+ *     2. The client code may not be packaged in a Chrome extension.
+ *     3. The client code may be part of a library packaged in a third-party
+ *        Chrome extension.
+ *
+ * @param {Array} languages List of languages to load, in the order they
+ *     should be loaded.  Newer messages replace older ones.  'en' is
+ *     automatically added as the first language if it is not already present.
+ */
+lib.MessageManager = function(languages) {
+  this.languages_ = languages.map((el) => el.replace(/-/g, '_'));
+
+  if (this.languages_.indexOf('en') == -1)
+    this.languages_.unshift('en');
+
+  this.messages = {};
+};
+
+/**
+ * Add message definitions to the message manager.
+ *
+ * This takes an object of the same format of a Chrome messages.json file.  See
+ * <https://developer.chrome.com/extensions/i18n-messages>.
+ */
+lib.MessageManager.prototype.addMessages = function(defs) {
+  for (var key in defs) {
+    var def = defs[key];
+
+    if (!def.placeholders) {
+      this.messages[key] = def.message;
+    } else {
+      // Replace "$NAME$" placeholders with "$1", etc.
+      this.messages[key] = def.message.replace(
+          /\$([a-z][^\s\$]+)\$/ig,
+          function(m, name) {
+            return defs[key].placeholders[name.toLowerCase()].content;
+          });
+    }
+  }
+};
+
+/**
+ * Load the first available language message bundle.
+ *
+ * @param {string} pattern A url pattern containing a "$1" where the locale
+ *     name should go.
+ * @param {function(Array,Array)} onComplete Function to be called when loading
+ *     is complete.  The two arrays are the list of successful and failed
+ *     locale names.  If the first parameter is length 0, no locales were
+ *     loaded.
+ */
+lib.MessageManager.prototype.findAndLoadMessages = function(
+    pattern, onComplete) {
+  var languages = this.languages_.concat();
+  var loaded = [];
+  var failed = [];
+
+  function onLanguageComplete(state) {
+    if (state) {
+      loaded = languages.shift();
+    } else {
+      failed = languages.shift();
+    }
+
+    if (languages.length) {
+      tryNextLanguage();
+    } else {
+      onComplete(loaded, failed);
+    }
+  }
+
+  var tryNextLanguage = function() {
+    this.loadMessages(this.replaceReferences(pattern, languages),
+                      onLanguageComplete.bind(this, true),
+                      onLanguageComplete.bind(this, false));
+  }.bind(this);
+
+  tryNextLanguage();
+};
+
+/**
+ * Load messages from a messages.json file.
+ */
+lib.MessageManager.prototype.loadMessages = function(
+    url, onSuccess, opt_onError) {
+  var xhr = new XMLHttpRequest();
+
+  xhr.onload = () => {
+    this.addMessages(JSON.parse(xhr.responseText));
+    onSuccess();
+  };
+  if (opt_onError)
+    xhr.onerror = () => opt_onError(xhr);
+
+  xhr.open('GET', url);
+  xhr.send();
+};
+
+/**
+ * Per-instance copy of replaceReferences.
+ */
+lib.MessageManager.prototype.replaceReferences = lib.i18n.replaceReferences;
+
+/**
+ * Get a message by name, optionally replacing arguments too.
+ *
+ * @param {string} msgname String containing the name of the message to get.
+ * @param {Array} opt_args Optional array containing the argument values.
+ * @param {string} opt_default Optional value to return if the msgname is not
+ *     found.  Returns the message name by default.
+ */
+lib.MessageManager.prototype.get = function(msgname, opt_args, opt_default) {
+  // First try the integrated browser getMessage.  We prefer that over any
+  // registered messages as only the browser supports translations.
+  let message = lib.i18n.getMessage(msgname, opt_args);
+  if (message)
+    return message;
+
+  // Look it up in the registered cache next.
+  message = this.messages[msgname];
+  if (!message) {
+    console.warn('Unknown message: ' + msgname);
+    message = opt_default === undefined ? msgname : opt_default;
+    // Register the message with the default to avoid multiple warnings.
+    this.messages[msgname] = message;
+  }
+
+  return this.replaceReferences(message, opt_args);
+};
+
+/**
+ * Process all of the "i18n" html attributes found in a given dom fragment.
+ *
+ * The real work happens in processI18nAttribute.
+ */
+lib.MessageManager.prototype.processI18nAttributes = function(dom) {
+  var nodes = dom.querySelectorAll('[i18n]');
+
+  for (var i = 0; i < nodes.length; i++)
+    this.processI18nAttribute(nodes[i]);
+};
+
+/**
+ * Process the "i18n" attribute in the specified node.
+ *
+ * The i18n attribute should contain a JSON object.  The keys are taken to
+ * be attribute names, and the values are message names.
+ *
+ * If the JSON object has a "_" (underscore) key, its value is used as the
+ * textContent of the element.
+ *
+ * Message names can refer to other attributes on the same element with by
+ * prefixing with a dollar sign.  For example...
+ *
+ *   <button id='send-button'
+ *           i18n='{"aria-label": "$id", "_": "SEND_BUTTON_LABEL"}'
+ *           ></button>
+ *
+ * The aria-label message name will be computed as "SEND_BUTTON_ARIA_LABEL".
+ * Notice that the "id" attribute was appended to the target attribute, and
+ * the result converted to UPPER_AND_UNDER style.
+ */
+lib.MessageManager.prototype.processI18nAttribute = function(node) {
+  // Convert the "lower-and-dashes" attribute names into
+  // "UPPER_AND_UNDER" style.
+  const thunk = (str) => str.replace(/-/g, '_').toUpperCase();
+
+  var i18n = node.getAttribute('i18n');
+  if (!i18n)
+    return;
+
+  try {
+    i18n = JSON.parse(i18n);
+  } catch (ex) {
+    console.error('Can\'t parse ' + node.tagName + '#' + node.id + ': ' + i18n);
+    throw ex;
+  }
+
+  // Load all the messages specified in the i18n attributes.
+  for (var key in i18n) {
+    // The node attribute we'll be setting.
+    var attr = key;
+
+    var msgname = i18n[key];
+    // For "=foo", re-use the referenced message name.
+    if (msgname.startsWith('=')) {
+      key = msgname.substr(1);
+      msgname = i18n[key];
+    }
+
+    // For "$foo", calculate the message name.
+    if (msgname.startsWith('$'))
+      msgname = thunk(node.getAttribute(msgname.substr(1)) + '_' + key);
+
+    // Finally load the message.
+    var msg = this.get(msgname);
+    if (attr == '_')
+      node.textContent = msg;
+    else
+      node.setAttribute(attr, msg);
+  }
+};
+// SOURCE FILE: libdot/js/lib_preference_manager.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Constructor for lib.PreferenceManager objects.
+ *
+ * These objects deal with persisting changes to stable storage and notifying
+ * consumers when preferences change.
+ *
+ * It is intended that the backing store could be something other than HTML5
+ * storage, but there aren't any use cases at the moment.  In the future there
+ * may be a chrome api to store sync-able name/value pairs, and we'd want
+ * that.
+ *
+ * @param {lib.Storage.*} storage The storage object to use as a backing
+ *     store.
+ * @param {string} opt_prefix The optional prefix to be used for all preference
+ *     names.  The '/' character should be used to separate levels of hierarchy,
+ *     if you're going to have that kind of thing.  If provided, the prefix
+ *     should start with a '/'.  If not provided, it defaults to '/'.
+ */
+lib.PreferenceManager = function(storage, opt_prefix) {
+  this.storage = storage;
+  this.storageObserver_ = this.onStorageChange_.bind(this);
+
+  this.isActive_ = false;
+  this.activate();
+
+  this.trace = false;
+
+  var prefix = opt_prefix || '/';
+  if (!prefix.endsWith('/'))
+    prefix += '/';
+
+  this.prefix = prefix;
+
+  // Internal state for when we're doing a bulk import from JSON and we want
+  // to elide redundant storage writes (for quota reasons).
+  this.isImportingJson_ = false;
+
+  this.prefRecords_ = {};
+  this.globalObservers_ = [];
+
+  this.childFactories_ = {};
+
+  // Map of list-name to {map of child pref managers}
+  // As in...
+  //
+  //  this.childLists_ = {
+  //    'profile-ids': {
+  //      'one': PreferenceManager,
+  //      'two': PreferenceManager,
+  //      ...
+  //    },
+  //
+  //    'frob-ids': {
+  //      ...
+  //    }
+  //  }
+  this.childLists_ = {};
+};
+
+/**
+ * Used internally to indicate that the current value of the preference should
+ * be taken from the default value defined with the preference.
+ *
+ * Equality tests against this value MUST use '===' or '!==' to be accurate.
+ */
+lib.PreferenceManager.prototype.DEFAULT_VALUE = Symbol('DEFAULT_VALUE');
+
+/**
+ * An individual preference.
+ *
+ * These objects are managed by the PreferenceManager, you shouldn't need to
+ * handle them directly.
+ */
+lib.PreferenceManager.Record = function(name, defaultValue) {
+  this.name = name;
+  this.defaultValue = defaultValue;
+  this.currentValue = this.DEFAULT_VALUE;
+  this.observers = [];
+};
+
+/**
+ * A local copy of the DEFAULT_VALUE constant to make it less verbose.
+ */
+lib.PreferenceManager.Record.prototype.DEFAULT_VALUE =
+    lib.PreferenceManager.prototype.DEFAULT_VALUE;
+
+/**
+ * Register a callback to be invoked when this preference changes.
+ *
+ * @param {function(value, string, lib.PreferenceManager} observer The function
+ *     to invoke.  It will receive the new value, the name of the preference,
+ *     and a reference to the PreferenceManager as parameters.
+ */
+lib.PreferenceManager.Record.prototype.addObserver = function(observer) {
+  this.observers.push(observer);
+};
+
+/**
+ * Unregister an observer callback.
+ *
+ * @param {function} observer A previously registered callback.
+ */
+lib.PreferenceManager.Record.prototype.removeObserver = function(observer) {
+  var i = this.observers.indexOf(observer);
+  if (i >= 0)
+    this.observers.splice(i, 1);
+};
+
+/**
+ * Fetch the value of this preference.
+ */
+lib.PreferenceManager.Record.prototype.get = function() {
+  if (this.currentValue === this.DEFAULT_VALUE) {
+    if (/^(string|number)$/.test(typeof this.defaultValue))
+      return this.defaultValue;
+
+    if (typeof this.defaultValue == 'object') {
+      // We want to return a COPY of the default value so that users can
+      // modify the array or object without changing the default value.
+      return JSON.parse(JSON.stringify(this.defaultValue));
+    }
+
+    return this.defaultValue;
+  }
+
+  return this.currentValue;
+};
+
+/**
+ * Stop this preference manager from tracking storage changes.
+ *
+ * Call this if you're going to swap out one preference manager for another so
+ * that you don't get notified about irrelevant changes.
+ */
+lib.PreferenceManager.prototype.deactivate = function() {
+  if (!this.isActive_)
+    throw new Error('Not activated');
+
+  this.isActive_ = false;
+  this.storage.removeObserver(this.storageObserver_);
+};
+
+/**
+ * Start tracking storage changes.
+ *
+ * If you previously deactivated this preference manager, you can reactivate it
+ * with this method.  You don't need to call this at initialization time, as
+ * it's automatically called as part of the constructor.
+ */
+lib.PreferenceManager.prototype.activate = function() {
+  if (this.isActive_)
+    throw new Error('Already activated');
+
+  this.isActive_ = true;
+  this.storage.addObserver(this.storageObserver_);
+};
+
+/**
+ * Read the backing storage for these preferences.
+ *
+ * You should do this once at initialization time to prime the local cache
+ * of preference values.  The preference manager will monitor the backing
+ * storage for changes, so you should not need to call this more than once.
+ *
+ * This function recursively reads storage for all child preference managers as
+ * well.
+ *
+ * This function is asynchronous, if you need to read preference values, you
+ * *must* wait for the callback.
+ *
+ * @param {function()} opt_callback Optional function to invoke when the read
+ *     has completed.
+ */
+lib.PreferenceManager.prototype.readStorage = function(opt_callback) {
+  var pendingChildren = 0;
+
+  function onChildComplete() {
+    if (--pendingChildren == 0 && opt_callback)
+      opt_callback();
+  }
+
+  var keys = Object.keys(this.prefRecords_).map((el) => this.prefix + el);
+
+  if (this.trace)
+    console.log('Preferences read: ' + this.prefix);
+
+  this.storage.getItems(keys, function(items) {
+      var prefixLength = this.prefix.length;
+
+      for (var key in items) {
+        var value = items[key];
+        var name = key.substr(prefixLength);
+        var needSync = (name in this.childLists_ &&
+                        (JSON.stringify(value) !=
+                         JSON.stringify(this.prefRecords_[name].currentValue)));
+
+        this.prefRecords_[name].currentValue = value;
+
+        if (needSync) {
+          pendingChildren++;
+          this.syncChildList(name, onChildComplete);
+        }
+      }
+
+      if (pendingChildren == 0 && opt_callback)
+        setTimeout(opt_callback);
+    }.bind(this));
+};
+
+/**
+ * Define a preference.
+ *
+ * This registers a name, default value, and onChange handler for a preference.
+ *
+ * @param {string} name The name of the preference.  This will be prefixed by
+ *     the prefix of this PreferenceManager before written to local storage.
+ * @param {string|number|boolean|Object|Array|null} value The default value of
+ *     this preference.  Anything that can be represented in JSON is a valid
+ *     default value.
+ * @param {function(value, string, lib.PreferenceManager} opt_observer A
+ *     function to invoke when the preference changes.  It will receive the new
+ *     value, the name of the preference, and a reference to the
+ *     PreferenceManager as parameters.
+ */
+lib.PreferenceManager.prototype.definePreference = function(
+    name, value, opt_onChange) {
+
+  var record = this.prefRecords_[name];
+  if (record) {
+    this.changeDefault(name, value);
+  } else {
+    record = this.prefRecords_[name] =
+        new lib.PreferenceManager.Record(name, value);
+  }
+
+  if (opt_onChange)
+    record.addObserver(opt_onChange);
+};
+
+/**
+ * Define multiple preferences with a single function call.
+ *
+ * @param {Array} defaults An array of 3-element arrays.  Each three element
+ *     array should contain the [key, value, onChange] parameters for a
+ *     preference.
+ */
+lib.PreferenceManager.prototype.definePreferences = function(defaults) {
+  for (var i = 0; i < defaults.length; i++) {
+    this.definePreference(defaults[i][0], defaults[i][1], defaults[i][2]);
+  }
+};
+
+/**
+ * Define an ordered list of child preferences.
+ *
+ * Child preferences are different from just storing an array of JSON objects
+ * in that each child is an instance of a preference manager.  This means you
+ * can observe changes to individual child preferences, and get some validation
+ * that you're not reading or writing to an undefined child preference value.
+ *
+ * @param {string} listName A name for the list of children.  This must be
+ *     unique in this preference manager.  The listName will become a
+ *     preference on this PreferenceManager used to store the ordered list of
+ *     child ids.  It is also used in get/add/remove operations to identify the
+ *     list of children to operate on.
+ * @param {function} childFactory A function that will be used to generate
+ *     instances of these children.  The factory function will receive the
+ *     parent lib.PreferenceManager object and a unique id for the new child
+ *     preferences.
+ */
+lib.PreferenceManager.prototype.defineChildren = function(
+    listName, childFactory) {
+
+  // Define a preference to hold the ordered list of child ids.
+  this.definePreference(listName, [],
+                        this.onChildListChange_.bind(this, listName));
+  this.childFactories_[listName] = childFactory;
+  this.childLists_[listName] = {};
+};
+
+/**
+ * Register to observe preference changes.
+ *
+ * @param {Function} global A callback that will happen for every preference.
+ *     Pass null if you don't need one.
+ * @param {Object} map A map of preference specific callbacks.  Pass null if
+ *     you don't need any.
+ */
+lib.PreferenceManager.prototype.addObservers = function(global, map) {
+  if (global && typeof global != 'function')
+    throw new Error('Invalid param: globals');
+
+  if (global)
+    this.globalObservers_.push(global);
+
+  if (!map)
+    return;
+
+  for (var name in map) {
+    if (!(name in this.prefRecords_))
+      throw new Error('Unknown preference: ' + name);
+
+    this.prefRecords_[name].addObserver(map[name]);
+  }
+};
+
+/**
+ * Dispatch the change observers for all known preferences.
+ *
+ * It may be useful to call this after readStorage completes, in order to
+ * get application state in sync with user preferences.
+ *
+ * This can be used if you've changed a preference manager out from under
+ * a live object, for example when switching to a different prefix.
+ */
+lib.PreferenceManager.prototype.notifyAll = function() {
+  for (var name in this.prefRecords_) {
+    this.notifyChange_(name);
+  }
+};
+
+/**
+ * Notify the change observers for a given preference.
+ *
+ * @param {string} name The name of the preference that changed.
+ */
+lib.PreferenceManager.prototype.notifyChange_ = function(name) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  var currentValue = record.get();
+
+  for (var i = 0; i < this.globalObservers_.length; i++)
+    this.globalObservers_[i](name, currentValue);
+
+  for (var i = 0; i < record.observers.length; i++) {
+    record.observers[i](currentValue, name, this);
+  }
+};
+
+/**
+ * Create a new child PreferenceManager for the given child list.
+ *
+ * The optional hint parameter is an opaque prefix added to the auto-generated
+ * unique id for this child.  Your child factory can parse out the prefix
+ * and use it.
+ *
+ * @param {string} listName The child list to create the new instance from.
+ * @param {string} opt_hint Optional hint to include in the child id.
+ * @param {string} opt_id Optional id to override the generated id.
+ */
+lib.PreferenceManager.prototype.createChild = function(listName, opt_hint,
+                                                       opt_id) {
+  var ids = this.get(listName);
+  var id;
+
+  if (opt_id) {
+    id = opt_id;
+    if (ids.indexOf(id) != -1)
+      throw new Error('Duplicate child: ' + listName + ': ' + id);
+
+  } else {
+    // Pick a random, unique 4-digit hex identifier for the new profile.
+    while (!id || ids.indexOf(id) != -1) {
+      id = lib.f.randomInt(1, 0xffff).toString(16);
+      id = lib.f.zpad(id, 4);
+      if (opt_hint)
+        id = opt_hint + ':' + id;
+    }
+  }
+
+  var childManager = this.childFactories_[listName](this, id);
+  childManager.trace = this.trace;
+  childManager.resetAll();
+
+  this.childLists_[listName][id] = childManager;
+
+  ids.push(id);
+  this.set(listName, ids, undefined, !this.isImportingJson_);
+
+  return childManager;
+};
+
+/**
+ * Remove a child preferences instance.
+ *
+ * Removes a child preference manager and clears any preferences stored in it.
+ *
+ * @param {string} listName The name of the child list containing the child to
+ *     remove.
+ * @param {string} id The child ID.
+ */
+lib.PreferenceManager.prototype.removeChild = function(listName, id) {
+  var prefs = this.getChild(listName, id);
+  prefs.resetAll();
+
+  var ids = this.get(listName);
+  var i = ids.indexOf(id);
+  if (i != -1) {
+    ids.splice(i, 1);
+    this.set(listName, ids, undefined, !this.isImportingJson_);
+  }
+
+  delete this.childLists_[listName][id];
+};
+
+/**
+ * Return a child PreferenceManager instance for a given id.
+ *
+ * If the child list or child id is not known this will return the specified
+ * default value or throw an exception if no default value is provided.
+ *
+ * @param {string} listName The child list to look in.
+ * @param {string} id The child ID.
+ * @param {*} opt_default The optional default value to return if the child
+ *     is not found.
+ */
+lib.PreferenceManager.prototype.getChild = function(listName, id, opt_default) {
+  if (!(listName in this.childLists_))
+    throw new Error('Unknown child list: ' + listName);
+
+  var childList = this.childLists_[listName];
+  if (!(id in childList)) {
+    if (typeof opt_default == 'undefined')
+      throw new Error('Unknown "' + listName + '" child: ' + id);
+
+    return opt_default;
+  }
+
+  return childList[id];
+};
+
+/**
+ * Calculate the difference between two lists of child ids.
+ *
+ * Given two arrays of child ids, this function will return an object
+ * with "added", "removed", and "common" properties.  Each property is
+ * a map of child-id to `true`.  For example, given...
+ *
+ *    a = ['child-x', 'child-y']
+ *    b = ['child-y']
+ *
+ *    diffChildLists(a, b) =>
+ *      { added: { 'child-x': true }, removed: {}, common: { 'child-y': true } }
+ *
+ * The added/removed properties assume that `a` is the current list.
+ *
+ * @param {Array[string]} a The most recent list of child ids.
+ * @param {Array[string]} b An older list of child ids.
+ * @return {Object} An object with added/removed/common properties.
+ */
+lib.PreferenceManager.diffChildLists = function(a, b) {
+  var rv = {
+    added: {},
+    removed: {},
+    common: {},
+  };
+
+  for (var i = 0; i < a.length; i++) {
+    if (b.indexOf(a[i]) != -1) {
+      rv.common[a[i]] = true;
+    } else {
+      rv.added[a[i]] = true;
+    }
+  }
+
+  for (var i = 0; i < b.length; i++) {
+    if ((b[i] in rv.added) || (b[i] in rv.common))
+      continue;
+
+    rv.removed[b[i]] = true;
+  }
+
+  return rv;
+};
+
+/**
+ * Synchronize a list of child PreferenceManagers instances with the current
+ * list stored in prefs.
+ *
+ * This will instantiate any missing managers and read current preference values
+ * from storage.  Any active managers that no longer appear in preferences will
+ * be deleted.
+ *
+ * @param {string} listName The child list to synchronize.
+ * @param {function()} opt_callback Optional function to invoke when the sync
+ *     is complete.
+ */
+lib.PreferenceManager.prototype.syncChildList = function(
+    listName, opt_callback) {
+
+  var pendingChildren = 0;
+  function onChildStorage() {
+    if (--pendingChildren == 0 && opt_callback)
+      opt_callback();
+  }
+
+  // The list of child ids that we *should* have a manager for.
+  var currentIds = this.get(listName);
+
+  // The known managers at the start of the sync.  Any manager still in this
+  // list at the end should be discarded.
+  var oldIds = Object.keys(this.childLists_[listName]);
+
+  var rv = lib.PreferenceManager.diffChildLists(currentIds, oldIds);
+
+  for (var i = 0; i < currentIds.length; i++) {
+    var id = currentIds[i];
+
+    var managerIndex = oldIds.indexOf(id);
+    if (managerIndex >= 0)
+      oldIds.splice(managerIndex, 1);
+
+    if (!this.childLists_[listName][id]) {
+      var childManager = this.childFactories_[listName](this, id);
+      if (!childManager) {
+        console.warn('Unable to restore child: ' + listName + ': ' + id);
+        continue;
+      }
+
+      childManager.trace = this.trace;
+      this.childLists_[listName][id] = childManager;
+      pendingChildren++;
+      childManager.readStorage(onChildStorage);
+    }
+  }
+
+  for (var i = 0; i < oldIds.length; i++) {
+    delete this.childLists_[listName][oldIds[i]];
+  }
+
+  if (!pendingChildren && opt_callback)
+    setTimeout(opt_callback);
+};
+
+/**
+ * Reset a preference to its default state.
+ *
+ * This will dispatch the onChange handler if the preference value actually
+ * changes.
+ *
+ * @param {string} name The preference to reset.
+ */
+lib.PreferenceManager.prototype.reset = function(name) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  this.storage.removeItem(this.prefix + name);
+
+  if (record.currentValue !== this.DEFAULT_VALUE) {
+    record.currentValue = this.DEFAULT_VALUE;
+    this.notifyChange_(name);
+  }
+};
+
+/**
+ * Reset all preferences back to their default state.
+ */
+lib.PreferenceManager.prototype.resetAll = function() {
+  var changed = [];
+
+  for (var listName in this.childLists_) {
+    var childList = this.childLists_[listName];
+    for (var id in childList) {
+      childList[id].resetAll();
+    }
+  }
+
+  for (var name in this.prefRecords_) {
+    if (this.prefRecords_[name].currentValue !== this.DEFAULT_VALUE) {
+      this.prefRecords_[name].currentValue = this.DEFAULT_VALUE;
+      changed.push(name);
+    }
+  }
+
+  var keys = Object.keys(this.prefRecords_).map(function(el) {
+      return this.prefix + el;
+  }.bind(this));
+
+  this.storage.removeItems(keys);
+
+  changed.forEach(this.notifyChange_.bind(this));
+};
+
+/**
+ * Return true if two values should be considered not-equal.
+ *
+ * If both values are the same scalar type and compare equal this function
+ * returns false (no difference), otherwise return true.
+ *
+ * This is used in places where we want to check if a preference has changed.
+ * Rather than take the time to compare complex values we just consider them
+ * to always be different.
+ *
+ * @param {*} a A value to compare.
+ * @param {*} b A value to compare.
+ */
+lib.PreferenceManager.prototype.diff = function(a, b) {
+  // If the types are different.
+  if ((typeof a) !== (typeof b)) {
+    return true;
+  }
+
+  // Or if the type is not a simple primitive one.
+  if (!(/^(undefined|boolean|number|string)$/.test(typeof a))) {
+    // Special case the null object.
+    if (a === null && b === null) {
+      return false;
+    } else {
+      return true;
+    }
+  }
+
+  // Do a normal compare for primitive types.
+  return a !== b;
+};
+
+/**
+ * Change the default value of a preference.
+ *
+ * This is useful when subclassing preference managers.
+ *
+ * The function does not alter the current value of the preference, unless
+ * it has the old default value.  When that happens, the change observers
+ * will be notified.
+ *
+ * @param {string} name The name of the parameter to change.
+ * @param {*} newValue The new default value for the preference.
+ */
+lib.PreferenceManager.prototype.changeDefault = function(name, newValue) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  if (!this.diff(record.defaultValue, newValue)) {
+    // Default value hasn't changed.
+    return;
+  }
+
+  if (record.currentValue !== this.DEFAULT_VALUE) {
+    // This pref has a specific value, just change the default and we're done.
+    record.defaultValue = newValue;
+    return;
+  }
+
+  record.defaultValue = newValue;
+
+  this.notifyChange_(name);
+};
+
+/**
+ * Change the default value of multiple preferences.
+ *
+ * @param {Object} map A map of name -> value pairs specifying the new default
+ *     values.
+ */
+lib.PreferenceManager.prototype.changeDefaults = function(map) {
+  for (var key in map) {
+    this.changeDefault(key, map[key]);
+  }
+};
+
+/**
+ * Set a preference to a specific value.
+ *
+ * This will dispatch the onChange handler if the preference value actually
+ * changes.
+ *
+ * @param {string} name The preference to set.
+ * @param {*} newValue The value to set.  Anything that can be represented in
+ *     JSON is a valid value.
+ * @param {function()=} onComplete Callback when the set call completes.
+ * @param {boolean=} saveToStorage Whether to commit the change to the backing
+ *     storage or only the in-memory record copy.
+ */
+lib.PreferenceManager.prototype.set = function(
+    name, newValue, onComplete=undefined, saveToStorage=true) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  var oldValue = record.get();
+
+  if (!this.diff(oldValue, newValue))
+    return;
+
+  if (this.diff(record.defaultValue, newValue)) {
+    record.currentValue = newValue;
+    if (saveToStorage)
+      this.storage.setItem(this.prefix + name, newValue, onComplete);
+  } else {
+    record.currentValue = this.DEFAULT_VALUE;
+    if (saveToStorage)
+      this.storage.removeItem(this.prefix + name, onComplete);
+  }
+
+  // We need to manually send out the notification on this instance.  If we
+  // The storage event won't fire a notification because we've already changed
+  // the currentValue, so it won't see a difference.  If we delayed changing
+  // currentValue until the storage event, a pref read immediately after a write
+  // would return the previous value.
+  //
+  // The notification is in a timeout so clients don't accidentally depend on
+  // a synchronous notification.
+  setTimeout(this.notifyChange_.bind(this, name), 0);
+};
+
+/**
+ * Get the value of a preference.
+ *
+ * @param {string} key The preference to get.
+ */
+lib.PreferenceManager.prototype.get = function(name) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  return record.get();
+};
+
+/**
+ * Return all non-default preferences as a JSON object.
+ *
+ * This includes any nested preference managers as well.
+ */
+lib.PreferenceManager.prototype.exportAsJson = function() {
+  var rv = {};
+
+  for (var name in this.prefRecords_) {
+    if (name in this.childLists_) {
+      rv[name] = [];
+      var childIds = this.get(name);
+      for (var i = 0; i < childIds.length; i++) {
+        var id = childIds[i];
+        rv[name].push({id: id, json: this.getChild(name, id).exportAsJson()});
+      }
+
+    } else {
+      var record = this.prefRecords_[name];
+      if (record.currentValue != this.DEFAULT_VALUE)
+        rv[name] = record.currentValue;
+    }
+  }
+
+  return rv;
+};
+
+/**
+ * Import a JSON blob of preferences previously generated with exportAsJson.
+ *
+ * This will create nested preference managers as well.
+ */
+lib.PreferenceManager.prototype.importFromJson = function(json, opt_onComplete) {
+  this.isImportingJson_ = true;
+
+  let pendingWrites = 0;
+  const onWriteStorage = () => {
+    if (--pendingWrites < 1) {
+      if (opt_onComplete)
+        opt_onComplete();
+
+      // We've delayed updates to the child arrays, so flush them now.
+      for (let name in json)
+        if (name in this.childLists_)
+          this.set(name, this.get(name));
+
+      this.isImportingJson_ = false;
+    }
+  };
+
+  for (var name in json) {
+    if (name in this.childLists_) {
+      var childList = json[name];
+      for (var i = 0; i < childList.length; i++) {
+        var id = childList[i].id;
+
+        var childPrefManager = this.childLists_[name][id];
+        if (!childPrefManager)
+          childPrefManager = this.createChild(name, null, id);
+
+        childPrefManager.importFromJson(childList[i].json, onWriteStorage);
+        pendingWrites++;
+      }
+
+    } else {
+      // The set is synchronous.
+      this.set(name, json[name]);
+    }
+  }
+
+  // If we didn't update any children, no async work has been queued, so make
+  // the completion callback directly.
+  if (pendingWrites == 0 && opt_onComplete)
+    opt_onComplete();
+};
+
+/**
+ * Called when one of the child list preferences changes.
+ */
+lib.PreferenceManager.prototype.onChildListChange_ = function(listName) {
+  this.syncChildList(listName);
+};
+
+/**
+ * Called when a key in the storage changes.
+ */
+lib.PreferenceManager.prototype.onStorageChange_ = function(map) {
+  for (var key in map) {
+    if (this.prefix) {
+      if (key.lastIndexOf(this.prefix, 0) != 0)
+        continue;
+    }
+
+    var name = key.substr(this.prefix.length);
+
+    if (!(name in this.prefRecords_)) {
+      // Sometimes we'll get notified about prefs that are no longer defined.
+      continue;
+    }
+
+    var record = this.prefRecords_[name];
+
+    var newValue = map[key].newValue;
+    var currentValue = record.currentValue;
+    if (currentValue === record.DEFAULT_VALUE)
+      currentValue = (void 0);
+
+    if (this.diff(currentValue, newValue)) {
+      if (typeof newValue == 'undefined' || newValue === null) {
+        record.currentValue = record.DEFAULT_VALUE;
+      } else {
+        record.currentValue = newValue;
+      }
+
+      this.notifyChange_(name);
+    }
+  }
+};
+// SOURCE FILE: libdot/js/lib_resource.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Storage for canned resources.
+ *
+ * These are usually non-JavaScript things that are collected during a build
+ * step and converted into a series of 'lib.resource.add(...)' calls.  See
+ * the "@resource" directive from libdot/bin/concat for the canonical use
+ * case.
+ *
+ * This is global storage, so you should prefix your resource names to avoid
+ * collisions.
+ */
+lib.resource = {
+  resources_: {}
+};
+
+/**
+ * Add a resource.
+ *
+ * @param {string} name A name for the resource.  You should prefix this to
+ *   avoid collisions with resources from a shared library.
+ * @param {string} type A mime type for the resource, or "raw" if not
+ *   applicable.
+ * @param {*} data The value of the resource.
+ */
+lib.resource.add = function(name, type, data) {
+  lib.resource.resources_[name] = {
+    type: type,
+    name: name,
+    data: data
+  };
+};
+
+/**
+ * Retrieve a resource record.
+ *
+ * The resource data is stored on the "data" property of the returned object.
+ *
+ * @param {string} name The name of the resource to get.
+ * @param {*} opt_defaultValue The optional value to return if the resource is
+ *   not defined.
+ * @return {object} An object with "type", "name", and "data" properties.
+ */
+lib.resource.get = function(name, opt_defaultValue) {
+  if (!(name in lib.resource.resources_)) {
+    if (typeof opt_defaultValue == 'undefined')
+      throw 'Unknown resource: ' + name;
+
+    return opt_defaultValue;
+  }
+
+  return lib.resource.resources_[name];
+};
+
+/**
+ * Retrieve resource data.
+ *
+ * @param {string} name The name of the resource to get.
+ * @param {*} opt_defaultValue The optional value to return if the resource is
+ *   not defined.
+ * @return {*} The resource data.
+ */
+lib.resource.getData = function(name, opt_defaultValue) {
+  if (!(name in lib.resource.resources_)) {
+    if (typeof opt_defaultValue == 'undefined')
+      throw 'Unknown resource: ' + name;
+
+    return opt_defaultValue;
+  }
+
+  return lib.resource.resources_[name].data;
+};
+
+/**
+ * Retrieve resource as a data: url.
+ *
+ * @param {string} name The name of the resource to get.
+ * @param {*} opt_defaultValue The optional value to return if the resource is
+ *   not defined.
+ * @return {*} A data: url encoded version of the resource.
+ */
+lib.resource.getDataUrl = function(name, opt_defaultValue) {
+  var resource = lib.resource.get(name, opt_defaultValue);
+  return 'data:' + resource.type + ',' + resource.data;
+};
+// SOURCE FILE: libdot/js/lib_storage.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Namespace for implementations of persistent, possibly cloud-backed
+ * storage.
+ */
+lib.Storage = new Object();
+// SOURCE FILE: libdot/js/lib_storage_chrome.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * chrome.storage based class with an async interface that is interchangeable
+ * with other lib.Storage.* implementations.
+ */
+lib.Storage.Chrome = function(storage) {
+  this.storage_ = storage;
+  this.observers_ = [];
+
+  chrome.storage.onChanged.addListener(this.onChanged_.bind(this));
+};
+
+/**
+ * Called by the storage implementation when the storage is modified.
+ */
+lib.Storage.Chrome.prototype.onChanged_ = function(changes, areaname) {
+  if (chrome.storage[areaname] != this.storage_)
+    return;
+
+  for (var i = 0; i < this.observers_.length; i++) {
+    this.observers_[i](changes);
+  }
+};
+
+/**
+ * Register a function to observe storage changes.
+ *
+ * @param {function(map)} callback The function to invoke when the storage
+ *     changes.
+ */
+lib.Storage.Chrome.prototype.addObserver = function(callback) {
+  this.observers_.push(callback);
+};
+
+/**
+ * Unregister a change observer.
+ *
+ * @param {function} observer A previously registered callback.
+ */
+lib.Storage.Chrome.prototype.removeObserver = function(callback) {
+  var i = this.observers_.indexOf(callback);
+  if (i != -1)
+    this.observers_.splice(i, 1);
+};
+
+/**
+ * Delete everything in this storage.
+ *
+ * @param {function(map)} callback The function to invoke when the delete
+ *     has completed.
+ */
+lib.Storage.Chrome.prototype.clear = function(opt_callback) {
+  this.storage_.clear();
+
+  if (opt_callback)
+    setTimeout(opt_callback, 0);
+};
+
+/**
+ * Return the current value of a storage item.
+ *
+ * @param {string} key The key to look up.
+ * @param {function(value) callback The function to invoke when the value has
+ *     been retrieved.
+ */
+lib.Storage.Chrome.prototype.getItem = function(key, callback) {
+  this.storage_.get(key, callback);
+};
+/**
+ * Fetch the values of multiple storage items.
+ *
+ * @param {Array} keys The keys to look up.
+ * @param {function(map) callback The function to invoke when the values have
+ *     been retrieved.
+ */
+
+lib.Storage.Chrome.prototype.getItems = function(keys, callback) {
+  this.storage_.get(keys, callback);
+};
+
+/**
+ * Set a value in storage.
+ *
+ * @param {string} key The key for the value to be stored.
+ * @param {*} value The value to be stored.  Anything that can be serialized
+ *     with JSON is acceptable.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     set is complete.  You don't have to wait for the set to complete in order
+ *     to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Chrome.prototype.setItem = function(key, value, opt_callback) {
+  const onComplete = () => {
+    const err = lib.f.lastError();
+    if (err) {
+      // Doesn't seem to be any better way of handling this.
+      // https://crbug.com/764759
+      if (err.indexOf('MAX_WRITE_OPERATIONS')) {
+        console.warn(`Will retry save of ${key} after exceeding quota: ${err}`);
+        setTimeout(() => this.setItem(key, value, onComplete), 1000);
+        return;
+      } else {
+        console.error(`Unknown runtime error: ${err}`);
+      }
+    }
+
+    if (opt_callback)
+      opt_callback();
+  };
+
+  var obj = {};
+  obj[key] = value;
+  this.storage_.set(obj, onComplete);
+};
+
+/**
+ * Set multiple values in storage.
+ *
+ * @param {Object} map A map of key/values to set in storage.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     set is complete.  You don't have to wait for the set to complete in order
+ *     to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Chrome.prototype.setItems = function(obj, opt_callback) {
+  this.storage_.set(obj, opt_callback);
+};
+
+/**
+ * Remove an item from storage.
+ *
+ * @param {string} key The key to be removed.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     remove is complete.  You don't have to wait for the set to complete in
+ *     order to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Chrome.prototype.removeItem = function(key, opt_callback) {
+  this.storage_.remove(key, opt_callback);
+};
+
+/**
+ * Remove multiple items from storage.
+ *
+ * @param {Array} keys The keys to be removed.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     remove is complete.  You don't have to wait for the set to complete in
+ *     order to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Chrome.prototype.removeItems = function(keys, opt_callback) {
+  this.storage_.remove(keys, opt_callback);
+};
+// SOURCE FILE: libdot/js/lib_storage_local.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * window.localStorage based class with an async interface that is
+ * interchangeable with other lib.Storage.* implementations.
+ */
+lib.Storage.Local = function() {
+  this.observers_ = [];
+  this.storage_ = window.localStorage;
+  window.addEventListener('storage', this.onStorage_.bind(this));
+};
+
+/**
+ * Called by the storage implementation when the storage is modified.
+ */
+lib.Storage.Local.prototype.onStorage_ = function(e) {
+  if (e.storageArea != this.storage_)
+    return;
+
+  // JS throws an exception if JSON.parse is given an empty string. So here we
+  // only parse if the value is truthy. This mean the empty string, undefined
+  // and null will not be parsed.
+  var prevValue = e.oldValue ? JSON.parse(e.oldValue) : e.oldValue;
+  var curValue = e.newValue ? JSON.parse(e.newValue) : e.newValue;
+  var o = {};
+  o[e.key] = {
+    oldValue: prevValue,
+    newValue: curValue
+  };
+
+  for (var i = 0; i < this.observers_.length; i++) {
+    this.observers_[i](o);
+  }
+};
+
+/**
+ * Register a function to observe storage changes.
+ *
+ * @param {function(map)} callback The function to invoke when the storage
+ *     changes.
+ */
+lib.Storage.Local.prototype.addObserver = function(callback) {
+  this.observers_.push(callback);
+};
+
+/**
+ * Unregister a change observer.
+ *
+ * @param {function} observer A previously registered callback.
+ */
+lib.Storage.Local.prototype.removeObserver = function(callback) {
+  var i = this.observers_.indexOf(callback);
+  if (i != -1)
+    this.observers_.splice(i, 1);
+};
+
+/**
+ * Delete everything in this storage.
+ *
+ * @param {function(map)} callback The function to invoke when the delete
+ *     has completed.
+ */
+lib.Storage.Local.prototype.clear = function(opt_callback) {
+  this.storage_.clear();
+
+  if (opt_callback)
+    setTimeout(opt_callback, 0);
+};
+
+/**
+ * Return the current value of a storage item.
+ *
+ * @param {string} key The key to look up.
+ * @param {function(value) callback The function to invoke when the value has
+ *     been retrieved.
+ */
+lib.Storage.Local.prototype.getItem = function(key, callback) {
+  var value = this.storage_.getItem(key);
+
+  if (typeof value == 'string') {
+    try {
+      value = JSON.parse(value);
+    } catch (e) {
+      // If we can't parse the value, just return it unparsed.
+    }
+  }
+
+  setTimeout(callback.bind(null, value), 0);
+};
+
+/**
+ * Fetch the values of multiple storage items.
+ *
+ * @param {Array} keys The keys to look up.
+ * @param {function(map) callback The function to invoke when the values have
+ *     been retrieved.
+ */
+lib.Storage.Local.prototype.getItems = function(keys, callback) {
+  var rv = {};
+
+  for (var i = keys.length - 1; i >= 0; i--) {
+    var key = keys[i];
+    var value = this.storage_.getItem(key);
+    if (typeof value == 'string') {
+      try {
+        rv[key] = JSON.parse(value);
+      } catch (e) {
+        // If we can't parse the value, just return it unparsed.
+        rv[key] = value;
+      }
+    } else {
+      keys.splice(i, 1);
+    }
+  }
+
+  setTimeout(callback.bind(null, rv), 0);
+};
+
+/**
+ * Set a value in storage.
+ *
+ * @param {string} key The key for the value to be stored.
+ * @param {*} value The value to be stored.  Anything that can be serialized
+ *     with JSON is acceptable.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     set is complete.  You don't have to wait for the set to complete in order
+ *     to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Local.prototype.setItem = function(key, value, opt_callback) {
+  this.storage_.setItem(key, JSON.stringify(value));
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+
+/**
+ * Set multiple values in storage.
+ *
+ * @param {Object} map A map of key/values to set in storage.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     set is complete.  You don't have to wait for the set to complete in order
+ *     to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Local.prototype.setItems = function(obj, opt_callback) {
+  for (var key in obj) {
+    this.storage_.setItem(key, JSON.stringify(obj[key]));
+  }
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+
+/**
+ * Remove an item from storage.
+ *
+ * @param {string} key The key to be removed.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     remove is complete.  You don't have to wait for the set to complete in
+ *     order to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Local.prototype.removeItem = function(key, opt_callback) {
+  this.storage_.removeItem(key);
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+
+/**
+ * Remove multiple items from storage.
+ *
+ * @param {Array} keys The keys to be removed.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     remove is complete.  You don't have to wait for the set to complete in
+ *     order to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Local.prototype.removeItems = function(ary, opt_callback) {
+  for (var i = 0; i < ary.length; i++) {
+    this.storage_.removeItem(ary[i]);
+  }
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+// SOURCE FILE: libdot/js/lib_storage_memory.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * In-memory storage class with an async interface that is interchangeable with
+ * other lib.Storage.* implementations.
+ */
+lib.Storage.Memory = function() {
+  this.observers_ = [];
+  this.storage_ = {};
+};
+
+/**
+ * Register a function to observe storage changes.
+ *
+ * @param {function(map)} callback The function to invoke when the storage
+ *     changes.
+ */
+lib.Storage.Memory.prototype.addObserver = function(callback) {
+  this.observers_.push(callback);
+};
+
+/**
+ * Unregister a change observer.
+ *
+ * @param {function} observer A previously registered callback.
+ */
+lib.Storage.Memory.prototype.removeObserver = function(callback) {
+  var i = this.observers_.indexOf(callback);
+  if (i != -1)
+    this.observers_.splice(i, 1);
+};
+
+/**
+ * Delete everything in this storage.
+ *
+ * @param {function(map)} callback The function to invoke when the delete
+ *     has completed.
+ */
+lib.Storage.Memory.prototype.clear = function(opt_callback) {
+  var e = {};
+  for (var key in this.storage_) {
+    e[key] = {oldValue: this.storage_[key], newValue: (void 0)};
+  }
+
+  this.storage_ = {};
+
+  setTimeout(function() {
+    for (var i = 0; i < this.observers_.length; i++) {
+      this.observers_[i](e);
+    }
+  }.bind(this), 0);
+
+  if (opt_callback)
+    setTimeout(opt_callback, 0);
+};
+
+/**
+ * Return the current value of a storage item.
+ *
+ * @param {string} key The key to look up.
+ * @param {function(value) callback The function to invoke when the value has
+ *     been retrieved.
+ */
+lib.Storage.Memory.prototype.getItem = function(key, callback) {
+  var value = this.storage_[key];
+
+  if (typeof value == 'string') {
+    try {
+      value = JSON.parse(value);
+    } catch (e) {
+      // If we can't parse the value, just return it unparsed.
+    }
+  }
+
+  setTimeout(callback.bind(null, value), 0);
+};
+
+/**
+ * Fetch the values of multiple storage items.
+ *
+ * @param {Array} keys The keys to look up.
+ * @param {function(map) callback The function to invoke when the values have
+ *     been retrieved.
+ */
+lib.Storage.Memory.prototype.getItems = function(keys, callback) {
+  var rv = {};
+
+  for (var i = keys.length - 1; i >= 0; i--) {
+    var key = keys[i];
+    var value = this.storage_[key];
+    if (typeof value == 'string') {
+      try {
+        rv[key] = JSON.parse(value);
+      } catch (e) {
+        // If we can't parse the value, just return it unparsed.
+        rv[key] = value;
+      }
+    } else {
+      keys.splice(i, 1);
+    }
+  }
+
+  setTimeout(callback.bind(null, rv), 0);
+};
+
+/**
+ * Set a value in storage.
+ *
+ * @param {string} key The key for the value to be stored.
+ * @param {*} value The value to be stored.  Anything that can be serialized
+ *     with JSON is acceptable.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     set is complete.  You don't have to wait for the set to complete in order
+ *     to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Memory.prototype.setItem = function(key, value, opt_callback) {
+  var oldValue = this.storage_[key];
+  this.storage_[key] = JSON.stringify(value);
+
+  var e = {};
+  e[key] = {oldValue: oldValue, newValue: value};
+
+  setTimeout(function() {
+    for (var i = 0; i < this.observers_.length; i++) {
+      this.observers_[i](e);
+    }
+  }.bind(this), 0);
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+
+/**
+ * Set multiple values in storage.
+ *
+ * @param {Object} map A map of key/values to set in storage.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     set is complete.  You don't have to wait for the set to complete in order
+ *     to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Memory.prototype.setItems = function(obj, opt_callback) {
+  var e = {};
+
+  for (var key in obj) {
+    e[key] = {oldValue: this.storage_[key], newValue: obj[key]};
+    this.storage_[key] = JSON.stringify(obj[key]);
+  }
+
+  setTimeout(function() {
+    for (var i = 0; i < this.observers_.length; i++) {
+      this.observers_[i](e);
+    }
+  }.bind(this));
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+
+/**
+ * Remove an item from storage.
+ *
+ * @param {string} key The key to be removed.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     remove is complete.  You don't have to wait for the set to complete in
+ *     order to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Memory.prototype.removeItem = function(key, opt_callback) {
+  delete this.storage_[key];
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+
+/**
+ * Remove multiple items from storage.
+ *
+ * @param {Array} keys The keys to be removed.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     remove is complete.  You don't have to wait for the set to complete in
+ *     order to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Memory.prototype.removeItems = function(ary, opt_callback) {
+  for (var i = 0; i < ary.length; i++) {
+    delete this.storage_[ary[i]];
+  }
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+// SOURCE FILE: libdot/third_party/fast-text-encoding/text.js
+/*
+ * Copyright 2017 Sam Thorogood. All rights reserved.
+ *
+ * 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
+ *
+ *     https://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.
+ */
+
+/**
+ * @fileoverview Polyfill for TextEncoder and TextDecoder.
+ *
+ * You probably want `text.min.js`, and not this file directly.
+ */
+
+(function(scope) {
+'use strict';
+
+// fail early
+if (scope['TextEncoder'] && scope['TextDecoder']) {
+  return false;
+}
+
+/**
+ * @constructor
+ * @param {string=} utfLabel
+ */
+function FastTextEncoder(utfLabel='utf-8') {
+  if (utfLabel !== 'utf-8') {
+    throw new RangeError(
+      `Failed to construct 'TextEncoder': The encoding label provided ('${utfLabel}') is invalid.`);
+  }
+}
+
+Object.defineProperty(FastTextEncoder.prototype, 'encoding', {value: 'utf-8'});
+
+/**
+ * @param {string} string
+ * @param {{stream: boolean}=} options
+ * @return {!Uint8Array}
+ */
+FastTextEncoder.prototype.encode = function(string, options={stream: false}) {
+  if (options.stream) {
+    throw new Error(`Failed to encode: the 'stream' option is unsupported.`);
+  }
+
+  let pos = 0;
+  const len = string.length;
+  const out = [];
+
+  let at = 0;  // output position
+  let tlen = Math.max(32, len + (len >> 1) + 7);  // 1.5x size
+  let target = new Uint8Array((tlen >> 3) << 3);  // ... but at 8 byte offset
+
+  while (pos < len) {
+    let value = string.charCodeAt(pos++);
+    if (value >= 0xd800 && value <= 0xdbff) {
+      // high surrogate
+      if (pos < len) {
+        const extra = string.charCodeAt(pos);
+        if ((extra & 0xfc00) === 0xdc00) {
+          ++pos;
+          value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
+        }
+      }
+      if (value >= 0xd800 && value <= 0xdbff) {
+        continue;  // drop lone surrogate
+      }
+    }
+
+    // expand the buffer if we couldn't write 4 bytes
+    if (at + 4 > target.length) {
+      tlen += 8;  // minimum extra
+      tlen *= (1.0 + (pos / string.length) * 2);  // take 2x the remaining
+      tlen = (tlen >> 3) << 3;  // 8 byte offset
+
+      const update = new Uint8Array(tlen);
+      update.set(target);
+      target = update;
+    }
+
+    if ((value & 0xffffff80) === 0) {  // 1-byte
+      target[at++] = value;  // ASCII
+      continue;
+    } else if ((value & 0xfffff800) === 0) {  // 2-byte
+      target[at++] = ((value >>  6) & 0x1f) | 0xc0;
+    } else if ((value & 0xffff0000) === 0) {  // 3-byte
+      target[at++] = ((value >> 12) & 0x0f) | 0xe0;
+      target[at++] = ((value >>  6) & 0x3f) | 0x80;
+    } else if ((value & 0xffe00000) === 0) {  // 4-byte
+      target[at++] = ((value >> 18) & 0x07) | 0xf0;
+      target[at++] = ((value >> 12) & 0x3f) | 0x80;
+      target[at++] = ((value >>  6) & 0x3f) | 0x80;
+    } else {
+      // FIXME: do we care
+      continue;
+    }
+
+    target[at++] = (value & 0x3f) | 0x80;
+  }
+
+  return target.slice(0, at);
+}
+
+/**
+ * @constructor
+ * @param {string=} utfLabel
+ * @param {{fatal: boolean}=} options
+ */
+function FastTextDecoder(utfLabel='utf-8', options={fatal: false}) {
+  if (utfLabel !== 'utf-8') {
+    throw new RangeError(
+      `Failed to construct 'TextDecoder': The encoding label provided ('${utfLabel}') is invalid.`);
+  }
+  if (options.fatal) {
+    throw new Error(`Failed to construct 'TextDecoder': the 'fatal' option is unsupported.`);
+  }
+}
+
+Object.defineProperty(FastTextDecoder.prototype, 'encoding', {value: 'utf-8'});
+
+Object.defineProperty(FastTextDecoder.prototype, 'fatal', {value: false});
+
+Object.defineProperty(FastTextDecoder.prototype, 'ignoreBOM', {value: false});
+
+/**
+ * @param {(!ArrayBuffer|!ArrayBufferView)} buffer
+ * @param {{stream: boolean}=} options
+ */
+FastTextDecoder.prototype.decode = function(buffer, options={stream: false}) {
+  if (options['stream']) {
+    throw new Error(`Failed to decode: the 'stream' option is unsupported.`);
+  }
+
+  const bytes = new Uint8Array(buffer);
+  let pos = 0;
+  const len = bytes.length;
+  const out = [];
+
+  while (pos < len) {
+    const byte1 = bytes[pos++];
+    if (byte1 === 0) {
+      break;  // NULL
+    }
+
+    if ((byte1 & 0x80) === 0) {  // 1-byte
+      out.push(byte1);
+    } else if ((byte1 & 0xe0) === 0xc0) {  // 2-byte
+      const byte2 = bytes[pos++] & 0x3f;
+      out.push(((byte1 & 0x1f) << 6) | byte2);
+    } else if ((byte1 & 0xf0) === 0xe0) {
+      const byte2 = bytes[pos++] & 0x3f;
+      const byte3 = bytes[pos++] & 0x3f;
+      out.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);
+    } else if ((byte1 & 0xf8) === 0xf0) {
+      const byte2 = bytes[pos++] & 0x3f;
+      const byte3 = bytes[pos++] & 0x3f;
+      const byte4 = bytes[pos++] & 0x3f;
+
+      // this can be > 0xffff, so possibly generate surrogates
+      let codepoint = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
+      if (codepoint > 0xffff) {
+        // codepoint &= ~0x10000;
+        codepoint -= 0x10000;
+        out.push((codepoint >>> 10) & 0x3ff | 0xd800)
+        codepoint = 0xdc00 | codepoint & 0x3ff;
+      }
+      out.push(codepoint);
+    } else {
+      // FIXME: we're ignoring this
+    }
+  }
+
+  return String.fromCharCode.apply(null, out);
+}
+
+scope['TextEncoder'] = FastTextEncoder;
+scope['TextDecoder'] = FastTextDecoder;
+
+}(typeof window !== 'undefined' ? window : (typeof global !== 'undefined' ? global : this)));
+// SOURCE FILE: libdot/third_party/intl-segmenter/intl-segmenter.js
+// Rough polyfill for Intl.Segmenter proposal
+//
+// https://github.com/tc39/proposal-intl-segmenter/blob/master/README.md
+//
+// Caveats and Limitations
+//  * granularity: 'line': 'strictness' option is not supported (ignored)
+//  * In Chrome, uses v8BreakIterator
+//  * Otherwise, uses very simplistic rules
+//    * Ignores locale; only "usable" on English
+//    * granularity: 'grapheme' does not understand combining characters
+//    * granularity: 'sentence' does not understand decimals
+
+(function(global) {
+  if ('Intl' in global && 'Segmenter' in global.Intl)
+    return;
+
+  global.Intl = global.Intl || {};
+
+  const GRANULARITIES = ['grapheme', 'word','sentence', 'line'];
+
+  // TODO: Implement https://www.unicode.org/reports/tr29/
+  const RULES = {
+    grapheme: {
+      grapheme: /^(.|\n)/
+    },
+    word: {
+      letter: /^[a-z](?:'?[a-z])*/i,
+      number: /^\d+([,.]\d+)*/
+    },
+    sentence: {
+      terminator: /^[^.?!\r\n]+[.?!]+[\r\n]?/,
+      separator: /^[^.?!\r\n]+[\r\n]?/
+    },
+    line: {
+      hard: /^\S*[\r\n]/,
+      soft: /^\S*\s*/
+    }
+  };
+
+  // Work around bug in v8BreakIterator where ICU's UWordBreak enum is
+  // used even if granularity is not "word". See the code in
+  // Runtime_BreakIteratorBreakType in runtime/runtime-i18n.cc for
+  // details.
+  function fixBreakType(value, granularity) {
+    // Undo the mapping of UWordBreak to string
+    const ruleStatus = {
+      none: 0, // UBRK_WORD_NONE
+      number: 100, // UBRK_WORD_NUMBER
+      letter: 200, // UBRK_WORD_LETTER
+      kana: 300, // UBRK_WORD_KANA
+      ideo: 400, // UBRK_WORD_IDEO
+      unknown: -1
+    }[value] || 0;
+
+
+    switch (granularity) {
+    case 'character':
+      return undefined;
+    case 'word':
+      return value;
+    case 'sentence':
+      // Map ULineBreakTag rule status to string.
+      return {
+        0: 'terminator',
+        100: 'separator'
+      }[ruleStatus] || value;
+    case 'line':
+      // Map ULineBreakTag rule status to string.
+      return {
+        0: 'soft',
+        100: 'hard'
+      }[ruleStatus] || value;
+    default:
+      return value;
+    }
+  }
+
+  function segment(locale, granularity, string) {
+    const breaks = [];
+    if ('v8BreakIterator' in global.Intl) {
+      if (granularity === 'grapheme')
+        granularity = 'character';
+      const vbi = new global.Intl.v8BreakIterator(locale, {type: granularity});
+      vbi.adoptText(string);
+      let last = 0;
+      let pos = vbi.next();
+      while (pos !== -1) {
+        breaks.push({
+          pos: vbi.current(),
+          segment: string.slice(last, pos),
+          breakType: fixBreakType(vbi.breakType(), granularity)
+        });
+        last = pos;
+        pos = vbi.next();
+      }
+    } else {
+      const rules = RULES[granularity];
+      let pos = 0;
+      while (pos < string.length) {
+        let found = false;
+        for (let rule of Object.keys(rules)) {
+          const re = rules[rule];
+          const m = string.slice(pos).match(re);
+          if (m) {
+            pos += m[0].length;
+            breaks.push({
+              pos: pos,
+              segment: m[0],
+              breakType: granularity === 'grapheme' ? undefined : rule
+            });
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          breaks.push({
+            pos: pos + 1,
+            segment: string.slice(pos, ++pos),
+            breakType: 'none'
+          });
+        }
+      }
+    }
+    breaks.initial = 0;
+    return breaks;
+  }
+
+  class $SegmentIterator$ {
+    constructor(string, breaks) {
+      this._cur = -1;
+      this._type = undefined;
+      this._breaks = breaks;
+    }
+
+    [Symbol.iterator]() { return this; }
+
+    next() {
+      if (this._cur < this._breaks.length)
+        ++this._cur;
+
+      if (this._cur >= this._breaks.length) {
+        this._type = undefined;
+        return {done: true, value: undefined};
+      }
+
+      this._type = this._breaks[this._cur].breakType;
+      return {
+        done: false,
+        value: {
+          segment: this._breaks[this._cur].segment,
+          breakType: this._breaks[this._cur].breakType
+        }
+      };
+    }
+
+    following(index = undefined) {
+      if (!this._breaks.length)
+        return true;
+      if (index === undefined) {
+        if (this._cur < this._breaks.length)
+          ++this._cur;
+      } else {
+        // TODO: binary search
+        for (this._cur = 0;
+             this._cur < this._breaks.length
+             && this._breaks[this._cur].pos < index;
+             ++this._cur) {}
+      }
+
+      this._type = this._cur < this._breaks.length
+        ? this._breaks[this._cur].breakType : undefined;
+      return this._cur + 1 >= this._breaks.length;
+    }
+
+    preceding(index = undefined) {
+      if (!this._breaks.length)
+        return true;
+      if (index === undefined) {
+        if (this._cur >= this._breaks.length)
+          --this._cur;
+        if (this._cur >= 0)
+          --this._cur;
+      } else {
+        // TODO: binary search
+        for (this._cur = this._breaks.length - 1;
+             this._cur >= 0
+             && this._breaks[this._cur].pos >= index;
+             --this._cur) {}
+      }
+
+      this._type =
+        this._cur + 1 >= this._breaks.length ? undefined :
+        this._breaks[this._cur + 1].breakType;
+      return this._cur < 0;
+    }
+
+    get position() {
+      if (this._cur < 0 || !this._breaks.length)
+        return this._breaks.initial;
+      if (this._cur >= this._breaks.length)
+        return this._breaks[this._breaks.length - 1].pos;
+      return this._breaks[this._cur].pos;
+    }
+
+    get breakType() {
+      return this._type;
+    }
+  }
+
+  global.Intl.Segmenter = class Segmenter {
+    constructor(locale, options) {
+      this._locale = Array.isArray(locale)
+        ? locale.map(s => String(s)) : String(locale || navigator.language);
+      options = Object.assign({granularity: 'grapheme'}, options);
+      this._granularity = GRANULARITIES.includes(options.granularity)
+        ? options.granularity : 'grapheme';
+    }
+
+    segment(string) {
+      return new $SegmentIterator$(
+        string, segment(this._locale, this._granularity, string));
+    }
+  };
+}(typeof window !== 'undefined' ? window : (typeof global !== 'undefined' ? global : this)));
+// SOURCE FILE: libdot/third_party/wcwidth/lib_wc.js
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of lib.wc source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * This JavaScript library is ported from the wcwidth.js module of node.js.
+ * The original implementation can be found at:
+ * https://npmjs.org/package/wcwidth.js
+ */
+
+/**
+ * JavaScript porting of Markus Kuhn's wcwidth() implementation
+ *
+ * The following explanation comes from the original C implementation:
+ *
+ * This is an implementation of wcwidth() and wcswidth() (defined in
+ * IEEE Std 1002.1-2001) for Unicode.
+ *
+ * https://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
+ * https://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
+ *
+ * In fixed-width output devices, Latin characters all occupy a single
+ * "cell" position of equal width, whereas ideographic CJK characters
+ * occupy two such cells. Interoperability between terminal-line
+ * applications and (teletype-style) character terminals using the
+ * UTF-8 encoding requires agreement on which character should advance
+ * the cursor by how many cell positions. No established formal
+ * standards exist at present on which Unicode character shall occupy
+ * how many cell positions on character terminals. These routines are
+ * a first attempt of defining such behavior based on simple rules
+ * applied to data provided by the Unicode Consortium.
+ *
+ * For some graphical characters, the Unicode standard explicitly
+ * defines a character-cell width via the definition of the East Asian
+ * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
+ * In all these cases, there is no ambiguity about which width a
+ * terminal shall use. For characters in the East Asian Ambiguous (A)
+ * class, the width choice depends purely on a preference of backward
+ * compatibility with either historic CJK or Western practice.
+ * Choosing single-width for these characters is easy to justify as
+ * the appropriate long-term solution, as the CJK practice of
+ * displaying these characters as double-width comes from historic
+ * implementation simplicity (8-bit encoded characters were displayed
+ * single-width and 16-bit ones double-width, even for Greek,
+ * Cyrillic, etc.) and not any typographic considerations.
+ *
+ * Much less clear is the choice of width for the Not East Asian
+ * (Neutral) class. Existing practice does not dictate a width for any
+ * of these characters. It would nevertheless make sense
+ * typographically to allocate two character cells to characters such
+ * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
+ * represented adequately with a single-width glyph. The following
+ * routines at present merely assign a single-cell width to all
+ * neutral characters, in the interest of simplicity. This is not
+ * entirely satisfactory and should be reconsidered before
+ * establishing a formal standard in lib.wc area. At the moment, the
+ * decision which Not East Asian (Neutral) characters should be
+ * represented by double-width glyphs cannot yet be answered by
+ * applying a simple rule from the Unicode database content. Setting
+ * up a proper standard for the behavior of UTF-8 character terminals
+ * will require a careful analysis not only of each Unicode character,
+ * but also of each presentation form, something the author of these
+ * routines has avoided to do so far.
+ *
+ * https://www.unicode.org/unicode/reports/tr11/
+ *
+ * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
+ *
+ * Permission to use, copy, modify, and distribute lib.wc software
+ * for any purpose and without fee is hereby granted. The author
+ * disclaims all warranties with regard to lib.wc software.
+ *
+ * Latest version: https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
+ */
+
+/**
+ * The following function defines the column width of an ISO 10646 character
+ * as follows:
+ *
+ *  - The null character (U+0000) has a column width of 0.
+ *  - Other C0/C1 control characters and DEL will lead to a return value of -1.
+ *  - Non-spacing and enclosing combining characters (general category code Mn
+ *    or Me in the Unicode database) have a column width of 0.
+ *  - SOFT HYPHEN (U+00AD) has a column width of 1.
+ *  - Other format characters (general category code Cf in the Unicode database)
+ *    and ZERO WIDTH SPACE (U+200B) have a column width of 0.
+ *  - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) have a
+ *    column width of 0.
+ *  - Spacing characters in the East Asian Wide (W) or East Asian Full-width (F)
+ *    category as defined in Unicode Technical Report #11 have a column width of
+ *    2.
+ *  - East Asian Ambiguous characters are taken into account if
+ *    regardCjkAmbiguous flag is enabled. They have a column width of 2.
+ *  - All remaining characters (including all printable ISO 8859-1 and WGL4
+ *    characters, Unicode control characters, etc.) have a column width of 1.
+ *
+ * This implementation assumes that characters are encoded in ISO 10646.
+ */
+
+lib.wc = {};
+
+// Width of a nul character.
+lib.wc.nulWidth = 0;
+
+// Width of a control character.
+lib.wc.controlWidth = 0;
+
+// Flag whether to consider East Asian Ambiguous characters.
+lib.wc.regardCjkAmbiguous = false;
+
+// Width of an East Asian Ambiguous character.
+lib.wc.cjkAmbiguousWidth = 2;
+
+// Sorted list of non-overlapping intervals of non-spacing characters
+// generated by the `./ranges.py` helper.
+lib.wc.combining = [
+    [0x00ad, 0x00ad], [0x0300, 0x036f], [0x0483, 0x0489],
+    [0x0591, 0x05bd], [0x05bf, 0x05bf], [0x05c1, 0x05c2],
+    [0x05c4, 0x05c5], [0x05c7, 0x05c7], [0x0610, 0x061a],
+    [0x061c, 0x061c], [0x064b, 0x065f], [0x0670, 0x0670],
+    [0x06d6, 0x06dc], [0x06df, 0x06e4], [0x06e7, 0x06e8],
+    [0x06ea, 0x06ed], [0x0711, 0x0711], [0x0730, 0x074a],
+    [0x07a6, 0x07b0], [0x07eb, 0x07f3], [0x07fd, 0x07fd],
+    [0x0816, 0x0819], [0x081b, 0x0823], [0x0825, 0x0827],
+    [0x0829, 0x082d], [0x0859, 0x085b], [0x08d3, 0x08e1],
+    [0x08e3, 0x0902], [0x093a, 0x093a], [0x093c, 0x093c],
+    [0x0941, 0x0948], [0x094d, 0x094d], [0x0951, 0x0957],
+    [0x0962, 0x0963], [0x0981, 0x0981], [0x09bc, 0x09bc],
+    [0x09c1, 0x09c4], [0x09cd, 0x09cd], [0x09e2, 0x09e3],
+    [0x09fe, 0x09fe], [0x0a01, 0x0a02], [0x0a3c, 0x0a3c],
+    [0x0a41, 0x0a42], [0x0a47, 0x0a48], [0x0a4b, 0x0a4d],
+    [0x0a51, 0x0a51], [0x0a70, 0x0a71], [0x0a75, 0x0a75],
+    [0x0a81, 0x0a82], [0x0abc, 0x0abc], [0x0ac1, 0x0ac5],
+    [0x0ac7, 0x0ac8], [0x0acd, 0x0acd], [0x0ae2, 0x0ae3],
+    [0x0afa, 0x0aff], [0x0b01, 0x0b01], [0x0b3c, 0x0b3c],
+    [0x0b3f, 0x0b3f], [0x0b41, 0x0b44], [0x0b4d, 0x0b4d],
+    [0x0b56, 0x0b56], [0x0b62, 0x0b63], [0x0b82, 0x0b82],
+    [0x0bc0, 0x0bc0], [0x0bcd, 0x0bcd], [0x0c00, 0x0c00],
+    [0x0c04, 0x0c04], [0x0c3e, 0x0c40], [0x0c46, 0x0c48],
+    [0x0c4a, 0x0c4d], [0x0c55, 0x0c56], [0x0c62, 0x0c63],
+    [0x0c81, 0x0c81], [0x0cbc, 0x0cbc], [0x0cbf, 0x0cbf],
+    [0x0cc6, 0x0cc6], [0x0ccc, 0x0ccd], [0x0ce2, 0x0ce3],
+    [0x0d00, 0x0d01], [0x0d3b, 0x0d3c], [0x0d41, 0x0d44],
+    [0x0d4d, 0x0d4d], [0x0d62, 0x0d63], [0x0dca, 0x0dca],
+    [0x0dd2, 0x0dd4], [0x0dd6, 0x0dd6], [0x0e31, 0x0e31],
+    [0x0e34, 0x0e3a], [0x0e47, 0x0e4e], [0x0eb1, 0x0eb1],
+    [0x0eb4, 0x0ebc], [0x0ec8, 0x0ecd], [0x0f18, 0x0f19],
+    [0x0f35, 0x0f35], [0x0f37, 0x0f37], [0x0f39, 0x0f39],
+    [0x0f71, 0x0f7e], [0x0f80, 0x0f84], [0x0f86, 0x0f87],
+    [0x0f8d, 0x0f97], [0x0f99, 0x0fbc], [0x0fc6, 0x0fc6],
+    [0x102d, 0x1030], [0x1032, 0x1037], [0x1039, 0x103a],
+    [0x103d, 0x103e], [0x1058, 0x1059], [0x105e, 0x1060],
+    [0x1071, 0x1074], [0x1082, 0x1082], [0x1085, 0x1086],
+    [0x108d, 0x108d], [0x109d, 0x109d], [0x1160, 0x11ff],
+    [0x135d, 0x135f], [0x1712, 0x1714], [0x1732, 0x1734],
+    [0x1752, 0x1753], [0x1772, 0x1773], [0x17b4, 0x17b5],
+    [0x17b7, 0x17bd], [0x17c6, 0x17c6], [0x17c9, 0x17d3],
+    [0x17dd, 0x17dd], [0x180b, 0x180e], [0x1885, 0x1886],
+    [0x18a9, 0x18a9], [0x1920, 0x1922], [0x1927, 0x1928],
+    [0x1932, 0x1932], [0x1939, 0x193b], [0x1a17, 0x1a18],
+    [0x1a1b, 0x1a1b], [0x1a56, 0x1a56], [0x1a58, 0x1a5e],
+    [0x1a60, 0x1a60], [0x1a62, 0x1a62], [0x1a65, 0x1a6c],
+    [0x1a73, 0x1a7c], [0x1a7f, 0x1a7f], [0x1ab0, 0x1abe],
+    [0x1b00, 0x1b03], [0x1b34, 0x1b34], [0x1b36, 0x1b3a],
+    [0x1b3c, 0x1b3c], [0x1b42, 0x1b42], [0x1b6b, 0x1b73],
+    [0x1b80, 0x1b81], [0x1ba2, 0x1ba5], [0x1ba8, 0x1ba9],
+    [0x1bab, 0x1bad], [0x1be6, 0x1be6], [0x1be8, 0x1be9],
+    [0x1bed, 0x1bed], [0x1bef, 0x1bf1], [0x1c2c, 0x1c33],
+    [0x1c36, 0x1c37], [0x1cd0, 0x1cd2], [0x1cd4, 0x1ce0],
+    [0x1ce2, 0x1ce8], [0x1ced, 0x1ced], [0x1cf4, 0x1cf4],
+    [0x1cf8, 0x1cf9], [0x1dc0, 0x1df9], [0x1dfb, 0x1dff],
+    [0x200b, 0x200f], [0x202a, 0x202e], [0x2060, 0x2064],
+    [0x2066, 0x206f], [0x20d0, 0x20f0], [0x2cef, 0x2cf1],
+    [0x2d7f, 0x2d7f], [0x2de0, 0x2dff], [0x302a, 0x302d],
+    [0x3099, 0x309a], [0xa66f, 0xa672], [0xa674, 0xa67d],
+    [0xa69e, 0xa69f], [0xa6f0, 0xa6f1], [0xa802, 0xa802],
+    [0xa806, 0xa806], [0xa80b, 0xa80b], [0xa825, 0xa826],
+    [0xa8c4, 0xa8c5], [0xa8e0, 0xa8f1], [0xa8ff, 0xa8ff],
+    [0xa926, 0xa92d], [0xa947, 0xa951], [0xa980, 0xa982],
+    [0xa9b3, 0xa9b3], [0xa9b6, 0xa9b9], [0xa9bc, 0xa9bd],
+    [0xa9e5, 0xa9e5], [0xaa29, 0xaa2e], [0xaa31, 0xaa32],
+    [0xaa35, 0xaa36], [0xaa43, 0xaa43], [0xaa4c, 0xaa4c],
+    [0xaa7c, 0xaa7c], [0xaab0, 0xaab0], [0xaab2, 0xaab4],
+    [0xaab7, 0xaab8], [0xaabe, 0xaabf], [0xaac1, 0xaac1],
+    [0xaaec, 0xaaed], [0xaaf6, 0xaaf6], [0xabe5, 0xabe5],
+    [0xabe8, 0xabe8], [0xabed, 0xabed], [0xfb1e, 0xfb1e],
+    [0xfe00, 0xfe0f], [0xfe20, 0xfe2f], [0xfeff, 0xfeff],
+    [0xfff9, 0xfffb], [0x101fd, 0x101fd], [0x102e0, 0x102e0],
+    [0x10376, 0x1037a], [0x10a01, 0x10a03], [0x10a05, 0x10a06],
+    [0x10a0c, 0x10a0f], [0x10a38, 0x10a3a], [0x10a3f, 0x10a3f],
+    [0x10ae5, 0x10ae6], [0x10d24, 0x10d27], [0x10f46, 0x10f50],
+    [0x11001, 0x11001], [0x11038, 0x11046], [0x1107f, 0x11081],
+    [0x110b3, 0x110b6], [0x110b9, 0x110ba], [0x11100, 0x11102],
+    [0x11127, 0x1112b], [0x1112d, 0x11134], [0x11173, 0x11173],
+    [0x11180, 0x11181], [0x111b6, 0x111be], [0x111c9, 0x111cc],
+    [0x1122f, 0x11231], [0x11234, 0x11234], [0x11236, 0x11237],
+    [0x1123e, 0x1123e], [0x112df, 0x112df], [0x112e3, 0x112ea],
+    [0x11300, 0x11301], [0x1133b, 0x1133c], [0x11340, 0x11340],
+    [0x11366, 0x1136c], [0x11370, 0x11374], [0x11438, 0x1143f],
+    [0x11442, 0x11444], [0x11446, 0x11446], [0x1145e, 0x1145e],
+    [0x114b3, 0x114b8], [0x114ba, 0x114ba], [0x114bf, 0x114c0],
+    [0x114c2, 0x114c3], [0x115b2, 0x115b5], [0x115bc, 0x115bd],
+    [0x115bf, 0x115c0], [0x115dc, 0x115dd], [0x11633, 0x1163a],
+    [0x1163d, 0x1163d], [0x1163f, 0x11640], [0x116ab, 0x116ab],
+    [0x116ad, 0x116ad], [0x116b0, 0x116b5], [0x116b7, 0x116b7],
+    [0x1171d, 0x1171f], [0x11722, 0x11725], [0x11727, 0x1172b],
+    [0x1182f, 0x11837], [0x11839, 0x1183a], [0x119d4, 0x119d7],
+    [0x119da, 0x119db], [0x119e0, 0x119e0], [0x11a01, 0x11a0a],
+    [0x11a33, 0x11a38], [0x11a3b, 0x11a3e], [0x11a47, 0x11a47],
+    [0x11a51, 0x11a56], [0x11a59, 0x11a5b], [0x11a8a, 0x11a96],
+    [0x11a98, 0x11a99], [0x11c30, 0x11c36], [0x11c38, 0x11c3d],
+    [0x11c3f, 0x11c3f], [0x11c92, 0x11ca7], [0x11caa, 0x11cb0],
+    [0x11cb2, 0x11cb3], [0x11cb5, 0x11cb6], [0x11d31, 0x11d36],
+    [0x11d3a, 0x11d3a], [0x11d3c, 0x11d3d], [0x11d3f, 0x11d45],
+    [0x11d47, 0x11d47], [0x11d90, 0x11d91], [0x11d95, 0x11d95],
+    [0x11d97, 0x11d97], [0x11ef3, 0x11ef4], [0x13430, 0x13438],
+    [0x16af0, 0x16af4], [0x16b30, 0x16b36], [0x16f4f, 0x16f4f],
+    [0x16f8f, 0x16f92], [0x1bc9d, 0x1bc9e], [0x1bca0, 0x1bca3],
+    [0x1d167, 0x1d169], [0x1d173, 0x1d182], [0x1d185, 0x1d18b],
+    [0x1d1aa, 0x1d1ad], [0x1d242, 0x1d244], [0x1da00, 0x1da36],
+    [0x1da3b, 0x1da6c], [0x1da75, 0x1da75], [0x1da84, 0x1da84],
+    [0x1da9b, 0x1da9f], [0x1daa1, 0x1daaf], [0x1e000, 0x1e006],
+    [0x1e008, 0x1e018], [0x1e01b, 0x1e021], [0x1e023, 0x1e024],
+    [0x1e026, 0x1e02a], [0x1e130, 0x1e136], [0x1e2ec, 0x1e2ef],
+    [0x1e8d0, 0x1e8d6], [0x1e944, 0x1e94a], [0xe0001, 0xe0001],
+    [0xe0020, 0xe007f], [0xe0100, 0xe01ef],
+];
+
+// Sorted list of non-overlapping intervals of East Asian Ambiguous characters
+// generated by the `./ranges.py` helper.
+lib.wc.ambiguous = [
+    [0x00a1, 0x00a1], [0x00a4, 0x00a4], [0x00a7, 0x00a8],
+    [0x00aa, 0x00aa], [0x00ad, 0x00ae], [0x00b0, 0x00b4],
+    [0x00b6, 0x00ba], [0x00bc, 0x00bf], [0x00c6, 0x00c6],
+    [0x00d0, 0x00d0], [0x00d7, 0x00d8], [0x00de, 0x00e1],
+    [0x00e6, 0x00e6], [0x00e8, 0x00ea], [0x00ec, 0x00ed],
+    [0x00f0, 0x00f0], [0x00f2, 0x00f3], [0x00f7, 0x00fa],
+    [0x00fc, 0x00fc], [0x00fe, 0x00fe], [0x0101, 0x0101],
+    [0x0111, 0x0111], [0x0113, 0x0113], [0x011b, 0x011b],
+    [0x0126, 0x0127], [0x012b, 0x012b], [0x0131, 0x0133],
+    [0x0138, 0x0138], [0x013f, 0x0142], [0x0144, 0x0144],
+    [0x0148, 0x014b], [0x014d, 0x014d], [0x0152, 0x0153],
+    [0x0166, 0x0167], [0x016b, 0x016b], [0x01ce, 0x01ce],
+    [0x01d0, 0x01d0], [0x01d2, 0x01d2], [0x01d4, 0x01d4],
+    [0x01d6, 0x01d6], [0x01d8, 0x01d8], [0x01da, 0x01da],
+    [0x01dc, 0x01dc], [0x0251, 0x0251], [0x0261, 0x0261],
+    [0x02c4, 0x02c4], [0x02c7, 0x02c7], [0x02c9, 0x02cb],
+    [0x02cd, 0x02cd], [0x02d0, 0x02d0], [0x02d8, 0x02db],
+    [0x02dd, 0x02dd], [0x02df, 0x02df], [0x0300, 0x036f],
+    [0x0391, 0x03a1], [0x03a3, 0x03a9], [0x03b1, 0x03c1],
+    [0x03c3, 0x03c9], [0x0401, 0x0401], [0x0410, 0x044f],
+    [0x0451, 0x0451], [0x1100, 0x115f], [0x2010, 0x2010],
+    [0x2013, 0x2016], [0x2018, 0x2019], [0x201c, 0x201d],
+    [0x2020, 0x2022], [0x2024, 0x2027], [0x2030, 0x2030],
+    [0x2032, 0x2033], [0x2035, 0x2035], [0x203b, 0x203b],
+    [0x203e, 0x203e], [0x2074, 0x2074], [0x207f, 0x207f],
+    [0x2081, 0x2084], [0x20ac, 0x20ac], [0x2103, 0x2103],
+    [0x2105, 0x2105], [0x2109, 0x2109], [0x2113, 0x2113],
+    [0x2116, 0x2116], [0x2121, 0x2122], [0x2126, 0x2126],
+    [0x212b, 0x212b], [0x2153, 0x2154], [0x215b, 0x215e],
+    [0x2160, 0x216b], [0x2170, 0x2179], [0x2189, 0x2189],
+    [0x2190, 0x2199], [0x21b8, 0x21b9], [0x21d2, 0x21d2],
+    [0x21d4, 0x21d4], [0x21e7, 0x21e7], [0x2200, 0x2200],
+    [0x2202, 0x2203], [0x2207, 0x2208], [0x220b, 0x220b],
+    [0x220f, 0x220f], [0x2211, 0x2211], [0x2215, 0x2215],
+    [0x221a, 0x221a], [0x221d, 0x2220], [0x2223, 0x2223],
+    [0x2225, 0x2225], [0x2227, 0x222c], [0x222e, 0x222e],
+    [0x2234, 0x2237], [0x223c, 0x223d], [0x2248, 0x2248],
+    [0x224c, 0x224c], [0x2252, 0x2252], [0x2260, 0x2261],
+    [0x2264, 0x2267], [0x226a, 0x226b], [0x226e, 0x226f],
+    [0x2282, 0x2283], [0x2286, 0x2287], [0x2295, 0x2295],
+    [0x2299, 0x2299], [0x22a5, 0x22a5], [0x22bf, 0x22bf],
+    [0x2312, 0x2312], [0x231a, 0x231b], [0x2329, 0x232a],
+    [0x23e9, 0x23ec], [0x23f0, 0x23f0], [0x23f3, 0x23f3],
+    [0x2460, 0x24e9], [0x24eb, 0x254b], [0x2550, 0x2573],
+    [0x2580, 0x258f], [0x2592, 0x2595], [0x25a0, 0x25a1],
+    [0x25a3, 0x25a9], [0x25b2, 0x25b3], [0x25b6, 0x25b7],
+    [0x25bc, 0x25bd], [0x25c0, 0x25c1], [0x25c6, 0x25c8],
+    [0x25cb, 0x25cb], [0x25ce, 0x25d1], [0x25e2, 0x25e5],
+    [0x25ef, 0x25ef], [0x25fd, 0x25fe], [0x2605, 0x2606],
+    [0x2609, 0x2609], [0x260e, 0x260f], [0x2614, 0x2615],
+    [0x261c, 0x261c], [0x261e, 0x261e], [0x2640, 0x2640],
+    [0x2642, 0x2642], [0x2648, 0x2653], [0x2660, 0x2661],
+    [0x2663, 0x2665], [0x2667, 0x266a], [0x266c, 0x266d],
+    [0x266f, 0x266f], [0x267f, 0x267f], [0x2693, 0x2693],
+    [0x269e, 0x269f], [0x26a1, 0x26a1], [0x26aa, 0x26ab],
+    [0x26bd, 0x26bf], [0x26c4, 0x26e1], [0x26e3, 0x26e3],
+    [0x26e8, 0x26ff], [0x2705, 0x2705], [0x270a, 0x270b],
+    [0x2728, 0x2728], [0x273d, 0x273d], [0x274c, 0x274c],
+    [0x274e, 0x274e], [0x2753, 0x2755], [0x2757, 0x2757],
+    [0x2776, 0x277f], [0x2795, 0x2797], [0x27b0, 0x27b0],
+    [0x27bf, 0x27bf], [0x2b1b, 0x2b1c], [0x2b50, 0x2b50],
+    [0x2b55, 0x2b59], [0x2e80, 0x2fdf], [0x2ff0, 0x303e],
+    [0x3040, 0x4dbf], [0x4e00, 0xa4cf], [0xa960, 0xa97f],
+    [0xac00, 0xd7a3], [0xe000, 0xfaff], [0xfe00, 0xfe19],
+    [0xfe30, 0xfe6f], [0xff01, 0xff60], [0xffe0, 0xffe6],
+    [0xfffd, 0xfffd], [0x16fe0, 0x16fe3], [0x17000, 0x18aff],
+    [0x1b000, 0x1b12f], [0x1b150, 0x1b152], [0x1b164, 0x1b167],
+    [0x1b170, 0x1b2ff], [0x1f004, 0x1f004], [0x1f0cf, 0x1f0cf],
+    [0x1f100, 0x1f10a], [0x1f110, 0x1f12d], [0x1f130, 0x1f169],
+    [0x1f170, 0x1f1ac], [0x1f200, 0x1f202], [0x1f210, 0x1f23b],
+    [0x1f240, 0x1f248], [0x1f250, 0x1f251], [0x1f260, 0x1f265],
+    [0x1f300, 0x1f320], [0x1f32d, 0x1f335], [0x1f337, 0x1f37c],
+    [0x1f37e, 0x1f393], [0x1f3a0, 0x1f3ca], [0x1f3cf, 0x1f3d3],
+    [0x1f3e0, 0x1f3f0], [0x1f3f4, 0x1f3f4], [0x1f3f8, 0x1f43e],
+    [0x1f440, 0x1f440], [0x1f442, 0x1f4fc], [0x1f4ff, 0x1f53d],
+    [0x1f54b, 0x1f54e], [0x1f550, 0x1f567], [0x1f57a, 0x1f57a],
+    [0x1f595, 0x1f596], [0x1f5a4, 0x1f5a4], [0x1f5fb, 0x1f64f],
+    [0x1f680, 0x1f6c5], [0x1f6cc, 0x1f6cc], [0x1f6d0, 0x1f6d2],
+    [0x1f6d5, 0x1f6d5], [0x1f6eb, 0x1f6ec], [0x1f6f4, 0x1f6fa],
+    [0x1f7e0, 0x1f7eb], [0x1f90d, 0x1f971], [0x1f973, 0x1f976],
+    [0x1f97a, 0x1f9a2], [0x1f9a5, 0x1f9aa], [0x1f9ae, 0x1f9ca],
+    [0x1f9cd, 0x1f9ff], [0x1fa70, 0x1fa73], [0x1fa78, 0x1fa7a],
+    [0x1fa80, 0x1fa82], [0x1fa90, 0x1fa95], [0x20000, 0x2fffd],
+    [0x30000, 0x3fffd], [0xe0100, 0xe01ef], [0xf0000, 0xffffd],
+    [0x100000, 0x10fffd],
+];
+
+// Sorted list of non-overlapping intervals of East Asian Unambiguous characters
+// generated by the `./ranges.py` helper.
+lib.wc.unambiguous = [
+    [0x1100, 0x115f], [0x231a, 0x231b], [0x2329, 0x232a],
+    [0x23e9, 0x23ec], [0x23f0, 0x23f0], [0x23f3, 0x23f3],
+    [0x25fd, 0x25fe], [0x2614, 0x2615], [0x2648, 0x2653],
+    [0x267f, 0x267f], [0x2693, 0x2693], [0x26a1, 0x26a1],
+    [0x26aa, 0x26ab], [0x26bd, 0x26be], [0x26c4, 0x26c5],
+    [0x26ce, 0x26ce], [0x26d4, 0x26d4], [0x26ea, 0x26ea],
+    [0x26f2, 0x26f3], [0x26f5, 0x26f5], [0x26fa, 0x26fa],
+    [0x26fd, 0x26fd], [0x2705, 0x2705], [0x270a, 0x270b],
+    [0x2728, 0x2728], [0x274c, 0x274c], [0x274e, 0x274e],
+    [0x2753, 0x2755], [0x2757, 0x2757], [0x2795, 0x2797],
+    [0x27b0, 0x27b0], [0x27bf, 0x27bf], [0x2b1b, 0x2b1c],
+    [0x2b50, 0x2b50], [0x2b55, 0x2b55], [0x2e80, 0x2fdf],
+    [0x2ff0, 0x303e], [0x3040, 0x3247], [0x3250, 0x4dbf],
+    [0x4e00, 0xa4cf], [0xa960, 0xa97f], [0xac00, 0xd7a3],
+    [0xf900, 0xfaff], [0xfe10, 0xfe19], [0xfe30, 0xfe6f],
+    [0xff01, 0xff60], [0xffe0, 0xffe6], [0x16fe0, 0x16fe3],
+    [0x17000, 0x18aff], [0x1b000, 0x1b12f], [0x1b150, 0x1b152],
+    [0x1b164, 0x1b167], [0x1b170, 0x1b2ff], [0x1f004, 0x1f004],
+    [0x1f0cf, 0x1f0cf], [0x1f18e, 0x1f18e], [0x1f191, 0x1f19a],
+    [0x1f200, 0x1f202], [0x1f210, 0x1f23b], [0x1f240, 0x1f248],
+    [0x1f250, 0x1f251], [0x1f260, 0x1f265], [0x1f300, 0x1f320],
+    [0x1f32d, 0x1f335], [0x1f337, 0x1f37c], [0x1f37e, 0x1f393],
+    [0x1f3a0, 0x1f3ca], [0x1f3cf, 0x1f3d3], [0x1f3e0, 0x1f3f0],
+    [0x1f3f4, 0x1f3f4], [0x1f3f8, 0x1f43e], [0x1f440, 0x1f440],
+    [0x1f442, 0x1f4fc], [0x1f4ff, 0x1f53d], [0x1f54b, 0x1f54e],
+    [0x1f550, 0x1f567], [0x1f57a, 0x1f57a], [0x1f595, 0x1f596],
+    [0x1f5a4, 0x1f5a4], [0x1f5fb, 0x1f64f], [0x1f680, 0x1f6c5],
+    [0x1f6cc, 0x1f6cc], [0x1f6d0, 0x1f6d2], [0x1f6d5, 0x1f6d5],
+    [0x1f6eb, 0x1f6ec], [0x1f6f4, 0x1f6fa], [0x1f7e0, 0x1f7eb],
+    [0x1f90d, 0x1f971], [0x1f973, 0x1f976], [0x1f97a, 0x1f9a2],
+    [0x1f9a5, 0x1f9aa], [0x1f9ae, 0x1f9ca], [0x1f9cd, 0x1f9ff],
+    [0x1fa70, 0x1fa73], [0x1fa78, 0x1fa7a], [0x1fa80, 0x1fa82],
+    [0x1fa90, 0x1fa95], [0x20000, 0x2fffd], [0x30000, 0x3fffd],
+];
+
+/**
+ * Binary search to check if the given unicode character is in the table.
+ *
+ * @param {integer} ucs A unicode character code.
+ * @param {Object} table A sorted list of internals to match against.
+ * @return {boolean} True if the given character is in the table.
+ */
+lib.wc.binaryTableSearch_ = function(ucs, table) {
+  var min = 0, max = table.length - 1;
+  var mid;
+
+  if (ucs < table[min][0] || ucs > table[max][1])
+    return false;
+  while (max >= min) {
+    mid = Math.floor((min + max) / 2);
+    if (ucs > table[mid][1]) {
+      min = mid + 1;
+    } else if (ucs < table[mid][0]) {
+      max = mid - 1;
+    } else {
+      return true;
+    }
+  }
+
+  return false;
+};
+
+/**
+ * Binary search to check if the given unicode character is a space character.
+ *
+ * @param {integer} ucs A unicode character code.
+ *
+ * @return {boolean} True if the given character is a space character; false
+ *     otherwise.
+ */
+lib.wc.isSpace = function(ucs) {
+  return lib.wc.binaryTableSearch_(ucs, lib.wc.combining);
+};
+
+/**
+ * Auxiliary function for checking if the given unicode character is a East
+ * Asian Ambiguous character.
+ *
+ * @param {integer} ucs A unicode character code.
+ *
+ * @return {boolean} True if the given character is a East Asian Ambiguous
+ * character.
+ */
+lib.wc.isCjkAmbiguous = function(ucs) {
+  return lib.wc.binaryTableSearch_(ucs, lib.wc.ambiguous);
+};
+
+/**
+ * Determine the column width of the given character.
+ *
+ * @param {integer} ucs A unicode character code.
+ *
+ * @return {integer} The column width of the given character.
+ */
+lib.wc.charWidth = function(ucs) {
+  if (lib.wc.regardCjkAmbiguous) {
+    return lib.wc.charWidthRegardAmbiguous(ucs);
+  } else {
+    return lib.wc.charWidthDisregardAmbiguous(ucs);
+  }
+};
+
+/**
+ * Determine the column width of the given character without considering East
+ * Asian Ambiguous characters.
+ *
+ * @param {integer} ucs A unicode character code.
+ *
+ * @return {integer} The column width of the given character.
+ */
+lib.wc.charWidthDisregardAmbiguous = function(ucs) {
+  // Optimize for ASCII characters.
+  if (ucs < 0x7f) {
+    if (ucs >= 0x20)
+      return 1;
+    else if (ucs == 0)
+      return lib.wc.nulWidth;
+    else /* if (ucs < 0x20) */
+      return lib.wc.controlWidth;
+  }
+
+  // Test for 8-bit control characters.
+  if (ucs < 0xa0)
+    return lib.wc.controlWidth;
+
+  // Binary search in table of non-spacing characters.
+  if (lib.wc.isSpace(ucs))
+    return 0;
+
+  // Binary search in table of wide characters.
+  return lib.wc.binaryTableSearch_(ucs, lib.wc.unambiguous) ? 2 : 1;
+};
+
+/**
+ * Determine the column width of the given character considering East Asian
+ * Ambiguous characters.
+ *
+ * @param {integer} ucs A unicode character code.
+ *
+ * @return {integer} The column width of the given character.
+ */
+lib.wc.charWidthRegardAmbiguous = function(ucs) {
+  if (lib.wc.isCjkAmbiguous(ucs))
+    return lib.wc.cjkAmbiguousWidth;
+
+  return lib.wc.charWidthDisregardAmbiguous(ucs);
+};
+
+/**
+ * Determine the column width of the given string.
+ *
+ * @param {string} str A string.
+ *
+ * @return {integer} The column width of the given string.
+ */
+lib.wc.strWidth = function(str) {
+  var width, rv = 0;
+
+  for (var i = 0; i < str.length;) {
+    var codePoint = str.codePointAt(i);
+    width = lib.wc.charWidth(codePoint);
+    if (width < 0)
+      return -1;
+    rv += width;
+    i += (codePoint <= 0xffff) ? 1 : 2;
+  }
+
+  return rv;
+};
+
+/**
+ * Get the substring at the given column offset of the given column width.
+ *
+ * @param {string} str The string to get substring from.
+ * @param {integer} start The starting column offset to get substring.
+ * @param {integer} opt_width The column width of the substring.
+ *
+ * @return {string} The substring.
+ */
+lib.wc.substr = function(str, start, opt_width) {
+  var startIndex = 0;
+  var endIndex, width;
+
+  // Fun edge case: Normally we associate zero width codepoints (like combining
+  // characters) with the previous codepoint, so we skip any leading ones while
+  // including trailing ones.  However, if there are zero width codepoints at
+  // the start of the string, and the substring starts at 0, lets include them
+  // in the result.  This also makes for a simple optimization for a common
+  // request.
+  if (start) {
+    for (width = 0; startIndex < str.length;) {
+      const codePoint = str.codePointAt(startIndex);
+      width += lib.wc.charWidth(codePoint);
+      if (width > start)
+        break;
+      startIndex += (codePoint <= 0xffff) ? 1 : 2;
+    }
+  }
+
+  if (opt_width != undefined) {
+    for (endIndex = startIndex, width = 0; endIndex < str.length;) {
+      const codePoint = str.codePointAt(endIndex);
+      width += lib.wc.charWidth(codePoint);
+      if (width > opt_width)
+        break;
+      endIndex += (codePoint <= 0xffff) ? 1 : 2;
+    }
+    return str.substring(startIndex, endIndex);
+  }
+
+  return str.substr(startIndex);
+};
+
+/**
+ * Get substring at the given start and end column offset.
+ *
+ * @param {string} str The string to get substring from.
+ * @param {integer} start The starting column offset.
+ * @param {integer} end The ending column offset.
+ *
+ * @return {string} The substring.
+ */
+lib.wc.substring = function(str, start, end) {
+  return lib.wc.substr(str, start, end - start);
+};
+lib.resource.add('libdot/changelog/version', 'text/plain',
+'2.0.0'
+);
+
+lib.resource.add('libdot/changelog/date', 'text/plain',
+'2019-06-17'
+);
+
+// This file was generated by libdot/bin/concat.sh.
+// It has been marked read-only for your safety.  Rather than
+// edit it directly, please modify one of these source files.
+//
+// hterm/audio/bell.ogg
+// hterm/images/icon-96.png
+
+'use strict';
+
+lib.resource.add('hterm/audio/bell', 'audio/ogg;base64',
+'T2dnUwACAAAAAAAAAADhqW5KAAAAAMFvEjYBHgF2b3JiaXMAAAAAAYC7AAAAAAAAAHcBAAAAAAC4' +
+'AU9nZ1MAAAAAAAAAAAAA4aluSgEAAAAAesI3EC3//////////////////8kDdm9yYmlzHQAAAFhp' +
+'cGguT3JnIGxpYlZvcmJpcyBJIDIwMDkwNzA5AAAAAAEFdm9yYmlzKUJDVgEACAAAADFMIMWA0JBV' +
+'AAAQAABgJCkOk2ZJKaWUoSh5mJRISSmllMUwiZiUicUYY4wxxhhjjDHGGGOMIDRkFQAABACAKAmO' +
+'o+ZJas45ZxgnjnKgOWlOOKcgB4pR4DkJwvUmY26mtKZrbs4pJQgNWQUAAAIAQEghhRRSSCGFFGKI' +
+'IYYYYoghhxxyyCGnnHIKKqigggoyyCCDTDLppJNOOumoo4466ii00EILLbTSSkwx1VZjrr0GXXxz' +
+'zjnnnHPOOeecc84JQkNWAQAgAAAEQgYZZBBCCCGFFFKIKaaYcgoyyIDQkFUAACAAgAAAAABHkRRJ' +
+'sRTLsRzN0SRP8ixREzXRM0VTVE1VVVVVdV1XdmXXdnXXdn1ZmIVbuH1ZuIVb2IVd94VhGIZhGIZh' +
+'GIZh+H3f933f930gNGQVACABAKAjOZbjKaIiGqLiOaIDhIasAgBkAAAEACAJkiIpkqNJpmZqrmmb' +
+'tmirtm3LsizLsgyEhqwCAAABAAQAAAAAAKBpmqZpmqZpmqZpmqZpmqZpmqZpmmZZlmVZlmVZlmVZ' +
+'lmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZQGjIKgBAAgBAx3Ecx3EkRVIkx3IsBwgNWQUAyAAA' +
+'CABAUizFcjRHczTHczzHczxHdETJlEzN9EwPCA1ZBQAAAgAIAAAAAABAMRzFcRzJ0SRPUi3TcjVX' +
+'cz3Xc03XdV1XVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVYHQkFUAAAQAACGdZpZq' +
+'gAgzkGEgNGQVAIAAAAAYoQhDDAgNWQUAAAQAAIih5CCa0JrzzTkOmuWgqRSb08GJVJsnuamYm3PO' +
+'OeecbM4Z45xzzinKmcWgmdCac85JDJqloJnQmnPOeRKbB62p0ppzzhnnnA7GGWGcc85p0poHqdlY' +
+'m3POWdCa5qi5FJtzzomUmye1uVSbc84555xzzjnnnHPOqV6czsE54Zxzzonam2u5CV2cc875ZJzu' +
+'zQnhnHPOOeecc84555xzzglCQ1YBAEAAAARh2BjGnYIgfY4GYhQhpiGTHnSPDpOgMcgppB6NjkZK' +
+'qYNQUhknpXSC0JBVAAAgAACEEFJIIYUUUkghhRRSSCGGGGKIIaeccgoqqKSSiirKKLPMMssss8wy' +
+'y6zDzjrrsMMQQwwxtNJKLDXVVmONteaec645SGultdZaK6WUUkoppSA0ZBUAAAIAQCBkkEEGGYUU' +
+'UkghhphyyimnoIIKCA1ZBQAAAgAIAAAA8CTPER3RER3RER3RER3RER3P8RxREiVREiXRMi1TMz1V' +
+'VFVXdm1Zl3Xbt4Vd2HXf133f141fF4ZlWZZlWZZlWZZlWZZlWZZlCUJDVgEAIAAAAEIIIYQUUkgh' +
+'hZRijDHHnINOQgmB0JBVAAAgAIAAAAAAR3EUx5EcyZEkS7IkTdIszfI0T/M00RNFUTRNUxVd0RV1' +
+'0xZlUzZd0zVl01Vl1XZl2bZlW7d9WbZ93/d93/d93/d93/d939d1IDRkFQAgAQCgIzmSIimSIjmO' +
+'40iSBISGrAIAZAAABACgKI7iOI4jSZIkWZImeZZniZqpmZ7pqaIKhIasAgAAAQAEAAAAAACgaIqn' +
+'mIqniIrniI4oiZZpiZqquaJsyq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7rukBo' +
+'yCoAQAIAQEdyJEdyJEVSJEVyJAcIDVkFAMgAAAgAwDEcQ1Ikx7IsTfM0T/M00RM90TM9VXRFFwgN' +
+'WQUAAAIACAAAAAAAwJAMS7EczdEkUVIt1VI11VItVVQ9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV' +
+'VVVVVVVVVVVV1TRN0zSB0JCVAAAZAAAjQQYZhBCKcpBCbj1YCDHmJAWhOQahxBiEpxAzDDkNInSQ' +
+'QSc9uJI5wwzz4FIoFURMg40lN44gDcKmXEnlOAhCQ1YEAFEAAIAxyDHEGHLOScmgRM4xCZ2UyDkn' +
+'pZPSSSktlhgzKSWmEmPjnKPSScmklBhLip2kEmOJrQAAgAAHAIAAC6HQkBUBQBQAAGIMUgophZRS' +
+'zinmkFLKMeUcUko5p5xTzjkIHYTKMQadgxAppRxTzinHHITMQeWcg9BBKAAAIMABACDAQig0ZEUA' +
+'ECcA4HAkz5M0SxQlSxNFzxRl1xNN15U0zTQ1UVRVyxNV1VRV2xZNVbYlTRNNTfRUVRNFVRVV05ZN' +
+'VbVtzzRl2VRV3RZV1bZl2xZ+V5Z13zNNWRZV1dZNVbV115Z9X9ZtXZg0zTQ1UVRVTRRV1VRV2zZV' +
+'17Y1UXRVUVVlWVRVWXZlWfdVV9Z9SxRV1VNN2RVVVbZV2fVtVZZ94XRVXVdl2fdVWRZ+W9eF4fZ9' +
+'4RhV1dZN19V1VZZ9YdZlYbd13yhpmmlqoqiqmiiqqqmqtm2qrq1bouiqoqrKsmeqrqzKsq+rrmzr' +
+'miiqrqiqsiyqqiyrsqz7qizrtqiquq3KsrCbrqvrtu8LwyzrunCqrq6rsuz7qizruq3rxnHrujB8' +
+'pinLpqvquqm6um7runHMtm0co6rqvirLwrDKsu/rui+0dSFRVXXdlF3jV2VZ921fd55b94WybTu/' +
+'rfvKceu60vg5z28cubZtHLNuG7+t+8bzKz9hOI6lZ5q2baqqrZuqq+uybivDrOtCUVV9XZVl3zdd' +
+'WRdu3zeOW9eNoqrquirLvrDKsjHcxm8cuzAcXds2jlvXnbKtC31jyPcJz2vbxnH7OuP2daOvDAnH' +
+'jwAAgAEHAIAAE8pAoSErAoA4AQAGIecUUxAqxSB0EFLqIKRUMQYhc05KxRyUUEpqIZTUKsYgVI5J' +
+'yJyTEkpoKZTSUgehpVBKa6GU1lJrsabUYu0gpBZKaS2U0lpqqcbUWowRYxAy56RkzkkJpbQWSmkt' +
+'c05K56CkDkJKpaQUS0otVsxJyaCj0kFIqaQSU0mptVBKa6WkFktKMbYUW24x1hxKaS2kEltJKcYU' +
+'U20txpojxiBkzknJnJMSSmktlNJa5ZiUDkJKmYOSSkqtlZJSzJyT0kFIqYOOSkkptpJKTKGU1kpK' +
+'sYVSWmwx1pxSbDWU0lpJKcaSSmwtxlpbTLV1EFoLpbQWSmmttVZraq3GUEprJaUYS0qxtRZrbjHm' +
+'GkppraQSW0mpxRZbji3GmlNrNabWam4x5hpbbT3WmnNKrdbUUo0txppjbb3VmnvvIKQWSmktlNJi' +
+'ai3G1mKtoZTWSiqxlZJabDHm2lqMOZTSYkmpxZJSjC3GmltsuaaWamwx5ppSi7Xm2nNsNfbUWqwt' +
+'xppTS7XWWnOPufVWAADAgAMAQIAJZaDQkJUAQBQAAEGIUs5JaRByzDkqCULMOSepckxCKSlVzEEI' +
+'JbXOOSkpxdY5CCWlFksqLcVWaykptRZrLQAAoMABACDABk2JxQEKDVkJAEQBACDGIMQYhAYZpRiD' +
+'0BikFGMQIqUYc05KpRRjzknJGHMOQioZY85BKCmEUEoqKYUQSkklpQIAAAocAAACbNCUWByg0JAV' +
+'AUAUAABgDGIMMYYgdFQyKhGETEonqYEQWgutddZSa6XFzFpqrbTYQAithdYySyXG1FpmrcSYWisA' +
+'AOzAAQDswEIoNGQlAJAHAEAYoxRjzjlnEGLMOegcNAgx5hyEDirGnIMOQggVY85BCCGEzDkIIYQQ' +
+'QuYchBBCCKGDEEIIpZTSQQghhFJK6SCEEEIppXQQQgihlFIKAAAqcAAACLBRZHOCkaBCQ1YCAHkA' +
+'AIAxSjkHoZRGKcYglJJSoxRjEEpJqXIMQikpxVY5B6GUlFrsIJTSWmw1dhBKaS3GWkNKrcVYa64h' +
+'pdZirDXX1FqMteaaa0otxlprzbkAANwFBwCwAxtFNicYCSo0ZCUAkAcAgCCkFGOMMYYUYoox55xD' +
+'CCnFmHPOKaYYc84555RijDnnnHOMMeecc845xphzzjnnHHPOOeecc44555xzzjnnnHPOOeecc845' +
+'55xzzgkAACpwAAAIsFFkc4KRoEJDVgIAqQAAABFWYowxxhgbCDHGGGOMMUYSYowxxhhjbDHGGGOM' +
+'McaYYowxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHG' +
+'GFtrrbXWWmuttdZaa6211lprrQBAvwoHAP8HG1ZHOCkaCyw0ZCUAEA4AABjDmHOOOQYdhIYp6KSE' +
+'DkIIoUNKOSglhFBKKSlzTkpKpaSUWkqZc1JSKiWlllLqIKTUWkottdZaByWl1lJqrbXWOgiltNRa' +
+'a6212EFIKaXWWostxlBKSq212GKMNYZSUmqtxdhirDGk0lJsLcYYY6yhlNZaazHGGGstKbXWYoy1' +
+'xlprSam11mKLNdZaCwDgbnAAgEiwcYaVpLPC0eBCQ1YCACEBAARCjDnnnHMQQgghUoox56CDEEII' +
+'IURKMeYcdBBCCCGEjDHnoIMQQgghhJAx5hx0EEIIIYQQOucchBBCCKGEUkrnHHQQQgghlFBC6SCE' +
+'EEIIoYRSSikdhBBCKKGEUkopJYQQQgmllFJKKaWEEEIIoYQSSimllBBCCKWUUkoppZQSQgghlFJK' +
+'KaWUUkIIoZRQSimllFJKCCGEUkoppZRSSgkhhFBKKaWUUkopIYQSSimllFJKKaUAAIADBwCAACPo' +
+'JKPKImw04cIDUGjISgCADAAAcdhq6ynWyCDFnISWS4SQchBiLhFSijlHsWVIGcUY1ZQxpRRTUmvo' +
+'nGKMUU+dY0oxw6yUVkookYLScqy1dswBAAAgCAAwECEzgUABFBjIAIADhAQpAKCwwNAxXAQE5BIy' +
+'CgwKx4Rz0mkDABCEyAyRiFgMEhOqgaJiOgBYXGDIB4AMjY20iwvoMsAFXdx1IIQgBCGIxQEUkICD' +
+'E2544g1PuMEJOkWlDgIAAAAA4AAAHgAAkg0gIiKaOY4Ojw+QEJERkhKTE5QAAAAAALABgA8AgCQF' +
+'iIiIZo6jw+MDJERkhKTE5AQlAAAAAAAAAAAACAgIAAAAAAAEAAAACAhPZ2dTAAQYOwAAAAAAAOGp' +
+'bkoCAAAAmc74DRgyNjM69TAzOTk74dnLubewsbagmZiNp4d0KbsExSY/I3XUTwJgkeZdn1HY4zoj' +
+'33/q9DFtv3Ui1/jmx7lCUtPt18/sYf9MkgAsAGRBd3gMGP4sU+qCPYBy9VrA3YqJosW3W2/ef1iO' +
+'/u3cg8ZG/57jU+pPmbGEJUgkfnaI39DbPqxddZphbMRmCc5rKlkUMkyx8iIoug5dJv1OYH9a59c+' +
+'3Gevqc7Z2XFdDjL/qHztRfjWEWxJ/aiGezjohu9HsCZdQBKbiH0VtU/3m85lDG2T/+xkZcYnX+E+' +
+'aqzv/xTgOoTFG+x7SNqQ4N+oAABSxuVXw77Jd5bmmTmuJakX7509HH0kGYKvARPpwfOSAPySPAc2' +
+'EkneDwB2HwAAJlQDYK5586N79GJCjx4+p6aDUd27XSvRyXLJkIC5YZ1jLv5lpOhZTz0s+DmnF1di' +
+'ptrnM6UDgIW11Xh8cHTd0/SmbgOAdxcyWwMAAGIrZ3fNSfZbzKiYrK4+tPqtnMVLOeWOG2kVvUY+' +
+'p2PJ/hkCl5aFRO4TLGYPZcIU3vYM1hohS4jHFlnyW/2T5J7kGsShXWT8N05V+3C/GPqJ1QdWisGP' +
+'xEzHqXISBPIinWDUt7IeJv/f5OtzBxpTzZZQ+CYEhHXfqG4aABQli72GJhN4oJv+hXcApAJSErAW' +
+'8G2raAX4NUcABnVt77CzZAB+LsHcVe+Q4h+QB1wh/ZrJTPxSBdI8mgTeAdTsQOoFUEng9BHcVPhx' +
+'SRRYkKWZJXOFYP6V4AEripJoEjXgA2wJRZHSExmJDm8F0A6gEXsg5a4ZsALItrMB7+fh7UKLvYWS' +
+'dtsDwFf1mzYzS1F82N1h2Oyt2e76B1QdS0SAsQigLPMOgJS9JRC7hFXA6kUsLFNKD5cA5cTRvgSq' +
+'Pc3Fl99xW3QTi/MHR8DEm6WnvaVQATwRqRKjywQ9BrrhugR2AKTsPQeQckrAOgDOhbTESyrXQ50C' +
+'kNpXdtWjW7W2/3UjeX3U95gIdalfRAoAmqUEiwp53hCdcCwlg47fcbfzlmQMAgaBkh7c+fcDgF+i' +
+'fwDXfzegLPcLYJsAAJQArTXjnh/uXGy3v1Hk3pV6/3t5ruW81f6prfbM2Q3WNVy98BwUtbCwhFhA' +
+'WuPev6Oe/4ZaFQUcgKrVs4defzh1TADA1DEh5b3VlDaECw5b+bPfkKos3tIAue3vJZOih3ga3l6O' +
+'3PSfIkrLv0PAS86PPdL7g8oc2KteNFKKzKRehOv2gJoFLBPXmaXvPBQILgJon0bbWBszrYZYYwE7' +
+'jl2j+vTdU7Vpk21LiU0QajPkywAAHqbUC0/YsYOdb4e6BOp7E0cCi04Ao/TgD8ZVAMid6h/A8IeB' +
+'Nkp6/xsAACZELEYIk+yvI6Qz1NN6lIftB/6IMWjWJNOqPTMedAmyaj6Es0QBklJpiSWWHnQ2CoYb' +
+'GWAmt+0gLQBFKCBnp2QUUQZ/1thtZDBJUpFWY82z34ocorB62oX7qB5y0oPAv/foxH25wVmgIHf2' +
+'xFOr8leZcBq1Kx3ZvCq9Bga639AxuHuPNL/71YCF4EywJpqHFAX6XF0sjVbuANnvvdLcrufYwOM/' +
+'iDa6iA468AYAAB6mNBMXcgTD8HSRqJ4vw8CjAlCEPACASlX/APwPOJKl9xQAAAPmnev2eWp33Xgy' +
+'w3Dvfz6myGk3oyP8YTKsCOvzAgALQi0o1c6Nzs2O2Pg2h4ACIJAgAGP0aNn5x0BDgVfH7u2TtyfD' +
+'cRIuYAyQhBF/lvSRAttgA6TPbWZA9gaUrZWAUEAA+Dx47Q3/r87HxUUqZmB0BmUuMlojFjHt1gDu' +
+'nnvuX8MImsjSq5WkzSzGS62OEIlOufWWezxWpv6FBgDgJVltfXFYtNAAnqU0xQoD0YLiXo5cF5QV' +
+'4CnY1tBLAkZCOABAhbk/AM+/AwSCCdlWAAAMcFjS7owb8GVDzveDiZvznbt2tF4bL5odN1YKl88T' +
+'AEABCZvufq9YCTBtMwVAQUEAwGtNltzSaHvADYC3TxLVjqiRA+OZAMhzcqEgRcAOwoCgvdTxsTHL' +
+'QEF6+oOb2+PAI8ciPQcXg7pOY+LjxQSv2fjmFuj34gGwz310/bGK6z3xgT887eomWULEaDd04wHe' +
+'tYxdjcgV2SxvSwn0VoZXJRqkRC5ASQ/muVoAUsX7AgAQMBNaVwAAlABRxT/1PmfqLqSRNDbhXb07' +
+'berpB3b94jpuWEZjBCD2OcdXFpCKEgCDfcFPMw8AAADUwT4lnUm50lmwrpMMhPQIKj6u0E8fr2vG' +
+'BngMNdIlrZsigjahljud6AFVg+tzXwUnXL3TJLpajaWKA4VAAAAMiFfqJgKAZ08XrtS3dxtQNYcp' +
+'PvYEG8ClvrQRJgBephwnNWJjtGqmp6VEPSvBe7EBiU3qgJbQAwD4Le8LAMDMhHbNAAAlgK+tFs5O' +
+'+YyJc9yCnJa3rxLPulGnxwsXV9Fsk2k4PisCAHC8FkwbGE9gJQAAoMnyksj0CdFMZLLgoz8M+Fxz' +
+'iwYBgIx+zHiCBAKAlBKNpF1sO9JpVcyEi9ar15YlHgrut5fPJnkdJ6vEwZPyAHQBIEDUrlMcBAAd' +
+'2KAS0Qq+JwRsE4AJZtMnAD6GnOYwYlOIZvtzUNdjreB7fiMkWI0CmBB6AIAKc38A9osEFlTSGECB' +
+'+cbeRDC0aRpLHqNPplcK/76Lxn2rpmqyXsYJWRi/FQAAAKBQk9MCAOibrQBQADCDsqpooPutd+05' +
+'Ce9g6iEdiYXgVmQAI4+4wskEBEiBloNQ6Ki0/KTQ0QjWfjxzi+AeuXKoMjEVfQOZzr0y941qLgM2' +
+'AExvbZOqcxZ6J6krlrj4y2j9AdgKDx6GnJsVLhbc42uq584+ouSdNBpoCiCVHrz+WzUA/DDtD8AT' +
+'gA3h0lMCAAzcFv+S+fSSNkeYWlTpb34mf2RfmqqJeMeklhHAfu7VoAEACgAApKRktL+KkQDWMwYC' +
+'UAAAAHCKsp80xhp91UjqQBw3x45cetqkjQEyu3G9B6N+R650Uq8OVig7wOm6Wun0ea4lKDPoabJs' +
+'6aLqgbhPzpv4KR4iODilw88ZpY7q1IOMcbASAOAVtmcCnobcrkG4KGS7/ZnskVWRNF9J0RUHKOnB' +
+'yy9WA8Dv6L4AAARMCQUA4GritfVM2lcZfH3Q3T/vZ47J2YHhcmBazjfdyuV25gLAzrc0cwAAAAAY' +
+'Ch6PdwAAAGyWjFW4yScjaWa2mGcofHxWxewKALglWBpLUvwwk+UOh5eNGyUOs1/EF+pZr+ud5Ozo' +
+'GwYdAABg2p52LiSgAY/ZVlOmilEgHn6G3OcwYjzI7vOj1t6xsx4S3lBY96EUQBF6AIBAmPYH4PoG' +
+'YCoJAADWe+OZJZi7/x76/yH7Lzf9M5XzRKnFPmveMsilQHwVAAAAAKB3LQD8PCIAAADga0QujBLy' +
+'wzeJ4a6Z/ERVBAUlAEDqvoM7BQBAuAguzFqILtmjH3Kd4wfKobnOhA3z85qWoRPm9hwoOHoDAAlC' +
+'bwDAA56FHAuXflHo3fe2ttG9XUDeA9YmYCBQ0oPr/1QC8IvuCwAAApbUAQCK22MmE3O78VAbHQT9' +
+'PIPNoT9zNc3l2Oe7TAVLANBufT8MAQAAAGzT4PS8AQAAoELGHb2uaCwwEv1EWhFriUkbAaAZ27/f' +
+'VZnTZXbWz3BwWpjUaMZKRj7dZ0J//gUeTdpVEwAAZOFsNxKAjQSgA+ABPoY8Jj5y2wje81jsXc/1' +
+'TOQWTDYZBmAkNDiqVwuA2NJ9AQAAEBKAt9Vrsfs/2N19MO91S9rd8EHTZHnzC5MYmfQEACy/FBcA' +
+'AADA5c4gi4z8RANs/m6FNXVo9DV46JG1BBDukqlw/Va5G7QbuGVSI+2aZaoLXJrdVj2zlC9Z5QEA' +
+'EFz/5QzgVZwAAAAA/oXcxyC6WfTu+09Ve/c766J4VTAGUFmA51+VANKi/QPoPwYgYAkA715OH4S0' +
+'s5KDHvj99MMq8TPFc3roKZnGOoT1bmIhVgc7XAMBAAAAAMAW1VbQw3gapzOpJd+Kd2fc4iSO62fJ' +
+'v9+movui1wUNPAj059N3OVxzk4gV73PmE8FIA2F5mRq37Evc76vLXfF4rD5UJJAw46hW6LZCb5sN' +
+'Ldx+kzMCAAB+hfy95+965ZCLP7B3/VlTHCvDEKtQhTm4KiCgAEAbrfbWTPssAAAAXpee1tVrozYY' +
+'n41wD1aeYtkKfswN5/SXPO0JDnhO/4laUortv/s412fybe/nONdncoCHnBVliu0CQGBWlPY/5Kwo' +
+'m2L/kruPM6Q7oz4tvDQy+bZ3HzOi+gNHA4DZEgA='
+);
+
+lib.resource.add('hterm/images/icon-96', 'image/png;base64',
+'iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAStklEQVR42u1dBXjrupL+RzIGmjIf' +
+'vAcu42NmZub3lpmZmZmZmRkuMzPDYaYyJG0Sa9b2p2z1eQtp7bzefpv/nKnkkSw7Gg1IshNsDtpo' +
+'o4022mijDWp/tlTgzbpJSqYvMoFTC9vjRD5JLb9RYaRkpk22SS28P8pacAaPdZ41KYMCI89YB6wN' +
+'3JzQJM3UIGqurfTlKQTAZtqENid5SlNdU804VmbbWQtA6HMkAAdADsBeAJ7mxwIhIhFSXJ9iRPw4' +
+'JYDEcqmGWEp1HhCI8gAtpXF7scB1ZRH9E3HObANCNy1AoGTegNDnCdE41tfQDH2t+CINQEpJ9Xp9' +
+'7oUDh3+nXK48DYAMIWQmANIkNTn6vP69e3d/zctfeu0nXNexmVn3F0gDAMxMlBoHuht0qnsEEekC' +
+'42SdGHmNxgVjgk4bPN04Yui8bhc534cQBH35RKrPN9sGdLnB1/Wuv+HW4f+6/tZvBHAaAJvmKr0A' +
+'jJGvyQMw8pLrrvqeT378Ax8UwrKeevoFgEhfjcGGO2JO+iuTt1SW5DHzyraDExyTlWwHjCQ/CAJc' +
+'ecU+XHn5xWDmVCGQFAKljsLbx8Ynvv3Bhx7/EQCzurimU04jADLsvK3r73/7W1//g1/6hU++uVqt' +
+'0X/dcBcKxRIsy9Ji34DPow2et6FzgcXFKk6fOY83vu4VEFKkDiYHB3roSz73sc+Oj08eOHzk+B9o' +
+'MyQABGk0gCIyOt9xHPvaD3/wnT/5VV/+meumpmbwD/98A0qdvVEBNhvMDCJaVXtM01GtVlEs+LBt' +
+'C1ngzW98tX/m7Llv/emf+83HarX6vbrfGECQRgBmlLP9Ix961499+zd/5XVj45P407/8FxQ7uiGl' +
+'QK1Ww1ZCvR6gXq3AsgQ8zwYzUkMIgXe+/Q1Dd9x5/6duv/P+R7QjprQaIHQd/8orLvnCJz/2/pfm' +
+'cj7+6rf+DK5XgOu6sT3dQtBawqjW6lhYXIRlSTAjE/T39eLSS/ZeEwqgE8CiYUV4vQIgTULTyFve' +
+'9Or3WJZN/3n9HTh3fgrFjhJmZmawFaGUwkJlEffc9xh83wMYqcFg7Noxinw+l9OBikirAabz7eju' +
+'6sxJKTE7W4bn5+D7PrYmtI/gAFJasCwb4IzaBMHzXE8LgBJC4I1GQRKAa4Xo6upEsZiH53nIRYLe' +
+'olDMCIIq+nq70dFRAGckgFKpAD+UgBaAgfRRkGvbliwUcoh8ABHFYSfWMnBrxOzL12PwKufzSvV5' +
+'5Tpmi5a0IASBQCgWcujs7ABn5AQic+b5rhNlAVAmTliTEwnA990wIxEEdUQYnxjHidMnAUIcBYAB' +
+'RqNDdC7BM8t0VtfTnGRd8FKdRIjJcVlCsAbPPA5UAK4rXLJjP7aNbkO9XoPrOrEQWHEm69Kua0ca' +
+'YEspvCBQ5toSp9EASCkt27ZF1PlCxBOZOPo5feY0Xpg8jHe/7V3YNjhqjDRac3mMVl1Oo40vtREt' +
+'W+2FYwdw/S03YHJ6EkODQ1hcXIQUcaeBlUIWsCwZ+QDLdZxcubKAtBpgNmzZliUa6yLMKiRGoBR2' +
+'79yN6666FlJYABgvRhAIncUSHn/iCdQrAZjjSAiKFQQRVEhZIRJASJEACICmlAKQUtqhBETjw5ij' +
+'uFqr4oWjBwHmF7/jVUHc6aRNXxAoZA3PdYXruvlldJfTaIATaQA4KU/CzNwMDp84DOYXf+hZXiij' +
+'hJz+DK0QAEd+RYTOOAcgMw0g24oskNYAIoCXxDpbnsOxM8fB5qacwKZD+3WQcS+VxQrYYXNVNGMh' +
+'I1odiIRQSHb8BmbCpgZYjmVLYi0ANmxQNKpOj50FFOB3WnDzEpOnFkGbuOXPimG5Ap0jLqZOLiKo' +
+'MyIsVhfB9lLEpFSQ+S26jh2Fo/n0YagRCUlLRhpAAIMIyWl9vBinAkbfoIPXf+0wnrlxAs/dPInK' +
+'VB1CUOsFkdhD6Nnp49oP98EvWfjvnzqGak0hVlwwFJsaoADK9vq2Y0eOOKUGJLTAjjQgFgBAy/gT' +
+'vbGIyXC0nX66jJd+YgC7X1nCo39/AccfmUVQU1F5y0d9rsvGJW/txuXv7oGqMx7+2/OoVxWIzE5S' +
+'OkfaBBGyhGPHc4G8YYjT+wDLDgUgJbQPWDGuL0/VcefvnMLRB2dw3Uf78dZv345D90zjsX++gPGj' +
+'C7peC8yNI7DjpSVcE476rlEPB++awmP/dCEaEMtqbAP1Fqzkhn0VaUAegMzABJkaIMG8epNEiE3R' +
+'0funce75Mi4NR+MV7+3B6NUFPPnvY3jupslISJkKoW9PDld/sA+7Xt6B8SMV3Pjzx3Di0TkENQaJ' +
+'5A1qM8VRljKPgpg58pcNHyCz0ADSTnhNDTBBglCZruPhvz+PY4/M4Jqwg6772AB2vqwDd/zmKYwd' +
+'WQAJpMalb+vGSz81AA6Ah/76HJ69KfI7tej6K7RPUKwaWQT1FmiAlJEJykXZZh5cE02FoaEJkpYE' +
+'wGsKwNQGAnDhQAUP/915TJ5YwPCleZSG3WwWvwgYvryAYr8Tm5wn/2Mc5cm481c9RzXWobQPyBpS' +
+'ikgDGgJAVvMARzY0AARwc7Y5Ckn3vK4TV7+/D5YncN+fnsWpJ+cgsnDICnj0n85DSOCSUBO6Rl08' +
+'8g8XcObZ+VgjSKweKRG1xgcIEQnA9QE46aMgwwlHAmBuOFFepeMRd8rI1cU4FBzYn8exh2bw6D9e' +
+'wNihCjgrR0wI21vAzb9yIrT/pfha7/y+nXj+5gk8EWrDzJlF/WxQUgMUwEtREGW/5RlpgJdaABq0' +
+'pAGicYFVFaBzxMGV7+vFvtd3YfpsFbf+6ok4KqovxqFoph+YBBAsMg7cPonTT83jsnd247J39IQR' +
+'UUcceR28cxrVcrBUX2sAa1Nar7dCAwhevCkDN7UADB9gSyEBaBVYYeT37PTw9u/aAbcg8Pi/XMAz' +
+'109gfqLhFAktgX46LbrOg395DscemAnD0X68+suGQ+3L4Y7fOhVHRA00nDBRa3wAEGuAA8DbqABI' +
+'kyEA2xFSrBHHM2xf4Ozz82HIOb5kbgSh1TDv69wLZdz0S8dxUTgRHLwkD2HRkgCIdBi6NBPmVpgg' +
+'L7krBkrnA6xIA0Qjfl4x9Bw7XInDzHo1hblJbZYoNkvP3zqFw/fPIKgqGNC7aNoEtUQDEJkg23Ec' +
+'v1qtrhkFiWYeTYzCUCEEeI15QDTSgjpnMerTmyUB1CsKrGACyvABQb1VAnAt13V8NAHRxGqotEMI' +
+'QUbJFgGtMhNuqQa4Ui9HbEgDKFknioKIhC4kbGUwFBhsOGHO/AqhCxAh5dOsBZFBMoqCGhpARJv7' +
+'ihul35oEt84E6U0ZCv1APp0T1tACsIhEpquZQhJsT2C9UAGjtqA2vDnPzOD/NUEqymcOJ94TcPJZ' +
+'zYSFHYKIjHlA+iXk/kvyeO1XDENYtK6J16kn53H375+OBbFukBkFtWoewHAdJ1qQKwAQWcyEtQaQ' +
+'4QPSmk6KZ6gXDlVAcn0x9vTpxTSjdhkBcOYmSO+KNTZlKK0GWHYoASJkZoJIABPHFnDbb5zEFxts' +
+'hqEtMkG2rfcEtAZsJAoimBpgGRqg062KVmsAmBH2V2NfWKZ1woxYAyIBwFABXma+nE30wytV4rU/' +
+'OK9xLWaGUmpJAHE+awEDUsrGnoCERsooyJYALfPaOEHNByBl7BGwKQsy8kYLUZ1kOTXyZprgUYJH' +
+'SBzrctLHDZ6huflCLt61qtWDWAMawsgOWgCe5+v+JYN4vT6AtAbIpSCIGuEcRoaG8TrXRcwzCeZ7' +
+'u2gcm4QIZn0QEudC5wGYdYxUt2PyjRSAyWsc6mvW6hW0CnpXzAdgQ6NZAdByJsgKBQAQGCp+oQFQ' +
+'8ePdhUIBxWJxXfrJYKQHNRUMMK9kuwhzc3O4eO+eeLQqpbLfFfMaAgAnhdDccrSpAZYtAUApxujI' +
+'EN725lfg3//7bvT19cOyLJhg44/ZCTo1y40yI79qmT4/5un2jTx0+XLtmAOAlUJXVx6ve83LdFkr' +
+'dsWMTZkUTpikjFyAJUxHFr6oDc918cDDT6KyMB8xzVFpmBpAGGZHiCgVZgoRphSlQkCQTvXxEhFk' +
+'lMolXnyseY28NMtlIjXaCzsHO7aPoFDIQ6nWCMDzXS2AdJvybMl4HiaSLyK89S2vxRte/wrU6vXG' +
+'IFrzOxdWTZcaMNtCgq15a9vNtWyTMjUncwEguSu2ISesO3vp3YDkE2ZSypiyQMO0JO331gTFryoJ' +
+'IXylVLrFOCtEpAHmaG5jbQ3Qb8r45XKFN2qCOCJpSUsxi/n5SlOP8rXB0WpoUgC8HgGwQYqI7AMH' +
+'j1G9zk2Ea20wgI5iPhqs8dMk6/26GrOyiqharc16nlffvn3EaWtAc/BcBw8+/Ojc+PjkKaMvuWkN' +
+'ME+YnZ17+rnnDxweHOi9iCM+gzbLOXLrG8piu46JIO5/4NHD9XpwbEPfEqjJ01R0XecDYcz8lvhF' +
+'MSEkwJIBaU76AZA+SsST5oHOmidqvsHQieYk6ya/ucysT/pPon6yLum/5tXN4uV45ocAKHEeWFdQ' +
+'YcpKKb4wNnH/xMTUjwGYArBofLHfuhfjeO+eXbu+/ms+946JyWl16NAxWmV80AZGImW+M0z/dxWU' +
+'NbvJNQzaqNK4ro13v/NN9C//doP4gz/+mxKAWWNQb2hHzL/s0n1XDfT3W3fe8wRAVmLytCE56HM3' +
+'LL/E+bRqb+niFZ9rSvD0nnHzd2Y+M3vs5Ckwc/S9QQMABgGc0cvS9fU8migi0uUDey7asfvQ4eMQ' +
+'louuzs74Am0sL4TZQhHHTpzG8FB/qdRR3DU9M/sUgJqmphfjhJaa9H1v9/Ztw/1PPn0QtWoNs7Oz' +
+'WBltATiOixMnzuCS/bvtgTBwCQXg6s5fNLdTmnkuSAKww0WrS7q6St7E5Ax6egbWWHpow3EcnDs/' +
+'EX8v6fDw4J4XDhzxASwAEOvSAF2Wu2j3jssAQqVSQ6+ULTQ/W3+pQy/dYHauEi9Sbhsd2gGgqB2x' +
+'BEDN+gCpy3rCCGjP5OQ0FHO0idGeDTexHRkoxvjEJHZsGxkE0APgnO5TYc6x1hKAIKJtu3dtGzp1' +
+'+hyKxY5oB6wpDWibIRenTp3D6OhQl5RyMAiC5w0TRCtpACW+rM8aGR7cPzTYX3ziqQPw/dzmm4gt' +
+'YOaYGZ7n4cTJs3jVK67xw++l23723AVtURLhaFIDEuGnG47+S33fo8mpWZQ6XUxPT6ONtfeD7dgR' +
+'j6NQyNHQ0MCOUAA2ANmMBpAhhGJo//eFy6lgFsjn823zsw6cnhyHUhw74kcfe8ozfMCKAkjOAYb2' +
+'7tk5cubsBTiuF3v35h1w2xwpRmgxZrBj+/AIgA4AY7pfsZYGyIi6uzv3hHOArocefQbMwNTUVFsD' +
+'mjdDIUmcDgfv6OhwH4CIjie0gJfVAF3J2bVjWzgB65TnL0ygs7NrnROwthZUqzWcPHUOV1y2txiu' +
+'JA/Pzc0/spYJEob5ye/Zs/NiZka5XEVPr4821gfP9xAN3nA9yB4c6Nt+cG5eLvPGDCdNUKNS7769' +
+'u3ZGX1NfqwfR+s//C/PDnH5TRq+kxun8fBkdxQJGhgd2Hjx01BBAwgQl7L/I5fyd4RJE3+TUdNjI' +
+'PKSc0AJg/T+JxNNnK5Uly3VuterJOpzh3hmts5DWKExy3/j6l2J4eAAjI4PbjG9UF6YQrMaBWRCu' +
+'fu4fHRn0Bvp7USzkUS4vmD9as+IP3cSHWL5eXGTUizk6v/IDubodM7+++qs+ENbsg2RxLlE/5pr1' +
+'Ew8H25aFnp6u2CFvGx0e0JHQGdMEJTWgkTo7d4xe3NfXg1KpiLe86TWg9ONtc3eKuVX3yatei5m1' +
+'AIa6pRT9QaCeb2YporBzx7Zd0chnRkgKbaSLsMLZcK6/rzecU53n5TSAEkw/HPkFy86BpJtq3LRB' +
+'IK6jq7NDhPOqPi0A0+cuuxq6EMas5bGJaVQWFWgTbrqVTdEX9f4ZvmfB9/3Il5bW2hNmnZbDB4om' +
+'Lpw/h7n5RYCa+3E0ToY4Jp9XiGSYk/WMvHmlxDEn7yN5ffN4mTzrM808G+0leJqVbG81njbfjFJH' +
+'Hr4no4lZ3fjRT06GoWxQ+eFHn7rTz/1Tv5QSrBQpZrAmfVMaQJyNOXHOPESjztJfs54uxFJWl5q1' +
+'zYuZRzD+RzAPEufoJFln2TyMv8axwUheJPGRVSMFEHe4ZckqMy8cOXLin5f7xVUyyPypwhKAHp13' +
+'IjJCVW4iHGAz30Q5mmx3I+dwyvbWE36x0ck1AFW9Gb+g06qmWkMQVuLEQEtuVldyjR/vFJqyjxNb' +
+'6+mTA6DV96HMvkx0ej2pAZZxoBL5QJ8oDKIW3jxnfA5twj1xUhPMjjd9wGpOOEgIgUzaxFG8RZ4F' +
+'Tgxos9N1atajtd+S1LytA26p8NKbQE7/0+BtpNakNtpoo4022vgf7lRPtKCE39oAAAAASUVORK5C' +
+'YII='
+);
+
+lib.resource.add('hterm/concat/date', 'text/plain',
+'Thu, 05 Dec 2019 19:54:18 +0000'
+);
+
+lib.resource.add('hterm/changelog/version', 'text/plain',
+'1.85'
+);
+
+lib.resource.add('hterm/changelog/date', 'text/plain',
+'2019-06-17'
+);
+
+lib.resource.add('hterm/git/HEAD', 'text/plain',
+'530691a7e349cc0038ef14f1eb2a7c6ce8971e73'
+);
+
+// This file was generated by libdot/bin/concat.sh.
+// It has been marked read-only for your safety.  Rather than
+// edit it directly, please modify one of these source files.
+//
+// hterm/js/hterm.js
+// hterm/js/hterm_accessibility_reader.js
+// hterm/js/hterm_contextmenu.js
+// hterm/js/hterm_frame.js
+// hterm/js/hterm_keyboard.js
+// hterm/js/hterm_keyboard_bindings.js
+// hterm/js/hterm_keyboard_keymap.js
+// hterm/js/hterm_keyboard_keypattern.js
+// hterm/js/hterm_options.js
+// hterm/js/hterm_parser.js
+// hterm/js/hterm_parser_identifiers.js
+// hterm/js/hterm_preference_manager.js
+// hterm/js/hterm_pubsub.js
+// hterm/js/hterm_screen.js
+// hterm/js/hterm_scrollport.js
+// hterm/js/hterm_terminal.js
+// hterm/js/hterm_terminal_io.js
+// hterm/js/hterm_text_attributes.js
+// hterm/js/hterm_vt.js
+// hterm/js/hterm_vt_character_map.js
+// hterm/audio/bell.ogg
+// hterm/images/icon-96.png
+
+'use strict';
+
+// SOURCE FILE: hterm/js/hterm.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Declares the hterm.* namespace and some basic shared utilities
+ * that are too small to deserve dedicated files.
+ */
+var hterm = {};
+
+/**
+ * The type of window hosting hterm.
+ *
+ * This is set as part of hterm.init().  The value is invalid until
+ * initialization completes.
+ */
+hterm.windowType = null;
+
+/**
+ * The OS we're running under.
+ *
+ * Used when setting up OS-specific behaviors.
+ *
+ * This is set as part of hterm.init().  The value is invalid until
+ * initialization completes.
+ */
+hterm.os = null;
+
+/**
+ * Warning message to display in the terminal when browser zoom is enabled.
+ *
+ * You can replace it with your own localized message.
+ */
+hterm.zoomWarningMessage = 'ZOOM != 100%';
+
+/**
+ * Brief overlay message displayed when text is copied to the clipboard.
+ *
+ * By default it is the unicode BLACK SCISSORS character, but you can
+ * replace it with your own localized message.
+ *
+ * This is only displayed when the 'enable-clipboard-notice' preference
+ * is enabled.
+ */
+hterm.notifyCopyMessage = '\u2702';
+
+
+/**
+ * Text shown in a desktop notification for the terminal
+ * bell.  \u226a is a unicode EIGHTH NOTE, %(title) will
+ * be replaced by the terminal title.
+ */
+hterm.desktopNotificationTitle = '\u266A %(title) \u266A';
+
+/**
+ * The hterm init function, registered with lib.registerInit().
+ *
+ * This is called during lib.init().
+ *
+ * @param {function} onInit The function lib.init() wants us to invoke when
+ *     initialization is complete.
+ */
+lib.registerInit('hterm', function(onInit) {
+  function initOs(os) {
+    hterm.os = os;
+
+    onInit();
+  }
+
+  function initMessageManager() {
+    lib.i18n.getAcceptLanguages((languages) => {
+      if (!hterm.messageManager)
+        hterm.messageManager = new lib.MessageManager(languages);
+
+      // If OS detection fails, then we'll still set the value to something.
+      // The OS logic in hterm tends to be best effort anyways.
+      lib.f.getOs().then(initOs).catch(initOs);
+    });
+  }
+
+  function onWindow(window) {
+    hterm.windowType = window.type;
+    initMessageManager();
+  }
+
+  function onTab(tab) {
+    if (tab && window.chrome) {
+      chrome.windows.get(tab.windowId, null, onWindow);
+    } else {
+      // TODO(rginda): This is where we end up for a v1 app's background page.
+      // Maybe windowType = 'none' would be more appropriate, or something.
+      hterm.windowType = 'normal';
+      initMessageManager();
+    }
+  }
+
+  if (!hterm.defaultStorage) {
+    if (window.chrome && chrome.storage && chrome.storage.sync) {
+      hterm.defaultStorage = new lib.Storage.Chrome(chrome.storage.sync);
+    } else {
+      hterm.defaultStorage = new lib.Storage.Local();
+    }
+  }
+
+  // The chrome.tabs API is not supported in packaged apps, and detecting if
+  // you're a packaged app is a little awkward.
+  var isPackagedApp = false;
+  if (window.chrome && chrome.runtime && chrome.runtime.getManifest) {
+    var manifest = chrome.runtime.getManifest();
+    isPackagedApp = manifest.app && manifest.app.background;
+  }
+
+  if (isPackagedApp) {
+    // Packaged apps are never displayed in browser tabs.
+    setTimeout(onWindow.bind(null, {type: 'popup'}), 0);
+  } else {
+    if (window.chrome && chrome.tabs) {
+      // The getCurrent method gets the tab that is "currently running", not the
+      // topmost or focused tab.
+      chrome.tabs.getCurrent(onTab);
+    } else {
+      setTimeout(onWindow.bind(null, {type: 'normal'}), 0);
+    }
+  }
+});
+
+/**
+ * Return decimal { width, height } for a given dom node.
+ */
+hterm.getClientSize = function(dom) {
+  return dom.getBoundingClientRect();
+};
+
+/**
+ * Return decimal width for a given dom node.
+ */
+hterm.getClientWidth = function(dom) {
+  return dom.getBoundingClientRect().width;
+};
+
+/**
+ * Return decimal height for a given dom node.
+ */
+hterm.getClientHeight = function(dom) {
+  return dom.getBoundingClientRect().height;
+};
+
+/**
+ * Copy the specified text to the system clipboard.
+ *
+ * We'll create selections on demand based on the content to copy.
+ *
+ * @param {HTMLDocument} document The document with the selection to copy.
+ * @param {string} str The string data to copy out.
+ */
+hterm.copySelectionToClipboard = function(document, str) {
+  // Request permission if need be.
+  const requestPermission = () => {
+    // Use the Permissions API if available.
+    if (navigator.permissions && navigator.permissions.query) {
+      return navigator.permissions.query({name: 'clipboard-write'})
+        .then((status) => {
+          const checkState = (resolve, reject) => {
+            switch (status.state) {
+              case 'granted':
+                return resolve();
+              case 'denied':
+                return reject();
+              default:
+                // Wait for the user to approve/disprove.
+                return new Promise((resolve, reject) => {
+                  status.onchange = () => checkState(resolve, reject);
+                });
+            }
+          };
+
+          return new Promise(checkState);
+        })
+        // If the platform doesn't support "clipboard-write", or is denied,
+        // we move on to the copying step anyways.
+        .catch(() => Promise.resolve());
+    } else {
+      // No permissions API, so resolve right away.
+      return Promise.resolve();
+    }
+  };
+
+  // Write to the clipboard.
+  const writeClipboard = () => {
+    // Use the Clipboard API if available.
+    if (navigator.clipboard && navigator.clipboard.writeText) {
+      // If this fails (perhaps due to focus changing windows), fallback to the
+      // legacy copy method.
+      return navigator.clipboard.writeText(str)
+        .catch(execCommand);
+    } else {
+      // No Clipboard API, so use the old execCommand style.
+      return execCommand();
+    }
+  };
+
+  // Write to the clipboard using the legacy execCommand method.
+  // TODO: Once we can rely on the Clipboard API everywhere, we can simplify
+  // this a lot by deleting the custom selection logic.
+  const execCommand = () => {
+    const copySource = document.createElement('pre');
+    copySource.id = 'hterm:copy-to-clipboard-source';
+    copySource.textContent = str;
+    copySource.style.cssText = (
+        '-webkit-user-select: text;' +
+        '-moz-user-select: text;' +
+        'position: absolute;' +
+        'top: -99px');
+
+    document.body.appendChild(copySource);
+
+    const selection = document.getSelection();
+    const anchorNode = selection.anchorNode;
+    const anchorOffset = selection.anchorOffset;
+    const focusNode = selection.focusNode;
+    const focusOffset = selection.focusOffset;
+
+    // FF sometimes throws NS_ERROR_FAILURE exceptions when we make this call.
+    // Catch it because a failure here leaks the copySource node.
+    // https://bugzilla.mozilla.org/show_bug.cgi?id=1178676
+    try {
+      selection.selectAllChildren(copySource);
+    } catch (ex) {}
+
+    try {
+      document.execCommand('copy');
+    } catch (firefoxException) {
+      // Ignore this. FF throws an exception if there was an error, even
+      // though the spec says just return false.
+    }
+
+    // IE doesn't support selection.extend.  This means that the selection won't
+    // return on IE.
+    if (selection.extend) {
+      // When running in the test harness, we won't have any related nodes.
+      if (anchorNode) {
+        selection.collapse(anchorNode, anchorOffset);
+      }
+      if (focusNode) {
+        selection.extend(focusNode, focusOffset);
+      }
+    }
+
+    copySource.parentNode.removeChild(copySource);
+
+    // Since execCommand is synchronous, resolve right away.
+    return Promise.resolve();
+  };
+
+  // Kick it all off!
+  return requestPermission().then(writeClipboard);
+};
+
+/**
+ * Paste the system clipboard into the element with focus.
+ *
+ * Note: In Chrome/Firefox app/extension environments, you'll need the
+ * "clipboardRead" permission.  In other environments, this might always
+ * fail as the browser frequently blocks access for security reasons.
+ *
+ * @param {HTMLDocument} The document to paste into.
+ * @return {boolean} True if the paste succeeded.
+ */
+hterm.pasteFromClipboard = function(document) {
+  try {
+    return document.execCommand('paste');
+  } catch (firefoxException) {
+    // Ignore this.  FF 40 and older would incorrectly throw an exception if
+    // there was an error instead of returning false.
+    return false;
+  }
+};
+
+/**
+ * Return a formatted message in the current locale.
+ *
+ * @param {string} name The name of the message to return.
+ * @param {Array<string>=} args The message arguments, if required.
+ * @param {string=} string The default message text.
+ * @return {string} The localized message.
+ */
+hterm.msg = function(name, args = [], string) {
+  return hterm.messageManager.get('HTERM_' + name, args, string);
+};
+
+/**
+ * Create a new notification.
+ *
+ * @param {Object} params Various parameters for the notification.
+ * @param {string} params.title The title (defaults to the window's title).
+ * @param {string} params.body The message body (main text).
+ */
+hterm.notify = function(params) {
+  var def = (curr, fallback) => curr !== undefined ? curr : fallback;
+  if (params === undefined || params === null)
+    params = {};
+
+  // Merge the user's choices with the default settings.  We don't take it
+  // directly in case it was stuffed with excess junk.
+  var options = {
+      'body': params.body,
+      'icon': def(params.icon, lib.resource.getDataUrl('hterm/images/icon-96')),
+  };
+
+  var title = def(params.title, window.document.title);
+  if (!title)
+    title = 'hterm';
+  title = lib.f.replaceVars(hterm.desktopNotificationTitle, {'title': title});
+
+  var n = new Notification(title, options);
+  n.onclick = function() {
+    window.focus();
+    this.close();
+  };
+  return n;
+};
+
+/**
+ * Launches url in a new tab.
+ *
+ * @param {string} url URL to launch in a new tab.
+ */
+hterm.openUrl = function(url) {
+  if (window.chrome && chrome.browser && chrome.browser.openTab) {
+    // For Chrome v2 apps, we need to use this API to properly open windows.
+    chrome.browser.openTab({'url': url});
+  } else {
+    const win = lib.f.openWindow(url, '_blank');
+    win.focus();
+  }
+};
+
+/**
+ * Constructor for a hterm.Size record.
+ *
+ * Instances of this class have public read/write members for width and height.
+ *
+ * @param {integer} width The width of this record.
+ * @param {integer} height The height of this record.
+ */
+hterm.Size = function(width, height) {
+  this.width = width;
+  this.height = height;
+};
+
+/**
+ * Adjust the width and height of this record.
+ *
+ * @param {integer} width The new width of this record.
+ * @param {integer} height The new height of this record.
+ */
+hterm.Size.prototype.resize = function(width, height) {
+  this.width = width;
+  this.height = height;
+};
+
+/**
+ * Return a copy of this record.
+ *
+ * @return {hterm.Size} A new hterm.Size instance with the same width and
+ * height.
+ */
+hterm.Size.prototype.clone = function() {
+  return new hterm.Size(this.width, this.height);
+};
+
+/**
+ * Set the height and width of this instance based on another hterm.Size.
+ *
+ * @param {hterm.Size} that The object to copy from.
+ */
+hterm.Size.prototype.setTo = function(that) {
+  this.width = that.width;
+  this.height = that.height;
+};
+
+/**
+ * Test if another hterm.Size instance is equal to this one.
+ *
+ * @param {hterm.Size} that The other hterm.Size instance.
+ * @return {boolean} True if both instances have the same width/height, false
+ *     otherwise.
+ */
+hterm.Size.prototype.equals = function(that) {
+  return this.width == that.width && this.height == that.height;
+};
+
+/**
+ * Return a string representation of this instance.
+ *
+ * @return {string} A string that identifies the width and height of this
+ *     instance.
+ */
+hterm.Size.prototype.toString = function() {
+  return '[hterm.Size: ' + this.width + ', ' + this.height + ']';
+};
+
+/**
+ * Constructor for a hterm.RowCol record.
+ *
+ * Instances of this class have public read/write members for row and column.
+ *
+ * This class includes an 'overflow' bit which is use to indicate that an
+ * attempt has been made to move the cursor column passed the end of the
+ * screen.  When this happens we leave the cursor column set to the last column
+ * of the screen but set the overflow bit.  In this state cursor movement
+ * happens normally, but any attempt to print new characters causes a cr/lf
+ * first.
+ *
+ * @param {integer} row The row of this record.
+ * @param {integer} column The column of this record.
+ * @param {boolean} opt_overflow Optional boolean indicating that the RowCol
+ *     has overflowed.
+ */
+hterm.RowCol = function(row, column, opt_overflow) {
+  this.row = row;
+  this.column = column;
+  this.overflow = !!opt_overflow;
+};
+
+/**
+ * Adjust the row and column of this record.
+ *
+ * @param {integer} row The new row of this record.
+ * @param {integer} column The new column of this record.
+ * @param {boolean} opt_overflow Optional boolean indicating that the RowCol
+ *     has overflowed.
+ */
+hterm.RowCol.prototype.move = function(row, column, opt_overflow) {
+  this.row = row;
+  this.column = column;
+  this.overflow = !!opt_overflow;
+};
+
+/**
+ * Return a copy of this record.
+ *
+ * @return {hterm.RowCol} A new hterm.RowCol instance with the same row and
+ * column.
+ */
+hterm.RowCol.prototype.clone = function() {
+  return new hterm.RowCol(this.row, this.column, this.overflow);
+};
+
+/**
+ * Set the row and column of this instance based on another hterm.RowCol.
+ *
+ * @param {hterm.RowCol} that The object to copy from.
+ */
+hterm.RowCol.prototype.setTo = function(that) {
+  this.row = that.row;
+  this.column = that.column;
+  this.overflow = that.overflow;
+};
+
+/**
+ * Test if another hterm.RowCol instance is equal to this one.
+ *
+ * @param {hterm.RowCol} that The other hterm.RowCol instance.
+ * @return {boolean} True if both instances have the same row/column, false
+ *     otherwise.
+ */
+hterm.RowCol.prototype.equals = function(that) {
+  return (this.row == that.row && this.column == that.column &&
+          this.overflow == that.overflow);
+};
+
+/**
+ * Return a string representation of this instance.
+ *
+ * @return {string} A string that identifies the row and column of this
+ *     instance.
+ */
+hterm.RowCol.prototype.toString = function() {
+  return ('[hterm.RowCol: ' + this.row + ', ' + this.column + ', ' +
+          this.overflow + ']');
+};
+// SOURCE FILE: hterm/js/hterm_accessibility_reader.js
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * AccessibilityReader responsible for rendering command output for AT.
+ *
+ * Renders command output for Assistive Technology using a live region. We don't
+ * use the visible rows of the terminal for rendering command output to the
+ * screen reader because the rendered content may be different from what we want
+ * read out by a screen reader. For example, we may not actually render every
+ * row of a large piece of output to the screen as it wouldn't be performant.
+ * But we want the screen reader to read it all out in order.
+ *
+ * @param {HTMLDivElement} div The div element where the live region should be
+ *     added.
+ */
+hterm.AccessibilityReader = function(div) {
+  this.document_ = div.ownerDocument;
+
+  // The live region element to add text to.
+  const liveRegion = this.document_.createElement('div');
+  liveRegion.id = 'hterm:accessibility-live-region';
+  liveRegion.style.cssText = `position: absolute;
+                              width: 0; height: 0;
+                              overflow: hidden;
+                              left: 0; top: 0;`;
+  div.appendChild(liveRegion);
+
+  // Whether command output should be rendered for Assistive Technology.
+  // This isn't always enabled because it has an impact on performance.
+  this.accessibilityEnabled = false;
+
+  // This live element is used for command output.
+  this.liveElement_ = this.document_.createElement('p');
+  this.liveElement_.setAttribute('aria-live', 'polite');
+  this.liveElement_.setAttribute('aria-label', '');
+  liveRegion.appendChild(this.liveElement_);
+
+  // This live element is used for speaking out the current screen when
+  // navigating through the scrollback buffer. It will interrupt existing
+  // announcements.
+  this.assertiveLiveElement_ = this.document_.createElement('p');
+  this.assertiveLiveElement_.setAttribute('aria-live', 'assertive');
+  this.assertiveLiveElement_.setAttribute('aria-label', '');
+  liveRegion.appendChild(this.assertiveLiveElement_);
+
+  // A queue of updates to announce.
+  this.queue_ = [];
+
+  // A timer which tracks when next to add items to the live region. null when
+  // not running. This is used to combine updates that occur in a small window,
+  // as well as to avoid too much output being added to the live region in one
+  // go which can cause the renderer to hang.
+  this.nextReadTimer_ = null;
+
+  // This is set to true if the cursor is about to update position on the
+  // screen. i.e. beforeCursorChange has been called but not afterCursorChange.
+  this.cursorIsChanging_ = false;
+
+  // This tracks changes that would be added to queue_ while the cursor is
+  // changing. This is done so that we can decide to discard these changes if
+  // we announce something as a result of the cursor change.
+  this.cursorChangeQueue_ = [];
+
+  // The string of text on the row that the cursor was last on. Only valid while
+  // cursorIsChanging_ is true.
+  this.lastCursorRowString_ = null;
+
+  // The row that the cursor was last on. Only valid while cursorIsChanging_ is
+  // true.
+  this.lastCursorRow_ = null;
+
+  // The column that the cursor was last on. Only valid while cursorIsChanging_
+  // is true.
+  this.lastCursorColumn_ = null;
+
+  // True if a keypress has been performed since the last cursor change.
+  this.hasUserGesture = false;
+};
+
+/**
+ * Delay in ms to use for merging strings to output.
+ *
+ * We merge strings together to avoid hanging the terminal and to ensure that
+ * aria updates make it to the screen reader. We want this to be short so
+ * there's not a big delay between typing/executing commands and hearing output.
+ *
+ * @constant
+ * @type {integer}
+ */
+hterm.AccessibilityReader.DELAY = 50;
+
+/**
+ * Enable accessibility-friendly features that have a performance impact.
+ *
+ * @param {boolean} enabled Whether to enable accessibility-friendly features.
+ */
+hterm.AccessibilityReader.prototype.setAccessibilityEnabled =
+    function(enabled) {
+  if (!enabled) {
+    this.clear();
+  }
+
+  this.accessibilityEnabled = enabled;
+};
+
+/**
+ * Decorate the document where the terminal <x-screen> resides. This is needed
+ * for listening to keystrokes on the screen.
+ *
+ * @param {HTMLDocument} doc The document where the <x-screen> resides.
+ */
+hterm.AccessibilityReader.prototype.decorate = function(doc) {
+  const handlers = ['keydown', 'keypress', 'keyup', 'textInput'];
+  handlers.forEach((handler) => {
+    doc.addEventListener(handler, () => { this.hasUserGesture = true; });
+  });
+};
+
+/**
+ * This should be called before the cursor on the screen is about to get
+ * updated. This allows cursor changes to be tracked and related notifications
+ * to be announced.
+ *
+ * @param {string} cursorRowString The text in the row that the cursor is
+ *     currently on.
+ * @param {integer} cursorRow The index of the row that the cursor is currently
+ *     on, including rows in the scrollback buffer.
+ * @param {integer} cursorColumn The index of the column that the cursor is
+ *     currently on.
+ */
+hterm.AccessibilityReader.prototype.beforeCursorChange =
+    function(cursorRowString, cursorRow, cursorColumn) {
+  // If accessibility is enabled we don't announce selection changes as these
+  // can have a performance impact.
+  if (!this.accessibilityEnabled) {
+    return;
+  }
+
+  // If there is no user gesture that can be tied to the cursor change, we
+  // don't want to announce anything.
+  if (!this.hasUserGesture || this.cursorIsChanging_) {
+    return;
+  }
+
+  this.cursorIsChanging_ = true;
+  this.lastCursorRowString_ = cursorRowString;
+  this.lastCursorRow_ = cursorRow;
+  this.lastCursorColumn_ = cursorColumn;
+};
+
+/**
+ * This should be called after the cursor on the screen has been updated. Note
+ * that several updates to the cursor may have happened between
+ * beforeCursorChange and afterCursorChange.
+ *
+ * This allows cursor changes to be tracked and related notifications to be
+ * announced.
+ *
+ * @param {string} cursorRowString The text in the row that the cursor is
+ *     currently on.
+ * @param {integer} cursorRow The index of the row that the cursor is currently
+ *     on, including rows in the scrollback buffer.
+ * @param {integer} cursorColumn The index of the column that the cursor is
+ *     currently on.
+ */
+hterm.AccessibilityReader.prototype.afterCursorChange =
+    function(cursorRowString, cursorRow, cursorColumn) {
+  // This can happen if clear() is called midway through a cursor change.
+  if (!this.cursorIsChanging_) {
+    return;
+  }
+  this.cursorIsChanging_ = false;
+
+  if (!this.announceAction_(cursorRowString, cursorRow, cursorColumn)) {
+    // If we don't announce a special action, we re-queue all the output that
+    // was queued during the selection change.
+    for (let i = 0; i < this.cursorChangeQueue_.length; ++i) {
+      this.announce(this.cursorChangeQueue_[i]);
+    }
+  }
+
+  this.cursorChangeQueue_ = [];
+  this.lastCursorRowString_ = null;
+  this.lastCursorRow_ = null;
+  this.lastCursorColumn_ = null;
+  this.hasUserGesture = false;
+};
+
+/**
+ * Announce the command output.
+ *
+ * @param {string} str The string to announce using a live region.
+ */
+hterm.AccessibilityReader.prototype.announce = function(str) {
+  if (!this.accessibilityEnabled) {
+    return;
+  }
+
+  // If the cursor is in the middle of changing, we queue up the output
+  // separately as we may not want it to be announced if it's part of a cursor
+  // change announcement.
+  if (this.cursorIsChanging_) {
+    this.cursorChangeQueue_.push(str);
+    return;
+  }
+
+  // Don't append newlines to the queue if the queue is empty. It won't have any
+  // impact.
+  if (str == '\n' && this.queue_.length > 0) {
+    this.queue_.push('');
+    // We don't need to trigger an announcement on newlines because they won't
+    // change the existing content that's output.
+    return;
+  }
+
+  if (this.queue_.length == 0) {
+    this.queue_.push(str);
+  } else {
+    // We put a space between strings that appear on the same line.
+    // TODO(raymes): We should check the location on the row and not add a space
+    // if the strings are joined together.
+    let padding = '';
+    if (this.queue_[this.queue_.length - 1].length != 0) {
+      padding = ' ';
+    }
+    this.queue_[this.queue_.length - 1] += padding + str;
+  }
+
+  // If we've already scheduled text being added to the live region, wait for it
+  // to happen.
+  if (this.nextReadTimer_) {
+    return;
+  }
+
+  // If there's only one item in the queue, we may get other text being added
+  // very soon after. In that case, wait a small delay so we can merge the
+  // related strings.
+  if (this.queue_.length == 1) {
+    this.nextReadTimer_ = setTimeout(this.addToLiveRegion_.bind(this),
+                                     hterm.AccessibilityReader.DELAY);
+  } else {
+    throw new Error(
+        'Expected only one item in queue_ or nextReadTimer_ to be running.');
+  }
+};
+
+/**
+ * Voice an announcement that will interrupt other announcements.
+ *
+ * @param {string} str The string to announce using a live region.
+ */
+hterm.AccessibilityReader.prototype.assertiveAnnounce = function(str) {
+  if (this.hasUserGesture && str == ' ') {
+    str = hterm.msg('SPACE_CHARACTER', [], 'Space');
+  }
+
+  // If the same string is announced twice, an attribute change won't be
+  // registered and the screen reader won't know that the string has changed.
+  // So we slightly change the string to ensure that the attribute change gets
+  // registered.
+  str = str.trim();
+  if (str == this.assertiveLiveElement_.getAttribute('aria-label')) {
+    str = '\n' + str;
+  }
+
+  this.clear();
+  this.assertiveLiveElement_.setAttribute('aria-label', str);
+};
+
+/**
+ * Add a newline to the text that will be announced to the live region.
+ */
+hterm.AccessibilityReader.prototype.newLine = function() {
+  this.announce('\n');
+};
+
+/**
+ * Clear the live region and any in-flight announcements.
+ */
+hterm.AccessibilityReader.prototype.clear = function() {
+  this.liveElement_.setAttribute('aria-label', '');
+  this.assertiveLiveElement_.setAttribute('aria-label', '');
+  clearTimeout(this.nextReadTimer_);
+  this.nextReadTimer_ = null;
+  this.queue_ = [];
+
+  this.cursorIsChanging_ = false;
+  this.cursorChangeQueue_ = [];
+  this.lastCursorRowString_ = null;
+  this.lastCursorRow_ = null;
+  this.lastCursorColumn_ = null;
+  this.hasUserGesture = false;
+};
+
+/**
+ * This will announce an action that is related to a cursor change, for example
+ * when the user deletes a character we want the character deleted to be
+ * announced. Similarly, when the user moves the cursor along the line, we want
+ * the characters selected to be announced.
+ *
+ * Note that this function is a heuristic. Because of the nature of terminal
+ * emulators, we can't distinguish input and output, which means we don't really
+ * know what output is the result of a keypress and what isn't. Also in some
+ * terminal applications certain announcements may make sense whereas others may
+ * not. This function should try to account for the most common cases.
+ *
+ * @param {string} cursorRowString The text in the row that the cursor is
+ *     currently on.
+ * @param {integer} cursorRow The index of the row that the cursor is currently
+ *     on, including rows in the scrollback buffer.
+ * @param {integer} cursorColumn The index of the column that the cursor is
+ *     currently on.
+ */
+hterm.AccessibilityReader.prototype.announceAction_ =
+    function(cursorRowString, cursorRow, cursorColumn) {
+  // If the cursor changes rows, we don't announce anything at present.
+  if (this.lastCursorRow_ != cursorRow) {
+    return false;
+  }
+
+  // The case when the row of text hasn't changed at all.
+  if (this.lastCursorRowString_ == cursorRowString) {
+    // Moving the cursor along the line. We check that no significant changes
+    // have been queued. If they have, it may not just be a cursor movement and
+    // it may be better to read those out.
+    if (this.lastCursorColumn_ != cursorColumn &&
+        this.cursorChangeQueue_.join('').trim() == '') {
+      // Announce the text between the old cursor position and the new one.
+      const start = Math.min(this.lastCursorColumn_, cursorColumn);
+      const len = Math.abs(cursorColumn - this.lastCursorColumn_);
+      this.assertiveAnnounce(
+          lib.wc.substr(this.lastCursorRowString_, start, len));
+      return true;
+    }
+    return false;
+  }
+
+  // The case when the row of text has changed.
+  if (this.lastCursorRowString_ != cursorRowString) {
+    // Spacebar. We manually announce this character since the screen reader may
+    // not announce the whitespace in a live region.
+    if (this.lastCursorColumn_ + 1 == cursorColumn) {
+      if (lib.wc.substr(cursorRowString, cursorColumn - 1, 1) == ' ' &&
+          this.cursorChangeQueue_.length > 0 &&
+          this.cursorChangeQueue_[0] == ' ') {
+        this.assertiveAnnounce(' ');
+        return true;
+      }
+    }
+
+    // Backspace and deletion.
+    // The position of the characters deleted is right after the current
+    // position of the cursor in the case of backspace and delete.
+    const cursorDeleted = cursorColumn;
+    // Check that the current row string is shorter than the previous. Also
+    // check that the start of the strings (up to the cursor) match.
+    if (lib.wc.strWidth(cursorRowString) <=
+        lib.wc.strWidth(this.lastCursorRowString_) &&
+        lib.wc.substr(this.lastCursorRowString_, 0, cursorDeleted) ==
+        lib.wc.substr(cursorRowString, 0, cursorDeleted)) {
+      // Find the length of the current row string ignoring space characters.
+      // These may be inserted at the end of the string when deleting characters
+      // so they should be ignored.
+      let lengthOfCurrentRow = lib.wc.strWidth(cursorRowString);
+      for (; lengthOfCurrentRow > 0; --lengthOfCurrentRow) {
+        if (lengthOfCurrentRow == cursorDeleted ||
+            lib.wc.substr(cursorRowString, lengthOfCurrentRow - 1, 1) != ' ') {
+          break;
+        }
+      }
+
+      const numCharsDeleted =
+          lib.wc.strWidth(this.lastCursorRowString_) - lengthOfCurrentRow;
+
+      // Check that the end of the strings match.
+      const lengthOfEndOfString = lengthOfCurrentRow - cursorDeleted;
+      const endOfLastRowString = lib.wc.substr(
+          this.lastCursorRowString_, cursorDeleted + numCharsDeleted,
+          lengthOfEndOfString);
+      const endOfCurrentRowString =
+          lib.wc.substr(cursorRowString, cursorDeleted, lengthOfEndOfString);
+      if (endOfLastRowString == endOfCurrentRowString) {
+        const deleted = lib.wc.substr(
+            this.lastCursorRowString_, cursorDeleted, numCharsDeleted);
+        if (deleted != '') {
+          this.assertiveAnnounce(deleted);
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  return false;
+};
+
+/**
+ * Add text from queue_ to the live region.
+ *
+ */
+hterm.AccessibilityReader.prototype.addToLiveRegion_ = function() {
+  this.nextReadTimer_ = null;
+
+  let str = this.queue_.join('\n').trim();
+
+  // If the same string is announced twice, an attribute change won't be
+  // registered and the screen reader won't know that the string has changed.
+  // So we slightly change the string to ensure that the attribute change gets
+  // registered.
+  if (str == this.liveElement_.getAttribute('aria-label')) {
+    str = '\n' + str;
+  }
+
+  this.liveElement_.setAttribute('aria-label', str);
+  this.queue_ = [];
+};
+// SOURCE FILE: hterm/js/hterm_contextmenu.js
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Context menu handling.
+ */
+
+/**
+ * Manage the context menu usually shown when right clicking.
+ */
+hterm.ContextMenu = function() {
+  // The document that contains this context menu.
+  this.document_ = null;
+  // The generated context menu (i.e. HTML elements).
+  this.element_ = null;
+  // The structured menu (i.e. JS objects).
+  this.menu_ = [];
+};
+
+/**
+ * Constant to add a separator to the context menu.
+ */
+hterm.ContextMenu.SEPARATOR = {};
+
+/**
+ * Bind context menu to a specific document element.
+ *
+ * @param {HTMLDocument} document The document to use when creating elements.
+ */
+hterm.ContextMenu.prototype.setDocument = function(document) {
+  if (this.element_) {
+    this.element_.remove();
+    this.element_ = null;
+  }
+  this.document_ = document;
+  this.regenerate_();
+  this.document_.body.appendChild(this.element_);
+};
+
+/**
+ * Regenerate the HTML elements based on internal menu state.
+ */
+hterm.ContextMenu.prototype.regenerate_ = function() {
+  if (!this.element_) {
+    this.element_ = this.document_.createElement('menu');
+    this.element_.id = 'hterm:context-menu';
+    this.element_.style.cssText = `
+        display: none;
+        border: solid 1px;
+        position: absolute;
+    `;
+  } else {
+    this.hide();
+  }
+
+  // Clear out existing menu entries.
+  while (this.element_.firstChild) {
+    this.element_.removeChild(this.element_.firstChild);
+  }
+
+  this.menu_.forEach(([name, action]) => {
+    const menuitem = this.document_.createElement('menuitem');
+    if (name === hterm.ContextMenu.SEPARATOR) {
+      menuitem.innerHTML = '<hr>';
+      menuitem.className = 'separator';
+    } else {
+      menuitem.innerText = name;
+      menuitem.addEventListener('mousedown', function(e) {
+        e.preventDefault();
+        action(e);
+      });
+    }
+    this.element_.appendChild(menuitem);
+  });
+};
+
+/**
+ * Set all the entries in the context menu.
+ *
+ * This is an array of arrays.  The first element in the array is the string to
+ * display while the second element is the function to call.
+ *
+ * The first element may also be the SEPARATOR constant to add a separator.
+ *
+ * This resets all existing menu entries.
+ *
+ * @param {Array<Array<string, function(Event)>>} items The menu entries.
+ */
+hterm.ContextMenu.prototype.setItems = function(items) {
+  this.menu_ = items;
+  this.regenerate_();
+};
+
+/**
+ * Show the context menu.
+ *
+ * The event is used to determine where to show the menu.
+ *
+ * If no menu entries are defined, then nothing will be shown.
+ *
+ * @param {Event} e The event triggering this display.
+ * @param {hterm.Terminal=} terminal The terminal object to get style info from.
+ */
+hterm.ContextMenu.prototype.show = function(e, terminal) {
+  // If there are no menu entries, then don't try to show anything.
+  if (this.menu_.length == 0) {
+    return;
+  }
+
+  // If we have the terminal, sync the style preferences over.
+  if (terminal) {
+    this.element_.style.backgroundColor = terminal.getBackgroundColor();
+    this.element_.style.color = terminal.getForegroundColor();
+    this.element_.style.fontSize = terminal.getFontSize();
+    this.element_.style.fontFamily = terminal.getFontFamily();
+  }
+
+  this.element_.style.top = `${e.clientY}px`;
+  this.element_.style.left = `${e.clientX}px`;
+  const docSize = hterm.getClientSize(this.document_.body);
+
+  this.element_.style.display = 'block';
+
+  // We can't calculate sizes until after it's displayed.
+  const eleSize = hterm.getClientSize(this.element_);
+  // Make sure the menu isn't clipped outside of the current element.
+  const minY = Math.max(0, docSize.height - eleSize.height);
+  const minX = Math.max(0, docSize.width - eleSize.width);
+  if (minY < e.clientY) {
+    this.element_.style.top = `${minY}px`;
+  }
+  if (minX < e.clientX) {
+    this.element_.style.left = `${minX}px`;
+  }
+};
+
+/**
+ * Hide the context menu.
+ */
+hterm.ContextMenu.prototype.hide = function() {
+  if (!this.element_) {
+    return;
+  }
+
+  this.element_.style.display = 'none';
+};
+// SOURCE FILE: hterm/js/hterm_frame.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * First draft of the interface between the terminal and a third party dialog.
+ *
+ * This is rough.  It's just the terminal->dialog layer.  To complete things
+ * we'll also need a command->terminal layer.  That will have to facilitate
+ * command->terminal->dialog or direct command->dialog communication.
+ *
+ * I imagine this class will change significantly when that happens.
+ */
+
+/**
+ * Construct a new frame for the given terminal.
+ *
+ * @param terminal {hterm.Terminal} The parent terminal object.
+ * @param url {String} The url to load in the frame.
+ * @param opt_options {Object} Optional options for the frame.  Not implemented.
+ */
+hterm.Frame = function(terminal, url, opt_options) {
+  this.terminal_ = terminal;
+  this.div_ = terminal.div_;
+  this.url = url;
+  this.options = opt_options || {};
+  this.iframe_ = null;
+  this.container_ = null;
+  this.messageChannel_ = null;
+};
+
+/**
+ * Handle messages from the iframe.
+ */
+hterm.Frame.prototype.onMessage_ = function(e) {
+  switch (e.data.name) {
+    case 'ipc-init-ok':
+      // We get this response after we send them ipc-init and they finish.
+      this.sendTerminalInfo_();
+      return;
+    case 'terminal-info-ok':
+      // We get this response after we send them terminal-info and they finish.
+      // Show the finished frame, and then rebind our message handler to the
+      // callback below.
+      this.container_.style.display = 'flex';
+      this.postMessage('visible');
+      this.messageChannel_.port1.onmessage = this.onMessage.bind(this);
+      this.onLoad();
+      return;
+    default:
+      console.log('Unknown message from frame:', e.data);
+      return;
+  }
+};
+
+/**
+ * Clients could override this, I guess.
+ *
+ * It doesn't support multiple listeners, but I'm not sure that would make sense
+ * here.  It's probably better to speak directly to our parents.
+ */
+hterm.Frame.prototype.onMessage = function() {};
+
+/**
+ * Handle iframe onLoad event.
+ */
+hterm.Frame.prototype.onLoad_ = function() {
+  this.messageChannel_ = new MessageChannel();
+  this.messageChannel_.port1.onmessage = this.onMessage_.bind(this);
+  this.messageChannel_.port1.start();
+  this.iframe_.contentWindow.postMessage(
+      {name: 'ipc-init', argv: [{messagePort: this.messageChannel_.port2}]},
+      this.url, [this.messageChannel_.port2]);
+};
+
+/**
+ * Clients may override this.
+ */
+hterm.Frame.prototype.onLoad = function() {};
+
+/**
+ * Sends the terminal-info message to the iframe.
+ */
+hterm.Frame.prototype.sendTerminalInfo_ = function() {
+  lib.i18n.getAcceptLanguages(function(languages) {
+      this.postMessage('terminal-info', [{
+         acceptLanguages: languages,
+         foregroundColor: this.terminal_.getForegroundColor(),
+         backgroundColor: this.terminal_.getBackgroundColor(),
+         cursorColor: this.terminal_.getCursorColor(),
+         fontSize: this.terminal_.getFontSize(),
+         fontFamily: this.terminal_.getFontFamily(),
+         baseURL: lib.f.getURL('/')
+          }]
+        );
+    }.bind(this));
+};
+
+/**
+ * User clicked the close button on the frame decoration.
+ */
+hterm.Frame.prototype.onCloseClicked_ = function() {
+  this.close();
+};
+
+/**
+ * Close this frame.
+ */
+hterm.Frame.prototype.close = function() {
+  if (!this.container_ || !this.container_.parentNode)
+      return;
+
+  this.container_.parentNode.removeChild(this.container_);
+  this.onClose();
+};
+
+
+/**
+ * Clients may override this.
+ */
+hterm.Frame.prototype.onClose = function() {};
+
+/**
+ * Send a message to the iframe.
+ */
+hterm.Frame.prototype.postMessage = function(name, argv) {
+  if (!this.messageChannel_)
+    throw new Error('Message channel is not set up.');
+
+  this.messageChannel_.port1.postMessage({name: name, argv: argv});
+};
+
+/**
+ * Show the UI for this frame.
+ *
+ * The iframe src is not loaded until this method is called.
+ */
+hterm.Frame.prototype.show = function() {
+  var self = this;
+
+  function opt(name, defaultValue) {
+    if (name in self.options)
+      return self.options[name];
+
+    return defaultValue;
+  }
+
+  var self = this;
+
+  if (this.container_ && this.container_.parentNode) {
+    console.error('Frame already visible');
+    return;
+  }
+
+  var headerHeight = '16px';
+
+  var divSize = hterm.getClientSize(this.div_);
+
+  var width = opt('width', 640);
+  var height = opt('height', 480);
+  var left = (divSize.width - width) / 2;
+  var top = (divSize.height - height) / 2;
+
+  var document = this.terminal_.document_;
+
+  var container = this.container_ = document.createElement('div');
+  container.style.cssText = (
+      'position: absolute;' +
+      'display: none;' +
+      'flex-direction: column;' +
+      'top: 10%;' +
+      'left: 4%;' +
+      'width: 90%;' +
+      'height: 80%;' +
+      'min-height: 20%;' +
+      'max-height: 80%;' +
+      'box-shadow: 0 0 2px ' + this.terminal_.getForegroundColor() + ';' +
+      'border: 2px ' + this.terminal_.getForegroundColor() + ' solid;');
+
+  if (false) {
+    // No use for the close button, so no use for the window header either.
+    var header = document.createElement('div');
+    header.style.cssText = (
+        'display: flex;' +
+        'justify-content: flex-end;' +
+        'height: ' + headerHeight + ';' +
+        'background-color: ' + this.terminal_.getForegroundColor() + ';' +
+        'color: ' + this.terminal_.getBackgroundColor() + ';' +
+        'font-size: 16px;' +
+        'font-family: ' + this.terminal_.getFontFamily());
+    container.appendChild(header);
+
+    var button = document.createElement('div');
+    button.setAttribute('role', 'button');
+    button.style.cssText = (
+        'margin-top: -3px;' +
+        'margin-right: 3px;' +
+        'cursor: pointer;');
+    button.textContent = '\u2a2f';
+    button.addEventListener('click', this.onCloseClicked_.bind(this));
+    header.appendChild(button);
+  }
+
+  var iframe = this.iframe_ = document.createElement('iframe');
+  iframe.onload = this.onLoad_.bind(this);
+  iframe.style.cssText = (
+      'display: flex;' +
+      'flex: 1;' +
+      'width: 100%');
+  iframe.setAttribute('src', this.url);
+  iframe.setAttribute('seamless', true);
+  container.appendChild(iframe);
+
+  this.div_.appendChild(container);
+};
+// SOURCE FILE: hterm/js/hterm_keyboard.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Keyboard handler.
+ *
+ * Consumes onKey* events and invokes onVTKeystroke on the associated
+ * hterm.Terminal object.
+ *
+ * See also: [XTERM] as referenced in vt.js.
+ *
+ * @param {hterm.Terminal} The Terminal object associated with this keyboard.
+ */
+hterm.Keyboard = function(terminal) {
+  // The parent vt interpreter.
+  this.terminal = terminal;
+
+  // The element we're currently capturing keyboard events for.
+  this.keyboardElement_ = null;
+
+  // The event handlers we are interested in, and their bound callbacks, saved
+  // so they can be uninstalled with removeEventListener, when required.
+  this.handlers_ = [
+      ['focusout', this.onFocusOut_.bind(this)],
+      ['keydown', this.onKeyDown_.bind(this)],
+      ['keypress', this.onKeyPress_.bind(this)],
+      ['keyup', this.onKeyUp_.bind(this)],
+      ['textInput', this.onTextInput_.bind(this)]
+  ];
+
+  /**
+   * The current key map.
+   */
+  this.keyMap = new hterm.Keyboard.KeyMap(this);
+
+  this.bindings = new hterm.Keyboard.Bindings(this);
+
+  /**
+   * none: Disable any AltGr related munging.
+   * ctrl-alt: Assume Ctrl+Alt means AltGr.
+   * left-alt: Assume left Alt means AltGr.
+   * right-alt: Assume right Alt means AltGr.
+   */
+  this.altGrMode = 'none';
+
+  /**
+   * If true, Shift-Insert will fall through to the browser as a paste.
+   * If false, the keystroke will be sent to the host.
+   */
+  this.shiftInsertPaste = true;
+
+  /**
+   * If true, home/end will control the terminal scrollbar and shift home/end
+   * will send the VT keycodes.  If false then home/end sends VT codes and
+   * shift home/end scrolls.
+   */
+  this.homeKeysScroll = false;
+
+  /**
+   * Same as above, except for page up/page down.
+   */
+  this.pageKeysScroll = false;
+
+  /**
+   * If true, Ctrl-Plus/Minus/Zero controls zoom.
+   * If false, Ctrl-Shift-Plus/Minus/Zero controls zoom, Ctrl-Minus sends ^_,
+   * Ctrl-Plus/Zero do nothing.
+   */
+  this.ctrlPlusMinusZeroZoom = true;
+
+  /**
+   * Ctrl+C copies if true, sends ^C to host if false.
+   * Ctrl+Shift+C sends ^C to host if true, copies if false.
+   */
+  this.ctrlCCopy = false;
+
+  /**
+   * Ctrl+V pastes if true, sends ^V to host if false.
+   * Ctrl+Shift+V sends ^V to host if true, pastes if false.
+   */
+  this.ctrlVPaste = false;
+
+  /**
+   * Enable/disable application keypad.
+   *
+   * This changes the way numeric keys are sent from the keyboard.
+   */
+  this.applicationKeypad = false;
+
+  /**
+   * Enable/disable the application cursor mode.
+   *
+   * This changes the way cursor keys are sent from the keyboard.
+   */
+  this.applicationCursor = false;
+
+  /**
+   * If true, the backspace should send BS ('\x08', aka ^H).  Otherwise
+   * the backspace key should send '\x7f'.
+   */
+  this.backspaceSendsBackspace = false;
+
+  /**
+   * Set whether the meta key sends a leading escape or not.
+   */
+  this.metaSendsEscape = true;
+
+  /**
+   * Set whether meta-V gets passed to host.
+   */
+  this.passMetaV = true;
+
+  /**
+   * Controls how the alt key is handled.
+   *
+   *  escape....... Send an ESC prefix.
+   *  8-bit........ Add 128 to the unshifted character as in xterm.
+   *  browser-key.. Wait for the keypress event and see what the browser says.
+   *                (This won't work well on platforms where the browser
+   *                 performs a default action for some alt sequences.)
+   *
+   * This setting only matters when alt is distinct from meta (altIsMeta is
+   * false.)
+   */
+  this.altSendsWhat = 'escape';
+
+  /**
+   * Set whether the alt key acts as a meta key, instead of producing 8-bit
+   * characters.
+   *
+   * True to enable, false to disable, null to autodetect based on platform.
+   */
+  this.altIsMeta = false;
+
+  /**
+   * If true, tries to detect DEL key events that are from alt-backspace on
+   * Chrome OS vs from a true DEL key press.
+   *
+   * Background: At the time of writing, on Chrome OS, alt-backspace is mapped
+   * to DEL. Some users may be happy with this, but others may be frustrated
+   * that it's impossible to do meta-backspace. If the user enables this pref,
+   * we use a trick to tell a true DEL keypress from alt-backspace: on
+   * alt-backspace, we will see the alt key go down, then get a DEL keystroke
+   * that indicates that alt is not pressed. See https://crbug.com/174410 .
+   */
+  this.altBackspaceIsMetaBackspace = false;
+
+  /**
+   * Used to keep track of the current alt-key state, which is necessary for
+   * the altBackspaceIsMetaBackspace preference above and for the altGrMode
+   * preference.  This is a bitmap with where bit positions correspond to the
+   * "location" property of the key event.
+   */
+  this.altKeyPressed = 0;
+
+  /**
+   * If true, Chrome OS media keys will be mapped to their F-key equivalent.
+   * E.g. "Back" will be mapped to F1. If false, Chrome will handle the keys.
+   */
+  this.mediaKeysAreFKeys = false;
+
+  /**
+   * Holds the previous setting of altSendsWhat when DECSET 1039 is used. When
+   * DECRST 1039 is used, altSendsWhat is changed back to this and this is
+   * nulled out.
+   */
+  this.previousAltSendsWhat_ = null;
+};
+
+/**
+ * Special handling for keyCodes in a keyboard layout.
+ */
+hterm.Keyboard.KeyActions = {
+  /**
+   * Call preventDefault and stopPropagation for this key event and nothing
+   * else.
+   */
+  CANCEL: Symbol('CANCEL'),
+
+  /**
+   * This performs the default terminal action for the key.  If used in the
+   * 'normal' action and the the keystroke represents a printable key, the
+   * character will be sent to the host.  If used in one of the modifier
+   * actions, the terminal will perform the normal action after (possibly)
+   * altering it.
+   *
+   *  - If the normal sequence starts with CSI, the sequence will be adjusted
+   *    to include the modifier parameter as described in [XTERM] in the final
+   *    table of the "PC-Style Function Keys" section.
+   *
+   *  - If the control key is down and the key represents a printable character,
+   *    and the uppercase version of the unshifted keycap is between
+   *    64 (ASCII '@') and 95 (ASCII '_'), then the uppercase version of the
+   *    unshifted keycap minus 64 is sent.  This makes '^@' send '\x00' and
+   *    '^_' send '\x1f'.  (Note that one higher that 0x1f is 0x20, which is
+   *    the first printable ASCII value.)
+   *
+   *  - If the alt key is down and the key represents a printable character then
+   *    the value of the character is shifted up by 128.
+   *
+   *  - If meta is down and configured to send an escape, '\x1b' will be sent
+   *    before the normal action is performed.
+   */
+  DEFAULT: Symbol('DEFAULT'),
+
+  /**
+   * Causes the terminal to opt out of handling the key event, instead letting
+   * the browser deal with it.
+   */
+  PASS: Symbol('PASS'),
+
+  /**
+   * Insert the first or second character of the keyCap, based on e.shiftKey.
+   * The key will be handled in onKeyDown, and e.preventDefault() will be
+   * called.
+   *
+   * It is useful for a modified key action, where it essentially strips the
+   * modifier while preventing the browser from reacting to the key.
+   */
+  STRIP: Symbol('STRIP')
+};
+
+/**
+ * Capture keyboard events sent to the associated element.
+ *
+ * This enables the keyboard.  Captured events are consumed by this class
+ * and will not perform their default action or bubble to other elements.
+ *
+ * Passing a null element will uninstall the keyboard handlers.
+ *
+ * @param {HTMLElement} element The element whose events should be captured, or
+ *     null to disable the keyboard.
+ */
+hterm.Keyboard.prototype.installKeyboard = function(element) {
+  if (element == this.keyboardElement_)
+    return;
+
+  if (element && this.keyboardElement_)
+    this.installKeyboard(null);
+
+  for (var i = 0; i < this.handlers_.length; i++) {
+    var handler = this.handlers_[i];
+    if (element) {
+      element.addEventListener(handler[0], handler[1]);
+    } else {
+      this.keyboardElement_.removeEventListener(handler[0], handler[1]);
+    }
+  }
+
+  this.keyboardElement_ = element;
+};
+
+/**
+ * Disable keyboard event capture.
+ *
+ * This will allow the browser to process key events normally.
+ */
+hterm.Keyboard.prototype.uninstallKeyboard = function() {
+  this.installKeyboard(null);
+};
+
+/**
+ * Handle onTextInput events.
+ *
+ * These are generated when using IMEs, Virtual Keyboards (VKs), compose keys,
+ * Unicode input, etc...
+ */
+hterm.Keyboard.prototype.onTextInput_ = function(e) {
+  if (!e.data)
+    return;
+
+  // Just pass the generated buffer straight down.  No need for us to split it
+  // up or otherwise parse it ahead of times.
+  this.terminal.onVTKeystroke(e.data);
+};
+
+/**
+ * Handle onKeyPress events.
+ *
+ * TODO(vapier): Drop this event entirely and only use keydown.
+ */
+hterm.Keyboard.prototype.onKeyPress_ = function(e) {
+  // FF doesn't set keyCode reliably in keypress events.  Stick to the which
+  // field here until we can move to keydown entirely.
+  const key = String.fromCharCode(e.which).toLowerCase();
+  if ((e.ctrlKey || e.metaKey) && (key == 'c' || key == 'v')) {
+    // On FF the key press (not key down) event gets fired for copy/paste.
+    // Let it fall through for the default browser behavior.
+    return;
+  }
+
+  if (e.keyCode == 9 /* Tab */) {
+    // On FF, a key press event will be fired in addition of key down for the
+    // Tab key if key down isn't handled. This would only happen if a custom
+    // PASS binding has been created and therefore this should be handled by the
+    // browser.
+    return;
+  }
+
+  if (e.altKey && this.altSendsWhat == 'browser-key' && e.charCode == 0) {
+    // If we got here because we were expecting the browser to handle an
+    // alt sequence but it didn't do it, then we might be on an OS without
+    // an enabled IME system.  In that case we fall back to xterm-like
+    // behavior.
+    //
+    // This happens here only as a fallback.  Typically these platforms should
+    // set altSendsWhat to either 'escape' or '8-bit'.
+    var ch = String.fromCharCode(e.keyCode);
+    if (!e.shiftKey)
+      ch = ch.toLowerCase();
+
+  } else if (e.charCode >= 32) {
+    ch = e.charCode;
+  }
+
+  if (ch)
+    this.terminal.onVTKeystroke(String.fromCharCode(ch));
+
+  e.preventDefault();
+  e.stopPropagation();
+};
+
+/**
+ * Prevent default handling for non-ctrl-shifted event.
+ *
+ * When combined with Chrome permission 'app.window.fullscreen.overrideEsc',
+ * and called for both key down and key up events,
+ * the ESC key remains usable within fullscreen Chrome app windows.
+ */
+hterm.Keyboard.prototype.preventChromeAppNonCtrlShiftDefault_ = function(e) {
+  if (!window.chrome || !window.chrome.app || !window.chrome.app.window)
+    return;
+  if (!e.ctrlKey || !e.shiftKey)
+    e.preventDefault();
+};
+
+hterm.Keyboard.prototype.onFocusOut_ = function(e) {
+  this.altKeyPressed = 0;
+};
+
+hterm.Keyboard.prototype.onKeyUp_ = function(e) {
+  if (e.keyCode == 18)
+    this.altKeyPressed = this.altKeyPressed & ~(1 << (e.location - 1));
+
+  if (e.keyCode == 27)
+    this.preventChromeAppNonCtrlShiftDefault_(e);
+};
+
+/**
+ * Handle onKeyDown events.
+ */
+hterm.Keyboard.prototype.onKeyDown_ = function(e) {
+  if (e.keyCode == 18)
+    this.altKeyPressed = this.altKeyPressed | (1 << (e.location - 1));
+
+  if (e.keyCode == 27)
+    this.preventChromeAppNonCtrlShiftDefault_(e);
+
+  var keyDef = this.keyMap.keyDefs[e.keyCode];
+  if (!keyDef) {
+    // If this key hasn't been explicitly registered, fall back to the unknown
+    // key mapping (keyCode == 0), and then automatically register it to avoid
+    // any further warnings here.
+    console.warn(`No definition for key ${e.key} (keyCode ${e.keyCode})`);
+    keyDef = this.keyMap.keyDefs[0];
+    this.keyMap.addKeyDef(e.keyCode, keyDef);
+  }
+
+  // The type of action we're going to use.
+  var resolvedActionType = null;
+
+  var self = this;
+  function getAction(name) {
+    // Get the key action for the given action name.  If the action is a
+    // function, dispatch it.  If the action defers to the normal action,
+    // resolve that instead.
+
+    resolvedActionType = name;
+
+    var action = keyDef[name];
+    if (typeof action == 'function')
+      action = action.apply(self.keyMap, [e, keyDef]);
+
+    if (action === DEFAULT && name != 'normal')
+      action = getAction('normal');
+
+    return action;
+  }
+
+  // Note that we use the triple-equals ('===') operator to test equality for
+  // these constants, in order to distinguish usage of the constant from usage
+  // of a literal string that happens to contain the same bytes.
+  var CANCEL = hterm.Keyboard.KeyActions.CANCEL;
+  var DEFAULT = hterm.Keyboard.KeyActions.DEFAULT;
+  var PASS = hterm.Keyboard.KeyActions.PASS;
+  var STRIP = hterm.Keyboard.KeyActions.STRIP;
+
+  var control = e.ctrlKey;
+  var alt = this.altIsMeta ? false : e.altKey;
+  var meta = this.altIsMeta ? (e.altKey || e.metaKey) : e.metaKey;
+
+  // In the key-map, we surround the keyCap for non-printables in "[...]"
+  var isPrintable = !(/^\[\w+\]$/.test(keyDef.keyCap));
+
+  switch (this.altGrMode) {
+    case 'ctrl-alt':
+    if (isPrintable && control && alt) {
+      // ctrl-alt-printable means altGr.  We clear out the control and
+      // alt modifiers and wait to see the charCode in the keydown event.
+      control = false;
+      alt = false;
+    }
+    break;
+
+    case 'right-alt':
+    if (isPrintable && (this.terminal.keyboard.altKeyPressed & 2)) {
+      control = false;
+      alt = false;
+    }
+    break;
+
+    case 'left-alt':
+    if (isPrintable && (this.terminal.keyboard.altKeyPressed & 1)) {
+      control = false;
+      alt = false;
+    }
+    break;
+  }
+
+  var action;
+
+  if (control) {
+    action = getAction('control');
+  } else if (alt) {
+    action = getAction('alt');
+  } else if (meta) {
+    action = getAction('meta');
+  } else {
+    action = getAction('normal');
+  }
+
+  // If e.maskShiftKey was set (during getAction) it means the shift key is
+  // already accounted for in the action, and we should not act on it any
+  // further. This is currently only used for Ctrl-Shift-Tab, which should send
+  // "CSI Z", not "CSI 1 ; 2 Z".
+  var shift = !e.maskShiftKey && e.shiftKey;
+
+  var keyDown = {
+    keyCode: e.keyCode,
+    shift: e.shiftKey, // not `var shift` from above.
+    ctrl: control,
+    alt: alt,
+    meta: meta
+  };
+
+  var binding = this.bindings.getBinding(keyDown);
+
+  if (binding) {
+    // Clear out the modifier bits so we don't try to munge the sequence
+    // further.
+    shift = control = alt = meta = false;
+    resolvedActionType = 'normal';
+    action = binding.action;
+
+    if (typeof action == 'function')
+      action = action.call(this, this.terminal, keyDown);
+  }
+
+  if (alt && this.altSendsWhat == 'browser-key' && action == DEFAULT) {
+    // When altSendsWhat is 'browser-key', we wait for the keypress event.
+    // In keypress, the browser should have set the event.charCode to the
+    // appropriate character.
+    // TODO(rginda): Character compositions will need some black magic.
+    action = PASS;
+  }
+
+  if (action === PASS || (action === DEFAULT && !(control || alt || meta))) {
+    // If this key is supposed to be handled by the browser, or it is an
+    // unmodified key with the default action, then exit this event handler.
+    // If it's an unmodified key, it'll be handled in onKeyPress where we
+    // can tell for sure which ASCII code to insert.
+    //
+    // This block needs to come before the STRIP test, otherwise we'll strip
+    // the modifier and think it's ok to let the browser handle the keypress.
+    // The browser won't know we're trying to ignore the modifiers and might
+    // perform some default action.
+    return;
+  }
+
+  if (action === STRIP) {
+    alt = control = false;
+    action = keyDef.normal;
+    if (typeof action == 'function')
+      action = action.apply(this.keyMap, [e, keyDef]);
+
+    if (action == DEFAULT && keyDef.keyCap.length == 2)
+      action = keyDef.keyCap.substr((shift ? 1 : 0), 1);
+  }
+
+  e.preventDefault();
+  e.stopPropagation();
+
+  if (action === CANCEL)
+    return;
+
+  if (action !== DEFAULT && typeof action != 'string') {
+    console.warn('Invalid action: ' + JSON.stringify(action));
+    return;
+  }
+
+  // Strip the modifier that is associated with the action, since we assume that
+  // modifier has already been accounted for in the action.
+  if (resolvedActionType == 'control') {
+    control = false;
+  } else if (resolvedActionType == 'alt') {
+    alt = false;
+  } else if (resolvedActionType == 'meta') {
+    meta = false;
+  }
+
+  if (typeof action == 'string' && action.substr(0, 2) == '\x1b[' &&
+      (alt || control || shift || meta)) {
+    // The action is an escape sequence that and it was triggered in the
+    // presence of a keyboard modifier, we may need to alter the action to
+    // include the modifier before sending it.
+
+    // The math is funky but aligns w/xterm.
+    let imod = 1;
+    if (shift)
+      imod += 1;
+    if (alt)
+      imod += 2;
+    if (control)
+      imod += 4;
+    if (meta)
+      imod += 8;
+    let mod = ';' + imod;
+
+    if (action.length == 3) {
+      // Some of the CSI sequences have zero parameters unless modified.
+      action = '\x1b[1' + mod + action.substr(2, 1);
+    } else {
+      // Others always have at least one parameter.
+      action = action.substr(0, action.length - 1) + mod +
+          action.substr(action.length - 1);
+    }
+
+  } else {
+    if (action === DEFAULT) {
+      action = keyDef.keyCap.substr((shift ? 1 : 0), 1);
+
+      if (control) {
+        var unshifted = keyDef.keyCap.substr(0, 1);
+        var code = unshifted.charCodeAt(0);
+        if (code >= 64 && code <= 95) {
+          action = String.fromCharCode(code - 64);
+        }
+      }
+    }
+
+    if (alt && this.altSendsWhat == '8-bit' && action.length == 1) {
+      var code = action.charCodeAt(0) + 128;
+      action = String.fromCharCode(code);
+    }
+
+    // We respect alt/metaSendsEscape even if the keymap action was a literal
+    // string.  Otherwise, every overridden alt/meta action would have to
+    // check alt/metaSendsEscape.
+    if ((alt && this.altSendsWhat == 'escape') ||
+        (meta && this.metaSendsEscape)) {
+      action = '\x1b' + action;
+    }
+  }
+
+  this.terminal.onVTKeystroke(action);
+};
+// SOURCE FILE: hterm/js/hterm_keyboard_bindings.js
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * A mapping from hterm.Keyboard.KeyPattern to an action.
+ *
+ * TODO(rginda): For now this bindings code is only used for user overrides.
+ * hterm.Keyboard.KeyMap still handles all of the built-in key mappings.
+ * It'd be nice if we migrated that over to be hterm.Keyboard.Bindings based.
+ */
+hterm.Keyboard.Bindings = function() {
+  this.bindings_ = {};
+};
+
+/**
+ * Remove all bindings.
+ */
+hterm.Keyboard.Bindings.prototype.clear = function () {
+  this.bindings_ = {};
+};
+
+/**
+ * Add a new binding.
+ *
+ * Internal API that assumes parsed objects as inputs.
+ * See the public addBinding for more details.
+ *
+ * @param {hterm.Keyboard.KeyPattern} keyPattern
+ * @param {string|function|hterm.Keyboard.KeyAction} action
+ */
+hterm.Keyboard.Bindings.prototype.addBinding_ = function(keyPattern, action) {
+  var binding = null;
+  var list = this.bindings_[keyPattern.keyCode];
+  if (list) {
+    for (var i = 0; i < list.length; i++) {
+      if (list[i].keyPattern.matchKeyPattern(keyPattern)) {
+        binding = list[i];
+        break;
+      }
+    }
+  }
+
+  if (binding) {
+    binding.action = action;
+  } else {
+    binding = {keyPattern: keyPattern, action: action};
+
+    if (!list) {
+      this.bindings_[keyPattern.keyCode] = [binding];
+    } else {
+      this.bindings_[keyPattern.keyCode].push(binding);
+
+      list.sort(function(a, b) {
+        return hterm.Keyboard.KeyPattern.sortCompare(
+            a.keyPattern, b.keyPattern);
+      });
+    }
+  }
+};
+
+/**
+ * Add a new binding.
+ *
+ * If a binding for the keyPattern already exists it will be overridden.
+ *
+ * More specific keyPatterns take precedence over those with wildcards.  Given
+ * bindings for "Ctrl-A" and "Ctrl-*-A", and a "Ctrl-A" keydown, the "Ctrl-A"
+ * binding will match even if "Ctrl-*-A" was created last.
+ *
+ * If action is a string, it will be passed through hterm.Parser.parseKeyAction.
+ *
+ * For example:
+ *   // Will replace Ctrl-P keystrokes with the string "hiya!".
+ *   addBinding('Ctrl-P', "'hiya!'");
+ *   // Will cancel the keystroke entirely (make it do nothing).
+ *   addBinding('Alt-D', hterm.Keyboard.KeyActions.CANCEL);
+ *   // Will execute the code and return the action.
+ *   addBinding('Ctrl-T', function() {
+ *     console.log('Got a T!');
+ *     return hterm.Keyboard.KeyActions.PASS;
+ *   });
+ *
+ * @param {string|hterm.Keyboard.KeyPattern} keyPattern
+ * @param {string|function|hterm.Keyboard.KeyAction} action
+ */
+hterm.Keyboard.Bindings.prototype.addBinding = function(key, action) {
+  // If we're given a hterm.Keyboard.KeyPattern object, pass it down.
+  if (typeof key != 'string') {
+    this.addBinding_(key, action);
+    return;
+  }
+
+  // Here we treat key as a string.
+  var p = new hterm.Parser();
+
+  p.reset(key);
+  var sequence;
+
+  try {
+    sequence = p.parseKeySequence();
+  } catch (ex) {
+    console.error(ex);
+    return;
+  }
+
+  if (!p.isComplete()) {
+    console.error(p.error('Expected end of sequence: ' + sequence));
+    return;
+  }
+
+  // If action is a string, parse it.  Otherwise assume it's callable.
+  if (typeof action == 'string') {
+    p.reset(action);
+    try {
+      action = p.parseKeyAction();
+    } catch (ex) {
+      console.error(ex);
+      return;
+    }
+  }
+
+  if (!p.isComplete()) {
+    console.error(p.error('Expected end of sequence: ' + sequence));
+    return;
+  }
+
+  this.addBinding_(new hterm.Keyboard.KeyPattern(sequence), action);
+};
+
+/**
+ * Add multiple bindings at a time using a map of {string: string, ...}
+ *
+ * This uses hterm.Parser to parse the maps key into KeyPatterns, and the
+ * map values into {string|function|KeyAction}.
+ *
+ * For example:
+ *  {
+ *    // Will replace Ctrl-P keystrokes with the string "hiya!".
+ *    'Ctrl-P': "'hiya!'",
+ *    // Will cancel the keystroke entirely (make it do nothing).
+ *    'Alt-D': hterm.Keyboard.KeyActions.CANCEL,
+ *  }
+ *
+ * @param {Object} map
+ */
+hterm.Keyboard.Bindings.prototype.addBindings = function(map) {
+  for (var key in map) {
+    this.addBinding(key, map[key]);
+  }
+};
+
+/**
+ * Return the binding that is the best match for the given keyDown record,
+ * or null if there is no match.
+ *
+ * @param {Object} keyDown An object with a keyCode property and zero or
+ *   more boolean properties representing key modifiers.  These property names
+ *   must match those defined in hterm.Keyboard.KeyPattern.modifiers.
+ */
+hterm.Keyboard.Bindings.prototype.getBinding = function(keyDown) {
+  var list = this.bindings_[keyDown.keyCode];
+  if (!list)
+    return null;
+
+  for (var i = 0; i < list.length; i++) {
+    var binding = list[i];
+    if (binding.keyPattern.matchKeyDown(keyDown))
+      return binding;
+  }
+
+  return null;
+};
+// SOURCE FILE: hterm/js/hterm_keyboard_keymap.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * The default key map for hterm.
+ *
+ * Contains a mapping of keyCodes to keyDefs (aka key definitions).  The key
+ * definition tells the hterm.Keyboard class how to handle keycodes.
+ *
+ * This should work for most cases, as the printable characters get handled
+ * in the keypress event.  In that case, even if the keycap is wrong in the
+ * key map, the correct character should be sent.
+ *
+ * Different layouts, such as Dvorak should work with this keymap, as those
+ * layouts typically move keycodes around on the keyboard without disturbing
+ * the actual keycaps.
+ *
+ * There may be issues with control keys on non-US keyboards or with keyboards
+ * that very significantly from the expectations here, in which case we may
+ * have to invent new key maps.
+ *
+ * The sequences defined in this key map come from [XTERM] as referenced in
+ * vt.js, starting with the section titled "Alt and Meta Keys".
+ */
+hterm.Keyboard.KeyMap = function(keyboard) {
+  this.keyboard = keyboard;
+  this.keyDefs = {};
+  this.reset();
+};
+
+/**
+ * Add a single key definition.
+ *
+ * The definition is an object containing the following fields: 'keyCap',
+ * 'normal', 'control', 'alt', and 'meta'.
+ *
+ *  - keyCap is a string identifying the key on the keyboard.  For printable
+ *    keys, the key cap should be exactly two characters, starting with the
+ *    unshifted version.  For example, 'aA', 'bB', '1!' and '=+'.  For
+ *    non-printable the key cap should be surrounded in square braces, as in
+ *    '[INS]', '[LEFT]'.  By convention, non-printable keycaps are in uppercase
+ *    but this is not a strict requirement.
+ *
+ *  - Normal is the action that should be performed when the key is pressed
+ *    in the absence of any modifier.  See below for the supported actions.
+ *
+ *  - Control is the action that should be performed when the key is pressed
+ *    along with the control modifier.  See below for the supported actions.
+ *
+ *  - Alt is the action that should be performed when the key is pressed
+ *    along with the alt modifier.  See below for the supported actions.
+ *
+ *  - Meta is the action that should be performed when the key is pressed
+ *    along with the meta modifier.  See below for the supported actions.
+ *
+ * Actions can be one of the hterm.Keyboard.KeyActions as documented below,
+ * a literal string, or an array.  If the action is a literal string then
+ * the string is sent directly to the host.  If the action is an array it
+ * is taken to be an escape sequence that may be altered by modifier keys.
+ * The second-to-last element of the array will be overwritten with the
+ * state of the modifier keys, as specified in the final table of "PC-Style
+ * Function Keys" from [XTERM].
+ */
+hterm.Keyboard.KeyMap.prototype.addKeyDef = function(keyCode, def) {
+  if (keyCode in this.keyDefs)
+    console.warn('Duplicate keyCode: ' + keyCode);
+
+  this.keyDefs[keyCode] = def;
+};
+
+/**
+ * Add multiple key definitions in a single call.
+ *
+ * This function takes the key definitions as variable argument list.  Each
+ * argument is the key definition specified as an array.
+ *
+ * (If the function took everything as one big hash we couldn't detect
+ * duplicates, and there would be a lot more typing involved.)
+ *
+ * Each key definition should have 6 elements: (keyCode, keyCap, normal action,
+ * control action, alt action and meta action).  See KeyMap.addKeyDef for the
+ * meaning of these elements.
+ */
+hterm.Keyboard.KeyMap.prototype.addKeyDefs = function(var_args) {
+  for (var i = 0; i < arguments.length; i++) {
+    this.addKeyDef(arguments[i][0],
+                   { keyCap: arguments[i][1],
+                     normal: arguments[i][2],
+                     control: arguments[i][3],
+                     alt: arguments[i][4],
+                     meta: arguments[i][5]
+                   });
+  }
+};
+
+/**
+ * Set up the default state for this keymap.
+ */
+hterm.Keyboard.KeyMap.prototype.reset = function() {
+  this.keyDefs = {};
+
+  var self = this;
+
+  // This function is used by the "macro" functions below.  It makes it
+  // possible to use the call() macro as an argument to any other macro.
+  function resolve(action, e, k) {
+    if (typeof action == 'function')
+      return action.apply(self, [e, k]);
+
+    return action;
+  }
+
+  // If not application keypad a, else b.  The keys that care about
+  // application keypad ignore it when the key is modified.
+  function ak(a, b) {
+    return function(e, k) {
+      var action = (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey ||
+                    !self.keyboard.applicationKeypad) ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  // If mod or not application cursor a, else b.  The keys that care about
+  // application cursor ignore it when the key is modified.
+  function ac(a, b) {
+    return function(e, k) {
+      var action = (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey ||
+                    !self.keyboard.applicationCursor) ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  // If not backspace-sends-backspace keypad a, else b.
+  function bs(a, b) {
+    return function(e, k) {
+      var action = !self.keyboard.backspaceSendsBackspace ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  // If not e.shiftKey a, else b.
+  function sh(a, b) {
+    return function(e, k) {
+      var action = !e.shiftKey ? a : b;
+      e.maskShiftKey = true;
+      return resolve(action, e, k);
+    };
+  }
+
+  // If not e.altKey a, else b.
+  function alt(a, b) {
+    return function(e, k) {
+      var action = !e.altKey ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  // If no modifiers a, else b.
+  function mod(a, b) {
+    return function(e, k) {
+      var action = !(e.shiftKey || e.ctrlKey || e.altKey || e.metaKey) ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  // Compute a control character for a given character.
+  function ctl(ch) { return String.fromCharCode(ch.charCodeAt(0) - 64); }
+
+  // Call a method on the keymap instance.
+  function c(m) { return function(e, k) { return this[m](e, k); }; }
+
+  // Ignore if not trapping media keys.
+  function med(fn) {
+    return function(e, k) {
+      if (!self.keyboard.mediaKeysAreFKeys) {
+        // Block Back, Forward, and Reload keys to avoid navigating away from
+        // the current page.
+        return (e.keyCode == 166 || e.keyCode == 167 || e.keyCode == 168) ?
+            hterm.Keyboard.KeyActions.CANCEL :
+            hterm.Keyboard.KeyActions.PASS;
+      }
+      return resolve(fn, e, k);
+    };
+  }
+
+  // Browser-specific differences.
+  if (window.navigator && navigator.userAgent) {
+    if (navigator.userAgent.includes('Firefox')) {
+      // Firefox defines some keys uniquely.  No other browser defines these is
+      // this way.  Some even conflict.  The keyCode field isn't well documented
+      // as it isn't standardized.  At some point we should switch to "key".
+      // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
+      // http://unixpapa.com/js/key.html
+      var keycapMute = 181;   // Mute
+      var keycapVolDn = 182;  // Volume Down
+      var keycapVolUp = 183;  // Volume Up
+      var keycapSC = 59;      // ;:
+      var keycapEP = 61;      // =+
+      var keycapMU = 173;     // -_
+
+      this.addKeyDefs(
+        // Firefox Italian +*.
+        [171, '+*', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')]
+      );
+    } else {
+      // All other browsers use these mappings.
+      var keycapMute = 173;   // Mute
+      var keycapVolDn = 174;  // Volume Down
+      var keycapVolUp = 175;  // Volume Up
+      var keycapSC = 186;     // ;:
+      var keycapEP = 187;     // =+
+      var keycapMU = 189;     // -_
+    }
+  }
+
+  var ESC = '\x1b';
+  var CSI = '\x1b[';
+  var SS3 = '\x1bO';
+
+  var CANCEL = hterm.Keyboard.KeyActions.CANCEL;
+  var DEFAULT = hterm.Keyboard.KeyActions.DEFAULT;
+  var PASS = hterm.Keyboard.KeyActions.PASS;
+  var STRIP = hterm.Keyboard.KeyActions.STRIP;
+
+  this.addKeyDefs(
+    // These fields are: [keycode, keycap, normal, control, alt, meta]
+
+    // The browser sends the keycode 0 for some keys.  We'll just assume it's
+    // going to do the right thing by default for those keys.
+    [0,   '[UNKNOWN]', PASS, PASS, PASS, PASS],
+
+    // First row.
+    // These bindings match xterm for lack of a better standard.  The emitted
+    // values might look like they're skipping values, but it's what xterm does.
+    // https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-PC-Style-Function-Keys
+    [27,  '[ESC]', ESC,                       DEFAULT, DEFAULT,     DEFAULT],
+    [112, '[F1]',  mod(SS3 + 'P', CSI + 'P'), DEFAULT, CSI + "23~", DEFAULT],
+    [113, '[F2]',  mod(SS3 + 'Q', CSI + 'Q'), DEFAULT, CSI + "24~", DEFAULT],
+    [114, '[F3]',  mod(SS3 + 'R', CSI + 'R'), DEFAULT, CSI + "25~", DEFAULT],
+    [115, '[F4]',  mod(SS3 + 'S', CSI + 'S'), DEFAULT, CSI + "26~", DEFAULT],
+    [116, '[F5]',  CSI + '15~',               DEFAULT, CSI + "28~", DEFAULT],
+    [117, '[F6]',  CSI + '17~',               DEFAULT, CSI + "29~", DEFAULT],
+    [118, '[F7]',  CSI + '18~',               DEFAULT, CSI + "31~", DEFAULT],
+    [119, '[F8]',  CSI + '19~',               DEFAULT, CSI + "32~", DEFAULT],
+    [120, '[F9]',  CSI + '20~',               DEFAULT, CSI + "33~", DEFAULT],
+    [121, '[F10]', CSI + '21~',               DEFAULT, CSI + "34~", DEFAULT],
+    [122, '[F11]', c('onF11_'),               DEFAULT, CSI + "42~", DEFAULT],
+    [123, '[F12]', CSI + '24~',               DEFAULT, CSI + "43~", DEFAULT],
+
+    // Second row.
+    [192, '`~', DEFAULT, sh(ctl('@'), ctl('^')),     DEFAULT,           PASS],
+    [49,  '1!', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [50,  '2@', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [51,  '3#', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [52,  '4$', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [53,  '5%', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [54,  '6^', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [55,  '7&', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [56,  '8*', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [57,  '9(', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [48,  '0)', DEFAULT, c('onPlusMinusZero_'),c('onAltNum_'),c('onPlusMinusZero_')],
+    [keycapMU, '-_', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')],
+    [keycapEP, '=+', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')],
+
+    [8,   '[BKSP]', bs('\x7f', '\b'), bs('\b', '\x7f'), DEFAULT,     DEFAULT],
+
+    // Third row.
+    [9,   '[TAB]', sh('\t', CSI + 'Z'), STRIP,     PASS,    DEFAULT],
+    [81,  'qQ',    DEFAULT,             ctl('Q'),  DEFAULT, DEFAULT],
+    [87,  'wW',    DEFAULT,             ctl('W'),  DEFAULT, DEFAULT],
+    [69,  'eE',    DEFAULT,             ctl('E'),  DEFAULT, DEFAULT],
+    [82,  'rR',    DEFAULT,             ctl('R'),  DEFAULT, DEFAULT],
+    [84,  'tT',    DEFAULT,             ctl('T'),  DEFAULT, DEFAULT],
+    [89,  'yY',    DEFAULT,             ctl('Y'),  DEFAULT, DEFAULT],
+    [85,  'uU',    DEFAULT,             ctl('U'),  DEFAULT, DEFAULT],
+    [73,  'iI',    DEFAULT,             ctl('I'),  DEFAULT, DEFAULT],
+    [79,  'oO',    DEFAULT,             ctl('O'),  DEFAULT, DEFAULT],
+    [80,  'pP',    DEFAULT,             ctl('P'),  DEFAULT, DEFAULT],
+    [219, '[{',    DEFAULT,             ctl('['),  DEFAULT, DEFAULT],
+    [221, ']}',    DEFAULT,             ctl(']'),  DEFAULT, DEFAULT],
+    [220, '\\|',   DEFAULT,             ctl('\\'), DEFAULT, DEFAULT],
+
+    // Fourth row. We let Ctrl-Shift-J pass for Chrome DevTools.
+    // To be compliant with xterm's behavior for modifiers on Enter
+    // would mean maximizing the window with Alt-Enter... so we don't
+    // want to do that. Our behavior on Enter is what most other
+    // modern emulators do.
+    [20,  '[CAPS]',  PASS,    PASS,                           PASS,    DEFAULT],
+    [65,  'aA',      DEFAULT, ctl('A'),                       DEFAULT, DEFAULT],
+    [83,  'sS',      DEFAULT, ctl('S'),                       DEFAULT, DEFAULT],
+    [68,  'dD',      DEFAULT, ctl('D'),                       DEFAULT, DEFAULT],
+    [70,  'fF',      DEFAULT, ctl('F'),                       DEFAULT, DEFAULT],
+    [71,  'gG',      DEFAULT, ctl('G'),                       DEFAULT, DEFAULT],
+    [72,  'hH',      DEFAULT, ctl('H'),                       DEFAULT, DEFAULT],
+    [74,  'jJ',      DEFAULT, sh(ctl('J'), PASS),             DEFAULT, DEFAULT],
+    [75,  'kK',      DEFAULT, sh(ctl('K'), c('onClear_')),    DEFAULT, DEFAULT],
+    [76,  'lL',      DEFAULT, sh(ctl('L'), PASS),             DEFAULT, DEFAULT],
+    [keycapSC, ';:', DEFAULT, STRIP,                          DEFAULT, DEFAULT],
+    [222, '\'"',     DEFAULT, STRIP,                          DEFAULT, DEFAULT],
+    [13,  '[ENTER]', '\r',    DEFAULT,                        DEFAULT, DEFAULT],
+
+    // Fifth row.  This includes the copy/paste shortcuts.  On some
+    // platforms it's Ctrl-C/V, on others it's Meta-C/V.  We assume either
+    // Ctrl-C/Meta-C should pass to the browser when there is a selection,
+    // and Ctrl-Shift-V/Meta-*-V should always pass to the browser (since
+    // these seem to be recognized as paste too).
+    [16,  '[SHIFT]', PASS, PASS,                   PASS,    DEFAULT],
+    [90,  'zZ',   DEFAULT, ctl('Z'),               DEFAULT, DEFAULT],
+    [88,  'xX',   DEFAULT, ctl('X'),               DEFAULT, DEFAULT],
+    [67,  'cC',   DEFAULT, c('onCtrlC_'),          DEFAULT, c('onMetaC_')],
+    [86,  'vV',   DEFAULT, c('onCtrlV_'),          DEFAULT, c('onMetaV_')],
+    [66,  'bB',   DEFAULT, sh(ctl('B'), PASS),     DEFAULT, sh(DEFAULT, PASS)],
+    [78,  'nN',   DEFAULT, c('onCtrlN_'),          DEFAULT, c('onMetaN_')],
+    [77,  'mM',   DEFAULT, ctl('M'),               DEFAULT, DEFAULT],
+    [188, ',<',   DEFAULT, alt(STRIP, PASS),       DEFAULT, DEFAULT],
+    [190, '.>',   DEFAULT, alt(STRIP, PASS),       DEFAULT, DEFAULT],
+    [191, '/?',   DEFAULT, sh(ctl('_'), ctl('?')), DEFAULT, DEFAULT],
+
+    // Sixth and final row.
+    [17,  '[CTRL]',  PASS,    PASS,     PASS,    PASS],
+    [18,  '[ALT]',   PASS,    PASS,     PASS,    PASS],
+    [91,  '[LAPL]',  PASS,    PASS,     PASS,    PASS],
+    [32,  ' ',       DEFAULT, ctl('@'), DEFAULT, DEFAULT],
+    [92,  '[RAPL]',  PASS,    PASS,     PASS,    PASS],
+    [93,  '[RMENU]', PASS,    PASS,     PASS,    PASS],
+
+    // These things.
+    [42,  '[PRTSCR]', PASS, PASS, PASS, PASS],
+    [145, '[SCRLK]',  PASS, PASS, PASS, PASS],
+    [19,  '[BREAK]',  PASS, PASS, PASS, PASS],
+
+    // The block of six keys above the arrows.
+    [45,  '[INSERT]', c('onKeyInsert_'),   DEFAULT, DEFAULT, DEFAULT],
+    [36,  '[HOME]',   c('onKeyHome_'),     DEFAULT, DEFAULT, DEFAULT],
+    [33,  '[PGUP]',   c('onKeyPageUp_'),   DEFAULT, DEFAULT, DEFAULT],
+    [46,  '[DEL]',    c('onKeyDel_'),      DEFAULT, DEFAULT, DEFAULT],
+    [35,  '[END]',    c('onKeyEnd_'),      DEFAULT, DEFAULT, DEFAULT],
+    [34,  '[PGDOWN]', c('onKeyPageDown_'), DEFAULT, DEFAULT, DEFAULT],
+
+    // Arrow keys.  When unmodified they respect the application cursor state,
+    // otherwise they always send the CSI codes.
+    [38, '[UP]',    c('onKeyArrowUp_'), DEFAULT, DEFAULT, DEFAULT],
+    [40, '[DOWN]',  c('onKeyArrowDown_'), DEFAULT, DEFAULT, DEFAULT],
+    [39, '[RIGHT]', ac(CSI + 'C', SS3 + 'C'), DEFAULT, DEFAULT, DEFAULT],
+    [37, '[LEFT]',  ac(CSI + 'D', SS3 + 'D'), DEFAULT, DEFAULT, DEFAULT],
+
+    [144, '[NUMLOCK]', PASS, PASS, PASS, PASS],
+
+    // On Apple keyboards, the NumLock key is a Clear key.  It also tends to be
+    // what KP5 sends when numlock is off.  Not clear if we could do anything
+    // useful with it, so just pass it along.
+    [12, '[CLEAR]', PASS, PASS, PASS, PASS],
+
+    // With numlock off, the keypad generates the same key codes as the arrows
+    // and 'block of six' for some keys, and null key codes for the rest.
+
+    // Keypad with numlock on generates unique key codes...
+    [96,  '[KP0]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [97,  '[KP1]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [98,  '[KP2]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [99,  '[KP3]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [100, '[KP4]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [101, '[KP5]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [102, '[KP6]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [103, '[KP7]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [104, '[KP8]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [105, '[KP9]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [107, '[KP+]', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')],
+    [109, '[KP-]', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')],
+    [106, '[KP*]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [111, '[KP/]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [110, '[KP.]', DEFAULT, DEFAULT, DEFAULT, DEFAULT]
+  );
+
+  // OS-specific differences.
+  if (hterm.os == 'cros') {
+    this.addKeyDefs(
+      // Chrome OS keyboard top row.  The media-keys-are-fkeys preference allows
+      // users to make these always behave as function keys (see those bindings
+      // above for more details).
+      [166, '[BACK]',   med(mod(SS3+'P', CSI+'P')), DEFAULT, CSI+'23~', DEFAULT],  // F1
+      [167, '[FWD]',    med(mod(SS3+'Q', CSI+'Q')), DEFAULT, CSI+'24~', DEFAULT],  // F2
+      [168, '[RELOAD]', med(mod(SS3+'R', CSI+'R')), DEFAULT, CSI+'25~', DEFAULT],  // F3
+      [183, '[FSCR]',   med(mod(SS3+'S', CSI+'S')), DEFAULT, CSI+'26~', DEFAULT],  // F4
+      [182, '[WINS]',   med(CSI + '15~'),           DEFAULT, CSI+'28~', DEFAULT],  // F5
+      [216, '[BRIT-]',  med(CSI + '17~'),           DEFAULT, CSI+'29~', DEFAULT],  // F6
+      [217, '[BRIT+]',  med(CSI + '18~'),           DEFAULT, CSI+'31~', DEFAULT],  // F7
+      [173, '[MUTE]',   med(CSI + '19~'),           DEFAULT, CSI+'32~', DEFAULT],  // F8
+      [174, '[VOL-]',   med(CSI + '20~'),           DEFAULT, CSI+'33~', DEFAULT],  // F9
+      [175, '[VOL+]',   med(CSI + '21~'),           DEFAULT, CSI+'34~', DEFAULT],  // F10
+
+      // We could make this into F11, but it'd be a bit weird.  Chrome allows us
+      // to see this and react, but it doesn't actually allow us to block or
+      // cancel it, so it makes the screen flash/lock still.
+      [152, '[POWER]',  DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+
+      // The Pixelbook has a slightly different layout.  This means half the keys
+      // above are off by one.  https://crbug.com/807513
+      [179, '[PLAY]',   med(CSI + '18~'),           DEFAULT, CSI + '31~', DEFAULT], // F7
+      // The settings / hamburgers / three hot dogs / menu / whatever-it's-called.
+      [154, '[DOGS]',   med(CSI + '23~'),           DEFAULT, CSI + '42~', DEFAULT], // F11
+
+      // We don't use this for anything, but keep it from popping up by default.
+      [153, '[ASSIST]', DEFAULT, DEFAULT, DEFAULT, DEFAULT]
+    );
+  }
+};
+
+/**
+ * Either allow the paste or send a key sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyInsert_ = function(e) {
+  if (this.keyboard.shiftInsertPaste && e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  return '\x1b[2~';
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyHome_ = function(e) {
+  if (!this.keyboard.homeKeysScroll ^ e.shiftKey) {
+    if ((e.altey || e.ctrlKey || e.shiftKey) ||
+        !this.keyboard.applicationCursor) {
+      return '\x1b[H';
+    }
+
+    return '\x1bOH';
+  }
+
+  this.keyboard.terminal.scrollHome();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyEnd_ = function(e) {
+  if (!this.keyboard.homeKeysScroll ^ e.shiftKey) {
+    if ((e.altKey || e.ctrlKey || e.shiftKey) ||
+        !this.keyboard.applicationCursor) {
+      return '\x1b[F';
+    }
+
+    return '\x1bOF';
+  }
+
+  this.keyboard.terminal.scrollEnd();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyPageUp_ = function(e) {
+  if (!this.keyboard.pageKeysScroll ^ e.shiftKey)
+    return '\x1b[5~';
+
+  this.keyboard.terminal.scrollPageUp();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Either send a true DEL, or sub in meta-backspace.
+ *
+ * On Chrome OS, if we know the alt key is down, but we get a DEL event that
+ * claims that the alt key is not pressed, we know the DEL was a synthetic
+ * one from a user that hit alt-backspace. Based on a user pref, we can sub
+ * in meta-backspace in this case.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyDel_ = function(e) {
+  if (this.keyboard.altBackspaceIsMetaBackspace &&
+      this.keyboard.altKeyPressed && !e.altKey)
+    return '\x1b\x7f';
+  return '\x1b[3~';
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyPageDown_ = function(e) {
+  if (!this.keyboard.pageKeysScroll ^ e.shiftKey)
+    return '\x1b[6~';
+
+  this.keyboard.terminal.scrollPageDown();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyArrowUp_ = function(e) {
+  if (!this.keyboard.applicationCursor && e.shiftKey) {
+    this.keyboard.terminal.scrollLineUp();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  return (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey ||
+          !this.keyboard.applicationCursor) ? '\x1b[A' : '\x1bOA';
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyArrowDown_ = function(e) {
+  if (!this.keyboard.applicationCursor && e.shiftKey) {
+    this.keyboard.terminal.scrollLineDown();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  return (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey ||
+          !this.keyboard.applicationCursor) ? '\x1b[B' : '\x1bOB';
+};
+
+/**
+ * Clear the primary/alternate screens and the scrollback buffer.
+ */
+hterm.Keyboard.KeyMap.prototype.onClear_ = function(e, keyDef) {
+  this.keyboard.terminal.wipeContents();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Handle F11 behavior (fullscreen) when not in a window.
+ *
+ * It would be nice to use the Fullscreen API, but the UX is slightly different
+ * a bad way: the Escape key is automatically registered for exiting.  If we let
+ * the browser handle F11 directly though, we still get to capture Escape.
+ */
+hterm.Keyboard.KeyMap.prototype.onF11_ = function(e, keyDef) {
+  if (hterm.windowType != 'popup')
+    return hterm.Keyboard.KeyActions.PASS;
+  else
+    return '\x1b[23~';
+};
+
+/**
+ * Either pass Ctrl-1..9 to the browser or send them to the host.
+ *
+ * Note that Ctrl-1 and Ctrl-9 don't actually have special sequences mapped
+ * to them in xterm or gnome-terminal.  The range is really Ctrl-2..8, but
+ * we handle 1..9 since Chrome treats the whole range special.
+ */
+hterm.Keyboard.KeyMap.prototype.onCtrlNum_ = function(e, keyDef) {
+  // Compute a control character for a given character.
+  function ctl(ch) { return String.fromCharCode(ch.charCodeAt(0) - 64); }
+
+  if (this.keyboard.terminal.passCtrlNumber && !e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  switch (keyDef.keyCap.substr(0, 1)) {
+    case '1': return '1';
+    case '2': return ctl('@');
+    case '3': return ctl('[');
+    case '4': return ctl('\\');
+    case '5': return ctl(']');
+    case '6': return ctl('^');
+    case '7': return ctl('_');
+    case '8': return '\x7f';
+    case '9': return '9';
+  }
+};
+
+/**
+ * Either pass Alt-1..9 to the browser or send them to the host.
+ */
+hterm.Keyboard.KeyMap.prototype.onAltNum_ = function(e, keyDef) {
+  if (this.keyboard.terminal.passAltNumber && !e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  return hterm.Keyboard.KeyActions.DEFAULT;
+};
+
+/**
+ * Either pass Meta-1..9 to the browser or send them to the host.
+ */
+hterm.Keyboard.KeyMap.prototype.onMetaNum_ = function(e, keyDef) {
+  if (this.keyboard.terminal.passMetaNumber && !e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  return hterm.Keyboard.KeyActions.DEFAULT;
+};
+
+/**
+ * Either send a ^C or interpret the keystroke as a copy command.
+ */
+hterm.Keyboard.KeyMap.prototype.onCtrlC_ = function(e, keyDef) {
+  var selection = this.keyboard.terminal.getDocument().getSelection();
+
+  if (!selection.isCollapsed) {
+    if (this.keyboard.ctrlCCopy && !e.shiftKey) {
+      // Ctrl-C should copy if there is a selection, send ^C otherwise.
+      // Perform the copy by letting the browser handle Ctrl-C.  On most
+      // browsers, this is the *only* way to place text on the clipboard from
+      // the 'drive-by' web.
+      if (this.keyboard.terminal.clearSelectionAfterCopy) {
+        setTimeout(selection.collapseToEnd.bind(selection), 50);
+      }
+      return hterm.Keyboard.KeyActions.PASS;
+    }
+
+    if (!this.keyboard.ctrlCCopy && e.shiftKey) {
+      // Ctrl-Shift-C should copy if there is a selection, send ^C otherwise.
+      // Perform the copy manually.  This only works in situations where
+      // document.execCommand('copy') is allowed.
+      if (this.keyboard.terminal.clearSelectionAfterCopy) {
+        setTimeout(selection.collapseToEnd.bind(selection), 50);
+      }
+      this.keyboard.terminal.copySelectionToClipboard();
+      return hterm.Keyboard.KeyActions.CANCEL;
+    }
+  }
+
+  return '\x03';
+};
+
+/**
+ * Either send a ^N or open a new window to the same location.
+ */
+hterm.Keyboard.KeyMap.prototype.onCtrlN_ = function(e, keyDef) {
+  if (e.shiftKey) {
+    lib.f.openWindow(document.location.href, '',
+                     'chrome=no,close=yes,resize=yes,scrollbars=yes,' +
+                     'minimizable=yes,width=' + window.innerWidth +
+                     ',height=' + window.innerHeight);
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  return '\x0e';
+};
+
+/**
+ * Either send a ^V or issue a paste command.
+ *
+ * The default behavior is to paste if the user presses Ctrl-Shift-V, and send
+ * a ^V if the user presses Ctrl-V. This can be flipped with the
+ * 'ctrl-v-paste' preference.
+ *
+ */
+hterm.Keyboard.KeyMap.prototype.onCtrlV_ = function(e, keyDef) {
+  if ((!e.shiftKey && this.keyboard.ctrlVPaste) ||
+      (e.shiftKey && !this.keyboard.ctrlVPaste)) {
+    // We try to do the pasting ourselves as not all browsers/OSs bind Ctrl-V to
+    // pasting.  Notably, on macOS, Ctrl-V/Ctrl-Shift-V do nothing.
+    // However, this might run into web restrictions, so if it fails, we still
+    // fallback to the letting the native behavior (hopefully) save us.
+    if (this.keyboard.terminal.paste())
+      return hterm.Keyboard.KeyActions.CANCEL;
+    else
+      return hterm.Keyboard.KeyActions.PASS;
+  }
+
+  return '\x16';
+};
+
+/**
+ * Either the default action or open a new window to the same location.
+ */
+hterm.Keyboard.KeyMap.prototype.onMetaN_ = function(e, keyDef) {
+  if (e.shiftKey) {
+    lib.f.openWindow(document.location.href, '',
+                     'chrome=no,close=yes,resize=yes,scrollbars=yes,' +
+                     'minimizable=yes,width=' + window.outerWidth +
+                     ',height=' + window.outerHeight);
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  return hterm.Keyboard.KeyActions.DEFAULT;
+};
+
+/**
+ * Either send a Meta-C or allow the browser to interpret the keystroke as a
+ * copy command.
+ *
+ * If there is no selection, or if the user presses Meta-Shift-C, then we'll
+ * transmit an '\x1b' (if metaSendsEscape is on) followed by 'c' or 'C'.
+ *
+ * If there is a selection, we defer to the browser.  In this case we clear out
+ * the selection so the user knows we heard them, and also to give them a
+ * chance to send a Meta-C by just hitting the key again.
+ */
+hterm.Keyboard.KeyMap.prototype.onMetaC_ = function(e, keyDef) {
+  var document = this.keyboard.terminal.getDocument();
+  if (e.shiftKey || document.getSelection().isCollapsed) {
+    // If the shift key is being held, or there is no document selection, send
+    // a Meta-C.  The keyboard code will add the ESC if metaSendsEscape is true,
+    // we just have to decide between 'c' and 'C'.
+    return keyDef.keyCap.substr(e.shiftKey ? 1 : 0, 1);
+  }
+
+  // Otherwise let the browser handle it as a copy command.
+  if (this.keyboard.terminal.clearSelectionAfterCopy) {
+    setTimeout(function() { document.getSelection().collapseToEnd(); }, 50);
+  }
+  return hterm.Keyboard.KeyActions.PASS;
+};
+
+/**
+ * Either PASS or DEFAULT Meta-V, depending on preference.
+ *
+ * Always PASS Meta-Shift-V to allow browser to interpret the keystroke as
+ * a paste command.
+ */
+hterm.Keyboard.KeyMap.prototype.onMetaV_ = function(e, keyDef) {
+  if (e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  return this.keyboard.passMetaV ?
+      hterm.Keyboard.KeyActions.PASS :
+      hterm.Keyboard.KeyActions.DEFAULT;
+};
+
+/**
+ * Handle font zooming.
+ *
+ * The browser's built-in zoom has a bit of an issue at certain zoom levels.
+ * At some magnifications, the measured height of a row of text differs from
+ * the height that was explicitly set.
+ *
+ * We override the browser zoom keys to change the ScrollPort's font size to
+ * avoid the issue.
+ */
+hterm.Keyboard.KeyMap.prototype.onPlusMinusZero_ = function(e, keyDef) {
+  if (!(this.keyboard.ctrlPlusMinusZeroZoom ^ e.shiftKey)) {
+    // If ctrl-PMZ controls zoom and the shift key is pressed, or
+    // ctrl-shift-PMZ controls zoom and this shift key is not pressed,
+    // then we want to send the control code instead of affecting zoom.
+    if (keyDef.keyCap == '-_')
+      return '\x1f';  // ^_
+
+    // Only ^_ is valid, the other sequences have no meaning.
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  if (this.keyboard.terminal.getZoomFactor() != 1) {
+    // If we're not at 1:1 zoom factor, let the Ctrl +/-/0 keys control the
+    // browser zoom, so it's easier to for the user to get back to 100%.
+    return hterm.Keyboard.KeyActions.PASS;
+  }
+
+  var cap = keyDef.keyCap.substr(0, 1);
+  if (cap == '0') {
+      this.keyboard.terminal.setFontSize(0);
+  } else {
+    var size = this.keyboard.terminal.getFontSize();
+
+    if (cap == '-' || keyDef.keyCap == '[KP-]') {
+      size -= 1;
+    } else {
+      size += 1;
+    }
+
+    this.keyboard.terminal.setFontSize(size);
+  }
+
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+// SOURCE FILE: hterm/js/hterm_keyboard_keypattern.js
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * A record of modifier bits and keycode used to define a key binding.
+ *
+ * The modifier names are enumerated in the static KeyPattern.modifiers
+ * property below.  Each modifier can be true, false, or "*".  True means
+ * the modifier key must be present, false means it must not, and "*" means
+ * it doesn't matter.
+ */
+hterm.Keyboard.KeyPattern = function(spec) {
+  this.wildcardCount = 0;
+  this.keyCode = spec.keyCode;
+
+  hterm.Keyboard.KeyPattern.modifiers.forEach(function(mod) {
+    this[mod] = spec[mod] || false;
+    if (this[mod] == '*')
+      this.wildcardCount++;
+  }.bind(this));
+};
+
+/**
+ * Valid modifier names.
+ */
+hterm.Keyboard.KeyPattern.modifiers = [
+  'shift', 'ctrl', 'alt', 'meta'
+];
+
+/**
+ * A compare callback for Array.prototype.sort().
+ *
+ * The bindings code wants to be sure to search through the strictest key
+ * patterns first, so that loosely defined patterns have a lower priority than
+ * exact patterns.
+ *
+ * @param {hterm.Keyboard.KeyPattern} a
+ * @param {hterm.Keyboard.KeyPattern} b
+ */
+hterm.Keyboard.KeyPattern.sortCompare = function(a, b) {
+  if (a.wildcardCount < b.wildcardCount)
+    return -1;
+
+  if (a.wildcardCount > b.wildcardCount)
+    return 1;
+
+  return 0;
+};
+
+/**
+ * Private method used to match this key pattern against other key patterns
+ * or key down events.
+ *
+ * @param {Object} The object to match.
+ * @param {boolean} True if we should ignore wildcards.  Useful when you want
+ *   to perform and exact match against another key pattern.
+ */
+hterm.Keyboard.KeyPattern.prototype.match_ = function(obj, exactMatch) {
+  if (this.keyCode != obj.keyCode)
+    return false;
+
+  var rv = true;
+
+  hterm.Keyboard.KeyPattern.modifiers.forEach(function(mod) {
+    var modValue = (mod in obj) ? obj[mod] : false;
+    if (!rv || (!exactMatch && this[mod] == '*') || this[mod] == modValue)
+      return;
+
+    rv = false;
+  }.bind(this));
+
+  return rv;
+};
+
+/**
+ * Return true if the given keyDown object is a match for this key pattern.
+ *
+ * @param {Object} keyDown An object with a keyCode property and zero or
+ *   more boolean properties representing key modifiers.  These property names
+ *   must match those defined in hterm.Keyboard.KeyPattern.modifiers.
+ */
+hterm.Keyboard.KeyPattern.prototype.matchKeyDown = function(keyDown) {
+  return this.match_(keyDown, false);
+};
+
+/**
+ * Return true if the given hterm.Keyboard.KeyPattern is exactly the same as
+ * this one.
+ *
+ * @param {hterm.Keyboard.KeyPattern}
+ */
+hterm.Keyboard.KeyPattern.prototype.matchKeyPattern = function(keyPattern) {
+  return this.match_(keyPattern, true);
+};
+// SOURCE FILE: hterm/js/hterm_options.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview This file implements the hterm.Options class,
+ * which stores current operating conditions for the terminal.  This object is
+ * used instead of a series of parameters to allow saving/restoring of cursor
+ * conditions easily, and to provide an easy place for common configuration
+ * options.
+ *
+ * Original code by Cory Maccarrone.
+ */
+
+/**
+ * Constructor for the hterm.Options class, optionally acting as a copy
+ * constructor.
+ *
+ * The defaults are as defined in http://www.vt100.net/docs/vt510-rm/DECSTR
+ * except that we enable autowrap (wraparound) by default since that seems to
+ * be what xterm does.
+ *
+ * @param {hterm.Options=} opt_copy Optional instance to copy.
+ * @constructor
+ */
+hterm.Options = function(opt_copy) {
+  // All attributes in this class are public to allow easy access by the
+  // terminal.
+
+  this.wraparound = opt_copy ? opt_copy.wraparound : true;
+  this.reverseWraparound = opt_copy ? opt_copy.reverseWraparound : false;
+  this.originMode = opt_copy ? opt_copy.originMode : false;
+  this.autoCarriageReturn = opt_copy ? opt_copy.autoCarriageReturn : false;
+  this.cursorVisible = opt_copy ? opt_copy.cursorVisible : false;
+  this.cursorBlink = opt_copy ? opt_copy.cursorBlink : false;
+  this.insertMode = opt_copy ? opt_copy.insertMode : false;
+  this.reverseVideo = opt_copy ? opt_copy.reverseVideo : false;
+  this.bracketedPaste = opt_copy ? opt_copy.bracketedPaste : false;
+};
+// SOURCE FILE: hterm/js/hterm_parser.js
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * Parses the key definition syntax used for user keyboard customizations.
+ */
+hterm.Parser = function() {
+  /**
+   * @type {string} The source string.
+   */
+  this.source = '';
+
+  /**
+   * @type {number} The current position.
+   */
+  this.pos = 0;
+
+  /**
+   * @type {string?} The character at the current position.
+   */
+  this.ch = null;
+};
+
+hterm.Parser.prototype.error = function(message) {
+  return new Error('Parse error at ' + this.pos + ': ' + message);
+};
+
+hterm.Parser.prototype.isComplete = function() {
+  return this.pos == this.source.length;
+};
+
+hterm.Parser.prototype.reset = function(source, opt_pos) {
+  this.source = source;
+  this.pos = opt_pos || 0;
+  this.ch = source.substr(0, 1);
+};
+
+/**
+ * Parse a key sequence.
+ *
+ * A key sequence is zero or more of the key modifiers defined in
+ * hterm.Parser.identifiers.modifierKeys followed by a key code.  Key
+ * codes can be an integer or an identifier from
+ * hterm.Parser.identifiers.keyCodes.  Modifiers and keyCodes should be joined
+ * by the dash character.
+ *
+ * An asterisk "*" can be used to indicate that the unspecified modifiers
+ * are optional.
+ *
+ * For example:
+ *   A: Matches only an unmodified "A" character.
+ *   65: Same as above.
+ *   0x41: Same as above.
+ *   Ctrl-A: Matches only Ctrl-A.
+ *   Ctrl-65: Same as above.
+ *   Ctrl-0x41: Same as above.
+ *   Ctrl-Shift-A: Matches only Ctrl-Shift-A.
+ *   Ctrl-*-A: Matches Ctrl-A, as well as any other key sequence that includes
+ *     at least the Ctrl and A keys.
+ *
+ * @return {Object} An object with shift, ctrl, alt, meta, keyCode
+ *   properties.
+ */
+hterm.Parser.prototype.parseKeySequence = function() {
+  var rv = {
+    keyCode: null
+  };
+
+  for (var k in hterm.Parser.identifiers.modifierKeys) {
+    rv[hterm.Parser.identifiers.modifierKeys[k]] = false;
+  }
+
+  while (this.pos < this.source.length) {
+    this.skipSpace();
+
+    var token = this.parseToken();
+    if (token.type == 'integer') {
+      rv.keyCode = token.value;
+
+    } else if (token.type == 'identifier') {
+      var ucValue = token.value.toUpperCase();
+      if (ucValue in hterm.Parser.identifiers.modifierKeys &&
+          hterm.Parser.identifiers.modifierKeys.hasOwnProperty(ucValue)) {
+        var mod = hterm.Parser.identifiers.modifierKeys[ucValue];
+        if (rv[mod] && rv[mod] != '*')
+          throw this.error('Duplicate modifier: ' + token.value);
+        rv[mod] = true;
+
+      } else if (ucValue in hterm.Parser.identifiers.keyCodes &&
+                 hterm.Parser.identifiers.keyCodes.hasOwnProperty(ucValue)) {
+        rv.keyCode = hterm.Parser.identifiers.keyCodes[ucValue];
+
+      } else {
+        throw this.error('Unknown key: ' + token.value);
+      }
+
+    } else if (token.type == 'symbol') {
+      if (token.value == '*') {
+        for (var id in hterm.Parser.identifiers.modifierKeys) {
+          var p = hterm.Parser.identifiers.modifierKeys[id];
+          if (!rv[p])
+            rv[p] =  '*';
+        }
+      } else {
+        throw this.error('Unexpected symbol: ' + token.value);
+      }
+    } else {
+      throw this.error('Expected integer or identifier');
+    }
+
+    this.skipSpace();
+
+    if (this.ch != '-')
+      break;
+
+    if (rv.keyCode != null)
+      throw this.error('Extra definition after target key');
+
+    this.advance(1);
+  }
+
+  if (rv.keyCode == null)
+    throw this.error('Missing target key');
+
+  return rv;
+};
+
+hterm.Parser.prototype.parseKeyAction = function() {
+  this.skipSpace();
+
+  var token = this.parseToken();
+
+  if (token.type == 'string')
+    return token.value;
+
+  if (token.type == 'identifier') {
+    if (token.value in hterm.Parser.identifiers.actions &&
+        hterm.Parser.identifiers.actions.hasOwnProperty(token.value))
+      return hterm.Parser.identifiers.actions[token.value];
+
+    throw this.error('Unknown key action: ' + token.value);
+  }
+
+  throw this.error('Expected string or identifier');
+
+};
+
+hterm.Parser.prototype.peekString = function() {
+  return this.ch == '\'' || this.ch == '"';
+};
+
+hterm.Parser.prototype.peekIdentifier = function() {
+  return this.ch.match(/[a-z_]/i);
+};
+
+hterm.Parser.prototype.peekInteger = function() {
+  return this.ch.match(/[0-9]/);
+};
+
+hterm.Parser.prototype.parseToken = function() {
+  if (this.ch == '*') {
+    var rv = {type: 'symbol', value: this.ch};
+    this.advance(1);
+    return rv;
+  }
+
+  if (this.peekIdentifier())
+    return {type: 'identifier', value: this.parseIdentifier()};
+
+  if (this.peekString())
+    return {type: 'string', value: this.parseString()};
+
+  if (this.peekInteger())
+    return {type: 'integer', value: this.parseInteger()};
+
+
+  throw this.error('Unexpected token');
+};
+
+hterm.Parser.prototype.parseIdentifier = function() {
+  if (!this.peekIdentifier())
+    throw this.error('Expected identifier');
+
+  return this.parsePattern(/[a-z0-9_]+/ig);
+};
+
+hterm.Parser.prototype.parseInteger = function() {
+  var base = 10;
+
+  if (this.ch == '0' && this.pos < this.source.length - 1 &&
+      this.source.substr(this.pos + 1, 1) == 'x') {
+    return parseInt(this.parsePattern(/0x[0-9a-f]+/gi));
+  }
+
+  return parseInt(this.parsePattern(/\d+/g));
+};
+
+/**
+ * Parse a single or double quoted string.
+ *
+ * The current position should point at the initial quote character.  Single
+ * quoted strings will be treated literally, double quoted will process escapes.
+ *
+ * TODO(rginda): Variable interpolation.
+ *
+ * @param {ParseState} parseState
+ * @param {string} quote A single or double-quote character.
+ * @return {string}
+ */
+hterm.Parser.prototype.parseString = function() {
+  var result = '';
+
+  var quote = this.ch;
+  if (quote != '"' && quote != '\'')
+    throw this.error('String expected');
+
+  this.advance(1);
+
+  var re = new RegExp('[\\\\' + quote + ']', 'g');
+
+  while (this.pos < this.source.length) {
+    re.lastIndex = this.pos;
+    if (!re.exec(this.source))
+      throw this.error('Unterminated string literal');
+
+    result += this.source.substring(this.pos, re.lastIndex - 1);
+
+    this.advance(re.lastIndex - this.pos - 1);
+
+    if (quote == '"' && this.ch == '\\') {
+      this.advance(1);
+      result += this.parseEscape();
+      continue;
+    }
+
+    if (quote == '\'' && this.ch == '\\') {
+      result += this.ch;
+      this.advance(1);
+      continue;
+    }
+
+    if (this.ch == quote) {
+      this.advance(1);
+      return result;
+    }
+  }
+
+  throw this.error('Unterminated string literal');
+};
+
+
+/**
+ * Parse an escape code from the current position (which should point to
+ * the first character AFTER the leading backslash.)
+ *
+ * @return {string}
+ */
+hterm.Parser.prototype.parseEscape = function() {
+  var map = {
+    '"': '"',
+    '\'': '\'',
+    '\\': '\\',
+    'a': '\x07',
+    'b': '\x08',
+    'e': '\x1b',
+    'f': '\x0c',
+    'n': '\x0a',
+    'r': '\x0d',
+    't': '\x09',
+    'v': '\x0b',
+    'x': function() {
+      var value = this.parsePattern(/[a-z0-9]{2}/ig);
+      return String.fromCharCode(parseInt(value, 16));
+    },
+    'u': function() {
+      var value = this.parsePattern(/[a-z0-9]{4}/ig);
+      return String.fromCharCode(parseInt(value, 16));
+    }
+  };
+
+  if (!(this.ch in map && map.hasOwnProperty(this.ch)))
+    throw this.error('Unknown escape: ' + this.ch);
+
+  var value = map[this.ch];
+  this.advance(1);
+
+  if (typeof value == 'function')
+    value = value.call(this);
+
+  return value;
+};
+
+/**
+ * Parse the given pattern starting from the current position.
+ *
+ * @param {RegExp} pattern A pattern representing the characters to span.  MUST
+ *   include the "global" RegExp flag.
+ * @return {string}
+ */
+hterm.Parser.prototype.parsePattern = function(pattern) {
+  if (!pattern.global)
+    throw this.error('Internal error: Span patterns must be global');
+
+  pattern.lastIndex = this.pos;
+  var ary = pattern.exec(this.source);
+
+  if (!ary || pattern.lastIndex - ary[0].length != this.pos)
+    throw this.error('Expected match for: ' + pattern);
+
+  this.pos = pattern.lastIndex - 1;
+  this.advance(1);
+
+  return ary[0];
+};
+
+
+/**
+ * Advance the current position.
+ *
+ * @param {number} count
+ */
+hterm.Parser.prototype.advance = function(count) {
+  this.pos += count;
+  this.ch = this.source.substr(this.pos, 1);
+};
+
+/**
+ * @param {string=} opt_expect A list of valid non-whitespace characters to
+ *   terminate on.
+ * @return {void}
+ */
+hterm.Parser.prototype.skipSpace = function(opt_expect) {
+  if (!/\s/.test(this.ch))
+    return;
+
+  var re = /\s+/gm;
+  re.lastIndex = this.pos;
+
+  var source = this.source;
+  if (re.exec(source))
+    this.pos = re.lastIndex;
+
+  this.ch = this.source.substr(this.pos, 1);
+
+  if (opt_expect) {
+    if (this.ch.indexOf(opt_expect) == -1) {
+      throw this.error('Expected one of ' + opt_expect + ', found: ' +
+          this.ch);
+    }
+  }
+};
+// SOURCE FILE: hterm/js/hterm_parser_identifiers.js
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Collections of identifier for hterm.Parser.
+ */
+hterm.Parser.identifiers = {};
+
+/**
+ * Modifier key names used when defining key sequences.
+ *
+ * These are upper case so we can normalize the user input and be forgiving.
+ * "CTRL-A" and "Ctrl-A" and "ctrl-a" are all accepted.
+ *
+ * Note: Names here cannot overlap with hterm.Parser.identifiers.keyCodes.
+ */
+hterm.Parser.identifiers.modifierKeys = {
+  SHIFT: 'shift',
+  CTRL: 'ctrl',
+  // Common alias.
+  CONTROL: 'ctrl',
+  ALT: 'alt',
+  META: 'meta'
+};
+
+/**
+ * Key codes useful when defining key sequences.
+ *
+ * Punctuation is mostly left out of this list because they can move around
+ * based on keyboard locale and browser.
+ *
+ * In a key sequence like "Ctrl-ESC", the ESC comes from this list of
+ * identifiers.  It is equivalent to "Ctrl-27" and "Ctrl-0x1b".
+ *
+ * These are upper case so we can normalize the user input and be forgiving.
+ * "Ctrl-ESC" and "Ctrl-Esc" an "Ctrl-esc" are all accepted.
+ *
+ * We also include common aliases for the same key.  "Esc" and "Escape" are the
+ * same key.
+ *
+ * Note: Names here cannot overlap with hterm.Parser.identifiers.modifierKeys.
+ */
+hterm.Parser.identifiers.keyCodes = {
+  // Top row.
+  ESCAPE: 27,
+  ESC: 27,
+  F1: 112,
+  F2: 113,
+  F3: 114,
+  F4: 115,
+  F5: 116,
+  F6: 117,
+  F7: 118,
+  F8: 119,
+  F9: 120,
+  F10: 121,
+  F11: 122,
+  F12: 123,
+
+  // Row two.
+  ONE: 49,
+  TWO: 50,
+  THREE: 51,
+  FOUR: 52,
+  FIVE: 53,
+  SIX: 54,
+  SEVEN: 55,
+  EIGHT: 56,
+  NINE: 57,
+  ZERO: 48,
+  BACKSPACE: 8,
+  BKSP: 8,
+  BS: 8,
+
+  // Row three.
+  TAB: 9,
+  Q: 81,
+  W: 87,
+  E: 69,
+  R: 82,
+  T: 84,
+  Y: 89,
+  U: 85,
+  I: 73,
+  O: 79,
+  P: 80,
+
+  // Row four.
+  CAPS_LOCK: 20,
+  CAPSLOCK: 20,
+  CAPS: 20,
+  A: 65,
+  S: 83,
+  D: 68,
+  F: 70,
+  G: 71,
+  H: 72,
+  J: 74,
+  K: 75,
+  L: 76,
+  // We map enter and return together even though enter should really be 10
+  // because most people don't know or care about the history here.  Plus,
+  // most keyboards/programs map them together already.  If they really want
+  // to bind them differently, they can also use the numeric value.
+  ENTER: 13,
+  ENT: 13,
+  RETURN: 13,
+  RET: 13,
+
+  // Row five.
+  Z: 90,
+  X: 88,
+  C: 67,
+  V: 86,
+  B: 66,
+  N: 78,
+  M: 77,
+
+  // Etc.
+  SPACE: 32,
+  SP: 32,
+  PRINT_SCREEN: 42,
+  PRTSC: 42,
+  SCROLL_LOCK: 145,
+  SCRLK: 145,
+  BREAK: 19,
+  BRK: 19,
+  INSERT: 45,
+  INS: 45,
+  HOME: 36,
+  PAGE_UP: 33,
+  PGUP: 33,
+  DELETE: 46,
+  DEL: 46,
+  END: 35,
+  PAGE_DOWN: 34,
+  PGDOWN: 34,
+  PGDN: 34,
+  UP: 38,
+  DOWN: 40,
+  RIGHT: 39,
+  LEFT: 37,
+  NUMLOCK: 144,
+
+  // Keypad
+  KP0: 96,
+  KP1: 97,
+  KP2: 98,
+  KP3: 99,
+  KP4: 100,
+  KP5: 101,
+  KP6: 102,
+  KP7: 103,
+  KP8: 104,
+  KP9: 105,
+  KP_PLUS: 107,
+  KP_ADD: 107,
+  KP_MINUS: 109,
+  KP_SUBTRACT: 109,
+  KP_STAR: 106,
+  KP_MULTIPLY: 106,
+  KP_DIVIDE: 111,
+  KP_DECIMAL: 110,
+  KP_PERIOD: 110,
+
+  // Chrome OS media keys
+  NAVIGATE_BACK: 166,
+  NAVIGATE_FORWARD: 167,
+  RELOAD: 168,
+  FULL_SCREEN: 183,
+  WINDOW_OVERVIEW: 182,
+  BRIGHTNESS_UP: 216,
+  BRIGHTNESS_DOWN: 217
+};
+
+/**
+ * Identifiers for use in key actions.
+ */
+hterm.Parser.identifiers.actions = {
+  /**
+   * Prevent the browser and operating system from handling the event.
+   */
+  CANCEL: hterm.Keyboard.KeyActions.CANCEL,
+
+  /**
+   * Wait for a "keypress" event, send the keypress charCode to the host.
+   */
+  DEFAULT: hterm.Keyboard.KeyActions.DEFAULT,
+
+  /**
+   * Let the browser or operating system handle the key.
+   */
+  PASS: hterm.Keyboard.KeyActions.PASS,
+
+  /**
+   * Scroll the terminal one line up.
+   */
+  scrollLineUp: function(terminal) {
+    terminal.scrollLineUp();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal one line down.
+   */
+  scrollLineDown: function(terminal) {
+    terminal.scrollLineDown();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal one page up.
+   */
+  scrollPageUp: function(terminal) {
+    terminal.scrollPageUp();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal one page down.
+   */
+  scrollPageDown: function(terminal) {
+    terminal.scrollPageDown();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal to the top.
+   */
+  scrollToTop: function(terminal) {
+    terminal.scrollHome();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal to the bottom.
+   */
+  scrollToBottom: function(terminal) {
+    terminal.scrollEnd();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Clear the active screen and move the cursor to (0,0).
+   */
+  clearScreen: function(terminal) {
+    terminal.clearHome();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Clear the scrollback buffer.
+   */
+  clearScrollback: function(terminal) {
+    terminal.clearScrollback();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Clear the terminal and scrollback buffer and move the cursor to (0,0).
+   */
+  clearTerminal: function(terminal) {
+    terminal.wipeContents();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Perform a full terminal reset.
+   */
+  fullReset: function(terminal) {
+    terminal.reset();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Perform a soft terminal reset.
+   */
+  softReset: function(terminal) {
+    terminal.softReset();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+};
+// SOURCE FILE: hterm/js/hterm_preference_manager.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * PreferenceManager subclass managing global NaSSH preferences.
+ *
+ * This is currently just an ordered list of known connection profiles.
+ */
+hterm.PreferenceManager = function(profileId) {
+  lib.PreferenceManager.call(this, hterm.defaultStorage,
+                             hterm.PreferenceManager.prefix_ + profileId);
+  Object.entries(hterm.PreferenceManager.defaultPreferences).forEach(
+      ([key, entry]) => {
+        this.definePreference(key, entry['default']);
+      });
+};
+
+/**
+ * The storage key prefix to namespace the preferences.
+ */
+hterm.PreferenceManager.prefix_ = '/hterm/profiles/';
+
+/**
+ * List all the defined profiles.
+ *
+ * @param {function(Array<string>)} callback Called with the list of profiles.
+ */
+hterm.PreferenceManager.listProfiles = function(callback) {
+  hterm.defaultStorage.getItems(null, (items) => {
+    const profiles = {};
+    for (let key of Object.keys(items)) {
+      if (key.startsWith(hterm.PreferenceManager.prefix_)) {
+        // Turn "/hterm/profiles/foo/bar/cow" to "foo/bar/cow".
+        const subKey = key.slice(hterm.PreferenceManager.prefix_.length);
+        // Turn "foo/bar/cow" into "foo".
+        profiles[subKey.split('/', 1)[0]] = true;
+      }
+    }
+    callback(Object.keys(profiles));
+  });
+};
+
+hterm.PreferenceManager.categories = {};
+hterm.PreferenceManager.categories.Keyboard = 'Keyboard';
+hterm.PreferenceManager.categories.Appearance = 'Appearance';
+hterm.PreferenceManager.categories.CopyPaste = 'CopyPaste';
+hterm.PreferenceManager.categories.Sounds = 'Sounds';
+hterm.PreferenceManager.categories.Scrolling = 'Scrolling';
+hterm.PreferenceManager.categories.Encoding = 'Encoding';
+hterm.PreferenceManager.categories.Extensions = 'Extensions';
+hterm.PreferenceManager.categories.Miscellaneous = 'Miscellaneous';
+
+/**
+ * List of categories, ordered by display order (top to bottom)
+ */
+hterm.PreferenceManager.categoryDefinitions = [
+  { id: hterm.PreferenceManager.categories.Appearance,
+    text: 'Appearance (fonts, colors, images)'},
+  { id: hterm.PreferenceManager.categories.CopyPaste,
+    text: 'Copy & Paste'},
+  { id: hterm.PreferenceManager.categories.Encoding,
+    text: 'Encoding'},
+  { id: hterm.PreferenceManager.categories.Keyboard,
+    text: 'Keyboard'},
+  { id: hterm.PreferenceManager.categories.Scrolling,
+    text: 'Scrolling'},
+  { id: hterm.PreferenceManager.categories.Sounds,
+    text: 'Sounds'},
+  { id: hterm.PreferenceManager.categories.Extensions,
+    text: 'Extensions'},
+  { id: hterm.PreferenceManager.categories.Miscellaneous,
+    text: 'Miscellaneous'}
+];
+
+/**
+ * Internal helper to create a default preference object.
+ *
+ * @param {hterm.PreferenceManager.categories} category The pref category.
+ * @param {string} name The user readable name/title.
+ * @param {Object} defaultValue The default pref value.
+ * @param {Object} type The type for this pref (or an array for enums).
+ * @param {string} help The user readable help text.
+ * @return {Object} The default pref object.
+ */
+hterm.PreferenceManager.definePref_ = function(
+    name, category, defaultValue, type, help) {
+  return {
+    'name': name,
+    'category': category,
+    'default': defaultValue,
+    'type': type,
+    'help': help,
+  };
+};
+
+hterm.PreferenceManager.defaultPreferences = {
+  'alt-gr-mode': hterm.PreferenceManager.definePref_(
+      'AltGr key mode',
+      hterm.PreferenceManager.categories.Keyboard,
+      null, [null, 'none', 'ctrl-alt', 'left-alt', 'right-alt'],
+      `Select an AltGr detection heuristic.\n` +
+      `\n` +
+      `'null': Autodetect based on navigator.language:\n` +
+      `      'en-us' => 'none', else => 'right-alt'\n` +
+      `'none': Disable any AltGr related munging.\n` +
+      `'ctrl-alt': Assume Ctrl+Alt means AltGr.\n` +
+      `'left-alt': Assume left Alt means AltGr.\n` +
+      `'right-alt': Assume right Alt means AltGr.`
+  ),
+
+  'alt-backspace-is-meta-backspace': hterm.PreferenceManager.definePref_(
+      'Alt-Backspace is Meta-Backspace',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `If set, undoes the Chrome OS Alt-Backspace->DEL remap, so that ` +
+      `Alt-Backspace indeed is Alt-Backspace.`
+  ),
+
+  'alt-is-meta': hterm.PreferenceManager.definePref_(
+      'Treat Alt key as Meta key',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `Whether the Alt key acts as a Meta key or as a distinct Alt key.`
+  ),
+
+  'alt-sends-what': hterm.PreferenceManager.definePref_(
+      'Alt key modifier handling',
+      hterm.PreferenceManager.categories.Keyboard,
+      'escape', ['escape', '8-bit', 'browser-key'],
+      `Controls how the Alt key is handled.\n` +
+      `\n` +
+      `  escape: Send an ESC prefix.\n` +
+      `  8-bit: Add 128 to the typed character as in xterm.\n` +
+      `  browser-key: Wait for the keypress event and see what the browser\n` +
+      `    says. (This won't work well on platforms where the browser\n` +
+      `    performs a default action for some Alt sequences.)`
+  ),
+
+  'audible-bell-sound': hterm.PreferenceManager.definePref_(
+      'Alert bell sound (URI)',
+      hterm.PreferenceManager.categories.Sounds,
+      'lib-resource:hterm/audio/bell', 'url',
+      `URL of the terminal bell sound. Empty string for no audible bell.`
+  ),
+
+  'desktop-notification-bell': hterm.PreferenceManager.definePref_(
+      'Create desktop notifications for alert bells',
+      hterm.PreferenceManager.categories.Sounds,
+      false, 'bool',
+      `If true, terminal bells in the background will create a Web ` +
+      `Notification. https://www.w3.org/TR/notifications/\n` +
+      `\n` +
+      `Displaying notifications requires permission from the user. When this ` +
+      `option is set to true, hterm will attempt to ask the user for ` +
+      `permission if necessary. Browsers may not show this permission ` +
+      `request if it was not triggered by a user action.\n` +
+      `\n` +
+      `Chrome extensions with the "notifications" permission have permission ` +
+      `to display notifications.`
+  ),
+
+  'background-color': hterm.PreferenceManager.definePref_(
+      'Background color',
+      hterm.PreferenceManager.categories.Appearance,
+      'rgb(16, 16, 16)', 'color',
+      `The background color for text with no other color attributes.`
+  ),
+
+  'background-image': hterm.PreferenceManager.definePref_(
+      'Background image',
+      hterm.PreferenceManager.categories.Appearance,
+      '', 'string',
+      `CSS value of the background image. Empty string for no image.\n` +
+      `\n` +
+      `For example:\n` +
+      `  url(https://goo.gl/anedTK)\n` +
+      `  linear-gradient(top bottom, blue, red)`
+  ),
+
+  'background-size': hterm.PreferenceManager.definePref_(
+      'Background image size',
+      hterm.PreferenceManager.categories.Appearance,
+      '', 'string',
+      `CSS value of the background image size.`
+  ),
+
+  'background-position': hterm.PreferenceManager.definePref_(
+      'Background image position',
+      hterm.PreferenceManager.categories.Appearance,
+      '', 'string',
+      `CSS value of the background image position.\n` +
+      `\n` +
+      `For example:\n` +
+      `  10% 10%\n` +
+      `  center`
+  ),
+
+  'backspace-sends-backspace': hterm.PreferenceManager.definePref_(
+      'Backspace key behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `If true, the backspace should send BS ('\\x08', aka ^H). Otherwise ` +
+      `the backspace key should send '\\x7f'.`
+  ),
+
+  'character-map-overrides': hterm.PreferenceManager.definePref_(
+      'Character map overrides',
+      hterm.PreferenceManager.categories.Appearance,
+      null, 'value',
+      `This is specified as an object. It is a sparse array, where each ` +
+      `property is the character set code and the value is an object that is ` +
+      `a sparse array itself. In that sparse array, each property is the ` +
+      `received character and the value is the displayed character.\n` +
+      `\n` +
+      `For example:\n` +
+      `  {"0":{"+":"\\u2192",",":"\\u2190","-":"\\u2191",".":"\\u2193", ` +
+      `"0":"\\u2588"}}`
+  ),
+
+  'close-on-exit': hterm.PreferenceManager.definePref_(
+      'Close window on exit',
+      hterm.PreferenceManager.categories.Miscellaneous,
+      true, 'bool',
+      `Whether to close the window when the command finishes executing.`
+  ),
+
+  'cursor-blink': hterm.PreferenceManager.definePref_(
+      'Cursor blink',
+      hterm.PreferenceManager.categories.Appearance,
+      false, 'bool',
+      `Whether the text cursor blinks by default. This can be toggled at ` +
+      `runtime via terminal escape sequences.`
+  ),
+
+  'cursor-blink-cycle': hterm.PreferenceManager.definePref_(
+      'Cursor blink rate',
+      hterm.PreferenceManager.categories.Appearance,
+      [1000, 500], 'value',
+      `The text cursor blink rate in milliseconds.\n` +
+      `\n` +
+      `A two element array, the first of which is how long the text cursor ` +
+      `should be on, second is how long it should be off.`
+  ),
+
+  'cursor-shape': hterm.PreferenceManager.definePref_(
+      'Text cursor shape',
+      hterm.PreferenceManager.categories.Appearance,
+      'BLOCK', ['BLOCK', 'BEAM', 'UNDERLINE'],
+      `The shape of the visible text cursor. This can be toggled at ` +
+      `runtime via terminal escape sequences.`
+  ),
+
+  'cursor-color': hterm.PreferenceManager.definePref_(
+      'Text cursor color',
+      hterm.PreferenceManager.categories.Appearance,
+      'rgba(255, 0, 0, 0.5)', 'color',
+      `The color of the visible text cursor.`
+  ),
+
+  'color-palette-overrides': hterm.PreferenceManager.definePref_(
+      'Initial color palette',
+      hterm.PreferenceManager.categories.Appearance,
+      null, 'value',
+      `Override colors in the default palette.\n` +
+      `\n` +
+      `This can be specified as an array or an object. If specified as an ` +
+      `object it is assumed to be a sparse array, where each property ` +
+      `is a numeric index into the color palette.\n` +
+      `\n` +
+      `Values can be specified as almost any CSS color value. This ` +
+      `includes #RGB, #RRGGBB, rgb(...), rgba(...), and any color names ` +
+      `that are also part of the standard X11 rgb.txt file.\n` +
+      `\n` +
+      `You can use 'null' to specify that the default value should be not ` +
+      `be changed. This is useful for skipping a small number of indices ` +
+      `when the value is specified as an array.\n` +
+      `\n` +
+      `For example, these both set color index 1 to blue:\n` +
+      `  {1: "#0000ff"}\n` +
+      `  [null, "#0000ff"]`
+  ),
+
+  'copy-on-select': hterm.PreferenceManager.definePref_(
+      'Automatically copy selected content',
+      hterm.PreferenceManager.categories.CopyPaste,
+      true, 'bool',
+      `Automatically copy mouse selection to the clipboard.`
+  ),
+
+  'use-default-window-copy': hterm.PreferenceManager.definePref_(
+      'Let the browser handle text copying',
+      hterm.PreferenceManager.categories.CopyPaste,
+      false, 'bool',
+      `Whether to use the default browser/OS's copy behavior.\n` +
+      `\n` +
+      `Allow the browser/OS to handle the copy event directly which might ` +
+      `improve compatibility with some systems (where copying doesn't work ` +
+      `at all), but makes the text selection less robust.\n` +
+      `\n` +
+      `For example, long lines that were automatically line wrapped will ` +
+      `be copied with the newlines still in them.`
+  ),
+
+  'clear-selection-after-copy': hterm.PreferenceManager.definePref_(
+      'Automatically clear text selection',
+      hterm.PreferenceManager.categories.CopyPaste,
+      true, 'bool',
+      `Whether to clear the selection after copying.`
+  ),
+
+  'ctrl-plus-minus-zero-zoom': hterm.PreferenceManager.definePref_(
+      'Ctrl-+/-/0 zoom behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      true, 'bool',
+      `If true, Ctrl-Plus/Minus/Zero controls zoom.\n` +
+      `If false, Ctrl-Shift-Plus/Minus/Zero controls zoom, Ctrl-Minus sends ` +
+      `^_, Ctrl-Plus/Zero do nothing.`
+  ),
+
+  'ctrl-c-copy': hterm.PreferenceManager.definePref_(
+      'Ctrl-C copy behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `Ctrl-C copies if true, send ^C to host if false.\n` +
+      `Ctrl-Shift-C sends ^C to host if true, copies if false.`
+  ),
+
+  'ctrl-v-paste': hterm.PreferenceManager.definePref_(
+      'Ctrl-V paste behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `Ctrl-V pastes if true, send ^V to host if false.\n` +
+      `Ctrl-Shift-V sends ^V to host if true, pastes if false.`
+  ),
+
+  'east-asian-ambiguous-as-two-column': hterm.PreferenceManager.definePref_(
+      'East Asian Ambiguous use two columns',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `Whether East Asian Ambiguous characters have two column width.`
+  ),
+
+  'enable-8-bit-control': hterm.PreferenceManager.definePref_(
+      'Support non-UTF-8 C1 control characters',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `True to enable 8-bit control characters, false to ignore them.\n` +
+      `\n` +
+      `We'll respect the two-byte versions of these control characters ` +
+      `regardless of this setting.`
+  ),
+
+  'enable-bold': hterm.PreferenceManager.definePref_(
+      'Bold text behavior',
+      hterm.PreferenceManager.categories.Appearance,
+      null, 'tristate',
+      `If true, use bold weight font for text with the bold/bright ` +
+      `attribute. False to use the normal weight font. Null to autodetect.`
+  ),
+
+  'enable-bold-as-bright': hterm.PreferenceManager.definePref_(
+      'Use bright colors with bold text',
+      hterm.PreferenceManager.categories.Appearance,
+      true, 'bool',
+      `If true, use bright colors (8-15 on a 16 color palette) for any text ` +
+      `with the bold attribute. False otherwise.`
+  ),
+
+  'enable-blink': hterm.PreferenceManager.definePref_(
+      'Enable blinking text',
+      hterm.PreferenceManager.categories.Appearance,
+      true, 'bool',
+      `If true, respect the blink attribute. False to ignore it.`
+  ),
+
+  'enable-clipboard-notice': hterm.PreferenceManager.definePref_(
+      'Show notification when copying content',
+      hterm.PreferenceManager.categories.CopyPaste,
+      true, 'bool',
+      `Whether to show a message in the terminal when the host writes to the ` +
+      `clipboard.`
+  ),
+
+  'enable-clipboard-write': hterm.PreferenceManager.definePref_(
+      'Allow remote clipboard writes',
+      hterm.PreferenceManager.categories.CopyPaste,
+      true, 'bool',
+      `Allow the remote host to write directly to the local system ` +
+      `clipboard.\n` +
+      `Read access is never granted regardless of this setting.\n` +
+      `\n` +
+      `This is used to control access to features like OSC-52.`
+  ),
+
+  'enable-dec12': hterm.PreferenceManager.definePref_(
+      'Allow changing of text cursor blinking',
+      hterm.PreferenceManager.categories.Miscellaneous,
+      false, 'bool',
+      `Respect the host's attempt to change the text cursor blink status ` +
+      `using DEC Private Mode 12.`
+  ),
+
+  'enable-csi-j-3': hterm.PreferenceManager.definePref_(
+      'Allow clearing of scrollback buffer (CSI-J-3)',
+      hterm.PreferenceManager.categories.Miscellaneous,
+      true, 'bool',
+      `Whether CSI-J (Erase Display) mode 3 may clear the terminal ` +
+      `scrollback buffer.\n` +
+      `\n` +
+      `Enabling this by default is safe.`
+  ),
+
+  'environment': hterm.PreferenceManager.definePref_(
+      'Environment variables',
+      hterm.PreferenceManager.categories.Miscellaneous,
+      {
+        // Signal ncurses based apps to use UTF-8 output instead of legacy
+        // drawing modes (which only work in ISO-2022 mode).  Since hterm is
+        // always UTF-8, this shouldn't cause problems.
+        'NCURSES_NO_UTF8_ACS': '1',
+        'TERM': 'xterm-256color',
+        // Set this env var that a bunch of mainstream terminal emulators set
+        // to indicate we support true colors.
+        // https://gist.github.com/XVilka/8346728
+        'COLORTERM': 'truecolor',
+      },
+      'value',
+      `The initial set of environment variables, as an object.`
+  ),
+
+  'font-family': hterm.PreferenceManager.definePref_(
+      'Text font family',
+      hterm.PreferenceManager.categories.Appearance,
+      '"DejaVu Sans Mono", "Noto Sans Mono", "Everson Mono", FreeMono, ' +
+      'Menlo, Terminal, monospace',
+      'string',
+      `Default font family for the terminal text.`
+  ),
+
+  'font-size': hterm.PreferenceManager.definePref_(
+      'Text font size',
+      hterm.PreferenceManager.categories.Appearance,
+      15, 'int',
+      `The default font size in pixels.`
+  ),
+
+  'font-smoothing': hterm.PreferenceManager.definePref_(
+      'Text font smoothing',
+      hterm.PreferenceManager.categories.Appearance,
+      'antialiased', 'string',
+      `CSS font-smoothing property.`
+  ),
+
+  'foreground-color': hterm.PreferenceManager.definePref_(
+      'Text color',
+      hterm.PreferenceManager.categories.Appearance,
+      'rgb(240, 240, 240)', 'color',
+      `The foreground color for text with no other color attributes.`
+  ),
+
+  'hide-mouse-while-typing': hterm.PreferenceManager.definePref_(
+      'Hide mouse cursor while typing',
+      hterm.PreferenceManager.categories.Keyboard,
+      null, 'tristate',
+      `Whether to automatically hide the mouse cursor when typing. ` +
+      `By default, autodetect whether the platform/OS handles this.\n` +
+      `\n` +
+      `Note: Some operating systems may override this setting and thus you ` +
+      `might not be able to always disable it.`
+  ),
+
+  'home-keys-scroll': hterm.PreferenceManager.definePref_(
+      'Home/End key scroll behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `If true, Home/End controls the terminal scrollbar and Shift-Home/` +
+      `Shift-End are sent to the remote host. If false, then Home/End are ` +
+      `sent to the remote host and Shift-Home/Shift-End scrolls.`
+  ),
+
+  'keybindings': hterm.PreferenceManager.definePref_(
+      'Keyboard bindings/shortcuts',
+      hterm.PreferenceManager.categories.Keyboard,
+      null, 'value',
+      `A map of key sequence to key actions. Key sequences include zero or ` +
+      `more modifier keys followed by a key code. Key codes can be decimal ` +
+      `or hexadecimal numbers, or a key identifier. Key actions can be ` +
+      `specified as a string to send to the host, or an action identifier. ` +
+      `For a full explanation of the format, see https://goo.gl/LWRndr.\n` +
+      `\n` +
+      `Sample keybindings:\n` +
+      `{\n` +
+      `  "Ctrl-Alt-K": "clearTerminal",\n` +
+      `  "Ctrl-Shift-L": "PASS",\n` +
+      `  "Ctrl-H": "'Hello World'"\n` +
+      `}`
+  ),
+
+  'media-keys-are-fkeys': hterm.PreferenceManager.definePref_(
+      'Media keys are Fkeys',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `If true, convert media keys to their Fkey equivalent. If false, let ` +
+      `the browser handle the keys.`
+  ),
+
+  'meta-sends-escape': hterm.PreferenceManager.definePref_(
+      'Meta key modifier handling',
+      hterm.PreferenceManager.categories.Keyboard,
+      true, 'bool',
+      `Send an ESC prefix when pressing a key while holding the Meta key.\n` +
+      `\n` +
+      `For example, when enabled, pressing Meta-K will send ^[k as if you ` +
+      `typed Escape then k. When disabled, only k will be sent.`
+  ),
+
+  'mouse-right-click-paste': hterm.PreferenceManager.definePref_(
+      'Mouse right clicks paste content',
+      hterm.PreferenceManager.categories.CopyPaste,
+      true, 'bool',
+      `Paste on right mouse button clicks.\n` +
+      `\n` +
+      `This option is independent of the "mouse-paste-button" setting.\n` +
+      `\n` +
+      `Note: This will handle left & right handed mice correctly.`
+  ),
+
+  'mouse-paste-button': hterm.PreferenceManager.definePref_(
+      'Mouse button paste',
+      hterm.PreferenceManager.categories.CopyPaste,
+      null, [null, 0, 1, 2, 3, 4, 5, 6],
+      `Mouse paste button, or null to autodetect.\n` +
+      `\n` +
+      `For autodetect, we'll use the middle mouse button for non-X11 ` +
+      `platforms (including Chrome OS). On X11, we'll use the right mouse ` +
+      `button (since the native window manager should paste via the middle ` +
+      `mouse button).\n` +
+      `\n` +
+      `0 == left (primary) button.\n` +
+      `1 == middle (auxiliary) button.\n` +
+      `2 == right (secondary) button.\n` +
+      `\n` +
+      `This option is independent of the setting for right-click paste.\n` +
+      `\n` +
+      `Note: This will handle left & right handed mice correctly.`
+  ),
+
+  'word-break-match-left': hterm.PreferenceManager.definePref_(
+      'Automatic selection halting (to the left)',
+      hterm.PreferenceManager.categories.CopyPaste,
+      '[^\\s\\[\\](){}<>"\'\\^!@#$%&*,;:`]', 'string',
+      `Regular expression to halt matching to the left (start) of a ` +
+      `selection.\n` +
+      `\n` +
+      `Normally this is a character class to reject specific characters.\n` +
+      `We allow "~" and "." by default as paths frequently start with those.`
+  ),
+
+  'word-break-match-right': hterm.PreferenceManager.definePref_(
+      'Automatic selection halting (to the right)',
+      hterm.PreferenceManager.categories.CopyPaste,
+      '[^\\s\\[\\](){}<>"\'\\^!@#$%&*,;:~.`]', 'string',
+      `Regular expression to halt matching to the right (end) of a ` +
+      `selection.\n` +
+      `\n` +
+      `Normally this is a character class to reject specific characters.`
+  ),
+
+  'word-break-match-middle': hterm.PreferenceManager.definePref_(
+      'Word break characters',
+      hterm.PreferenceManager.categories.CopyPaste,
+      '[^\\s\\[\\](){}<>"\'\\^]*', 'string',
+      `Regular expression to match all the characters in the middle.\n` +
+      `\n` +
+      `Normally this is a character class to reject specific characters.\n` +
+      `\n` +
+      `Used to expand the selection surrounding the starting point.`
+  ),
+
+  'page-keys-scroll': hterm.PreferenceManager.definePref_(
+      'Page Up/Down key scroll behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `If true, Page Up/Page Down controls the terminal scrollbar and ` +
+      `Shift-Page Up/Shift-Page Down are sent to the remote host. If false, ` +
+      `then Page Up/Page Down are sent to the remote host and Shift-Page Up/` +
+      `Shift-Page Down scrolls.`
+  ),
+
+  'pass-alt-number': hterm.PreferenceManager.definePref_(
+      'Pass Alt-1..9 key behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      null, 'tristate',
+      `Whether Alt-1..9 is passed to the browser.\n` +
+      `\n` +
+      `This is handy when running hterm in a browser tab, so that you don't ` +
+      `lose Chrome's "switch to tab" keyboard accelerators. When not running ` +
+      `in a tab it's better to send these keys to the host so they can be ` +
+      `used in vim or emacs.\n` +
+      `\n` +
+      `If true, Alt-1..9 will be handled by the browser. If false, Alt-1..9 ` +
+      `will be sent to the host. If null, autodetect based on browser ` +
+      `platform and window type.`
+  ),
+
+  'pass-ctrl-number': hterm.PreferenceManager.definePref_(
+      'Pass Ctrl-1..9 key behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      null, 'tristate',
+      `Whether Ctrl-1..9 is passed to the browser.\n` +
+      `\n` +
+      `This is handy when running hterm in a browser tab, so that you don't ` +
+      `lose Chrome's "switch to tab" keyboard accelerators. When not running ` +
+      `in a tab it's better to send these keys to the host so they can be ` +
+      `used in vim or emacs.\n` +
+      `\n` +
+      `If true, Ctrl-1..9 will be handled by the browser. If false, ` +
+      `Ctrl-1..9 will be sent to the host. If null, autodetect based on ` +
+      `browser platform and window type.`
+  ),
+
+  'pass-meta-number': hterm.PreferenceManager.definePref_(
+      'Pass Meta-1..9 key behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      null, 'tristate',
+      `Whether Meta-1..9 is passed to the browser.\n` +
+      `\n` +
+      `This is handy when running hterm in a browser tab, so that you don't ` +
+      `lose Chrome's "switch to tab" keyboard accelerators. When not running ` +
+      `in a tab it's better to send these keys to the host so they can be ` +
+      `used in vim or emacs.\n` +
+      `\n` +
+      `If true, Meta-1..9 will be handled by the browser. If false, ` +
+      `Meta-1..9 will be sent to the host. If null, autodetect based on ` +
+      `browser platform and window type.`
+  ),
+
+  'pass-meta-v': hterm.PreferenceManager.definePref_(
+      'Pass Meta-V key behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      true, 'bool',
+      `Whether Meta-V gets passed to host.`
+  ),
+
+  'paste-on-drop': hterm.PreferenceManager.definePref_(
+      'Allow drag & drop to paste',
+      hterm.PreferenceManager.categories.CopyPaste,
+      true, 'bool',
+      `If true, Drag and dropped text will paste into terminal.\n` +
+      `If false, dropped text will be ignored.`
+  ),
+
+  'receive-encoding': hterm.PreferenceManager.definePref_(
+      'Receive encoding',
+      hterm.PreferenceManager.categories.Encoding,
+      'utf-8', ['utf-8', 'raw'],
+      `Set the expected encoding for data received from the host.\n` +
+      `If the encodings do not match, visual bugs are likely to be ` +
+      `observed.\n` +
+      `\n` +
+      `Valid values are 'utf-8' and 'raw'.`
+  ),
+
+  'scroll-on-keystroke': hterm.PreferenceManager.definePref_(
+      'Scroll to bottom after keystroke',
+      hterm.PreferenceManager.categories.Scrolling,
+      true, 'bool',
+      `Whether to scroll to the bottom on any keystroke.`
+  ),
+
+  'scroll-on-output': hterm.PreferenceManager.definePref_(
+      'Scroll to bottom after new output',
+      hterm.PreferenceManager.categories.Scrolling,
+      false, 'bool',
+      `Whether to scroll to the bottom on terminal output.`
+  ),
+
+  'scrollbar-visible': hterm.PreferenceManager.definePref_(
+      'Scrollbar visibility',
+      hterm.PreferenceManager.categories.Scrolling,
+      true, 'bool',
+      `The vertical scrollbar mode.`
+  ),
+
+  'scroll-wheel-may-send-arrow-keys': hterm.PreferenceManager.definePref_(
+      'Emulate arrow keys with scroll wheel',
+      hterm.PreferenceManager.categories.Scrolling,
+      false, 'bool',
+      `When using the alternative screen buffer, and DECCKM (Application ` +
+      `Cursor Keys) is active, mouse wheel scroll events will emulate arrow ` +
+      `keys.\n` +
+      `\n` +
+      `It can be temporarily disabled by holding the Shift key.\n` +
+      `\n` +
+      `This frequently comes up when using pagers (less) or reading man ` +
+      `pages or text editors (vi/nano) or using screen/tmux.`
+  ),
+
+  'scroll-wheel-move-multiplier': hterm.PreferenceManager.definePref_(
+      'Mouse scroll wheel multiplier',
+      hterm.PreferenceManager.categories.Scrolling,
+      1, 'int',
+      `The multiplier for scroll wheel events when measured in pixels.\n` +
+      `\n` +
+      `Alters how fast the page scrolls.`
+  ),
+
+  'terminal-encoding': hterm.PreferenceManager.definePref_(
+      'Terminal encoding',
+      hterm.PreferenceManager.categories.Encoding,
+      'utf-8', ['iso-2022', 'utf-8', 'utf-8-locked'],
+      `The default terminal encoding (DOCS).\n` +
+      `\n` +
+      `ISO-2022 enables character map translations (like graphics maps).\n` +
+      `UTF-8 disables support for those.\n` +
+      `\n` +
+      `The locked variant means the encoding cannot be changed at runtime ` +
+      `via terminal escape sequences.\n` +
+      `\n` +
+      `You should stick with UTF-8 unless you notice broken rendering with ` +
+      `legacy applications.`
+  ),
+
+  'shift-insert-paste': hterm.PreferenceManager.definePref_(
+      'Shift-Insert paste',
+      hterm.PreferenceManager.categories.Keyboard,
+      true, 'bool',
+      `Whether Shift-Insert is used for pasting or is sent to the remote host.`
+  ),
+
+  'user-css': hterm.PreferenceManager.definePref_(
+      'Custom CSS (URI)',
+      hterm.PreferenceManager.categories.Appearance,
+      '', 'url',
+      `URL of user stylesheet to include in the terminal document.`
+  ),
+
+  'user-css-text': hterm.PreferenceManager.definePref_(
+      'Custom CSS (inline text)',
+      hterm.PreferenceManager.categories.Appearance,
+      '', 'multiline-string',
+      `Custom CSS text for styling the terminal.`
+  ),
+
+  'allow-images-inline': hterm.PreferenceManager.definePref_(
+      'Allow inline image display',
+      hterm.PreferenceManager.categories.Extensions,
+      null, 'tristate',
+      `Whether to allow the remote host to display images in the terminal.\n` +
+      `\n` +
+      `By default, we prompt until a choice is made.`
+  ),
+};
+
+hterm.PreferenceManager.prototype =
+    Object.create(lib.PreferenceManager.prototype);
+hterm.PreferenceManager.constructor = hterm.PreferenceManager;
+// SOURCE FILE: hterm/js/hterm_pubsub.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Utility class used to add publish/subscribe/unsubscribe functionality to
+ * an existing object.
+ */
+hterm.PubSub = function() {
+  this.observers_ = {};
+};
+
+/**
+ * Add publish, subscribe, and unsubscribe methods to an existing object.
+ *
+ * No other properties of the object are touched, so there is no need to
+ * worry about clashing private properties.
+ *
+ * @param {Object} obj The object to add this behavior to.
+ */
+hterm.PubSub.addBehavior = function(obj) {
+  var pubsub = new hterm.PubSub();
+  for (var m in hterm.PubSub.prototype) {
+    obj[m] = hterm.PubSub.prototype[m].bind(pubsub);
+  }
+};
+
+/**
+ * Subscribe to be notified of messages about a subject.
+ *
+ * @param {string} subject The subject to subscribe to.
+ * @param {function(Object)} callback The function to invoke for notifications.
+ */
+hterm.PubSub.prototype.subscribe = function(subject, callback) {
+  if (!(subject in this.observers_))
+    this.observers_[subject] = [];
+
+  this.observers_[subject].push(callback);
+};
+
+/**
+ * Unsubscribe from a subject.
+ *
+ * @param {string} subject The subject to unsubscribe from.
+ * @param {function(Object)} callback A callback previously registered via
+ *     subscribe().
+ */
+hterm.PubSub.prototype.unsubscribe = function(subject, callback) {
+  var list = this.observers_[subject];
+  if (!list)
+    throw 'Invalid subject: ' + subject;
+
+  var i = list.indexOf(callback);
+  if (i < 0)
+    throw 'Not subscribed: ' + subject;
+
+  list.splice(i, 1);
+};
+
+/**
+ * Publish a message about a subject.
+ *
+ * Subscribers (and the optional final callback) are invoked asynchronously.
+ * This method will return before anyone is actually notified.
+ *
+ * @param {string} subject The subject to publish about.
+ * @param {Object} e An arbitrary object associated with this notification.
+ * @param {function(Object)} opt_lastCallback An optional function to call after
+ *     all subscribers have been notified.
+ */
+hterm.PubSub.prototype.publish = function(subject, e, opt_lastCallback) {
+  function notifyList(i) {
+    // Set this timeout before invoking the callback, so we don't have to
+    // concern ourselves with exceptions.
+    if (i < list.length - 1)
+      setTimeout(notifyList, 0, i + 1);
+
+    list[i](e);
+  }
+
+  var list = this.observers_[subject];
+  if (list) {
+    // Copy the list, in case it changes while we're notifying.
+    list = [].concat(list);
+  }
+
+  if (opt_lastCallback) {
+    if (list) {
+      list.push(opt_lastCallback);
+    } else {
+      list = [opt_lastCallback];
+    }
+  }
+
+  if (list)
+    setTimeout(notifyList, 0, 0);
+};
+// SOURCE FILE: hterm/js/hterm_screen.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview This class represents a single terminal screen full of text.
+ *
+ * It maintains the current cursor position and has basic methods for text
+ * insert and overwrite, and adding or removing rows from the screen.
+ *
+ * This class has no knowledge of the scrollback buffer.
+ *
+ * The number of rows on the screen is determined only by the number of rows
+ * that the caller inserts into the screen.  If a caller wants to ensure a
+ * constant number of rows on the screen, it's their responsibility to remove a
+ * row for each row inserted.
+ *
+ * The screen width, in contrast, is enforced locally.
+ *
+ *
+ * In practice...
+ * - The hterm.Terminal class holds two hterm.Screen instances.  One for the
+ * primary screen and one for the alternate screen.
+ *
+ * - The html.Screen class only cares that rows are HTMLElements.  In the
+ * larger context of hterm, however, the rows happen to be displayed by an
+ * hterm.ScrollPort and have to follow a few rules as a result.  Each
+ * row must be rooted by the custom HTML tag 'x-row', and each must have a
+ * rowIndex property that corresponds to the index of the row in the context
+ * of the scrollback buffer.  These invariants are enforced by hterm.Terminal
+ * because that is the class using the hterm.Screen in the context of an
+ * hterm.ScrollPort.
+ */
+
+/**
+ * Create a new screen instance.
+ *
+ * The screen initially has no rows and a maximum column count of 0.
+ *
+ * @param {integer} opt_columnCount The maximum number of columns for this
+ *    screen.  See insertString() and overwriteString() for information about
+ *    what happens when too many characters are added too a row.  Defaults to
+ *    0 if not provided.
+ */
+hterm.Screen = function(opt_columnCount) {
+  /**
+   * Public, read-only access to the rows in this screen.
+   */
+  this.rowsArray = [];
+
+  // The max column width for this screen.
+  this.columnCount_ = opt_columnCount || 80;
+
+  // The current color, bold, underline and blink attributes.
+  this.textAttributes = new hterm.TextAttributes(window.document);
+
+  // Current zero-based cursor coordinates.
+  this.cursorPosition = new hterm.RowCol(0, 0);
+
+  // Saved state used by DECSC and related settings.  This is only for saving
+  // and restoring specific state, not for the current/active state.
+  this.cursorState_ = new hterm.Screen.CursorState(this);
+
+  // The node containing the row that the cursor is positioned on.
+  this.cursorRowNode_ = null;
+
+  // The node containing the span of text that the cursor is positioned on.
+  this.cursorNode_ = null;
+
+  // The offset in column width into cursorNode_ where the cursor is positioned.
+  this.cursorOffset_ = null;
+
+  // Regexes for expanding word selections.
+  this.wordBreakMatchLeft = null;
+  this.wordBreakMatchRight = null;
+  this.wordBreakMatchMiddle = null;
+};
+
+/**
+ * Return the screen size as an hterm.Size object.
+ *
+ * @return {hterm.Size} hterm.Size object representing the current number
+ *     of rows and columns in this screen.
+ */
+hterm.Screen.prototype.getSize = function() {
+  return new hterm.Size(this.columnCount_, this.rowsArray.length);
+};
+
+/**
+ * Return the current number of rows in this screen.
+ *
+ * @return {integer} The number of rows in this screen.
+ */
+hterm.Screen.prototype.getHeight = function() {
+  return this.rowsArray.length;
+};
+
+/**
+ * Return the current number of columns in this screen.
+ *
+ * @return {integer} The number of columns in this screen.
+ */
+hterm.Screen.prototype.getWidth = function() {
+  return this.columnCount_;
+};
+
+/**
+ * Set the maximum number of columns per row.
+ *
+ * @param {integer} count The maximum number of columns per row.
+ */
+hterm.Screen.prototype.setColumnCount = function(count) {
+  this.columnCount_ = count;
+
+  if (this.cursorPosition.column >= count)
+    this.setCursorPosition(this.cursorPosition.row, count - 1);
+};
+
+/**
+ * Remove the first row from the screen and return it.
+ *
+ * @return {HTMLElement} The first row in this screen.
+ */
+hterm.Screen.prototype.shiftRow = function() {
+  return this.shiftRows(1)[0];
+};
+
+/**
+ * Remove rows from the top of the screen and return them as an array.
+ *
+ * @param {integer} count The number of rows to remove.
+ * @return {Array.<HTMLElement>} The selected rows.
+ */
+hterm.Screen.prototype.shiftRows = function(count) {
+  return this.rowsArray.splice(0, count);
+};
+
+/**
+ * Insert a row at the top of the screen.
+ *
+ * @param {HTMLElement} row The row to insert.
+ */
+hterm.Screen.prototype.unshiftRow = function(row) {
+  this.rowsArray.splice(0, 0, row);
+};
+
+/**
+ * Insert rows at the top of the screen.
+ *
+ * @param {Array.<HTMLElement>} rows The rows to insert.
+ */
+hterm.Screen.prototype.unshiftRows = function(rows) {
+  this.rowsArray.unshift.apply(this.rowsArray, rows);
+};
+
+/**
+ * Remove the last row from the screen and return it.
+ *
+ * @return {HTMLElement} The last row in this screen.
+ */
+hterm.Screen.prototype.popRow = function() {
+  return this.popRows(1)[0];
+};
+
+/**
+ * Remove rows from the bottom of the screen and return them as an array.
+ *
+ * @param {integer} count The number of rows to remove.
+ * @return {Array.<HTMLElement>} The selected rows.
+ */
+hterm.Screen.prototype.popRows = function(count) {
+  return this.rowsArray.splice(this.rowsArray.length - count, count);
+};
+
+/**
+ * Insert a row at the bottom of the screen.
+ *
+ * @param {HTMLElement} row The row to insert.
+ */
+hterm.Screen.prototype.pushRow = function(row) {
+  this.rowsArray.push(row);
+};
+
+/**
+ * Insert rows at the bottom of the screen.
+ *
+ * @param {Array.<HTMLElement>} rows The rows to insert.
+ */
+hterm.Screen.prototype.pushRows = function(rows) {
+  rows.push.apply(this.rowsArray, rows);
+};
+
+/**
+ * Insert a row at the specified row of the screen.
+ *
+ * @param {integer} index The index to insert the row.
+ * @param {HTMLElement} row The row to insert.
+ */
+hterm.Screen.prototype.insertRow = function(index, row) {
+  this.rowsArray.splice(index, 0, row);
+};
+
+/**
+ * Insert rows at the specified row of the screen.
+ *
+ * @param {integer} index The index to insert the rows.
+ * @param {Array.<HTMLElement>} rows The rows to insert.
+ */
+hterm.Screen.prototype.insertRows = function(index, rows) {
+  for (var i = 0; i < rows.length; i++) {
+    this.rowsArray.splice(index + i, 0, rows[i]);
+  }
+};
+
+/**
+ * Remove a row from the screen and return it.
+ *
+ * @param {integer} index The index of the row to remove.
+ * @return {HTMLElement} The selected row.
+ */
+hterm.Screen.prototype.removeRow = function(index) {
+  return this.rowsArray.splice(index, 1)[0];
+};
+
+/**
+ * Remove rows from the bottom of the screen and return them as an array.
+ *
+ * @param {integer} index The index to start removing rows.
+ * @param {integer} count The number of rows to remove.
+ * @return {Array.<HTMLElement>} The selected rows.
+ */
+hterm.Screen.prototype.removeRows = function(index, count) {
+  return this.rowsArray.splice(index, count);
+};
+
+/**
+ * Invalidate the current cursor position.
+ *
+ * This sets this.cursorPosition to (0, 0) and clears out some internal
+ * data.
+ *
+ * Attempting to insert or overwrite text while the cursor position is invalid
+ * will raise an obscure exception.
+ */
+hterm.Screen.prototype.invalidateCursorPosition = function() {
+  this.cursorPosition.move(0, 0);
+  this.cursorRowNode_ = null;
+  this.cursorNode_ = null;
+  this.cursorOffset_ = null;
+};
+
+/**
+ * Clear the contents of the cursor row.
+ */
+hterm.Screen.prototype.clearCursorRow = function() {
+  this.cursorRowNode_.innerHTML = '';
+  this.cursorRowNode_.removeAttribute('line-overflow');
+  this.cursorOffset_ = 0;
+  this.cursorPosition.column = 0;
+  this.cursorPosition.overflow = false;
+
+  var text;
+  if (this.textAttributes.isDefault()) {
+    text = '';
+  } else {
+    text = lib.f.getWhitespace(this.columnCount_);
+  }
+
+  // We shouldn't honor inverse colors when clearing an area, to match
+  // xterm's back color erase behavior.
+  var inverse = this.textAttributes.inverse;
+  this.textAttributes.inverse = false;
+  this.textAttributes.syncColors();
+
+  var node = this.textAttributes.createContainer(text);
+  this.cursorRowNode_.appendChild(node);
+  this.cursorNode_ = node;
+
+  this.textAttributes.inverse = inverse;
+  this.textAttributes.syncColors();
+};
+
+/**
+ * Mark the current row as having overflowed to the next line.
+ *
+ * The line overflow state is used when converting a range of rows into text.
+ * It makes it possible to recombine two or more overflow terminal rows into
+ * a single line.
+ *
+ * This is distinct from the cursor being in the overflow state.  Cursor
+ * overflow indicates that printing at the cursor position will commit a
+ * line overflow, unless it is preceded by a repositioning of the cursor
+ * to a non-overflow state.
+ */
+hterm.Screen.prototype.commitLineOverflow = function() {
+  this.cursorRowNode_.setAttribute('line-overflow', true);
+};
+
+/**
+ * Relocate the cursor to a give row and column.
+ *
+ * @param {integer} row The zero based row.
+ * @param {integer} column The zero based column.
+ */
+hterm.Screen.prototype.setCursorPosition = function(row, column) {
+  if (!this.rowsArray.length) {
+    console.warn('Attempt to set cursor position on empty screen.');
+    return;
+  }
+
+  if (row >= this.rowsArray.length) {
+    console.error('Row out of bounds: ' + row);
+    row = this.rowsArray.length - 1;
+  } else if (row < 0) {
+    console.error('Row out of bounds: ' + row);
+    row = 0;
+  }
+
+  if (column >= this.columnCount_) {
+    console.error('Column out of bounds: ' + column);
+    column = this.columnCount_ - 1;
+  } else if (column < 0) {
+    console.error('Column out of bounds: ' + column);
+    column = 0;
+  }
+
+  this.cursorPosition.overflow = false;
+
+  var rowNode = this.rowsArray[row];
+  var node = rowNode.firstChild;
+
+  if (!node) {
+    node = rowNode.ownerDocument.createTextNode('');
+    rowNode.appendChild(node);
+  }
+
+  var currentColumn = 0;
+
+  if (rowNode == this.cursorRowNode_) {
+    if (column >= this.cursorPosition.column - this.cursorOffset_) {
+      node = this.cursorNode_;
+      currentColumn = this.cursorPosition.column - this.cursorOffset_;
+    }
+  } else {
+    this.cursorRowNode_ = rowNode;
+  }
+
+  this.cursorPosition.move(row, column);
+
+  while (node) {
+    var offset = column - currentColumn;
+    var width = hterm.TextAttributes.nodeWidth(node);
+    if (!node.nextSibling || width > offset) {
+      this.cursorNode_ = node;
+      this.cursorOffset_ = offset;
+      return;
+    }
+
+    currentColumn += width;
+    node = node.nextSibling;
+  }
+};
+
+/**
+ * Set the provided selection object to be a caret selection at the current
+ * cursor position.
+ */
+hterm.Screen.prototype.syncSelectionCaret = function(selection) {
+  try {
+    selection.collapse(this.cursorNode_, this.cursorOffset_);
+  } catch (firefoxIgnoredException) {
+    // FF can throw an exception if the range is off, rather than just not
+    // performing the collapse.
+  }
+};
+
+/**
+ * Split a single node into two nodes at the given offset.
+ *
+ * For example:
+ * Given the DOM fragment '<div><span>Hello World</span></div>', call splitNode_
+ * passing the span and an offset of 6.  This would modify the fragment to
+ * become: '<div><span>Hello </span><span>World</span></div>'.  If the span
+ * had any attributes they would have been copied to the new span as well.
+ *
+ * The to-be-split node must have a container, so that the new node can be
+ * placed next to it.
+ *
+ * @param {HTMLNode} node The node to split.
+ * @param {integer} offset The offset into the node where the split should
+ *     occur.
+ */
+hterm.Screen.prototype.splitNode_ = function(node, offset) {
+  var afterNode = node.cloneNode(false);
+
+  var textContent = node.textContent;
+  node.textContent = hterm.TextAttributes.nodeSubstr(node, 0, offset);
+  afterNode.textContent = lib.wc.substr(textContent, offset);
+
+  if (afterNode.textContent)
+    node.parentNode.insertBefore(afterNode, node.nextSibling);
+  if (!node.textContent)
+    node.parentNode.removeChild(node);
+};
+
+/**
+ * Ensure that text is clipped and the cursor is clamped to the column count.
+ */
+hterm.Screen.prototype.maybeClipCurrentRow = function() {
+  var width = hterm.TextAttributes.nodeWidth(this.cursorRowNode_);
+
+  if (width <= this.columnCount_) {
+    // Current row does not need clipping, but may need clamping.
+    if (this.cursorPosition.column >= this.columnCount_) {
+      this.setCursorPosition(this.cursorPosition.row, this.columnCount_ - 1);
+      this.cursorPosition.overflow = true;
+    }
+
+    return;
+  }
+
+  // Save off the current column so we can maybe restore it later.
+  var currentColumn = this.cursorPosition.column;
+
+  // Move the cursor to the final column.
+  this.setCursorPosition(this.cursorPosition.row, this.columnCount_ - 1);
+
+  // Remove any text that partially overflows.
+  width = hterm.TextAttributes.nodeWidth(this.cursorNode_);
+
+  if (this.cursorOffset_ < width - 1) {
+    this.cursorNode_.textContent = hterm.TextAttributes.nodeSubstr(
+        this.cursorNode_, 0, this.cursorOffset_ + 1);
+  }
+
+  // Remove all nodes after the cursor.
+  var rowNode = this.cursorRowNode_;
+  var node = this.cursorNode_.nextSibling;
+
+  while (node) {
+    rowNode.removeChild(node);
+    node = this.cursorNode_.nextSibling;
+  }
+
+  if (currentColumn < this.columnCount_) {
+    // If the cursor was within the screen before we started then restore its
+    // position.
+    this.setCursorPosition(this.cursorPosition.row, currentColumn);
+  } else {
+    // Otherwise leave it at the the last column in the overflow state.
+    this.cursorPosition.overflow = true;
+  }
+};
+
+/**
+ * Insert a string at the current character position using the current
+ * text attributes.
+ *
+ * You must call maybeClipCurrentRow() after in order to clip overflowed
+ * text and clamp the cursor.
+ *
+ * It is also up to the caller to properly maintain the line overflow state
+ * using hterm.Screen..commitLineOverflow().
+ */
+hterm.Screen.prototype.insertString = function(str, wcwidth=undefined) {
+  var cursorNode = this.cursorNode_;
+  var cursorNodeText = cursorNode.textContent;
+
+  this.cursorRowNode_.removeAttribute('line-overflow');
+
+  // We may alter the width of the string by prepending some missing
+  // whitespaces, so we need to record the string width ahead of time.
+  if (wcwidth === undefined)
+    wcwidth = lib.wc.strWidth(str);
+
+  // No matter what, before this function exits the cursor column will have
+  // moved this much.
+  this.cursorPosition.column += wcwidth;
+
+  // Local cache of the cursor offset.
+  var offset = this.cursorOffset_;
+
+  // Reverse offset is the offset measured from the end of the string.
+  // Zero implies that the cursor is at the end of the cursor node.
+  var reverseOffset = hterm.TextAttributes.nodeWidth(cursorNode) - offset;
+
+  if (reverseOffset < 0) {
+    // A negative reverse offset means the cursor is positioned past the end
+    // of the characters on this line.  We'll need to insert the missing
+    // whitespace.
+    var ws = lib.f.getWhitespace(-reverseOffset);
+
+    // This whitespace should be completely unstyled.  Underline, background
+    // color, and strikethrough would be visible on whitespace, so we can't use
+    // one of those spans to hold the text.
+    if (!(this.textAttributes.underline ||
+          this.textAttributes.strikethrough ||
+          this.textAttributes.background ||
+          this.textAttributes.wcNode ||
+          !this.textAttributes.asciiNode ||
+          this.textAttributes.tileData != null)) {
+      // Best case scenario, we can just pretend the spaces were part of the
+      // original string.
+      str = ws + str;
+    } else if (cursorNode.nodeType == Node.TEXT_NODE ||
+               !(cursorNode.wcNode ||
+                 !cursorNode.asciiNode ||
+                 cursorNode.tileNode ||
+                 cursorNode.style.textDecoration ||
+                 cursorNode.style.textDecorationStyle ||
+                 cursorNode.style.textDecorationLine ||
+                 cursorNode.style.backgroundColor)) {
+      // Second best case, the current node is able to hold the whitespace.
+      cursorNode.textContent = (cursorNodeText += ws);
+    } else {
+      // Worst case, we have to create a new node to hold the whitespace.
+      var wsNode = cursorNode.ownerDocument.createTextNode(ws);
+      this.cursorRowNode_.insertBefore(wsNode, cursorNode.nextSibling);
+      this.cursorNode_ = cursorNode = wsNode;
+      this.cursorOffset_ = offset = -reverseOffset;
+      cursorNodeText = ws;
+    }
+
+    // We now know for sure that we're at the last character of the cursor node.
+    reverseOffset = 0;
+  }
+
+  if (this.textAttributes.matchesContainer(cursorNode)) {
+    // The new text can be placed directly in the cursor node.
+    if (reverseOffset == 0) {
+      cursorNode.textContent = cursorNodeText + str;
+    } else if (offset == 0) {
+      cursorNode.textContent = str + cursorNodeText;
+    } else {
+      cursorNode.textContent =
+          hterm.TextAttributes.nodeSubstr(cursorNode, 0, offset) +
+          str + hterm.TextAttributes.nodeSubstr(cursorNode, offset);
+    }
+
+    this.cursorOffset_ += wcwidth;
+    return;
+  }
+
+  // The cursor node is the wrong style for the new text.  If we're at the
+  // beginning or end of the cursor node, then the adjacent node is also a
+  // potential candidate.
+
+  if (offset == 0) {
+    // At the beginning of the cursor node, the check the previous sibling.
+    var previousSibling = cursorNode.previousSibling;
+    if (previousSibling &&
+        this.textAttributes.matchesContainer(previousSibling)) {
+      previousSibling.textContent += str;
+      this.cursorNode_ = previousSibling;
+      this.cursorOffset_ = lib.wc.strWidth(previousSibling.textContent);
+      return;
+    }
+
+    var newNode = this.textAttributes.createContainer(str);
+    this.cursorRowNode_.insertBefore(newNode, cursorNode);
+    this.cursorNode_ = newNode;
+    this.cursorOffset_ = wcwidth;
+    return;
+  }
+
+  if (reverseOffset == 0) {
+    // At the end of the cursor node, the check the next sibling.
+    var nextSibling = cursorNode.nextSibling;
+    if (nextSibling &&
+        this.textAttributes.matchesContainer(nextSibling)) {
+      nextSibling.textContent = str + nextSibling.textContent;
+      this.cursorNode_ = nextSibling;
+      this.cursorOffset_ = lib.wc.strWidth(str);
+      return;
+    }
+
+    var newNode = this.textAttributes.createContainer(str);
+    this.cursorRowNode_.insertBefore(newNode, nextSibling);
+    this.cursorNode_ = newNode;
+    // We specifically need to include any missing whitespace here, since it's
+    // going in a new node.
+    this.cursorOffset_ = hterm.TextAttributes.nodeWidth(newNode);
+    return;
+  }
+
+  // Worst case, we're somewhere in the middle of the cursor node.  We'll
+  // have to split it into two nodes and insert our new container in between.
+  this.splitNode_(cursorNode, offset);
+  var newNode = this.textAttributes.createContainer(str);
+  this.cursorRowNode_.insertBefore(newNode, cursorNode.nextSibling);
+  this.cursorNode_ = newNode;
+  this.cursorOffset_ = wcwidth;
+};
+
+/**
+ * Overwrite the text at the current cursor position.
+ *
+ * You must call maybeClipCurrentRow() after in order to clip overflowed
+ * text and clamp the cursor.
+ *
+ * It is also up to the caller to properly maintain the line overflow state
+ * using hterm.Screen..commitLineOverflow().
+ */
+hterm.Screen.prototype.overwriteString = function(str, wcwidth=undefined) {
+  var maxLength = this.columnCount_ - this.cursorPosition.column;
+  if (!maxLength)
+    return;
+
+  if (wcwidth === undefined)
+    wcwidth = lib.wc.strWidth(str);
+
+  if (this.textAttributes.matchesContainer(this.cursorNode_) &&
+      this.cursorNode_.textContent.substr(this.cursorOffset_) == str) {
+    // This overwrite would be a no-op, just move the cursor and return.
+    this.cursorOffset_ += wcwidth;
+    this.cursorPosition.column += wcwidth;
+    return;
+  }
+
+  this.deleteChars(Math.min(wcwidth, maxLength));
+  this.insertString(str, wcwidth);
+};
+
+/**
+ * Forward-delete one or more characters at the current cursor position.
+ *
+ * Text to the right of the deleted characters is shifted left.  Only affects
+ * characters on the same row as the cursor.
+ *
+ * @param {integer} count The column width of characters to delete.  This is
+ *     clamped to the column width minus the cursor column.
+ * @return {integer} The column width of the characters actually deleted.
+ */
+hterm.Screen.prototype.deleteChars = function(count) {
+  var node = this.cursorNode_;
+  var offset = this.cursorOffset_;
+
+  var currentCursorColumn = this.cursorPosition.column;
+  count = Math.min(count, this.columnCount_ - currentCursorColumn);
+  if (!count)
+    return 0;
+
+  var rv = count;
+  var startLength, endLength;
+
+  while (node && count) {
+    // Sanity check so we don't loop forever, but we don't also go quietly.
+    if (count < 0) {
+      console.error(`Deleting ${rv} chars went negative: ${count}`);
+      break;
+    }
+
+    startLength = hterm.TextAttributes.nodeWidth(node);
+    node.textContent = hterm.TextAttributes.nodeSubstr(node, 0, offset) +
+        hterm.TextAttributes.nodeSubstr(node, offset + count);
+    endLength = hterm.TextAttributes.nodeWidth(node);
+
+    // Deal with splitting wide characters.  There are two ways: we could delete
+    // the first column or the second column.  In both cases, we delete the wide
+    // character and replace one of the columns with a space (since the other
+    // was deleted).  If there are more chars to delete, the next loop will pick
+    // up the slack.
+    if (node.wcNode && offset < startLength &&
+        ((endLength && startLength == endLength) || (!endLength && offset == 1))) {
+      // No characters were deleted when there should be.  We're probably trying
+      // to delete one column width from a wide character node.  We remove the
+      // wide character node here and replace it with a single space.
+      var spaceNode = this.textAttributes.createContainer(' ');
+      node.parentNode.insertBefore(spaceNode, offset ? node : node.nextSibling);
+      node.textContent = '';
+      endLength = 0;
+      count -= 1;
+    } else
+      count -= startLength - endLength;
+
+    var nextNode = node.nextSibling;
+    if (endLength == 0 && node != this.cursorNode_) {
+      node.parentNode.removeChild(node);
+    }
+    node = nextNode;
+    offset = 0;
+  }
+
+  // Remove this.cursorNode_ if it is an empty non-text node.
+  if (this.cursorNode_.nodeType != Node.TEXT_NODE &&
+      !this.cursorNode_.textContent) {
+    var cursorNode = this.cursorNode_;
+    if (cursorNode.previousSibling) {
+      this.cursorNode_ = cursorNode.previousSibling;
+      this.cursorOffset_ = hterm.TextAttributes.nodeWidth(
+          cursorNode.previousSibling);
+    } else if (cursorNode.nextSibling) {
+      this.cursorNode_ = cursorNode.nextSibling;
+      this.cursorOffset_ = 0;
+    } else {
+      var emptyNode = this.cursorRowNode_.ownerDocument.createTextNode('');
+      this.cursorRowNode_.appendChild(emptyNode);
+      this.cursorNode_ = emptyNode;
+      this.cursorOffset_ = 0;
+    }
+    this.cursorRowNode_.removeChild(cursorNode);
+  }
+
+  return rv;
+};
+
+/**
+ * Finds first X-ROW of a line containing specified X-ROW.
+ * Used to support line overflow.
+ *
+ * @param {Node} row X-ROW to begin search for first row of line.
+ * @return {Node} The X-ROW that is at the beginning of the line.
+ **/
+hterm.Screen.prototype.getLineStartRow_ = function(row) {
+  while (row.previousSibling &&
+         row.previousSibling.hasAttribute('line-overflow')) {
+    row = row.previousSibling;
+  }
+  return row;
+};
+
+/**
+ * Gets text of a line beginning with row.
+ * Supports line overflow.
+ *
+ * @param {Node} row First X-ROW of line.
+ * @return {string} Text content of line.
+ **/
+hterm.Screen.prototype.getLineText_ = function(row) {
+  var rowText = "";
+  while (row) {
+    rowText += row.textContent;
+    if (row.hasAttribute('line-overflow')) {
+      row = row.nextSibling;
+    } else {
+      break;
+    }
+  }
+  return rowText;
+};
+
+/**
+ * Returns X-ROW that is ancestor of the node.
+ *
+ * @param {Node} node Node to get X-ROW ancestor for.
+ * @return {Node} X-ROW ancestor of node, or null if not found.
+ **/
+hterm.Screen.prototype.getXRowAncestor_ = function(node) {
+  while (node) {
+    if (node.nodeName === 'X-ROW')
+      break;
+    node = node.parentNode;
+  }
+  return node;
+};
+
+/**
+ * Returns position within line of character at offset within node.
+ * Supports line overflow.
+ *
+ * @param {Node} row X-ROW at beginning of line.
+ * @param {Node} node Node to get position of.
+ * @param {integer} offset Offset into node.
+ *
+ * @return {integer} Position within line of character at offset within node.
+ **/
+hterm.Screen.prototype.getPositionWithOverflow_ = function(row, node, offset) {
+  if (!node)
+    return -1;
+  var ancestorRow = this.getXRowAncestor_(node);
+  if (!ancestorRow)
+    return -1;
+  var position = 0;
+  while (ancestorRow != row) {
+    position += hterm.TextAttributes.nodeWidth(row);
+    if (row.hasAttribute('line-overflow') && row.nextSibling) {
+      row = row.nextSibling;
+    } else {
+      return -1;
+    }
+  }
+  return position + this.getPositionWithinRow_(row, node, offset);
+};
+
+/**
+ * Returns position within row of character at offset within node.
+ * Does not support line overflow.
+ *
+ * @param {Node} row X-ROW to get position within.
+ * @param {Node} node Node to get position for.
+ * @param {integer} offset Offset within node to get position for.
+ * @return {integer} Position within row of character at offset within node.
+ **/
+hterm.Screen.prototype.getPositionWithinRow_ = function(row, node, offset) {
+  if (node.parentNode != row) {
+    // If we traversed to the top node, then there's nothing to find here.
+    if (node.parentNode == null)
+      return -1;
+
+    return this.getPositionWithinRow_(node.parentNode, node, offset) +
+           this.getPositionWithinRow_(row, node.parentNode, 0);
+  }
+  var position = 0;
+  for (var i = 0; i < row.childNodes.length; i++) {
+    var currentNode = row.childNodes[i];
+    if (currentNode == node)
+      return position + offset;
+    position += hterm.TextAttributes.nodeWidth(currentNode);
+  }
+  return -1;
+};
+
+/**
+ * Returns the node and offset corresponding to position within line.
+ * Supports line overflow.
+ *
+ * @param {Node} row X-ROW at beginning of line.
+ * @param {integer} position Position within line to retrieve node and offset.
+ * @return {Array} Two element array containing node and offset respectively.
+ **/
+hterm.Screen.prototype.getNodeAndOffsetWithOverflow_ = function(row, position) {
+  while (row && position > hterm.TextAttributes.nodeWidth(row)) {
+    if (row.hasAttribute('line-overflow') && row.nextSibling) {
+      position -= hterm.TextAttributes.nodeWidth(row);
+      row = row.nextSibling;
+    } else {
+      return -1;
+    }
+  }
+  return this.getNodeAndOffsetWithinRow_(row, position);
+};
+
+/**
+ * Returns the node and offset corresponding to position within row.
+ * Does not support line overflow.
+ *
+ * @param {Node} row X-ROW to get position within.
+ * @param {integer} position Position within row to retrieve node and offset.
+ * @return {Array} Two element array containing node and offset respectively.
+ **/
+hterm.Screen.prototype.getNodeAndOffsetWithinRow_ = function(row, position) {
+  for (var i = 0; i < row.childNodes.length; i++) {
+    var node = row.childNodes[i];
+    var nodeTextWidth = hterm.TextAttributes.nodeWidth(node);
+    if (position <= nodeTextWidth) {
+      if (node.nodeName === 'SPAN') {
+        /** Drill down to node contained by SPAN. **/
+        return this.getNodeAndOffsetWithinRow_(node, position);
+      } else {
+        return [node, position];
+      }
+    }
+    position -= nodeTextWidth;
+  }
+  return null;
+};
+
+/**
+ * Returns the node and offset corresponding to position within line.
+ * Supports line overflow.
+ *
+ * @param {Node} row X-ROW at beginning of line.
+ * @param {integer} start Start position of range within line.
+ * @param {integer} end End position of range within line.
+ * @param {Range} range Range to modify.
+ **/
+hterm.Screen.prototype.setRange_ = function(row, start, end, range) {
+  var startNodeAndOffset = this.getNodeAndOffsetWithOverflow_(row, start);
+  if (startNodeAndOffset == null)
+    return;
+  var endNodeAndOffset = this.getNodeAndOffsetWithOverflow_(row, end);
+  if (endNodeAndOffset == null)
+    return;
+  range.setStart(startNodeAndOffset[0], startNodeAndOffset[1]);
+  range.setEnd(endNodeAndOffset[0], endNodeAndOffset[1]);
+};
+
+/**
+ * Expands selection to surrounding string with word break matches.
+ *
+ * @param {Selection} selection Selection to expand.
+ * @param {string} leftMatch left word break match.
+ * @param {string} rightMatch right word break match.
+ * @param {string} insideMatch inside word break match.
+ */
+hterm.Screen.prototype.expandSelectionWithWordBreakMatches_ =
+    function(selection, leftMatch, rightMatch, insideMatch) {
+  if (!selection)
+    return;
+
+  var range = selection.getRangeAt(0);
+  if (!range || range.toString().match(/\s/))
+    return;
+
+  const rowElement = this.getXRowAncestor_(range.startContainer);
+  if (!rowElement)
+    return;
+  const row = this.getLineStartRow_(rowElement);
+  if (!row)
+    return;
+
+  var startPosition = this.getPositionWithOverflow_(row,
+                                                    range.startContainer,
+                                                    range.startOffset);
+  if (startPosition == -1)
+    return;
+  var endPosition = this.getPositionWithOverflow_(row,
+                                                  range.endContainer,
+                                                  range.endOffset);
+  if (endPosition == -1)
+    return;
+
+  //Move start to the left.
+  var rowText = this.getLineText_(row);
+  var lineUpToRange = lib.wc.substring(rowText, 0, endPosition);
+  var leftRegularExpression = new RegExp(leftMatch + insideMatch + "$");
+  var expandedStart = lineUpToRange.search(leftRegularExpression);
+  if (expandedStart == -1 || expandedStart > startPosition)
+    return;
+
+  //Move end to the right.
+  var lineFromRange = lib.wc.substring(rowText, startPosition,
+                                       lib.wc.strWidth(rowText));
+  var rightRegularExpression = new RegExp("^" + insideMatch + rightMatch);
+  var found = lineFromRange.match(rightRegularExpression);
+  if (!found)
+    return;
+  var expandedEnd = startPosition + lib.wc.strWidth(found[0]);
+  if (expandedEnd == -1 || expandedEnd < endPosition)
+    return;
+
+  this.setRange_(row, expandedStart, expandedEnd, range);
+  selection.addRange(range);
+};
+
+/**
+ * Expands selection to surrounding string using the user's settings.
+ *
+ * @param {Selection} selection Selection to expand.
+ */
+hterm.Screen.prototype.expandSelection = function(selection) {
+  this.expandSelectionWithWordBreakMatches_(
+      selection,
+      this.wordBreakMatchLeft,
+      this.wordBreakMatchRight,
+      this.wordBreakMatchMiddle);
+};
+
+/**
+ * Expands selection to surrounding URL using a set of fixed match settings.
+ *
+ * @param {Selection} selection Selection to expand.
+ */
+hterm.Screen.prototype.expandSelectionForUrl = function(selection) {
+  this.expandSelectionWithWordBreakMatches_(
+      selection,
+      "[^\\s\\[\\](){}<>\"'\\^!@#$%&*,;:`]",
+      "[^\\s\\[\\](){}<>\"'\\^!@#$%&*,;:~.`]",
+      "[^\\s\\[\\](){}<>\"'\\^]*");
+};
+
+/**
+ * Save the current cursor state to the corresponding screens.
+ *
+ * @param {hterm.VT} vt The VT object to read graphic codeset details from.
+ */
+hterm.Screen.prototype.saveCursorAndState = function(vt) {
+  this.cursorState_.save(vt);
+};
+
+/**
+ * Restore the saved cursor state in the corresponding screens.
+ *
+ * @param {hterm.VT} vt The VT object to write graphic codeset details to.
+ */
+hterm.Screen.prototype.restoreCursorAndState = function(vt) {
+  this.cursorState_.restore(vt);
+};
+
+/**
+ * Track all the things related to the current "cursor".
+ *
+ * The set of things saved & restored here is defined by DEC:
+ * https://vt100.net/docs/vt510-rm/DECSC.html
+ * - Cursor position
+ * - Character attributes set by the SGR command
+ * - Character sets (G0, G1, G2, or G3) currently in GL and GR
+ * - Wrap flag (autowrap or no autowrap)
+ * - State of origin mode (DECOM)
+ * - Selective erase attribute
+ * - Any single shift 2 (SS2) or single shift 3 (SS3) functions sent
+ *
+ * These are done on a per-screen basis.
+ */
+hterm.Screen.CursorState = function(screen) {
+  this.screen_ = screen;
+  this.cursor = null;
+  this.textAttributes = null;
+  this.GL = this.GR = this.G0 = this.G1 = this.G2 = this.G3 = null;
+};
+
+/**
+ * Save all the cursor state.
+ *
+ * @param {hterm.VT} vt The VT object to read graphic codeset details from.
+ */
+hterm.Screen.CursorState.prototype.save = function(vt) {
+  this.cursor = vt.terminal.saveCursor();
+
+  this.textAttributes = this.screen_.textAttributes.clone();
+
+  this.GL = vt.GL;
+  this.GR = vt.GR;
+
+  this.G0 = vt.G0;
+  this.G1 = vt.G1;
+  this.G2 = vt.G2;
+  this.G3 = vt.G3;
+};
+
+/**
+ * Restore the previously saved cursor state.
+ *
+ * @param {hterm.VT} vt The VT object to write graphic codeset details to.
+ */
+hterm.Screen.CursorState.prototype.restore = function(vt) {
+  vt.terminal.restoreCursor(this.cursor);
+
+  // Cursor restore includes char attributes (bold/etc...), but does not change
+  // the color palette (which are a terminal setting).
+  const tattrs = this.textAttributes.clone();
+  tattrs.colorPalette = this.screen_.textAttributes.colorPalette;
+  tattrs.syncColors();
+
+  this.screen_.textAttributes = tattrs;
+
+  vt.GL = this.GL;
+  vt.GR = this.GR;
+
+  vt.G0 = this.G0;
+  vt.G1 = this.G1;
+  vt.G2 = this.G2;
+  vt.G3 = this.G3;
+};
+// SOURCE FILE: hterm/js/hterm_scrollport.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * A 'viewport' view of fixed-height rows with support for selection and
+ * copy-to-clipboard.
+ *
+ * 'Viewport' in this case means that only the visible rows are in the DOM.
+ * If the rowProvider has 100,000 rows, but the ScrollPort is only 25 rows
+ * tall, then only 25 dom nodes are created.  The ScrollPort will ask the
+ * RowProvider to create new visible rows on demand as they are scrolled in
+ * to the visible area.
+ *
+ * This viewport is designed so that select and copy-to-clipboard still works,
+ * even when all or part of the selection is scrolled off screen.
+ *
+ * Note that the X11 mouse clipboard does not work properly when all or part
+ * of the selection is off screen.  It would be difficult to fix this without
+ * adding significant overhead to pathologically large selection cases.
+ *
+ * The RowProvider should return rows rooted by the custom tag name 'x-row'.
+ * This ensures that we can quickly assign the correct display height
+ * to the rows with css.
+ *
+ * @param {RowProvider} rowProvider An object capable of providing rows as
+ *     raw text or row nodes.
+ */
+hterm.ScrollPort = function(rowProvider) {
+  hterm.PubSub.addBehavior(this);
+
+  this.rowProvider_ = rowProvider;
+
+  // SWAG the character size until we can measure it.
+  this.characterSize = new hterm.Size(10, 10);
+
+  // DOM node used for character measurement.
+  this.ruler_ = null;
+
+  this.selection = new hterm.ScrollPort.Selection(this);
+
+  // A map of rowIndex => rowNode for each row that is drawn as part of a
+  // pending redraw_() call.  Null if there is no pending redraw_ call.
+  this.currentRowNodeCache_ = null;
+
+  // A map of rowIndex => rowNode for each row that was drawn as part of the
+  // previous redraw_() call.
+  this.previousRowNodeCache_ = {};
+
+  // Used during scroll events to detect when the underlying cause is a resize.
+  this.lastScreenWidth_ = null;
+  this.lastScreenHeight_ = null;
+
+  // True if the user should be allowed to select text in the terminal.
+  // This is disabled when the host requests mouse drag events so that we don't
+  // end up with two notions of selection.
+  this.selectionEnabled_ = true;
+
+  // The last row count returned by the row provider, re-populated during
+  // syncScrollHeight().
+  this.lastRowCount_ = 0;
+
+  // The scroll wheel pixel delta multiplier to increase/decrease
+  // the scroll speed of mouse wheel events. See: https://goo.gl/sXelnq
+  this.scrollWheelMultiplier_ = 1;
+
+  // The last touch events we saw to support touch based scrolling.  Indexed
+  // by touch identifier since we can have more than one touch active.
+  this.lastTouch_ = {};
+
+  /**
+   * True if the last scroll caused the scrollport to show the final row.
+   */
+  this.isScrolledEnd = true;
+
+  /**
+   * A guess at the current scrollbar width, fixed in resize().
+   */
+  this.currentScrollbarWidthPx = 16;
+
+  /**
+   * Whether the ctrl-v key on the screen should paste.
+   */
+  this.ctrlVPaste = false;
+
+  /**
+   * Whether to paste on dropped text.
+   */
+  this.pasteOnDrop = true;
+
+  this.div_ = null;
+  this.document_ = null;
+
+  // Collection of active timeout handles.
+  this.timeouts_ = {};
+
+  this.observers_ = {};
+
+  // Offscreen selection rows that are set with 'aria-hidden'.
+  // They must be unset when selection changes or the rows are visible.
+  this.ariaHiddenSelectionRows_ = [];
+
+  this.DEBUG_ = false;
+};
+
+/**
+ * Proxy for the native selection object which understands how to walk up the
+ * DOM to find the containing row node and sort out which comes first.
+ *
+ * @param {hterm.ScrollPort} scrollPort The parent hterm.ScrollPort instance.
+ */
+hterm.ScrollPort.Selection = function(scrollPort) {
+  this.scrollPort_ = scrollPort;
+
+  /**
+   * The row containing the start of the selection.
+   *
+   * This may be partially or fully selected.  It may be the selection anchor
+   * or the focus, but its rowIndex is guaranteed to be less-than-or-equal-to
+   * that of the endRow.
+   *
+   * If only one row is selected then startRow == endRow.  If there is no
+   * selection or the selection is collapsed then startRow == null.
+   */
+  this.startRow = null;
+
+  /**
+   * The row containing the end of the selection.
+   *
+   * This may be partially or fully selected.  It may be the selection anchor
+   * or the focus, but its rowIndex is guaranteed to be greater-than-or-equal-to
+   * that of the startRow.
+   *
+   * If only one row is selected then startRow == endRow.  If there is no
+   * selection or the selection is collapsed then startRow == null.
+   */
+  this.endRow = null;
+
+  /**
+   * True if startRow != endRow.
+   */
+  this.isMultiline = null;
+
+  /**
+   * True if the selection is just a point rather than a range.
+   */
+  this.isCollapsed = null;
+};
+
+/**
+ * Given a list of DOM nodes and a container, return the DOM node that
+ * is first according to a depth-first search.
+ *
+ * Returns null if none of the children are found.
+ */
+hterm.ScrollPort.Selection.prototype.findFirstChild = function(
+    parent, childAry) {
+  var node = parent.firstChild;
+
+  while (node) {
+    if (childAry.indexOf(node) != -1)
+      return node;
+
+    if (node.childNodes.length) {
+      var rv = this.findFirstChild(node, childAry);
+      if (rv)
+        return rv;
+    }
+
+    node = node.nextSibling;
+  }
+
+  return null;
+};
+
+/**
+ * Synchronize this object with the current DOM selection.
+ *
+ * This is a one-way synchronization, the DOM selection is copied to this
+ * object, not the other way around.
+ */
+hterm.ScrollPort.Selection.prototype.sync = function() {
+  var self = this;
+
+  // The dom selection object has no way to tell which nodes come first in
+  // the document, so we have to figure that out.
+  //
+  // This function is used when we detect that the "anchor" node is first.
+  function anchorFirst() {
+    self.startRow = anchorRow;
+    self.startNode = selection.anchorNode;
+    self.startOffset = selection.anchorOffset;
+    self.endRow = focusRow;
+    self.endNode = selection.focusNode;
+    self.endOffset = selection.focusOffset;
+  }
+
+  // This function is used when we detect that the "focus" node is first.
+  function focusFirst() {
+    self.startRow = focusRow;
+    self.startNode = selection.focusNode;
+    self.startOffset = selection.focusOffset;
+    self.endRow = anchorRow;
+    self.endNode = selection.anchorNode;
+    self.endOffset = selection.anchorOffset;
+  }
+
+  var selection = this.scrollPort_.getDocument().getSelection();
+
+  this.startRow = null;
+  this.endRow = null;
+  this.isMultiline = null;
+  this.isCollapsed = !selection || selection.isCollapsed;
+
+  if (!selection) {
+    return;
+  }
+
+  // Usually collapsed selections wouldn't be interesting, however screen
+  // readers will set a collapsed selection as they navigate through the DOM.
+  // It is important to preserve these nodes in the DOM as scrolling happens
+  // so that screen reader navigation isn't cleared.
+  const accessibilityEnabled = this.scrollPort_.accessibilityReader_ &&
+      this.scrollPort_.accessibilityReader_.accessibilityEnabled;
+  if (this.isCollapsed && !accessibilityEnabled) {
+    return;
+  }
+
+  var anchorRow = selection.anchorNode;
+  while (anchorRow && anchorRow.nodeName != 'X-ROW') {
+    anchorRow = anchorRow.parentNode;
+  }
+
+  if (!anchorRow) {
+    // Don't set a selection if it's not a row node that's selected.
+    return;
+  }
+
+  var focusRow = selection.focusNode;
+  while (focusRow && focusRow.nodeName != 'X-ROW') {
+    focusRow = focusRow.parentNode;
+  }
+
+  if (!focusRow) {
+    // Don't set a selection if it's not a row node that's selected.
+    return;
+  }
+
+  if (anchorRow.rowIndex < focusRow.rowIndex) {
+    anchorFirst();
+
+  } else if (anchorRow.rowIndex > focusRow.rowIndex) {
+    focusFirst();
+
+  } else if (selection.focusNode == selection.anchorNode) {
+    if (selection.anchorOffset < selection.focusOffset) {
+      anchorFirst();
+    } else {
+      focusFirst();
+    }
+
+  } else {
+    // The selection starts and ends in the same row, but isn't contained all
+    // in a single node.
+    var firstNode = this.findFirstChild(
+        anchorRow, [selection.anchorNode, selection.focusNode]);
+
+    if (!firstNode)
+      throw new Error('Unexpected error syncing selection.');
+
+    if (firstNode == selection.anchorNode) {
+      anchorFirst();
+    } else {
+      focusFirst();
+    }
+  }
+
+  this.isMultiline = anchorRow.rowIndex != focusRow.rowIndex;
+};
+
+
+/**
+ * Turn a div into this hterm.ScrollPort.
+ */
+hterm.ScrollPort.prototype.decorate = function(div, callback) {
+  this.div_ = div;
+
+  this.iframe_ = div.ownerDocument.createElement('iframe');
+  this.iframe_.style.cssText = (
+      'border: 0;' +
+      'height: 100%;' +
+      'position: absolute;' +
+      'width: 100%');
+
+  div.appendChild(this.iframe_);
+
+  const onLoad = () => {
+    this.paintIframeContents_();
+    if (callback) {
+      callback();
+    }
+  };
+
+  // Insert Iframe content asynchronously in FF.  Otherwise when the frame's
+  // load event fires in FF it clears out the content of the iframe.
+  if ('mozInnerScreenX' in window) { // detect a FF only property
+    this.iframe_.addEventListener('load', () => onLoad());
+  } else {
+    onLoad();
+  }
+};
+
+
+/**
+ * Initialises the content of this.iframe_. This needs to be done asynchronously
+ * in FF after the Iframe's load event has fired.
+ * @private
+ */
+hterm.ScrollPort.prototype.paintIframeContents_ = function() {
+  this.iframe_.contentWindow.addEventListener('resize',
+                                              this.onResize_.bind(this));
+
+  var doc = this.document_ = this.iframe_.contentDocument;
+  doc.body.style.cssText = (
+      'margin: 0px;' +
+      'padding: 0px;' +
+      'height: 100%;' +
+      'width: 100%;' +
+      'overflow: hidden;' +
+      'cursor: var(--hterm-mouse-cursor-style);' +
+      '-webkit-user-select: none;' +
+      '-moz-user-select: none;');
+
+  const metaCharset = doc.createElement('meta');
+  metaCharset.setAttribute('charset', 'utf-8');
+  doc.head.appendChild(metaCharset);
+
+  if (this.DEBUG_) {
+    // When we're debugging we add padding to the body so that the offscreen
+    // elements are visible.
+    this.document_.body.style.paddingTop =
+        this.document_.body.style.paddingBottom =
+        'calc(var(--hterm-charsize-height) * 3)';
+  }
+
+  var style = doc.createElement('style');
+  style.textContent = (
+      'x-row {' +
+      '  display: block;' +
+      '  height: var(--hterm-charsize-height);' +
+      '  line-height: var(--hterm-charsize-height);' +
+      '}');
+  doc.head.appendChild(style);
+
+  this.userCssLink_ = doc.createElement('link');
+  this.userCssLink_.setAttribute('rel', 'stylesheet');
+
+  this.userCssText_ = doc.createElement('style');
+  doc.head.appendChild(this.userCssText_);
+
+  // TODO(rginda): Sorry, this 'screen_' isn't the same thing as hterm.Screen
+  // from screen.js.  I need to pick a better name for one of them to avoid
+  // the collision.
+  // We make this field editable even though we don't actually allow anything
+  // to be edited here so that Chrome will do the right thing with virtual
+  // keyboards and IMEs.  But make sure we turn off all the input helper logic
+  // that doesn't make sense here, and might inadvertently mung or save input.
+  // Some of these attributes are standard while others are browser specific,
+  // but should be safely ignored by other browsers.
+  this.screen_ = doc.createElement('x-screen');
+  this.screen_.setAttribute('contenteditable', 'true');
+  this.screen_.setAttribute('spellcheck', 'false');
+  this.screen_.setAttribute('autocomplete', 'off');
+  this.screen_.setAttribute('autocorrect', 'off');
+  this.screen_.setAttribute('autocapitalize', 'none');
+
+  // In some ways the terminal behaves like a text box but not in all ways. It
+  // is not editable in the same ways a text box is editable and the content we
+  // want to be read out by a screen reader does not always align with the edits
+  // (selection changes) that happen in the terminal window. Use the log role so
+  // that the screen reader doesn't treat it like a text box and announce all
+  // selection changes. The announcements that we want spoken are generated
+  // by a separate live region, which gives more control over what will be
+  // spoken.
+  this.screen_.setAttribute('role', 'log');
+  this.screen_.setAttribute('aria-live', 'off');
+  this.screen_.setAttribute('aria-roledescription', 'Terminal');
+
+  // Set aria-readonly to indicate to the screen reader that the text on the
+  // screen is not modifiable by the html cursor. It may be modifiable by
+  // sending input to the application running in the terminal, but this is
+  // orthogonal to the DOM's notion of modifiable.
+  this.screen_.setAttribute('aria-readonly', 'true');
+  this.screen_.setAttribute('tabindex', '-1');
+  this.screen_.style.cssText = (
+      'caret-color: transparent;' +
+      'display: block;' +
+      'font-family: monospace;' +
+      'font-size: 15px;' +
+      'font-variant-ligatures: none;' +
+      'height: 100%;' +
+      'overflow-y: scroll; overflow-x: hidden;' +
+      'white-space: pre;' +
+      'width: 100%;' +
+      'outline: none !important');
+
+  doc.body.appendChild(this.screen_);
+
+  this.screen_.addEventListener('scroll', this.onScroll_.bind(this));
+  this.screen_.addEventListener('wheel', this.onScrollWheel_.bind(this));
+  this.screen_.addEventListener('touchstart', this.onTouch_.bind(this));
+  this.screen_.addEventListener('touchmove', this.onTouch_.bind(this));
+  this.screen_.addEventListener('touchend', this.onTouch_.bind(this));
+  this.screen_.addEventListener('touchcancel', this.onTouch_.bind(this));
+  this.screen_.addEventListener('copy', this.onCopy_.bind(this));
+  this.screen_.addEventListener('paste', this.onPaste_.bind(this));
+  this.screen_.addEventListener('drop', this.onDragAndDrop_.bind(this));
+
+  doc.body.addEventListener('keydown', this.onBodyKeyDown_.bind(this));
+
+  // Add buttons to make accessible scrolling through terminal history work
+  // well. These are positioned off-screen until they are selected, at which
+  // point they are moved on-screen.
+  const scrollButtonHeight = 30;
+  const scrollButtonBorder = 1;
+  const scrollButtonTotalHeight = scrollButtonHeight + 2 * scrollButtonBorder;
+  const scrollButtonStyle = `right: 0px;
+                             position:fixed;
+                             z-index: 1;
+                             text-align: center;
+                             cursor: pointer;
+                             height: ${scrollButtonHeight}px;
+                             width: 110px;
+                             line-height: ${scrollButtonHeight}px;
+                             border-width: ${scrollButtonBorder}px;
+                             border-style: solid;
+                             font-weight: bold;`;
+  // Note: we use a <div> rather than a <button> because we don't want it to be
+  // focusable. If it's focusable this interferes with the contenteditable
+  // focus.
+  this.scrollUpButton_ = this.document_.createElement('div');
+  this.scrollUpButton_.id = 'hterm:a11y:page-up';
+  this.scrollUpButton_.innerText = hterm.msg('BUTTON_PAGE_UP', [], 'Page up');
+  this.scrollUpButton_.setAttribute('role', 'button');
+  this.scrollUpButton_.style.cssText = scrollButtonStyle;
+  this.scrollUpButton_.style.top = -scrollButtonTotalHeight + 'px';
+  this.scrollUpButton_.addEventListener('click', this.scrollPageUp.bind(this));
+
+  this.scrollDownButton_ = this.document_.createElement('div');
+  this.scrollDownButton_.id = 'hterm:a11y:page-down';
+  this.scrollDownButton_.innerText =
+      hterm.msg('BUTTON_PAGE_DOWN', [], 'Page down');
+  this.scrollDownButton_.setAttribute('role', 'button');
+  this.scrollDownButton_.style.cssText = scrollButtonStyle;
+  this.scrollDownButton_.style.bottom = -scrollButtonTotalHeight + 'px';
+  this.scrollDownButton_.addEventListener(
+      'click', this.scrollPageDown.bind(this));
+
+  // We only allow the scroll buttons to display after a delay, otherwise the
+  // page up button can flash onto the screen during the intial change in focus.
+  // This seems to be because it is the first element inside the <x-screen>
+  // element, which will get focussed on page load.
+  this.allowScrollButtonsToDisplay_ = false;
+  setTimeout(() => { this.allowScrollButtonsToDisplay_ = true; }, 500);
+  this.document_.addEventListener('selectionchange', () => {
+    this.selection.sync();
+
+    if (!this.allowScrollButtonsToDisplay_)
+      return;
+
+    const accessibilityEnabled = this.accessibilityReader_ &&
+        this.accessibilityReader_.accessibilityEnabled;
+
+    const selectedElement = this.document_.getSelection().anchorNode;
+    if (accessibilityEnabled && selectedElement == this.scrollUpButton_) {
+      this.scrollUpButton_.style.top = '0px';
+    } else {
+      this.scrollUpButton_.style.top = -scrollButtonTotalHeight + 'px';
+    }
+    if (accessibilityEnabled && selectedElement == this.scrollDownButton_) {
+      this.scrollDownButton_.style.bottom = '0px';
+    } else {
+      this.scrollDownButton_.style.bottom = -scrollButtonTotalHeight + 'px';
+    }
+  });
+
+  this.screen_.appendChild(this.scrollUpButton_);
+
+  // This is the main container for the fixed rows.
+  this.rowNodes_ = doc.createElement('div');
+  this.rowNodes_.id = 'hterm:row-nodes';
+  this.rowNodes_.style.cssText = (
+      'display: block;' +
+      'position: fixed;' +
+      'overflow: hidden;' +
+      '-webkit-user-select: text;' +
+      '-moz-user-select: text;');
+  this.screen_.appendChild(this.rowNodes_);
+
+  this.screen_.appendChild(this.scrollDownButton_);
+
+  // Two nodes to hold offscreen text during the copy event.
+  this.topSelectBag_ = doc.createElement('x-select-bag');
+  this.topSelectBag_.style.cssText = (
+      'display: block;' +
+      'overflow: hidden;' +
+      'height: var(--hterm-charsize-height);' +
+      'white-space: pre;');
+
+  this.bottomSelectBag_ = this.topSelectBag_.cloneNode();
+
+  // Nodes above the top fold and below the bottom fold are hidden.  They are
+  // only used to hold rows that are part of the selection but are currently
+  // scrolled off the top or bottom of the visible range.
+  this.topFold_ = doc.createElement('x-fold');
+  this.topFold_.id = 'hterm:top-fold-for-row-selection';
+  this.topFold_.style.cssText = 'display: block;';
+  this.rowNodes_.appendChild(this.topFold_);
+
+  this.bottomFold_ = this.topFold_.cloneNode();
+  this.bottomFold_.id = 'hterm:bottom-fold-for-row-selection';
+  this.rowNodes_.appendChild(this.bottomFold_);
+
+  // This hidden div accounts for the vertical space that would be consumed by
+  // all the rows in the buffer if they were visible.  It's what causes the
+  // scrollbar to appear on the 'x-screen', and it moves within the screen when
+  // the scrollbar is moved.
+  //
+  // It is set 'visibility: hidden' to keep the browser from trying to include
+  // it in the selection when a user 'drag selects' upwards (drag the mouse to
+  // select and scroll at the same time).  Without this, the selection gets
+  // out of whack.
+  this.scrollArea_ = doc.createElement('div');
+  this.scrollArea_.id = 'hterm:scrollarea';
+  this.scrollArea_.style.cssText = 'visibility: hidden';
+  this.screen_.appendChild(this.scrollArea_);
+
+  // This svg element is used to detect when the browser is zoomed.  It must be
+  // placed in the outermost document for currentScale to be correct.
+  // TODO(rginda): This means that hterm nested in an iframe will not correctly
+  // detect browser zoom level.  We should come up with a better solution.
+  // Note: This must be http:// else Chrome cannot create the element correctly.
+  var xmlns = 'http://www.w3.org/2000/svg';
+  this.svg_ = this.div_.ownerDocument.createElementNS(xmlns, 'svg');
+  this.svg_.id = 'hterm:zoom-detector';
+  this.svg_.setAttribute('xmlns', xmlns);
+  this.svg_.setAttribute('version', '1.1');
+  this.svg_.style.cssText = (
+      'position: absolute;' +
+      'top: 0;' +
+      'left: 0;' +
+      'visibility: hidden');
+
+
+  // We send focus to this element just before a paste happens, so we can
+  // capture the pasted text and forward it on to someone who cares.
+  this.pasteTarget_ = doc.createElement('textarea');
+  this.pasteTarget_.id = 'hterm:ctrl-v-paste-target';
+  this.pasteTarget_.setAttribute('tabindex', '-1');
+  this.pasteTarget_.setAttribute('aria-hidden', 'true');
+  this.pasteTarget_.style.cssText = (
+    'position: absolute;' +
+    'height: 1px;' +
+    'width: 1px;' +
+    'left: 0px; ' +
+    'bottom: 0px;' +
+    'opacity: 0');
+  this.pasteTarget_.contentEditable = true;
+
+  this.screen_.appendChild(this.pasteTarget_);
+  this.pasteTarget_.addEventListener(
+      'textInput', this.handlePasteTargetTextInput_.bind(this));
+
+  this.resize();
+};
+
+/**
+ * Set the AccessibilityReader object to use to announce page scroll updates.
+ *
+ * @param {hterm.AccessibilityReader} accessibilityReader for announcing page
+ *     scroll updates.
+ */
+hterm.ScrollPort.prototype.setAccessibilityReader =
+    function(accessibilityReader) {
+  this.accessibilityReader_ = accessibilityReader;
+};
+
+/**
+ * Scroll the terminal one page up (minus one line) relative to the current
+ * position.
+ */
+hterm.ScrollPort.prototype.scrollPageUp = function() {
+  if (this.getTopRowIndex() == 0) {
+    return;
+  }
+
+  const i = this.getTopRowIndex();
+  this.scrollRowToTop(i - this.visibleRowCount + 1);
+
+  this.assertiveAnnounce_();
+};
+
+/**
+ * Scroll the terminal one page down (minus one line) relative to the current
+ * position.
+ */
+hterm.ScrollPort.prototype.scrollPageDown = function() {
+  if (this.isScrolledEnd) {
+    return;
+  }
+
+  const i = this.getTopRowIndex();
+  this.scrollRowToTop(i + this.visibleRowCount - 1);
+
+  this.assertiveAnnounce_();
+};
+
+/**
+ * Select the font-family and font-smoothing for this scrollport.
+ *
+ * @param {string} fontFamily Value of the CSS 'font-family' to use for this
+ *     scrollport.  Should be a monospace font.
+ * @param {string} opt_smoothing Optional value for '-webkit-font-smoothing'.
+ *     Defaults to an empty string if not specified.
+ */
+hterm.ScrollPort.prototype.setFontFamily = function(fontFamily, opt_smoothing) {
+  this.screen_.style.fontFamily = fontFamily;
+  if (opt_smoothing) {
+    this.screen_.style.webkitFontSmoothing = opt_smoothing;
+  } else {
+    this.screen_.style.webkitFontSmoothing = '';
+  }
+
+  this.syncCharacterSize();
+};
+
+hterm.ScrollPort.prototype.getFontFamily = function() {
+  return this.screen_.style.fontFamily;
+};
+
+/**
+ * Set a custom stylesheet to include in the scrollport.
+ *
+ * Defaults to null, meaning no custom css is loaded.  Set it back to null or
+ * the empty string to remove a previously applied custom css.
+ */
+hterm.ScrollPort.prototype.setUserCssUrl = function(url) {
+  if (url) {
+    this.userCssLink_.setAttribute('href', url);
+
+    if (!this.userCssLink_.parentNode)
+      this.document_.head.appendChild(this.userCssLink_);
+  } else if (this.userCssLink_.parentNode) {
+    this.document_.head.removeChild(this.userCssLink_);
+  }
+};
+
+hterm.ScrollPort.prototype.setUserCssText = function(text) {
+  this.userCssText_.textContent = text;
+};
+
+hterm.ScrollPort.prototype.focus = function() {
+  this.iframe_.focus();
+  this.screen_.focus();
+  this.publish('focus');
+};
+
+hterm.ScrollPort.prototype.getForegroundColor = function() {
+  return this.screen_.style.color;
+};
+
+hterm.ScrollPort.prototype.setForegroundColor = function(color) {
+  this.screen_.style.color = color;
+  this.scrollUpButton_.style.backgroundColor = color;
+  this.scrollDownButton_.style.backgroundColor = color;
+};
+
+hterm.ScrollPort.prototype.getBackgroundColor = function() {
+  return this.screen_.style.backgroundColor;
+};
+
+hterm.ScrollPort.prototype.setBackgroundColor = function(color) {
+  this.screen_.style.backgroundColor = color;
+  this.scrollUpButton_.style.color = color;
+  this.scrollDownButton_.style.color = color;
+};
+
+hterm.ScrollPort.prototype.setBackgroundImage = function(image) {
+  this.screen_.style.backgroundImage = image;
+};
+
+hterm.ScrollPort.prototype.setBackgroundSize = function(size) {
+  this.screen_.style.backgroundSize = size;
+};
+
+hterm.ScrollPort.prototype.setBackgroundPosition = function(position) {
+  this.screen_.style.backgroundPosition = position;
+};
+
+hterm.ScrollPort.prototype.setCtrlVPaste = function(ctrlVPaste) {
+  this.ctrlVPaste = ctrlVPaste;
+};
+
+hterm.ScrollPort.prototype.setPasteOnDrop = function(pasteOnDrop) {
+  this.pasteOnDrop = pasteOnDrop;
+};
+
+/**
+ * Get the usable size of the scrollport screen.
+ *
+ * The width will not include the scrollbar width.
+ */
+hterm.ScrollPort.prototype.getScreenSize = function() {
+  var size = hterm.getClientSize(this.screen_);
+  return {
+    height: size.height,
+    width: size.width - this.currentScrollbarWidthPx
+  };
+};
+
+/**
+ * Get the usable width of the scrollport screen.
+ *
+ * This the widget width minus scrollbar width.
+ */
+hterm.ScrollPort.prototype.getScreenWidth = function() {
+  return this.getScreenSize().width ;
+};
+
+/**
+ * Get the usable height of the scrollport screen.
+ */
+hterm.ScrollPort.prototype.getScreenHeight = function() {
+  return this.getScreenSize().height;
+};
+
+/**
+ * Return the document that holds the visible rows of this hterm.ScrollPort.
+ */
+hterm.ScrollPort.prototype.getDocument = function() {
+  return this.document_;
+};
+
+/**
+ * Returns the x-screen element that holds the rows of this hterm.ScrollPort.
+ */
+hterm.ScrollPort.prototype.getScreenNode = function() {
+  return this.screen_;
+};
+
+/**
+ * Clear out any cached rowNodes.
+ */
+hterm.ScrollPort.prototype.resetCache = function() {
+  this.currentRowNodeCache_ = null;
+  this.previousRowNodeCache_ = {};
+};
+
+/**
+ * Change the current rowProvider.
+ *
+ * This will clear the row cache and cause a redraw.
+ *
+ * @param {Object} rowProvider An object capable of providing the rows
+ *     in this hterm.ScrollPort.
+ */
+hterm.ScrollPort.prototype.setRowProvider = function(rowProvider) {
+  this.resetCache();
+  this.rowProvider_ = rowProvider;
+  this.scheduleRedraw();
+};
+
+/**
+ * Inform the ScrollPort that the root DOM nodes for some or all of the visible
+ * rows are no longer valid.
+ *
+ * Specifically, this should be called if this.rowProvider_.getRowNode() now
+ * returns an entirely different node than it did before.  It does not
+ * need to be called if the content of a row node is the only thing that
+ * changed.
+ *
+ * This skips some of the overhead of a full redraw, but should not be used
+ * in cases where the scrollport has been scrolled, or when the row count has
+ * changed.
+ */
+hterm.ScrollPort.prototype.invalidate = function() {
+  var node = this.topFold_.nextSibling;
+  while (node != this.bottomFold_) {
+    var nextSibling = node.nextSibling;
+    node.parentElement.removeChild(node);
+    node = nextSibling;
+  }
+
+  this.previousRowNodeCache_ = null;
+  var topRowIndex = this.getTopRowIndex();
+  var bottomRowIndex = this.getBottomRowIndex(topRowIndex);
+
+  this.drawVisibleRows_(topRowIndex, bottomRowIndex);
+};
+
+hterm.ScrollPort.prototype.scheduleInvalidate = function() {
+  if (this.timeouts_.invalidate)
+    return;
+
+  var self = this;
+  this.timeouts_.invalidate = setTimeout(function () {
+      delete self.timeouts_.invalidate;
+      self.invalidate();
+    }, 0);
+};
+
+/**
+ * Set the font size of the ScrollPort.
+ */
+hterm.ScrollPort.prototype.setFontSize = function(px) {
+  this.screen_.style.fontSize = px + 'px';
+  this.syncCharacterSize();
+};
+
+/**
+ * Return the current font size of the ScrollPort.
+ */
+hterm.ScrollPort.prototype.getFontSize = function() {
+  return parseInt(this.screen_.style.fontSize);
+};
+
+/**
+ * Measure the size of a single character in pixels.
+ *
+ * @param {string} opt_weight The font weight to measure, or 'normal' if
+ *     omitted.
+ * @return {hterm.Size} A new hterm.Size object.
+ */
+hterm.ScrollPort.prototype.measureCharacterSize = function(opt_weight) {
+  // Number of lines used to average the height of a single character.
+  var numberOfLines = 100;
+  // Number of chars per line used to average the width of a single character.
+  var lineLength = 100;
+
+  if (!this.ruler_) {
+    this.ruler_ = this.document_.createElement('div');
+    this.ruler_.id = 'hterm:ruler-character-size';
+    this.ruler_.style.cssText = (
+        'position: absolute;' +
+        'top: 0;' +
+        'left: 0;' +
+        'visibility: hidden;' +
+        'height: auto !important;' +
+        'width: auto !important;');
+
+    // We need to put the text in a span to make the size calculation
+    // work properly in Firefox
+    this.rulerSpan_ = this.document_.createElement('span');
+    this.rulerSpan_.id = 'hterm:ruler-span-workaround';
+    this.rulerSpan_.innerHTML =
+        ('X'.repeat(lineLength) + '\r').repeat(numberOfLines);
+    this.ruler_.appendChild(this.rulerSpan_);
+
+    this.rulerBaseline_ = this.document_.createElement('span');
+    this.rulerSpan_.id = 'hterm:ruler-baseline';
+    // We want to collapse it on the baseline
+    this.rulerBaseline_.style.fontSize = '0px';
+    this.rulerBaseline_.textContent = 'X';
+  }
+
+  this.rulerSpan_.style.fontWeight = opt_weight || '';
+
+  this.rowNodes_.appendChild(this.ruler_);
+  var rulerSize = hterm.getClientSize(this.rulerSpan_);
+
+  var size = new hterm.Size(rulerSize.width / lineLength,
+                            rulerSize.height / numberOfLines);
+
+  this.ruler_.appendChild(this.rulerBaseline_);
+  this.ruler_.removeChild(this.rulerBaseline_);
+
+  this.rowNodes_.removeChild(this.ruler_);
+
+  this.div_.ownerDocument.body.appendChild(this.svg_);
+  size.zoomFactor = this.svg_.currentScale;
+  this.div_.ownerDocument.body.removeChild(this.svg_);
+
+  return size;
+};
+
+/**
+ * Synchronize the character size.
+ *
+ * This will re-measure the current character size and adjust the height
+ * of an x-row to match.
+ */
+hterm.ScrollPort.prototype.syncCharacterSize = function() {
+  this.characterSize = this.measureCharacterSize();
+
+  this.resize();
+};
+
+/**
+ * Reset dimensions and visible row count to account for a change in the
+ * dimensions of the 'x-screen'.
+ */
+hterm.ScrollPort.prototype.resize = function() {
+  this.currentScrollbarWidthPx = hterm.getClientWidth(this.screen_) -
+    this.screen_.clientWidth;
+
+  this.syncScrollHeight();
+  this.syncRowNodesDimensions_();
+
+  var self = this;
+  this.publish(
+      'resize', { scrollPort: this },
+      function() {
+        self.scrollRowToBottom(self.rowProvider_.getRowCount());
+        self.scheduleRedraw();
+      });
+};
+
+/**
+ * Announce text content on the current screen for the screen reader.
+ */
+hterm.ScrollPort.prototype.assertiveAnnounce_ = function() {
+  if (!this.accessibilityReader_) {
+    return;
+  }
+
+  const topRow = this.getTopRowIndex();
+  const bottomRow = this.getBottomRowIndex(topRow);
+
+  let percentScrolled = 100 * topRow /
+      Math.max(1, this.rowProvider_.getRowCount() - this.visibleRowCount);
+  percentScrolled = Math.min(100, Math.round(percentScrolled));
+  let currentScreenContent = hterm.msg('ANNOUNCE_CURRENT_SCREEN_HEADER',
+                                       [percentScrolled],
+                                       '$1% scrolled,');
+  currentScreenContent += '\n';
+
+  for (let i = topRow; i <= bottomRow; ++i) {
+    const node = this.fetchRowNode_(i);
+    currentScreenContent += node.textContent + '\n';
+  }
+
+  this.accessibilityReader_.assertiveAnnounce(currentScreenContent);
+};
+
+/**
+ * Set the position and size of the row nodes element.
+ */
+hterm.ScrollPort.prototype.syncRowNodesDimensions_ = function() {
+  var screenSize = this.getScreenSize();
+
+  this.lastScreenWidth_ = screenSize.width;
+  this.lastScreenHeight_ = screenSize.height;
+
+  // We don't want to show a partial row because it would be distracting
+  // in a terminal, so we floor any fractional row count.
+  this.visibleRowCount = lib.f.smartFloorDivide(
+      screenSize.height, this.characterSize.height);
+
+  // Then compute the height of our integral number of rows.
+  var visibleRowsHeight = this.visibleRowCount * this.characterSize.height;
+
+  // Then the difference between the screen height and total row height needs to
+  // be made up for as top margin.  We need to record this value so it
+  // can be used later to determine the topRowIndex.
+  this.visibleRowTopMargin = 0;
+  this.visibleRowBottomMargin = screenSize.height - visibleRowsHeight;
+
+  this.topFold_.style.marginBottom = this.visibleRowTopMargin + 'px';
+
+
+  var topFoldOffset = 0;
+  var node = this.topFold_.previousSibling;
+  while (node) {
+    topFoldOffset += hterm.getClientHeight(node);
+    node = node.previousSibling;
+  }
+
+  // Set the dimensions of the visible rows container.
+  this.rowNodes_.style.width = screenSize.width + 'px';
+  this.rowNodes_.style.height = visibleRowsHeight + topFoldOffset + 'px';
+  this.rowNodes_.style.left = this.screen_.offsetLeft + 'px';
+  this.rowNodes_.style.top = this.screen_.offsetTop - topFoldOffset + 'px';
+};
+
+hterm.ScrollPort.prototype.syncScrollHeight = function() {
+  // Resize the scroll area to appear as though it contains every row.
+  this.lastRowCount_ = this.rowProvider_.getRowCount();
+  this.scrollArea_.style.height = (this.characterSize.height *
+                                   this.lastRowCount_ +
+                                   this.visibleRowTopMargin +
+                                   this.visibleRowBottomMargin +
+                                   'px');
+};
+
+/**
+ * Schedule a redraw to happen asynchronously.
+ *
+ * If this method is called multiple times before the redraw has a chance to
+ * run only one redraw occurs.
+ */
+hterm.ScrollPort.prototype.scheduleRedraw = function() {
+  if (this.timeouts_.redraw)
+    return;
+
+  var self = this;
+  this.timeouts_.redraw = setTimeout(function () {
+      delete self.timeouts_.redraw;
+      self.redraw_();
+    }, 0);
+};
+
+/**
+ * Update the state of scroll up/down buttons.
+ *
+ * If the viewport is at the top or bottom row of output, these buttons will
+ * be made transparent and clicking them shouldn't scroll any further.
+ */
+hterm.ScrollPort.prototype.updateScrollButtonState_ = function() {
+  const setButton = (button, disabled) => {
+    button.setAttribute('aria-disabled', disabled ? 'true' : 'false');
+    button.style.opacity = disabled ? 0.5 : 1;
+  };
+  setButton(this.scrollUpButton_, this.getTopRowIndex() == 0);
+  setButton(this.scrollDownButton_, this.isScrolledEnd);
+};
+
+/**
+ * Redraw the current hterm.ScrollPort based on the current scrollbar position.
+ *
+ * When redrawing, we are careful to make sure that the rows that start or end
+ * the current selection are not touched in any way.  Doing so would disturb
+ * the selection, and cleaning up after that would cause flashes at best and
+ * incorrect selection at worst.  Instead, we modify the DOM around these nodes.
+ * We even stash the selection start/end outside of the visible area if
+ * they are not supposed to be visible in the hterm.ScrollPort.
+ */
+hterm.ScrollPort.prototype.redraw_ = function() {
+  this.resetSelectBags_();
+  this.selection.sync();
+
+  this.syncScrollHeight();
+
+  this.currentRowNodeCache_ = {};
+
+  var topRowIndex = this.getTopRowIndex();
+  var bottomRowIndex = this.getBottomRowIndex(topRowIndex);
+
+  this.drawTopFold_(topRowIndex);
+  this.drawBottomFold_(bottomRowIndex);
+  this.drawVisibleRows_(topRowIndex, bottomRowIndex);
+  this.ariaHideOffscreenSelectionRows_(topRowIndex, bottomRowIndex);
+
+  this.syncRowNodesDimensions_();
+
+  this.previousRowNodeCache_ = this.currentRowNodeCache_;
+  this.currentRowNodeCache_ = null;
+
+  this.isScrolledEnd = (
+    this.getTopRowIndex() + this.visibleRowCount >= this.lastRowCount_);
+
+  this.updateScrollButtonState_();
+};
+
+/**
+ * Ensure that the nodes above the top fold are as they should be.
+ *
+ * If the selection start and/or end nodes are above the visible range
+ * of this hterm.ScrollPort then the dom will be adjusted so that they appear
+ * before the top fold (the first x-fold element, aka this.topFold).
+ *
+ * If not, the top fold will be the first element.
+ *
+ * It is critical that this method does not move the selection nodes.  Doing
+ * so would clear the current selection.  Instead, the rest of the DOM is
+ * adjusted around them.
+ */
+hterm.ScrollPort.prototype.drawTopFold_ = function(topRowIndex) {
+  if (!this.selection.startRow ||
+      this.selection.startRow.rowIndex >= topRowIndex) {
+    // Selection is entirely below the top fold, just make sure the fold is
+    // the first child.
+    if (this.rowNodes_.firstChild != this.topFold_)
+      this.rowNodes_.insertBefore(this.topFold_, this.rowNodes_.firstChild);
+
+    return;
+  }
+
+  if (!this.selection.isMultiline ||
+      this.selection.endRow.rowIndex >= topRowIndex) {
+    // Only the startRow is above the fold.
+    if (this.selection.startRow.nextSibling != this.topFold_)
+      this.rowNodes_.insertBefore(this.topFold_,
+                                  this.selection.startRow.nextSibling);
+  } else {
+    // Both rows are above the fold.
+    if (this.selection.endRow.nextSibling != this.topFold_) {
+      this.rowNodes_.insertBefore(this.topFold_,
+                                  this.selection.endRow.nextSibling);
+    }
+
+    // Trim any intermediate lines.
+    while (this.selection.startRow.nextSibling !=
+           this.selection.endRow) {
+      this.rowNodes_.removeChild(this.selection.startRow.nextSibling);
+    }
+  }
+
+  while(this.rowNodes_.firstChild != this.selection.startRow) {
+    this.rowNodes_.removeChild(this.rowNodes_.firstChild);
+  }
+};
+
+/**
+ * Ensure that the nodes below the bottom fold are as they should be.
+ *
+ * If the selection start and/or end nodes are below the visible range
+ * of this hterm.ScrollPort then the dom will be adjusted so that they appear
+ * after the bottom fold (the second x-fold element, aka this.bottomFold).
+ *
+ * If not, the bottom fold will be the last element.
+ *
+ * It is critical that this method does not move the selection nodes.  Doing
+ * so would clear the current selection.  Instead, the rest of the DOM is
+ * adjusted around them.
+ */
+hterm.ScrollPort.prototype.drawBottomFold_ = function(bottomRowIndex) {
+  if (!this.selection.endRow ||
+      this.selection.endRow.rowIndex <= bottomRowIndex) {
+    // Selection is entirely above the bottom fold, just make sure the fold is
+    // the last child.
+    if (this.rowNodes_.lastChild != this.bottomFold_)
+      this.rowNodes_.appendChild(this.bottomFold_);
+
+    return;
+  }
+
+  if (!this.selection.isMultiline ||
+      this.selection.startRow.rowIndex <= bottomRowIndex) {
+    // Only the endRow is below the fold.
+    if (this.bottomFold_.nextSibling != this.selection.endRow)
+      this.rowNodes_.insertBefore(this.bottomFold_,
+                                  this.selection.endRow);
+  } else {
+    // Both rows are below the fold.
+    if (this.bottomFold_.nextSibling != this.selection.startRow) {
+      this.rowNodes_.insertBefore(this.bottomFold_,
+                                  this.selection.startRow);
+    }
+
+    // Trim any intermediate lines.
+    while (this.selection.startRow.nextSibling !=
+           this.selection.endRow) {
+      this.rowNodes_.removeChild(this.selection.startRow.nextSibling);
+    }
+  }
+
+  while(this.rowNodes_.lastChild != this.selection.endRow) {
+    this.rowNodes_.removeChild(this.rowNodes_.lastChild);
+  }
+};
+
+/**
+ * Ensure that the rows between the top and bottom folds are as they should be.
+ *
+ * This method assumes that drawTopFold_() and drawBottomFold_() have already
+ * run, and that they have left any visible selection row (selection start
+ * or selection end) between the folds.
+ *
+ * It recycles DOM nodes from the previous redraw where possible, but will ask
+ * the rowSource to make new nodes if necessary.
+ *
+ * It is critical that this method does not move the selection nodes.  Doing
+ * so would clear the current selection.  Instead, the rest of the DOM is
+ * adjusted around them.
+ */
+hterm.ScrollPort.prototype.drawVisibleRows_ = function(
+    topRowIndex, bottomRowIndex) {
+  var self = this;
+
+  // Keep removing nodes, starting with currentNode, until we encounter
+  // targetNode.  Throws on failure.
+  function removeUntilNode(currentNode, targetNode) {
+    while (currentNode != targetNode) {
+      if (!currentNode)
+        throw 'Did not encounter target node';
+
+      if (currentNode == self.bottomFold_)
+        throw 'Encountered bottom fold before target node';
+
+      var deadNode = currentNode;
+      currentNode = currentNode.nextSibling;
+      deadNode.parentNode.removeChild(deadNode);
+    }
+  }
+
+  // Shorthand for things we're going to use a lot.
+  var selectionStartRow = this.selection.startRow;
+  var selectionEndRow = this.selection.endRow;
+  var bottomFold = this.bottomFold_;
+
+  // The node we're examining during the current iteration.
+  var node = this.topFold_.nextSibling;
+
+  var targetDrawCount = Math.min(this.visibleRowCount,
+                                 this.rowProvider_.getRowCount());
+
+  for (var drawCount = 0; drawCount < targetDrawCount; drawCount++) {
+    var rowIndex = topRowIndex + drawCount;
+
+    if (node == bottomFold) {
+      // We've hit the bottom fold, we need to insert a new row.
+      var newNode = this.fetchRowNode_(rowIndex);
+      if (!newNode) {
+        console.log("Couldn't fetch row index: " + rowIndex);
+        break;
+      }
+
+      this.rowNodes_.insertBefore(newNode, node);
+      continue;
+    }
+
+    if (node.rowIndex == rowIndex) {
+      // This node is in the right place, move along.
+      node = node.nextSibling;
+      continue;
+    }
+
+    if (selectionStartRow && selectionStartRow.rowIndex == rowIndex) {
+      // The selection start row is supposed to be here, remove nodes until
+      // we find it.
+      removeUntilNode(node, selectionStartRow);
+      node = selectionStartRow.nextSibling;
+      continue;
+    }
+
+    if (selectionEndRow && selectionEndRow.rowIndex == rowIndex) {
+      // The selection end row is supposed to be here, remove nodes until
+      // we find it.
+      removeUntilNode(node, selectionEndRow);
+      node = selectionEndRow.nextSibling;
+      continue;
+    }
+
+    if (node == selectionStartRow || node == selectionEndRow) {
+      // We encountered the start/end of the selection, but we don't want it
+      // yet.  Insert a new row instead.
+      var newNode = this.fetchRowNode_(rowIndex);
+      if (!newNode) {
+        console.log("Couldn't fetch row index: " + rowIndex);
+        break;
+      }
+
+      this.rowNodes_.insertBefore(newNode, node);
+      continue;
+    }
+
+    // There is nothing special about this node, but it's in our way.  Replace
+    // it with the node that should be here.
+    var newNode = this.fetchRowNode_(rowIndex);
+    if (!newNode) {
+      console.log("Couldn't fetch row index: " + rowIndex);
+      break;
+    }
+
+    if (node == newNode) {
+      node = node.nextSibling;
+      continue;
+    }
+
+    this.rowNodes_.insertBefore(newNode, node);
+    if (!newNode.nextSibling)
+      debugger;
+    this.rowNodes_.removeChild(node);
+    node = newNode.nextSibling;
+  }
+
+  if (node != this.bottomFold_)
+    removeUntilNode(node, bottomFold);
+};
+
+/**
+ * Ensure aria-hidden is set on any selection rows that are offscreen.
+ *
+ * The attribute aria-hidden is set to 'true' so that hidden rows are ignored
+ * by screen readers.  We keep a list of currently hidden rows so they can be
+ * reset each time this function is called as the selection and/or scrolling
+ * may have changed.
+ *
+ * @param {number} topRowIndex Index of top row on screen.
+ * @param {number} bottomRowIndex Index of bottom row on screen.
+ */
+hterm.ScrollPort.prototype.ariaHideOffscreenSelectionRows_ = function(
+    topRowIndex, bottomRowIndex) {
+  // Reset previously hidden selection rows.
+  const hiddenRows = this.ariaHiddenSelectionRows_;
+  let row;
+  while (row = hiddenRows.pop()) {
+    row.removeAttribute('aria-hidden');
+  }
+
+  function checkRow(row) {
+    if (row && (row.rowIndex < topRowIndex || row.rowIndex > bottomRowIndex)) {
+      row.setAttribute('aria-hidden', 'true');
+      hiddenRows.push(row);
+    }
+  }
+  checkRow(this.selection.startRow);
+  checkRow(this.selection.endRow);
+};
+
+/**
+ * Empty out both select bags and remove them from the document.
+ *
+ * These nodes hold the text between the start and end of the selection
+ * when that text is otherwise off screen.  They are filled out in the
+ * onCopy_ event.
+ */
+hterm.ScrollPort.prototype.resetSelectBags_ = function() {
+  if (this.topSelectBag_.parentNode) {
+    this.topSelectBag_.textContent = '';
+    this.topSelectBag_.parentNode.removeChild(this.topSelectBag_);
+  }
+
+  if (this.bottomSelectBag_.parentNode) {
+    this.bottomSelectBag_.textContent = '';
+    this.bottomSelectBag_.parentNode.removeChild(this.bottomSelectBag_);
+  }
+};
+
+/**
+ * Place a row node in the cache of visible nodes.
+ *
+ * This method may only be used during a redraw_.
+ */
+hterm.ScrollPort.prototype.cacheRowNode_ = function(rowNode) {
+  this.currentRowNodeCache_[rowNode.rowIndex] = rowNode;
+};
+
+/**
+ * Fetch the row node for the given index.
+ *
+ * This will return a node from the cache if possible, or will request one
+ * from the RowProvider if not.
+ *
+ * If a redraw_ is in progress the row will be added to the current cache.
+ */
+hterm.ScrollPort.prototype.fetchRowNode_ = function(rowIndex) {
+  var node;
+
+  if (this.previousRowNodeCache_ && rowIndex in this.previousRowNodeCache_) {
+    node = this.previousRowNodeCache_[rowIndex];
+  } else {
+    node = this.rowProvider_.getRowNode(rowIndex);
+  }
+
+  if (this.currentRowNodeCache_)
+    this.cacheRowNode_(node);
+
+  return node;
+};
+
+/**
+ * Select all rows in the viewport.
+ */
+hterm.ScrollPort.prototype.selectAll = function() {
+  var firstRow;
+
+  if (this.topFold_.nextSibling.rowIndex != 0) {
+    while (this.topFold_.previousSibling) {
+      this.rowNodes_.removeChild(this.topFold_.previousSibling);
+    }
+
+    firstRow = this.fetchRowNode_(0);
+    this.rowNodes_.insertBefore(firstRow, this.topFold_);
+    this.syncRowNodesDimensions_();
+  } else {
+    firstRow = this.topFold_.nextSibling;
+  }
+
+  var lastRowIndex = this.rowProvider_.getRowCount() - 1;
+  var lastRow;
+
+  if (this.bottomFold_.previousSibling.rowIndex != lastRowIndex) {
+    while (this.bottomFold_.nextSibling) {
+      this.rowNodes_.removeChild(this.bottomFold_.nextSibling);
+    }
+
+    lastRow = this.fetchRowNode_(lastRowIndex);
+    this.rowNodes_.appendChild(lastRow);
+  } else {
+    lastRow = this.bottomFold_.previousSibling.rowIndex;
+  }
+
+  var selection = this.document_.getSelection();
+  selection.collapse(firstRow, 0);
+  selection.extend(lastRow, lastRow.childNodes.length);
+
+  this.selection.sync();
+};
+
+/**
+ * Return the maximum scroll position in pixels.
+ */
+hterm.ScrollPort.prototype.getScrollMax_ = function(e) {
+  return (hterm.getClientHeight(this.scrollArea_) +
+          this.visibleRowTopMargin + this.visibleRowBottomMargin -
+          hterm.getClientHeight(this.screen_));
+};
+
+/**
+ * Scroll the given rowIndex to the top of the hterm.ScrollPort.
+ *
+ * @param {integer} rowIndex Index of the target row.
+ */
+hterm.ScrollPort.prototype.scrollRowToTop = function(rowIndex) {
+  this.syncScrollHeight();
+
+  this.isScrolledEnd = (
+    rowIndex + this.visibleRowCount >= this.lastRowCount_);
+
+  var scrollTop = rowIndex * this.characterSize.height +
+      this.visibleRowTopMargin;
+
+  var scrollMax = this.getScrollMax_();
+  if (scrollTop > scrollMax)
+    scrollTop = scrollMax;
+
+  if (this.screen_.scrollTop == scrollTop)
+    return;
+
+  this.screen_.scrollTop = scrollTop;
+  this.scheduleRedraw();
+};
+
+/**
+ * Scroll the given rowIndex to the bottom of the hterm.ScrollPort.
+ *
+ * @param {integer} rowIndex Index of the target row.
+ */
+hterm.ScrollPort.prototype.scrollRowToBottom = function(rowIndex) {
+  this.syncScrollHeight();
+
+  this.isScrolledEnd = (
+    rowIndex + this.visibleRowCount >= this.lastRowCount_);
+
+  var scrollTop = rowIndex * this.characterSize.height +
+      this.visibleRowTopMargin + this.visibleRowBottomMargin;
+  scrollTop -= this.visibleRowCount * this.characterSize.height;
+
+  if (scrollTop < 0)
+    scrollTop = 0;
+
+  if (this.screen_.scrollTop == scrollTop)
+    return;
+
+  this.screen_.scrollTop = scrollTop;
+};
+
+/**
+ * Return the row index of the first visible row.
+ *
+ * This is based on the scroll position.  If a redraw_ is in progress this
+ * returns the row that *should* be at the top.
+ */
+hterm.ScrollPort.prototype.getTopRowIndex = function() {
+  return Math.round(this.screen_.scrollTop / this.characterSize.height);
+};
+
+/**
+ * Return the row index of the last visible row.
+ *
+ * This is based on the scroll position.  If a redraw_ is in progress this
+ * returns the row that *should* be at the bottom.
+ */
+hterm.ScrollPort.prototype.getBottomRowIndex = function(topRowIndex) {
+  return topRowIndex + this.visibleRowCount - 1;
+};
+
+/**
+ * Handler for scroll events.
+ *
+ * The onScroll event fires when scrollArea's scrollTop property changes.  This
+ * may be due to the user manually move the scrollbar, or a programmatic change.
+ */
+hterm.ScrollPort.prototype.onScroll_ = function(e) {
+  var screenSize = this.getScreenSize();
+  if (screenSize.width != this.lastScreenWidth_ ||
+      screenSize.height != this.lastScreenHeight_) {
+    // This event may also fire during a resize (but before the resize event!).
+    // This happens when the browser moves the scrollbar as part of the resize.
+    // In these cases, we want to ignore the scroll event and let onResize
+    // handle things.  If we don't, then we end up scrolling to the wrong
+    // position after a resize.
+    this.resize();
+    return;
+  }
+
+  this.redraw_();
+  this.publish('scroll', { scrollPort: this });
+};
+
+/**
+ * Clients can override this if they want to hear scrollwheel events.
+ *
+ * Clients may call event.preventDefault() if they want to keep the scrollport
+ * from also handling the events.
+ */
+hterm.ScrollPort.prototype.onScrollWheel = function(e) {};
+
+/**
+ * Handler for scroll-wheel events.
+ *
+ * The onScrollWheel event fires when the user moves their scrollwheel over this
+ * hterm.ScrollPort.  Because the frontmost element in the hterm.ScrollPort is
+ * a fixed position DIV, the scroll wheel does nothing by default.  Instead, we
+ * have to handle it manually.
+ */
+hterm.ScrollPort.prototype.onScrollWheel_ = function(e) {
+  this.onScrollWheel(e);
+
+  // Ignore the event if it was already handled (preventDefault was called),
+  // or if it is non-cancelable since preventDefault is ignored for these.
+  // See https://crbug.com/894223 where blink sends non-cancelable touchpad
+  // scrollWheel events.
+  if (e.defaultPrevented || !e.cancelable)
+    return;
+
+  // Figure out how far this event wants us to scroll.
+  const delta = this.scrollWheelDelta(e);
+
+  let top = this.screen_.scrollTop - delta.y;
+  if (top < 0)
+    top = 0;
+
+  var scrollMax = this.getScrollMax_();
+  if (top > scrollMax)
+    top = scrollMax;
+
+  if (top != this.screen_.scrollTop) {
+    // Moving scrollTop causes a scroll event, which triggers the redraw.
+    this.screen_.scrollTop = top;
+
+    // Only preventDefault when we've actually scrolled.  If there's nothing
+    // to scroll we want to pass the event through so Chrome can detect the
+    // overscroll.
+    e.preventDefault();
+  }
+};
+
+/**
+ * Calculate how far a wheel event should scroll.
+ *
+ * This normalizes the browser's concept of a scroll (pixels, lines, etc...)
+ * into a standard pixel distance.
+ *
+ * @param {WheelEvent} e The mouse wheel event to process.
+ * @return {Object} The x & y of how far (in pixels) to scroll.
+ */
+hterm.ScrollPort.prototype.scrollWheelDelta = function(e) {
+  const delta = {x: 0, y: 0};
+
+  switch (e.deltaMode) {
+    case WheelEvent.DOM_DELTA_PIXEL:
+      delta.x = e.deltaX * this.scrollWheelMultiplier_;
+      delta.y = e.deltaY * this.scrollWheelMultiplier_;
+      break;
+    case WheelEvent.DOM_DELTA_LINE:
+      delta.x = e.deltaX * this.characterSize.width;
+      delta.y = e.deltaY * this.characterSize.height;
+      break;
+    case WheelEvent.DOM_DELTA_PAGE:
+      delta.x = e.deltaX * this.characterSize.width * this.screen_.getWidth();
+      delta.y = e.deltaY * this.characterSize.height * this.screen_.getHeight();
+      break;
+  }
+
+  // The Y sign is inverted from what we would expect: up/down are
+  // negative/positive respectively.  The X sign is sane though: left/right
+  // are negative/positive respectively.
+  delta.y *= -1;
+
+  return delta;
+};
+
+
+/**
+ * Clients can override this if they want to hear touch events.
+ *
+ * Clients may call event.preventDefault() if they want to keep the scrollport
+ * from also handling the events.
+ */
+hterm.ScrollPort.prototype.onTouch = function(e) {};
+
+/**
+ * Handler for touch events.
+ */
+hterm.ScrollPort.prototype.onTouch_ = function(e) {
+  this.onTouch(e);
+
+  if (e.defaultPrevented)
+    return;
+
+  // Extract the fields from the Touch event that we need.  If we saved the
+  // event directly, it has references to other objects (like x-row) that
+  // might stick around for a long time.  This way we only have small objects
+  // in our lastTouch_ state.
+  var scrubTouch = function(t) {
+    return {
+      id: t.identifier,
+      y: t.clientY,
+      x: t.clientX,
+    };
+  };
+
+  var i, touch;
+  switch (e.type) {
+    case 'touchstart':
+      // Workaround focus bug on CrOS if possible.
+      // TODO(vapier): Drop this once https://crbug.com/919222 is fixed.
+      if (hterm.os == 'cros' && window.chrome && chrome.windows) {
+        chrome.windows.getCurrent((win) => {
+          if (!win.focused) {
+            chrome.windows.update(win.id, {focused: true});
+          }
+        });
+      }
+
+      // Save the current set of touches.
+      for (i = 0; i < e.changedTouches.length; ++i) {
+        touch = scrubTouch(e.changedTouches[i]);
+        this.lastTouch_[touch.id] = touch;
+      }
+      break;
+
+    case 'touchcancel':
+    case 'touchend':
+      // Throw away existing touches that we're finished with.
+      for (i = 0; i < e.changedTouches.length; ++i)
+        delete this.lastTouch_[e.changedTouches[i].identifier];
+      break;
+
+    case 'touchmove':
+      // Walk all of the touches in this one event and merge all of their
+      // changes into one delta.  This lets multiple fingers scroll faster.
+      var delta = 0;
+      for (i = 0; i < e.changedTouches.length; ++i) {
+        touch = scrubTouch(e.changedTouches[i]);
+        delta += (this.lastTouch_[touch.id].y - touch.y);
+        this.lastTouch_[touch.id] = touch;
+      }
+
+      // Invert to match the touchscreen scrolling direction of browser windows.
+      delta *= -1;
+
+      var top = this.screen_.scrollTop - delta;
+      if (top < 0)
+        top = 0;
+
+      var scrollMax = this.getScrollMax_();
+      if (top > scrollMax)
+        top = scrollMax;
+
+      if (top != this.screen_.scrollTop) {
+        // Moving scrollTop causes a scroll event, which triggers the redraw.
+        this.screen_.scrollTop = top;
+      }
+      break;
+  }
+
+  // To disable gestures or anything else interfering with our scrolling.
+  e.preventDefault();
+};
+
+/**
+ * Handler for resize events.
+ *
+ * The browser will resize us such that the top row stays at the top, but we
+ * prefer to the bottom row to stay at the bottom.
+ */
+hterm.ScrollPort.prototype.onResize_ = function(e) {
+  // Re-measure, since onResize also happens for browser zoom changes.
+  this.syncCharacterSize();
+};
+
+/**
+ * Clients can override this if they want to hear copy events.
+ *
+ * Clients may call event.preventDefault() if they want to keep the scrollport
+ * from also handling the events.
+ */
+hterm.ScrollPort.prototype.onCopy = function(e) { };
+
+/**
+ * Handler for copy-to-clipboard events.
+ *
+ * If some or all of the selected rows are off screen we may need to fill in
+ * the rows between selection start and selection end.  This handler determines
+ * if we're missing some of the selected text, and if so populates one or both
+ * of the "select bags" with the missing text.
+ */
+hterm.ScrollPort.prototype.onCopy_ = function(e) {
+  this.onCopy(e);
+
+  if (e.defaultPrevented)
+    return;
+
+  this.resetSelectBags_();
+  this.selection.sync();
+
+  if (this.selection.isCollapsed ||
+      this.selection.endRow.rowIndex - this.selection.startRow.rowIndex < 2) {
+    return;
+  }
+
+  var topRowIndex = this.getTopRowIndex();
+  var bottomRowIndex = this.getBottomRowIndex(topRowIndex);
+
+  if (this.selection.startRow.rowIndex < topRowIndex) {
+    // Start of selection is above the top fold.
+    var endBackfillIndex;
+
+    if (this.selection.endRow.rowIndex < topRowIndex) {
+      // Entire selection is above the top fold.
+      endBackfillIndex = this.selection.endRow.rowIndex;
+    } else {
+      // Selection extends below the top fold.
+      endBackfillIndex = this.topFold_.nextSibling.rowIndex;
+    }
+
+    this.topSelectBag_.textContent = this.rowProvider_.getRowsText(
+        this.selection.startRow.rowIndex + 1, endBackfillIndex);
+    this.rowNodes_.insertBefore(this.topSelectBag_,
+                                this.selection.startRow.nextSibling);
+    this.syncRowNodesDimensions_();
+  }
+
+  if (this.selection.endRow.rowIndex > bottomRowIndex) {
+    // Selection ends below the bottom fold.
+    var startBackfillIndex;
+
+    if (this.selection.startRow.rowIndex > bottomRowIndex) {
+      // Entire selection is below the bottom fold.
+      startBackfillIndex = this.selection.startRow.rowIndex + 1;
+    } else {
+      // Selection starts above the bottom fold.
+      startBackfillIndex = this.bottomFold_.previousSibling.rowIndex + 1;
+    }
+
+    this.bottomSelectBag_.textContent = this.rowProvider_.getRowsText(
+        startBackfillIndex, this.selection.endRow.rowIndex);
+    this.rowNodes_.insertBefore(this.bottomSelectBag_, this.selection.endRow);
+  }
+};
+
+/**
+ * Focuses on the paste target on a ctrl-v keydown event, as in
+ * FF a content editable element must be focused before the paste event.
+ */
+hterm.ScrollPort.prototype.onBodyKeyDown_ = function(e) {
+  if (!this.ctrlVPaste)
+    return;
+
+  if ((e.ctrlKey || e.metaKey) && e.keyCode == 86 /* 'V' */)
+    this.pasteTarget_.focus();
+};
+
+/**
+ * Handle a paste event on the the ScrollPort's screen element.
+ *
+ * TODO: Handle ClipboardData.files transfers.  https://crbug.com/433581.
+ */
+hterm.ScrollPort.prototype.onPaste_ = function(e) {
+  this.pasteTarget_.focus();
+
+  var self = this;
+  setTimeout(function() {
+      self.publish('paste', { text: self.pasteTarget_.value });
+      self.pasteTarget_.value = '';
+      self.focus();
+    }, 0);
+};
+
+/**
+ * Handles a textInput event on the paste target. Stops this from
+ * propagating as we want this to be handled in the onPaste_ method.
+ */
+hterm.ScrollPort.prototype.handlePasteTargetTextInput_ = function(e) {
+  e.stopPropagation();
+};
+
+/**
+ * Handle a drop event on the the ScrollPort's screen element.
+ *
+ * By default we try to copy in the structured format (HTML/whatever).
+ * The shift key can select plain text though.
+ *
+ * TODO: Handle DataTransfer.files transfers.  https://crbug.com/433581.
+ *
+ * @param {DragEvent} e The drag event that fired us.
+ */
+hterm.ScrollPort.prototype.onDragAndDrop_ = function(e) {
+  if (!this.pasteOnDrop)
+    return;
+
+  e.preventDefault();
+
+  let data;
+  let format;
+
+  // If the shift key active, try to find a "rich" text source (but not plain
+  // text).  e.g. text/html is OK.
+  if (e.shiftKey) {
+    e.dataTransfer.types.forEach((t) => {
+      if (!format && t != 'text/plain' && t.startsWith('text/'))
+        format = t;
+    });
+
+    // If we found a non-plain text source, try it out first.
+    if (format)
+      data = e.dataTransfer.getData(format);
+  }
+
+  // If we haven't loaded anything useful, fall back to plain text.
+  if (!data)
+    data = e.dataTransfer.getData('text/plain');
+
+  if (data)
+    this.publish('paste', {text: data});
+};
+
+/**
+ * Set the vertical scrollbar mode of the ScrollPort.
+ */
+hterm.ScrollPort.prototype.setScrollbarVisible = function(state) {
+  this.screen_.style.overflowY = state ? 'scroll' : 'hidden';
+};
+
+/**
+ * Set scroll wheel multiplier. This alters how much the screen scrolls on
+ * mouse wheel events.
+ */
+hterm.ScrollPort.prototype.setScrollWheelMoveMultipler = function(multiplier) {
+  this.scrollWheelMultiplier_ = multiplier;
+};
+// SOURCE FILE: hterm/js/hterm_terminal.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Constructor for the Terminal class.
+ *
+ * A Terminal pulls together the hterm.ScrollPort, hterm.Screen and hterm.VT100
+ * classes to provide the complete terminal functionality.
+ *
+ * There are a number of lower-level Terminal methods that can be called
+ * directly to manipulate the cursor, text, scroll region, and other terminal
+ * attributes.  However, the primary method is interpret(), which parses VT
+ * escape sequences and invokes the appropriate Terminal methods.
+ *
+ * This class was heavily influenced by Cory Maccarrone's Framebuffer class.
+ *
+ * TODO(rginda): Eventually we're going to need to support characters which are
+ * displayed twice as wide as standard latin characters.  This is to support
+ * CJK (and possibly other character sets).
+ *
+ * @param {string} opt_profileId Optional preference profile name.  If not
+ *     provided, defaults to 'default'.
+ */
+hterm.Terminal = function(opt_profileId) {
+  this.profileId_ = null;
+
+  // Two screen instances.
+  this.primaryScreen_ = new hterm.Screen();
+  this.alternateScreen_ = new hterm.Screen();
+
+  // The "current" screen.
+  this.screen_ = this.primaryScreen_;
+
+  // The local notion of the screen size.  ScreenBuffers also have a size which
+  // indicates their present size.  During size changes, the two may disagree.
+  // Also, the inactive screen's size is not altered until it is made the active
+  // screen.
+  this.screenSize = new hterm.Size(0, 0);
+
+  // The scroll port we'll be using to display the visible rows.
+  this.scrollPort_ = new hterm.ScrollPort(this);
+  this.scrollPort_.subscribe('resize', this.onResize_.bind(this));
+  this.scrollPort_.subscribe('scroll', this.onScroll_.bind(this));
+  this.scrollPort_.subscribe('paste', this.onPaste_.bind(this));
+  this.scrollPort_.subscribe('focus', this.onScrollportFocus_.bind(this));
+  this.scrollPort_.onCopy = this.onCopy_.bind(this);
+
+  // The div that contains this terminal.
+  this.div_ = null;
+
+  // The document that contains the scrollPort.  Defaulted to the global
+  // document here so that the terminal is functional even if it hasn't been
+  // inserted into a document yet, but re-set in decorate().
+  this.document_ = window.document;
+
+  // The rows that have scrolled off screen and are no longer addressable.
+  this.scrollbackRows_ = [];
+
+  // Saved tab stops.
+  this.tabStops_ = [];
+
+  // Keep track of whether default tab stops have been erased; after a TBC
+  // clears all tab stops, defaults aren't restored on resize until a reset.
+  this.defaultTabStops = true;
+
+  // The VT's notion of the top and bottom rows.  Used during some VT
+  // cursor positioning and scrolling commands.
+  this.vtScrollTop_ = null;
+  this.vtScrollBottom_ = null;
+
+  // The DIV element for the visible cursor.
+  this.cursorNode_ = null;
+
+  // The current cursor shape of the terminal.
+  this.cursorShape_ = hterm.Terminal.cursorShape.BLOCK;
+
+  // Cursor blink on/off cycle in ms, overwritten by prefs once they're loaded.
+  this.cursorBlinkCycle_ = [100, 100];
+
+  // Pre-bound onCursorBlink_ handler, so we don't have to do this for each
+  // cursor on/off servicing.
+  this.myOnCursorBlink_ = this.onCursorBlink_.bind(this);
+
+  // These prefs are cached so we don't have to read from local storage with
+  // each output and keystroke.  They are initialized by the preference manager.
+  this.backgroundColor_ = null;
+  this.foregroundColor_ = null;
+  this.scrollOnOutput_ = null;
+  this.scrollOnKeystroke_ = null;
+  this.scrollWheelArrowKeys_ = null;
+
+  // True if we should override mouse event reporting to allow local selection.
+  this.defeatMouseReports_ = false;
+
+  // Whether to auto hide the mouse cursor when typing.
+  this.setAutomaticMouseHiding();
+  // Timer to keep mouse visible while it's being used.
+  this.mouseHideDelay_ = null;
+
+  // Terminal bell sound.
+  this.bellAudio_ = this.document_.createElement('audio');
+  this.bellAudio_.id = 'hterm:bell-audio';
+  this.bellAudio_.setAttribute('preload', 'auto');
+
+  // The AccessibilityReader object for announcing command output.
+  this.accessibilityReader_ = null;
+
+  // The context menu object.
+  this.contextMenu = new hterm.ContextMenu();
+
+  // All terminal bell notifications that have been generated (not necessarily
+  // shown).
+  this.bellNotificationList_ = [];
+
+  // Whether we have permission to display notifications.
+  this.desktopNotificationBell_ = false;
+
+  // Cursor position and attributes saved with DECSC.
+  this.savedOptions_ = {};
+
+  // The current mode bits for the terminal.
+  this.options_ = new hterm.Options();
+
+  // Timeouts we might need to clear.
+  this.timeouts_ = {};
+
+  // The VT escape sequence interpreter.
+  this.vt = new hterm.VT(this);
+
+  this.saveCursorAndState(true);
+
+  // The keyboard handler.
+  this.keyboard = new hterm.Keyboard(this);
+
+  // General IO interface that can be given to third parties without exposing
+  // the entire terminal object.
+  this.io = new hterm.Terminal.IO(this);
+
+  // True if mouse-click-drag should scroll the terminal.
+  this.enableMouseDragScroll = true;
+
+  this.copyOnSelect = null;
+  this.mouseRightClickPaste = null;
+  this.mousePasteButton = null;
+
+  // Whether to use the default window copy behavior.
+  this.useDefaultWindowCopy = false;
+
+  this.clearSelectionAfterCopy = true;
+
+  this.realizeSize_(80, 24);
+  this.setDefaultTabStops();
+
+  // Whether we allow images to be shown.
+  this.allowImagesInline = null;
+
+  this.reportFocus = false;
+
+  this.setProfile(opt_profileId || 'default',
+                  function() { this.onTerminalReady(); }.bind(this));
+};
+
+/**
+ * Possible cursor shapes.
+ */
+hterm.Terminal.cursorShape = {
+  BLOCK: 'BLOCK',
+  BEAM: 'BEAM',
+  UNDERLINE: 'UNDERLINE'
+};
+
+/**
+ * Clients should override this to be notified when the terminal is ready
+ * for use.
+ *
+ * The terminal initialization is asynchronous, and shouldn't be used before
+ * this method is called.
+ */
+hterm.Terminal.prototype.onTerminalReady = function() { };
+
+/**
+ * Default tab with of 8 to match xterm.
+ */
+hterm.Terminal.prototype.tabWidth = 8;
+
+/**
+ * Select a preference profile.
+ *
+ * This will load the terminal preferences for the given profile name and
+ * associate subsequent preference changes with the new preference profile.
+ *
+ * @param {string} profileId The name of the preference profile.  Forward slash
+ *     characters will be removed from the name.
+ * @param {function} opt_callback Optional callback to invoke when the profile
+ *     transition is complete.
+ */
+hterm.Terminal.prototype.setProfile = function(profileId, opt_callback) {
+  this.profileId_ = profileId.replace(/\//g, '');
+
+  var terminal = this;
+
+  if (this.prefs_)
+    this.prefs_.deactivate();
+
+  this.prefs_ = new hterm.PreferenceManager(this.profileId_);
+  this.prefs_.addObservers(null, {
+    'alt-gr-mode': function(v) {
+      if (v == null) {
+        if (navigator.language.toLowerCase() == 'en-us') {
+          v = 'none';
+        } else {
+          v = 'right-alt';
+        }
+      } else if (typeof v == 'string') {
+        v = v.toLowerCase();
+      } else {
+        v = 'none';
+      }
+
+      if (!/^(none|ctrl-alt|left-alt|right-alt)$/.test(v))
+        v = 'none';
+
+      terminal.keyboard.altGrMode = v;
+    },
+
+    'alt-backspace-is-meta-backspace': function(v) {
+      terminal.keyboard.altBackspaceIsMetaBackspace = v;
+    },
+
+    'alt-is-meta': function(v) {
+      terminal.keyboard.altIsMeta = v;
+    },
+
+    'alt-sends-what': function(v) {
+      if (!/^(escape|8-bit|browser-key)$/.test(v))
+        v = 'escape';
+
+      terminal.keyboard.altSendsWhat = v;
+    },
+
+    'audible-bell-sound': function(v) {
+      var ary = v.match(/^lib-resource:(\S+)/);
+      if (ary) {
+        terminal.bellAudio_.setAttribute('src',
+                                         lib.resource.getDataUrl(ary[1]));
+      } else {
+        terminal.bellAudio_.setAttribute('src', v);
+      }
+    },
+
+    'desktop-notification-bell': function(v) {
+      if (v && Notification) {
+        terminal.desktopNotificationBell_ =
+            Notification.permission === 'granted';
+        if (!terminal.desktopNotificationBell_) {
+          // Note: We don't call Notification.requestPermission here because
+          // Chrome requires the call be the result of a user action (such as an
+          // onclick handler), and pref listeners are run asynchronously.
+          //
+          // A way of working around this would be to display a dialog in the
+          // terminal with a "click-to-request-permission" button.
+          console.warn('desktop-notification-bell is true but we do not have ' +
+                       'permission to display notifications.');
+        }
+      } else {
+        terminal.desktopNotificationBell_ = false;
+      }
+    },
+
+    'background-color': function(v) {
+      terminal.setBackgroundColor(v);
+    },
+
+    'background-image': function(v) {
+      terminal.scrollPort_.setBackgroundImage(v);
+    },
+
+    'background-size': function(v) {
+      terminal.scrollPort_.setBackgroundSize(v);
+    },
+
+    'background-position': function(v) {
+      terminal.scrollPort_.setBackgroundPosition(v);
+    },
+
+    'backspace-sends-backspace': function(v) {
+      terminal.keyboard.backspaceSendsBackspace = v;
+    },
+
+    'character-map-overrides': function(v) {
+      if (!(v == null || v instanceof Object)) {
+        console.warn('Preference character-map-modifications is not an ' +
+                     'object: ' + v);
+        return;
+      }
+
+      terminal.vt.characterMaps.reset();
+      terminal.vt.characterMaps.setOverrides(v);
+    },
+
+    'cursor-blink': function(v) {
+      terminal.setCursorBlink(!!v);
+    },
+
+    'cursor-shape': function(v) {
+      terminal.setCursorShape(v);
+    },
+
+    'cursor-blink-cycle': function(v) {
+        if (v instanceof Array &&
+            typeof v[0] == 'number' &&
+            typeof v[1] == 'number') {
+          terminal.cursorBlinkCycle_ = v;
+        } else if (typeof v == 'number') {
+          terminal.cursorBlinkCycle_ = [v, v];
+        } else {
+          // Fast blink indicates an error.
+          terminal.cursorBlinkCycle_ = [100, 100];
+        }
+    },
+
+    'cursor-color': function(v) {
+      terminal.setCursorColor(v);
+    },
+
+    'color-palette-overrides': function(v) {
+      if (!(v == null || v instanceof Object || v instanceof Array)) {
+        console.warn('Preference color-palette-overrides is not an array or ' +
+                     'object: ' + v);
+        return;
+      }
+
+      lib.colors.colorPalette = lib.colors.stockColorPalette.concat();
+
+      if (v) {
+        for (var key in v) {
+          var i = parseInt(key);
+          if (isNaN(i) || i < 0 || i > 255) {
+            console.log('Invalid value in palette: ' + key + ': ' + v[key]);
+            continue;
+          }
+
+          if (v[i]) {
+            var rgb = lib.colors.normalizeCSS(v[i]);
+            if (rgb)
+              lib.colors.colorPalette[i] = rgb;
+          }
+        }
+      }
+
+      terminal.primaryScreen_.textAttributes.resetColorPalette();
+      terminal.alternateScreen_.textAttributes.resetColorPalette();
+    },
+
+    'copy-on-select': function(v) {
+      terminal.copyOnSelect = !!v;
+    },
+
+    'use-default-window-copy': function(v) {
+      terminal.useDefaultWindowCopy = !!v;
+    },
+
+    'clear-selection-after-copy': function(v) {
+      terminal.clearSelectionAfterCopy = !!v;
+    },
+
+    'ctrl-plus-minus-zero-zoom': function(v) {
+      terminal.keyboard.ctrlPlusMinusZeroZoom = v;
+    },
+
+    'ctrl-c-copy': function(v) {
+      terminal.keyboard.ctrlCCopy = v;
+    },
+
+    'ctrl-v-paste': function(v) {
+      terminal.keyboard.ctrlVPaste = v;
+      terminal.scrollPort_.setCtrlVPaste(v);
+    },
+
+    'paste-on-drop': function(v) {
+      terminal.scrollPort_.setPasteOnDrop(v);
+    },
+
+    'east-asian-ambiguous-as-two-column': function(v) {
+      lib.wc.regardCjkAmbiguous = v;
+    },
+
+    'enable-8-bit-control': function(v) {
+      terminal.vt.enable8BitControl = !!v;
+    },
+
+    'enable-bold': function(v) {
+      terminal.syncBoldSafeState();
+    },
+
+    'enable-bold-as-bright': function(v) {
+      terminal.primaryScreen_.textAttributes.enableBoldAsBright = !!v;
+      terminal.alternateScreen_.textAttributes.enableBoldAsBright = !!v;
+    },
+
+    'enable-blink': function(v) {
+      terminal.setTextBlink(!!v);
+    },
+
+    'enable-clipboard-write': function(v) {
+      terminal.vt.enableClipboardWrite = !!v;
+    },
+
+    'enable-dec12': function(v) {
+      terminal.vt.enableDec12 = !!v;
+    },
+
+    'enable-csi-j-3': function(v) {
+      terminal.vt.enableCsiJ3 = !!v;
+    },
+
+    'font-family': function(v) {
+      terminal.syncFontFamily();
+    },
+
+    'font-size': function(v) {
+      v = parseInt(v);
+      if (v <= 0) {
+        console.error(`Invalid font size: ${v}`);
+        return;
+      }
+
+      terminal.setFontSize(v);
+    },
+
+    'font-smoothing': function(v) {
+      terminal.syncFontFamily();
+    },
+
+    'foreground-color': function(v) {
+      terminal.setForegroundColor(v);
+    },
+
+    'hide-mouse-while-typing': function(v) {
+      terminal.setAutomaticMouseHiding(v);
+    },
+
+    'home-keys-scroll': function(v) {
+      terminal.keyboard.homeKeysScroll = v;
+    },
+
+    'keybindings': function(v) {
+      terminal.keyboard.bindings.clear();
+
+      if (!v)
+        return;
+
+      if (!(v instanceof Object)) {
+        console.error('Error in keybindings preference: Expected object');
+        return;
+      }
+
+      try {
+        terminal.keyboard.bindings.addBindings(v);
+      } catch (ex) {
+        console.error('Error in keybindings preference: ' + ex);
+      }
+    },
+
+    'media-keys-are-fkeys': function(v) {
+      terminal.keyboard.mediaKeysAreFKeys = v;
+    },
+
+    'meta-sends-escape': function(v) {
+      terminal.keyboard.metaSendsEscape = v;
+    },
+
+    'mouse-right-click-paste': function(v) {
+      terminal.mouseRightClickPaste = v;
+    },
+
+    'mouse-paste-button': function(v) {
+      terminal.syncMousePasteButton();
+    },
+
+    'page-keys-scroll': function(v) {
+      terminal.keyboard.pageKeysScroll = v;
+    },
+
+    'pass-alt-number': function(v) {
+      if (v == null) {
+        // Let Alt-1..9 pass to the browser (to control tab switching) on
+        // non-OS X systems, or if hterm is not opened in an app window.
+        v = (hterm.os != 'mac' && hterm.windowType != 'popup');
+      }
+
+      terminal.passAltNumber = v;
+    },
+
+    'pass-ctrl-number': function(v) {
+      if (v == null) {
+        // Let Ctrl-1..9 pass to the browser (to control tab switching) on
+        // non-OS X systems, or if hterm is not opened in an app window.
+        v = (hterm.os != 'mac' && hterm.windowType != 'popup');
+      }
+
+      terminal.passCtrlNumber = v;
+    },
+
+    'pass-meta-number': function(v) {
+      if (v == null) {
+        // Let Meta-1..9 pass to the browser (to control tab switching) on
+        // OS X systems, or if hterm is not opened in an app window.
+        v = (hterm.os == 'mac' && hterm.windowType != 'popup');
+      }
+
+      terminal.passMetaNumber = v;
+    },
+
+    'pass-meta-v': function(v) {
+      terminal.keyboard.passMetaV = v;
+    },
+
+    'receive-encoding': function(v) {
+       if (!(/^(utf-8|raw)$/).test(v)) {
+         console.warn('Invalid value for "receive-encoding": ' + v);
+         v = 'utf-8';
+       }
+
+       terminal.vt.characterEncoding = v;
+    },
+
+    'scroll-on-keystroke': function(v) {
+      terminal.scrollOnKeystroke_ = v;
+    },
+
+    'scroll-on-output': function(v) {
+      terminal.scrollOnOutput_ = v;
+    },
+
+    'scrollbar-visible': function(v) {
+      terminal.setScrollbarVisible(v);
+    },
+
+    'scroll-wheel-may-send-arrow-keys': function(v) {
+      terminal.scrollWheelArrowKeys_ = v;
+    },
+
+    'scroll-wheel-move-multiplier': function(v) {
+      terminal.setScrollWheelMoveMultipler(v);
+    },
+
+    'shift-insert-paste': function(v) {
+      terminal.keyboard.shiftInsertPaste = v;
+    },
+
+    'terminal-encoding': function(v) {
+      terminal.vt.setEncoding(v);
+    },
+
+    'user-css': function(v) {
+      terminal.scrollPort_.setUserCssUrl(v);
+    },
+
+    'user-css-text': function(v) {
+      terminal.scrollPort_.setUserCssText(v);
+    },
+
+    'word-break-match-left': function(v) {
+      terminal.primaryScreen_.wordBreakMatchLeft = v;
+      terminal.alternateScreen_.wordBreakMatchLeft = v;
+    },
+
+    'word-break-match-right': function(v) {
+      terminal.primaryScreen_.wordBreakMatchRight = v;
+      terminal.alternateScreen_.wordBreakMatchRight = v;
+    },
+
+    'word-break-match-middle': function(v) {
+      terminal.primaryScreen_.wordBreakMatchMiddle = v;
+      terminal.alternateScreen_.wordBreakMatchMiddle = v;
+    },
+
+    'allow-images-inline': function(v) {
+      terminal.allowImagesInline = v;
+    },
+  });
+
+  this.prefs_.readStorage(function() {
+    this.prefs_.notifyAll();
+
+    if (opt_callback)
+      opt_callback();
+  }.bind(this));
+};
+
+
+/**
+ * Returns the preferences manager used for configuring this terminal.
+ *
+ * @return {hterm.PreferenceManager}
+ */
+hterm.Terminal.prototype.getPrefs = function() {
+  return this.prefs_;
+};
+
+/**
+ * Enable or disable bracketed paste mode.
+ *
+ * @param {boolean} state The value to set.
+ */
+hterm.Terminal.prototype.setBracketedPaste = function(state) {
+  this.options_.bracketedPaste = state;
+};
+
+/**
+ * Set the color for the cursor.
+ *
+ * If you want this setting to persist, set it through prefs_, rather than
+ * with this method.
+ *
+ * @param {string=} color The color to set.  If not defined, we reset to the
+ *     saved user preference.
+ */
+hterm.Terminal.prototype.setCursorColor = function(color) {
+  if (color === undefined)
+    color = this.prefs_.get('cursor-color');
+
+  this.setCssVar('cursor-color', color);
+};
+
+/**
+ * Return the current cursor color as a string.
+ * @return {string}
+ */
+hterm.Terminal.prototype.getCursorColor = function() {
+  return this.getCssVar('cursor-color');
+};
+
+/**
+ * Enable or disable mouse based text selection in the terminal.
+ *
+ * @param {boolean} state The value to set.
+ */
+hterm.Terminal.prototype.setSelectionEnabled = function(state) {
+  this.enableMouseDragScroll = state;
+};
+
+/**
+ * Set the background color.
+ *
+ * If you want this setting to persist, set it through prefs_, rather than
+ * with this method.
+ *
+ * @param {string=} color The color to set.  If not defined, we reset to the
+ *     saved user preference.
+ */
+hterm.Terminal.prototype.setBackgroundColor = function(color) {
+  if (color === undefined)
+    color = this.prefs_.get('background-color');
+
+  this.backgroundColor_ = lib.colors.normalizeCSS(color);
+  this.primaryScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_);
+  this.alternateScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_);
+  this.scrollPort_.setBackgroundColor(color);
+};
+
+/**
+ * Return the current terminal background color.
+ *
+ * Intended for use by other classes, so we don't have to expose the entire
+ * prefs_ object.
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getBackgroundColor = function() {
+  return this.backgroundColor_;
+};
+
+/**
+ * Set the foreground color.
+ *
+ * If you want this setting to persist, set it through prefs_, rather than
+ * with this method.
+ *
+ * @param {string=} color The color to set.  If not defined, we reset to the
+ *     saved user preference.
+ */
+hterm.Terminal.prototype.setForegroundColor = function(color) {
+  if (color === undefined)
+    color = this.prefs_.get('foreground-color');
+
+  this.foregroundColor_ = lib.colors.normalizeCSS(color);
+  this.primaryScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_);
+  this.alternateScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_);
+  this.scrollPort_.setForegroundColor(color);
+};
+
+/**
+ * Return the current terminal foreground color.
+ *
+ * Intended for use by other classes, so we don't have to expose the entire
+ * prefs_ object.
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getForegroundColor = function() {
+  return this.foregroundColor_;
+};
+
+/**
+ * Create a new instance of a terminal command and run it with a given
+ * argument string.
+ *
+ * @param {function} commandClass The constructor for a terminal command.
+ * @param {string} argString The argument string to pass to the command.
+ */
+hterm.Terminal.prototype.runCommandClass = function(commandClass, argString) {
+  var environment = this.prefs_.get('environment');
+  if (typeof environment != 'object' || environment == null)
+    environment = {};
+
+  var self = this;
+  this.command = new commandClass(
+      { argString: argString || '',
+        io: this.io.push(),
+        environment: environment,
+        onExit: function(code) {
+          self.io.pop();
+          self.uninstallKeyboard();
+          if (self.prefs_.get('close-on-exit'))
+              window.close();
+        }
+      });
+
+  this.installKeyboard();
+  this.command.run();
+};
+
+/**
+ * Returns true if the current screen is the primary screen, false otherwise.
+ *
+ * @return {boolean}
+ */
+hterm.Terminal.prototype.isPrimaryScreen = function() {
+  return this.screen_ == this.primaryScreen_;
+};
+
+/**
+ * Install the keyboard handler for this terminal.
+ *
+ * This will prevent the browser from seeing any keystrokes sent to the
+ * terminal.
+ */
+hterm.Terminal.prototype.installKeyboard = function() {
+  this.keyboard.installKeyboard(this.scrollPort_.getDocument().body);
+};
+
+/**
+ * Uninstall the keyboard handler for this terminal.
+ */
+hterm.Terminal.prototype.uninstallKeyboard = function() {
+  this.keyboard.installKeyboard(null);
+};
+
+/**
+ * Set a CSS variable.
+ *
+ * Normally this is used to set variables in the hterm namespace.
+ *
+ * @param {string} name The variable to set.
+ * @param {string} value The value to assign to the variable.
+ * @param {string?} opt_prefix The variable namespace/prefix to use.
+ */
+hterm.Terminal.prototype.setCssVar = function(name, value,
+                                              opt_prefix='--hterm-') {
+  this.document_.documentElement.style.setProperty(
+      `${opt_prefix}${name}`, value);
+};
+
+/**
+ * Get a CSS variable.
+ *
+ * Normally this is used to get variables in the hterm namespace.
+ *
+ * @param {string} name The variable to read.
+ * @param {string?} opt_prefix The variable namespace/prefix to use.
+ * @return {string} The current setting for this variable.
+ */
+hterm.Terminal.prototype.getCssVar = function(name, opt_prefix='--hterm-') {
+  return this.document_.documentElement.style.getPropertyValue(
+      `${opt_prefix}${name}`);
+};
+
+/**
+ * Set the font size for this terminal.
+ *
+ * Call setFontSize(0) to reset to the default font size.
+ *
+ * This function does not modify the font-size preference.
+ *
+ * @param {number} px The desired font size, in pixels.
+ */
+hterm.Terminal.prototype.setFontSize = function(px) {
+  if (px <= 0)
+    px = this.prefs_.get('font-size');
+
+  this.scrollPort_.setFontSize(px);
+  this.setCssVar('charsize-width', this.scrollPort_.characterSize.width + 'px');
+  this.setCssVar('charsize-height',
+                 this.scrollPort_.characterSize.height + 'px');
+};
+
+/**
+ * Get the current font size.
+ *
+ * @return {number}
+ */
+hterm.Terminal.prototype.getFontSize = function() {
+  return this.scrollPort_.getFontSize();
+};
+
+/**
+ * Get the current font family.
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getFontFamily = function() {
+  return this.scrollPort_.getFontFamily();
+};
+
+/**
+ * Set the CSS "font-family" for this terminal.
+ */
+hterm.Terminal.prototype.syncFontFamily = function() {
+  this.scrollPort_.setFontFamily(this.prefs_.get('font-family'),
+                                 this.prefs_.get('font-smoothing'));
+  this.syncBoldSafeState();
+};
+
+/**
+ * Set this.mousePasteButton based on the mouse-paste-button pref,
+ * autodetecting if necessary.
+ */
+hterm.Terminal.prototype.syncMousePasteButton = function() {
+  var button = this.prefs_.get('mouse-paste-button');
+  if (typeof button == 'number') {
+    this.mousePasteButton = button;
+    return;
+  }
+
+  if (hterm.os != 'linux') {
+    this.mousePasteButton = 1;  // Middle mouse button.
+  } else {
+    this.mousePasteButton = 2;  // Right mouse button.
+  }
+};
+
+/**
+ * Enable or disable bold based on the enable-bold pref, autodetecting if
+ * necessary.
+ */
+hterm.Terminal.prototype.syncBoldSafeState = function() {
+  var enableBold = this.prefs_.get('enable-bold');
+  if (enableBold !== null) {
+    this.primaryScreen_.textAttributes.enableBold = enableBold;
+    this.alternateScreen_.textAttributes.enableBold = enableBold;
+    return;
+  }
+
+  var normalSize = this.scrollPort_.measureCharacterSize();
+  var boldSize = this.scrollPort_.measureCharacterSize('bold');
+
+  var isBoldSafe = normalSize.equals(boldSize);
+  if (!isBoldSafe) {
+    console.warn('Bold characters disabled: Size of bold weight differs ' +
+                 'from normal.  Font family is: ' +
+                 this.scrollPort_.getFontFamily());
+  }
+
+  this.primaryScreen_.textAttributes.enableBold = isBoldSafe;
+  this.alternateScreen_.textAttributes.enableBold = isBoldSafe;
+};
+
+/**
+ * Control text blinking behavior.
+ *
+ * @param {boolean=} state Whether to enable support for blinking text.
+ */
+hterm.Terminal.prototype.setTextBlink = function(state) {
+  if (state === undefined)
+    state = this.prefs_.get('enable-blink');
+  this.setCssVar('blink-node-duration', state ? '0.7s' : '0');
+};
+
+/**
+ * Set the mouse cursor style based on the current terminal mode.
+ */
+hterm.Terminal.prototype.syncMouseStyle = function() {
+  this.setCssVar('mouse-cursor-style',
+                 this.vt.mouseReport == this.vt.MOUSE_REPORT_DISABLED ?
+                     'var(--hterm-mouse-cursor-text)' :
+                     'var(--hterm-mouse-cursor-default)');
+};
+
+/**
+ * Return a copy of the current cursor position.
+ *
+ * @return {hterm.RowCol} The RowCol object representing the current position.
+ */
+hterm.Terminal.prototype.saveCursor = function() {
+  return this.screen_.cursorPosition.clone();
+};
+
+/**
+ * Return the current text attributes.
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getTextAttributes = function() {
+  return this.screen_.textAttributes;
+};
+
+/**
+ * Set the text attributes.
+ *
+ * @param {string} textAttributes The attributes to set.
+ */
+hterm.Terminal.prototype.setTextAttributes = function(textAttributes) {
+  this.screen_.textAttributes = textAttributes;
+};
+
+/**
+ * Return the current browser zoom factor applied to the terminal.
+ *
+ * @return {number} The current browser zoom factor.
+ */
+hterm.Terminal.prototype.getZoomFactor = function() {
+  return this.scrollPort_.characterSize.zoomFactor;
+};
+
+/**
+ * Change the title of this terminal's window.
+ *
+ * @param {string} title The title to set.
+ */
+hterm.Terminal.prototype.setWindowTitle = function(title) {
+  window.document.title = title;
+};
+
+/**
+ * Restore a previously saved cursor position.
+ *
+ * @param {hterm.RowCol} cursor The position to restore.
+ */
+hterm.Terminal.prototype.restoreCursor = function(cursor) {
+  var row = lib.f.clamp(cursor.row, 0, this.screenSize.height - 1);
+  var column = lib.f.clamp(cursor.column, 0, this.screenSize.width - 1);
+  this.screen_.setCursorPosition(row, column);
+  if (cursor.column > column ||
+      cursor.column == column && cursor.overflow) {
+    this.screen_.cursorPosition.overflow = true;
+  }
+};
+
+/**
+ * Clear the cursor's overflow flag.
+ */
+hterm.Terminal.prototype.clearCursorOverflow = function() {
+  this.screen_.cursorPosition.overflow = false;
+};
+
+/**
+ * Save the current cursor state to the corresponding screens.
+ *
+ * See the hterm.Screen.CursorState class for more details.
+ *
+ * @param {boolean=} both If true, update both screens, else only update the
+ *     current screen.
+ */
+hterm.Terminal.prototype.saveCursorAndState = function(both) {
+  if (both) {
+    this.primaryScreen_.saveCursorAndState(this.vt);
+    this.alternateScreen_.saveCursorAndState(this.vt);
+  } else
+    this.screen_.saveCursorAndState(this.vt);
+};
+
+/**
+ * Restore the saved cursor state in the corresponding screens.
+ *
+ * See the hterm.Screen.CursorState class for more details.
+ *
+ * @param {boolean=} both If true, update both screens, else only update the
+ *     current screen.
+ */
+hterm.Terminal.prototype.restoreCursorAndState = function(both) {
+  if (both) {
+    this.primaryScreen_.restoreCursorAndState(this.vt);
+    this.alternateScreen_.restoreCursorAndState(this.vt);
+  } else
+    this.screen_.restoreCursorAndState(this.vt);
+};
+
+/**
+ * Sets the cursor shape
+ *
+ * @param {string} shape The shape to set.
+ */
+hterm.Terminal.prototype.setCursorShape = function(shape) {
+  this.cursorShape_ = shape;
+  this.restyleCursor_();
+};
+
+/**
+ * Get the cursor shape
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getCursorShape = function() {
+  return this.cursorShape_;
+};
+
+/**
+ * Set the width of the terminal, resizing the UI to match.
+ *
+ * @param {number} columnCount
+ */
+hterm.Terminal.prototype.setWidth = function(columnCount) {
+  if (columnCount == null) {
+    this.div_.style.width = '100%';
+    return;
+  }
+
+  this.div_.style.width = Math.ceil(
+      this.scrollPort_.characterSize.width *
+      columnCount + this.scrollPort_.currentScrollbarWidthPx) + 'px';
+  this.realizeSize_(columnCount, this.screenSize.height);
+  this.scheduleSyncCursorPosition_();
+};
+
+/**
+ * Set the height of the terminal, resizing the UI to match.
+ *
+ * @param {number} rowCount The height in rows.
+ */
+hterm.Terminal.prototype.setHeight = function(rowCount) {
+  if (rowCount == null) {
+    this.div_.style.height = '100%';
+    return;
+  }
+
+  this.div_.style.height =
+      this.scrollPort_.characterSize.height * rowCount + 'px';
+  this.realizeSize_(this.screenSize.width, rowCount);
+  this.scheduleSyncCursorPosition_();
+};
+
+/**
+ * Deal with terminal size changes.
+ *
+ * @param {number} columnCount The number of columns.
+ * @param {number} rowCount The number of rows.
+ */
+hterm.Terminal.prototype.realizeSize_ = function(columnCount, rowCount) {
+  if (columnCount != this.screenSize.width)
+    this.realizeWidth_(columnCount);
+
+  if (rowCount != this.screenSize.height)
+    this.realizeHeight_(rowCount);
+
+  // Send new terminal size to plugin.
+  this.io.onTerminalResize_(columnCount, rowCount);
+};
+
+/**
+ * Deal with terminal width changes.
+ *
+ * This function does what needs to be done when the terminal width changes
+ * out from under us.  It happens here rather than in onResize_() because this
+ * code may need to run synchronously to handle programmatic changes of
+ * terminal width.
+ *
+ * Relying on the browser to send us an async resize event means we may not be
+ * in the correct state yet when the next escape sequence hits.
+ *
+ * @param {number} columnCount The number of columns.
+ */
+hterm.Terminal.prototype.realizeWidth_ = function(columnCount) {
+  if (columnCount <= 0)
+    throw new Error('Attempt to realize bad width: ' + columnCount);
+
+  var deltaColumns = columnCount - this.screen_.getWidth();
+
+  this.screenSize.width = columnCount;
+  this.screen_.setColumnCount(columnCount);
+
+  if (deltaColumns > 0) {
+    if (this.defaultTabStops)
+      this.setDefaultTabStops(this.screenSize.width - deltaColumns);
+  } else {
+    for (var i = this.tabStops_.length - 1; i >= 0; i--) {
+      if (this.tabStops_[i] < columnCount)
+        break;
+
+      this.tabStops_.pop();
+    }
+  }
+
+  this.screen_.setColumnCount(this.screenSize.width);
+};
+
+/**
+ * Deal with terminal height changes.
+ *
+ * This function does what needs to be done when the terminal height changes
+ * out from under us.  It happens here rather than in onResize_() because this
+ * code may need to run synchronously to handle programmatic changes of
+ * terminal height.
+ *
+ * Relying on the browser to send us an async resize event means we may not be
+ * in the correct state yet when the next escape sequence hits.
+ *
+ * @param {number} rowCount The number of rows.
+ */
+hterm.Terminal.prototype.realizeHeight_ = function(rowCount) {
+  if (rowCount <= 0)
+    throw new Error('Attempt to realize bad height: ' + rowCount);
+
+  var deltaRows = rowCount - this.screen_.getHeight();
+
+  this.screenSize.height = rowCount;
+
+  var cursor = this.saveCursor();
+
+  if (deltaRows < 0) {
+    // Screen got smaller.
+    deltaRows *= -1;
+    while (deltaRows) {
+      var lastRow = this.getRowCount() - 1;
+      if (lastRow - this.scrollbackRows_.length == cursor.row)
+        break;
+
+      if (this.getRowText(lastRow))
+        break;
+
+      this.screen_.popRow();
+      deltaRows--;
+    }
+
+    var ary = this.screen_.shiftRows(deltaRows);
+    this.scrollbackRows_.push.apply(this.scrollbackRows_, ary);
+
+    // We just removed rows from the top of the screen, we need to update
+    // the cursor to match.
+    cursor.row = Math.max(cursor.row - deltaRows, 0);
+  } else if (deltaRows > 0) {
+    // Screen got larger.
+
+    if (deltaRows <= this.scrollbackRows_.length) {
+      var scrollbackCount = Math.min(deltaRows, this.scrollbackRows_.length);
+      var rows = this.scrollbackRows_.splice(
+          this.scrollbackRows_.length - scrollbackCount, scrollbackCount);
+      this.screen_.unshiftRows(rows);
+      deltaRows -= scrollbackCount;
+      cursor.row += scrollbackCount;
+    }
+
+    if (deltaRows)
+      this.appendRows_(deltaRows);
+  }
+
+  this.setVTScrollRegion(null, null);
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Scroll the terminal to the top of the scrollback buffer.
+ */
+hterm.Terminal.prototype.scrollHome = function() {
+  this.scrollPort_.scrollRowToTop(0);
+};
+
+/**
+ * Scroll the terminal to the end.
+ */
+hterm.Terminal.prototype.scrollEnd = function() {
+  this.scrollPort_.scrollRowToBottom(this.getRowCount());
+};
+
+/**
+ * Scroll the terminal one page up (minus one line) relative to the current
+ * position.
+ */
+hterm.Terminal.prototype.scrollPageUp = function() {
+  this.scrollPort_.scrollPageUp();
+};
+
+/**
+ * Scroll the terminal one page down (minus one line) relative to the current
+ * position.
+ */
+hterm.Terminal.prototype.scrollPageDown = function() {
+  this.scrollPort_.scrollPageDown();
+};
+
+/**
+ * Scroll the terminal one line up relative to the current position.
+ */
+hterm.Terminal.prototype.scrollLineUp = function() {
+  var i = this.scrollPort_.getTopRowIndex();
+  this.scrollPort_.scrollRowToTop(i - 1);
+};
+
+/**
+ * Scroll the terminal one line down relative to the current position.
+ */
+hterm.Terminal.prototype.scrollLineDown = function() {
+  var i = this.scrollPort_.getTopRowIndex();
+  this.scrollPort_.scrollRowToTop(i + 1);
+};
+
+/**
+ * Clear primary screen, secondary screen, and the scrollback buffer.
+ */
+hterm.Terminal.prototype.wipeContents = function() {
+  this.clearHome(this.primaryScreen_);
+  this.clearHome(this.alternateScreen_);
+
+  this.clearScrollback();
+};
+
+/**
+ * Clear scrollback buffer.
+ */
+hterm.Terminal.prototype.clearScrollback = function() {
+  // Move to the end of the buffer in case the screen was scrolled back.
+  // We're going to throw it away which would leave the display invalid.
+  this.scrollEnd();
+
+  this.scrollbackRows_.length = 0;
+  this.scrollPort_.resetCache();
+
+  [this.primaryScreen_, this.alternateScreen_].forEach((screen) => {
+    const bottom = screen.getHeight();
+    this.renumberRows_(0, bottom, screen);
+  });
+
+  this.syncCursorPosition_();
+  this.scrollPort_.invalidate();
+};
+
+/**
+ * Full terminal reset.
+ *
+ * Perform a full reset to the default values listed in
+ * https://vt100.net/docs/vt510-rm/RIS.html
+ */
+hterm.Terminal.prototype.reset = function() {
+  this.vt.reset();
+
+  this.clearAllTabStops();
+  this.setDefaultTabStops();
+
+  const resetScreen = (screen) => {
+    // We want to make sure to reset the attributes before we clear the screen.
+    // The attributes might be used to initialize default/empty rows.
+    screen.textAttributes.reset();
+    screen.textAttributes.resetColorPalette();
+    this.clearHome(screen);
+    screen.saveCursorAndState(this.vt);
+  };
+  resetScreen(this.primaryScreen_);
+  resetScreen(this.alternateScreen_);
+
+  // Reset terminal options to their default values.
+  this.options_ = new hterm.Options();
+  this.setCursorBlink(!!this.prefs_.get('cursor-blink'));
+
+  this.setVTScrollRegion(null, null);
+
+  this.setCursorVisible(true);
+};
+
+/**
+ * Soft terminal reset.
+ *
+ * Perform a soft reset to the default values listed in
+ * http://www.vt100.net/docs/vt510-rm/DECSTR#T5-9
+ */
+hterm.Terminal.prototype.softReset = function() {
+  this.vt.reset();
+
+  // Reset terminal options to their default values.
+  this.options_ = new hterm.Options();
+
+  // We show the cursor on soft reset but do not alter the blink state.
+  this.options_.cursorBlink = !!this.timeouts_.cursorBlink;
+
+  const resetScreen = (screen) => {
+    // Xterm also resets the color palette on soft reset, even though it doesn't
+    // seem to be documented anywhere.
+    screen.textAttributes.reset();
+    screen.textAttributes.resetColorPalette();
+    screen.saveCursorAndState(this.vt);
+  };
+  resetScreen(this.primaryScreen_);
+  resetScreen(this.alternateScreen_);
+
+  // The xterm man page explicitly says this will happen on soft reset.
+  this.setVTScrollRegion(null, null);
+
+  // Xterm also shows the cursor on soft reset, but does not alter the blink
+  // state.
+  this.setCursorVisible(true);
+};
+
+/**
+ * Move the cursor forward to the next tab stop, or to the last column
+ * if no more tab stops are set.
+ */
+hterm.Terminal.prototype.forwardTabStop = function() {
+  var column = this.screen_.cursorPosition.column;
+
+  for (var i = 0; i < this.tabStops_.length; i++) {
+    if (this.tabStops_[i] > column) {
+      this.setCursorColumn(this.tabStops_[i]);
+      return;
+    }
+  }
+
+  // xterm does not clear the overflow flag on HT or CHT.
+  var overflow = this.screen_.cursorPosition.overflow;
+  this.setCursorColumn(this.screenSize.width - 1);
+  this.screen_.cursorPosition.overflow = overflow;
+};
+
+/**
+ * Move the cursor backward to the previous tab stop, or to the first column
+ * if no previous tab stops are set.
+ */
+hterm.Terminal.prototype.backwardTabStop = function() {
+  var column = this.screen_.cursorPosition.column;
+
+  for (var i = this.tabStops_.length - 1; i >= 0; i--) {
+    if (this.tabStops_[i] < column) {
+      this.setCursorColumn(this.tabStops_[i]);
+      return;
+    }
+  }
+
+  this.setCursorColumn(1);
+};
+
+/**
+ * Set a tab stop at the given column.
+ *
+ * @param {integer} column Zero based column.
+ */
+hterm.Terminal.prototype.setTabStop = function(column) {
+  for (var i = this.tabStops_.length - 1; i >= 0; i--) {
+    if (this.tabStops_[i] == column)
+      return;
+
+    if (this.tabStops_[i] < column) {
+      this.tabStops_.splice(i + 1, 0, column);
+      return;
+    }
+  }
+
+  this.tabStops_.splice(0, 0, column);
+};
+
+/**
+ * Clear the tab stop at the current cursor position.
+ *
+ * No effect if there is no tab stop at the current cursor position.
+ */
+hterm.Terminal.prototype.clearTabStopAtCursor = function() {
+  var column = this.screen_.cursorPosition.column;
+
+  var i = this.tabStops_.indexOf(column);
+  if (i == -1)
+    return;
+
+  this.tabStops_.splice(i, 1);
+};
+
+/**
+ * Clear all tab stops.
+ */
+hterm.Terminal.prototype.clearAllTabStops = function() {
+  this.tabStops_.length = 0;
+  this.defaultTabStops = false;
+};
+
+/**
+ * Set up the default tab stops, starting from a given column.
+ *
+ * This sets a tabstop every (column % this.tabWidth) column, starting
+ * from the specified column, or 0 if no column is provided.  It also flags
+ * future resizes to set them up.
+ *
+ * This does not clear the existing tab stops first, use clearAllTabStops
+ * for that.
+ *
+ * @param {integer} opt_start Optional starting zero based starting column, useful
+ *     for filling out missing tab stops when the terminal is resized.
+ */
+hterm.Terminal.prototype.setDefaultTabStops = function(opt_start) {
+  var start = opt_start || 0;
+  var w = this.tabWidth;
+  // Round start up to a default tab stop.
+  start = start - 1 - ((start - 1) % w) + w;
+  for (var i = start; i < this.screenSize.width; i += w) {
+    this.setTabStop(i);
+  }
+
+  this.defaultTabStops = true;
+};
+
+/**
+ * Interpret a sequence of characters.
+ *
+ * Incomplete escape sequences are buffered until the next call.
+ *
+ * @param {string} str Sequence of characters to interpret or pass through.
+ */
+hterm.Terminal.prototype.interpret = function(str) {
+  this.scheduleSyncCursorPosition_();
+  this.vt.interpret(str);
+};
+
+/**
+ * Take over the given DIV for use as the terminal display.
+ *
+ * @param {HTMLDivElement} div The div to use as the terminal display.
+ */
+hterm.Terminal.prototype.decorate = function(div) {
+  const charset = div.ownerDocument.characterSet.toLowerCase();
+  if (charset != 'utf-8') {
+    console.warn(`Document encoding should be set to utf-8, not "${charset}";` +
+                 ` Add <meta charset='utf-8'/> to your HTML <head> to fix.`);
+  }
+
+  this.div_ = div;
+
+  this.accessibilityReader_ = new hterm.AccessibilityReader(div);
+
+  this.scrollPort_.decorate(div, () => this.setupScrollPort_());
+};
+
+/**
+ * Initialisation of ScrollPort properties which need to be set after its DOM
+ * has been initialised.
+ * @private
+ */
+hterm.Terminal.prototype.setupScrollPort_ = function() {
+  this.scrollPort_.setBackgroundImage(this.prefs_.get('background-image'));
+  this.scrollPort_.setBackgroundSize(this.prefs_.get('background-size'));
+  this.scrollPort_.setBackgroundPosition(
+      this.prefs_.get('background-position'));
+  this.scrollPort_.setUserCssUrl(this.prefs_.get('user-css'));
+  this.scrollPort_.setUserCssText(this.prefs_.get('user-css-text'));
+  this.scrollPort_.setAccessibilityReader(this.accessibilityReader_);
+
+  this.div_.focus = this.focus.bind(this);
+
+  this.setFontSize(this.prefs_.get('font-size'));
+  this.syncFontFamily();
+
+  this.setScrollbarVisible(this.prefs_.get('scrollbar-visible'));
+  this.setScrollWheelMoveMultipler(
+      this.prefs_.get('scroll-wheel-move-multiplier'));
+
+  this.document_ = this.scrollPort_.getDocument();
+  this.accessibilityReader_.decorate(this.document_);
+
+  this.document_.body.oncontextmenu = function() { return false; };
+  this.contextMenu.setDocument(this.document_);
+
+  var onMouse = this.onMouse_.bind(this);
+  var screenNode = this.scrollPort_.getScreenNode();
+  screenNode.addEventListener('mousedown', onMouse);
+  screenNode.addEventListener('mouseup', onMouse);
+  screenNode.addEventListener('mousemove', onMouse);
+  this.scrollPort_.onScrollWheel = onMouse;
+
+  screenNode.addEventListener('keydown', this.onKeyboardActivity_.bind(this));
+
+  screenNode.addEventListener(
+      'focus', this.onFocusChange_.bind(this, true));
+  // Listen for mousedown events on the screenNode as in FF the focus
+  // events don't bubble.
+  screenNode.addEventListener('mousedown', function() {
+    setTimeout(this.onFocusChange_.bind(this, true));
+  }.bind(this));
+
+  screenNode.addEventListener(
+      'blur', this.onFocusChange_.bind(this, false));
+
+  var style = this.document_.createElement('style');
+  style.textContent =
+      ('.cursor-node[focus="false"] {' +
+       '  box-sizing: border-box;' +
+       '  background-color: transparent !important;' +
+       '  border-width: 2px;' +
+       '  border-style: solid;' +
+       '}' +
+       'menu {' +
+       '  margin: 0;' +
+       '  padding: 0;' +
+       '  cursor: var(--hterm-mouse-cursor-pointer);' +
+       '}' +
+       'menuitem {' +
+       '  white-space: nowrap;' +
+       '  border-bottom: 1px dashed;' +
+       '  display: block;' +
+       '  padding: 0.3em 0.3em 0 0.3em;' +
+       '}' +
+       'menuitem.separator {' +
+       '  border-bottom: none;' +
+       '  height: 0.5em;' +
+       '  padding: 0;' +
+       '}' +
+       'menuitem:hover {' +
+       '  color: var(--hterm-cursor-color);' +
+       '}' +
+       '.wc-node {' +
+       '  display: inline-block;' +
+       '  text-align: center;' +
+       '  width: calc(var(--hterm-charsize-width) * 2);' +
+       '  line-height: var(--hterm-charsize-height);' +
+       '}' +
+       ':root {' +
+       '  --hterm-charsize-width: ' + this.scrollPort_.characterSize.width + 'px;' +
+       '  --hterm-charsize-height: ' + this.scrollPort_.characterSize.height + 'px;' +
+       // Default position hides the cursor for when the window is initializing.
+       '  --hterm-cursor-offset-col: -1;' +
+       '  --hterm-cursor-offset-row: -1;' +
+       '  --hterm-blink-node-duration: 0.7s;' +
+       '  --hterm-mouse-cursor-default: default;' +
+       '  --hterm-mouse-cursor-text: text;' +
+       '  --hterm-mouse-cursor-pointer: pointer;' +
+       '  --hterm-mouse-cursor-style: var(--hterm-mouse-cursor-text);' +
+       '}' +
+       '.uri-node:hover {' +
+       '  text-decoration: underline;' +
+       '  cursor: var(--hterm-mouse-cursor-pointer);' +
+       '}' +
+       '@keyframes blink {' +
+       '  from { opacity: 1.0; }' +
+       '  to { opacity: 0.0; }' +
+       '}' +
+       '.blink-node {' +
+       '  animation-name: blink;' +
+       '  animation-duration: var(--hterm-blink-node-duration);' +
+       '  animation-iteration-count: infinite;' +
+       '  animation-timing-function: ease-in-out;' +
+       '  animation-direction: alternate;' +
+       '}');
+  // Insert this stock style as the first node so that any user styles will
+  // override w/out having to use !important everywhere.  The rules above mix
+  // runtime variables with default ones designed to be overridden by the user,
+  // but we can wait for a concrete case from the users to determine the best
+  // way to split the sheet up to before & after the user-css settings.
+  this.document_.head.insertBefore(style, this.document_.head.firstChild);
+
+  this.cursorNode_ = this.document_.createElement('div');
+  this.cursorNode_.id = 'hterm:terminal-cursor';
+  this.cursorNode_.className = 'cursor-node';
+  this.cursorNode_.style.cssText =
+      ('position: absolute;' +
+       'left: calc(var(--hterm-charsize-width) * var(--hterm-cursor-offset-col));' +
+       'top: calc(var(--hterm-charsize-height) * var(--hterm-cursor-offset-row));' +
+       'display: ' + (this.options_.cursorVisible ? '' : 'none') + ';' +
+       'width: var(--hterm-charsize-width);' +
+       'height: var(--hterm-charsize-height);' +
+       'background-color: var(--hterm-cursor-color);' +
+       'border-color: var(--hterm-cursor-color);' +
+       '-webkit-transition: opacity, background-color 100ms linear;' +
+       '-moz-transition: opacity, background-color 100ms linear;');
+
+  this.setCursorColor();
+  this.setCursorBlink(!!this.prefs_.get('cursor-blink'));
+  this.restyleCursor_();
+
+  this.document_.body.appendChild(this.cursorNode_);
+
+  // When 'enableMouseDragScroll' is off we reposition this element directly
+  // under the mouse cursor after a click.  This makes Chrome associate
+  // subsequent mousemove events with the scroll-blocker.  Since the
+  // scroll-blocker is a peer (not a child) of the scrollport, the mousemove
+  // events do not cause the scrollport to scroll.
+  //
+  // It's a hack, but it's the cleanest way I could find.
+  this.scrollBlockerNode_ = this.document_.createElement('div');
+  this.scrollBlockerNode_.id = 'hterm:mouse-drag-scroll-blocker';
+  this.scrollBlockerNode_.setAttribute('aria-hidden', 'true');
+  this.scrollBlockerNode_.style.cssText =
+      ('position: absolute;' +
+       'top: -99px;' +
+       'display: block;' +
+       'width: 10px;' +
+       'height: 10px;');
+  this.document_.body.appendChild(this.scrollBlockerNode_);
+
+  this.scrollPort_.onScrollWheel = onMouse;
+  ['mousedown', 'mouseup', 'mousemove', 'click', 'dblclick',
+   ].forEach(function(event) {
+       this.scrollBlockerNode_.addEventListener(event, onMouse);
+       this.cursorNode_.addEventListener(event, onMouse);
+       this.document_.addEventListener(event, onMouse);
+     }.bind(this));
+
+  this.cursorNode_.addEventListener('mousedown', function() {
+      setTimeout(this.focus.bind(this));
+    }.bind(this));
+
+  this.setReverseVideo(false);
+
+  this.scrollPort_.focus();
+  this.scrollPort_.scheduleRedraw();
+};
+
+/**
+ * Return the HTML document that contains the terminal DOM nodes.
+ *
+ * @return {HTMLDocument}
+ */
+hterm.Terminal.prototype.getDocument = function() {
+  return this.document_;
+};
+
+/**
+ * Focus the terminal.
+ */
+hterm.Terminal.prototype.focus = function() {
+  this.scrollPort_.focus();
+};
+
+/**
+ * Return the HTML Element for a given row index.
+ *
+ * This is a method from the RowProvider interface.  The ScrollPort uses
+ * it to fetch rows on demand as they are scrolled into view.
+ *
+ * TODO(rginda): Consider saving scrollback rows as (HTML source, text content)
+ * pairs to conserve memory.
+ *
+ * @param {integer} index The zero-based row index, measured relative to the
+ *     start of the scrollback buffer.  On-screen rows will always have the
+ *     largest indices.
+ * @return {HTMLElement} The 'x-row' element containing for the requested row.
+ */
+hterm.Terminal.prototype.getRowNode = function(index) {
+  if (index < this.scrollbackRows_.length)
+    return this.scrollbackRows_[index];
+
+  var screenIndex = index - this.scrollbackRows_.length;
+  return this.screen_.rowsArray[screenIndex];
+};
+
+/**
+ * Return the text content for a given range of rows.
+ *
+ * This is a method from the RowProvider interface.  The ScrollPort uses
+ * it to fetch text content on demand when the user attempts to copy their
+ * selection to the clipboard.
+ *
+ * @param {integer} start The zero-based row index to start from, measured
+ *     relative to the start of the scrollback buffer.  On-screen rows will
+ *     always have the largest indices.
+ * @param {integer} end The zero-based row index to end on, measured
+ *     relative to the start of the scrollback buffer.
+ * @return {string} A single string containing the text value of the range of
+ *     rows.  Lines will be newline delimited, with no trailing newline.
+ */
+hterm.Terminal.prototype.getRowsText = function(start, end) {
+  var ary = [];
+  for (var i = start; i < end; i++) {
+    var node = this.getRowNode(i);
+    ary.push(node.textContent);
+    if (i < end - 1 && !node.getAttribute('line-overflow'))
+      ary.push('\n');
+  }
+
+  return ary.join('');
+};
+
+/**
+ * Return the text content for a given row.
+ *
+ * This is a method from the RowProvider interface.  The ScrollPort uses
+ * it to fetch text content on demand when the user attempts to copy their
+ * selection to the clipboard.
+ *
+ * @param {integer} index The zero-based row index to return, measured
+ *     relative to the start of the scrollback buffer.  On-screen rows will
+ *     always have the largest indices.
+ * @return {string} A string containing the text value of the selected row.
+ */
+hterm.Terminal.prototype.getRowText = function(index) {
+  var node = this.getRowNode(index);
+  return node.textContent;
+};
+
+/**
+ * Return the total number of rows in the addressable screen and in the
+ * scrollback buffer of this terminal.
+ *
+ * This is a method from the RowProvider interface.  The ScrollPort uses
+ * it to compute the size of the scrollbar.
+ *
+ * @return {integer} The number of rows in this terminal.
+ */
+hterm.Terminal.prototype.getRowCount = function() {
+  return this.scrollbackRows_.length + this.screen_.rowsArray.length;
+};
+
+/**
+ * Create DOM nodes for new rows and append them to the end of the terminal.
+ *
+ * This is the only correct way to add a new DOM node for a row.  Notice that
+ * the new row is appended to the bottom of the list of rows, and does not
+ * require renumbering (of the rowIndex property) of previous rows.
+ *
+ * If you think you want a new blank row somewhere in the middle of the
+ * terminal, look into moveRows_().
+ *
+ * This method does not pay attention to vtScrollTop/Bottom, since you should
+ * be using moveRows() in cases where they would matter.
+ *
+ * The cursor will be positioned at column 0 of the first inserted line.
+ *
+ * @param {number} count The number of rows to created.
+ */
+hterm.Terminal.prototype.appendRows_ = function(count) {
+  var cursorRow = this.screen_.rowsArray.length;
+  var offset = this.scrollbackRows_.length + cursorRow;
+  for (var i = 0; i < count; i++) {
+    var row = this.document_.createElement('x-row');
+    row.appendChild(this.document_.createTextNode(''));
+    row.rowIndex = offset + i;
+    this.screen_.pushRow(row);
+  }
+
+  var extraRows = this.screen_.rowsArray.length - this.screenSize.height;
+  if (extraRows > 0) {
+    var ary = this.screen_.shiftRows(extraRows);
+    Array.prototype.push.apply(this.scrollbackRows_, ary);
+    if (this.scrollPort_.isScrolledEnd)
+      this.scheduleScrollDown_();
+  }
+
+  if (cursorRow >= this.screen_.rowsArray.length)
+    cursorRow = this.screen_.rowsArray.length - 1;
+
+  this.setAbsoluteCursorPosition(cursorRow, 0);
+};
+
+/**
+ * Relocate rows from one part of the addressable screen to another.
+ *
+ * This is used to recycle rows during VT scrolls (those which are driven
+ * by VT commands, rather than by the user manipulating the scrollbar.)
+ *
+ * In this case, the blank lines scrolled into the scroll region are made of
+ * the nodes we scrolled off.  These have their rowIndex properties carefully
+ * renumbered so as not to confuse the ScrollPort.
+ *
+ * @param {number} fromIndex The start index.
+ * @param {number} count The number of rows to move.
+ * @param {number} toIndex The destination index.
+ */
+hterm.Terminal.prototype.moveRows_ = function(fromIndex, count, toIndex) {
+  var ary = this.screen_.removeRows(fromIndex, count);
+  this.screen_.insertRows(toIndex, ary);
+
+  var start, end;
+  if (fromIndex < toIndex) {
+    start = fromIndex;
+    end = toIndex + count;
+  } else {
+    start = toIndex;
+    end = fromIndex + count;
+  }
+
+  this.renumberRows_(start, end);
+  this.scrollPort_.scheduleInvalidate();
+};
+
+/**
+ * Renumber the rowIndex property of the given range of rows.
+ *
+ * The start and end indices are relative to the screen, not the scrollback.
+ * Rows in the scrollback buffer cannot be renumbered.  Since they are not
+ * addressable (you can't delete them, scroll them, etc), you should have
+ * no need to renumber scrollback rows.
+ *
+ * @param {number} start The start index.
+ * @param {number} end The end index.
+ * @param {hterm.Screen} opt_screen The screen to renumber.
+ */
+hterm.Terminal.prototype.renumberRows_ = function(start, end, opt_screen) {
+  var screen = opt_screen || this.screen_;
+
+  var offset = this.scrollbackRows_.length;
+  for (var i = start; i < end; i++) {
+    screen.rowsArray[i].rowIndex = offset + i;
+  }
+};
+
+/**
+ * Print a string to the terminal.
+ *
+ * This respects the current insert and wraparound modes.  It will add new lines
+ * to the end of the terminal, scrolling off the top into the scrollback buffer
+ * if necessary.
+ *
+ * The string is *not* parsed for escape codes.  Use the interpret() method if
+ * that's what you're after.
+ *
+ * @param{string} str The string to print.
+ */
+hterm.Terminal.prototype.print = function(str) {
+  this.scheduleSyncCursorPosition_();
+
+  // Basic accessibility output for the screen reader.
+  this.accessibilityReader_.announce(str);
+
+  var startOffset = 0;
+
+  var strWidth = lib.wc.strWidth(str);
+  // Fun edge case: If the string only contains zero width codepoints (like
+  // combining characters), we make sure to iterate at least once below.
+  if (strWidth == 0 && str)
+    strWidth = 1;
+
+  while (startOffset < strWidth) {
+    if (this.options_.wraparound && this.screen_.cursorPosition.overflow) {
+      this.screen_.commitLineOverflow();
+      this.newLine(true);
+    }
+
+    var count = strWidth - startOffset;
+    var didOverflow = false;
+    var substr;
+
+    if (this.screen_.cursorPosition.column + count >= this.screenSize.width) {
+      didOverflow = true;
+      count = this.screenSize.width - this.screen_.cursorPosition.column;
+    }
+
+    if (didOverflow && !this.options_.wraparound) {
+      // If the string overflowed the line but wraparound is off, then the
+      // last printed character should be the last of the string.
+      // TODO: This will add to our problems with multibyte UTF-16 characters.
+      substr = lib.wc.substr(str, startOffset, count - 1) +
+          lib.wc.substr(str, strWidth - 1);
+      count = strWidth;
+    } else {
+      substr = lib.wc.substr(str, startOffset, count);
+    }
+
+    var tokens = hterm.TextAttributes.splitWidecharString(substr);
+    for (var i = 0; i < tokens.length; i++) {
+      this.screen_.textAttributes.wcNode = tokens[i].wcNode;
+      this.screen_.textAttributes.asciiNode = tokens[i].asciiNode;
+
+      if (this.options_.insertMode) {
+        this.screen_.insertString(tokens[i].str, tokens[i].wcStrWidth);
+      } else {
+        this.screen_.overwriteString(tokens[i].str, tokens[i].wcStrWidth);
+      }
+      this.screen_.textAttributes.wcNode = false;
+      this.screen_.textAttributes.asciiNode = true;
+    }
+
+    this.screen_.maybeClipCurrentRow();
+    startOffset += count;
+  }
+
+  if (this.scrollOnOutput_)
+    this.scrollPort_.scrollRowToBottom(this.getRowCount());
+};
+
+/**
+ * Set the VT scroll region.
+ *
+ * This also resets the cursor position to the absolute (0, 0) position, since
+ * that's what xterm appears to do.
+ *
+ * Setting the scroll region to the full height of the terminal will clear
+ * the scroll region.  This is *NOT* what most terminals do.  We're explicitly
+ * going "off-spec" here because it makes `screen` and `tmux` overflow into the
+ * local scrollback buffer, which means the scrollbars and shift-pgup/pgdn
+ * continue to work as most users would expect.
+ *
+ * @param {integer} scrollTop The zero-based top of the scroll region.
+ * @param {integer} scrollBottom The zero-based bottom of the scroll region,
+ *     inclusive.
+ */
+hterm.Terminal.prototype.setVTScrollRegion = function(scrollTop, scrollBottom) {
+  if (scrollTop == 0 && scrollBottom == this.screenSize.height - 1) {
+    this.vtScrollTop_ = null;
+    this.vtScrollBottom_ = null;
+  } else {
+    this.vtScrollTop_ = scrollTop;
+    this.vtScrollBottom_ = scrollBottom;
+  }
+};
+
+/**
+ * Return the top row index according to the VT.
+ *
+ * This will return 0 unless the terminal has been told to restrict scrolling
+ * to some lower row.  It is used for some VT cursor positioning and scrolling
+ * commands.
+ *
+ * @return {integer} The topmost row in the terminal's scroll region.
+ */
+hterm.Terminal.prototype.getVTScrollTop = function() {
+  if (this.vtScrollTop_ != null)
+    return this.vtScrollTop_;
+
+  return 0;
+};
+
+/**
+ * Return the bottom row index according to the VT.
+ *
+ * This will return the height of the terminal unless the it has been told to
+ * restrict scrolling to some higher row.  It is used for some VT cursor
+ * positioning and scrolling commands.
+ *
+ * @return {integer} The bottom most row in the terminal's scroll region.
+ */
+hterm.Terminal.prototype.getVTScrollBottom = function() {
+  if (this.vtScrollBottom_ != null)
+    return this.vtScrollBottom_;
+
+  return this.screenSize.height - 1;
+};
+
+/**
+ * Process a '\n' character.
+ *
+ * If the cursor is on the final row of the terminal this will append a new
+ * blank row to the screen and scroll the topmost row into the scrollback
+ * buffer.
+ *
+ * Otherwise, this moves the cursor to column zero of the next row.
+ *
+ * @param {boolean=} dueToOverflow Whether the newline is due to wraparound of
+ *     the terminal.
+ */
+hterm.Terminal.prototype.newLine = function(dueToOverflow = false) {
+  if (!dueToOverflow)
+    this.accessibilityReader_.newLine();
+
+  var cursorAtEndOfScreen = (this.screen_.cursorPosition.row ==
+                             this.screen_.rowsArray.length - 1);
+
+  if (this.vtScrollBottom_ != null) {
+    // A VT Scroll region is active, we never append new rows.
+    if (this.screen_.cursorPosition.row == this.vtScrollBottom_) {
+      // We're at the end of the VT Scroll Region, perform a VT scroll.
+      this.vtScrollUp(1);
+      this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row, 0);
+    } else if (cursorAtEndOfScreen) {
+      // We're at the end of the screen, the only thing to do is put the
+      // cursor to column 0.
+      this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row, 0);
+    } else {
+      // Anywhere else, advance the cursor row, and reset the column.
+      this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row + 1, 0);
+    }
+  } else if (cursorAtEndOfScreen) {
+    // We're at the end of the screen.  Append a new row to the terminal,
+    // shifting the top row into the scrollback.
+    this.appendRows_(1);
+  } else {
+    // Anywhere else in the screen just moves the cursor.
+    this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row + 1, 0);
+  }
+};
+
+/**
+ * Like newLine(), except maintain the cursor column.
+ */
+hterm.Terminal.prototype.lineFeed = function() {
+  var column = this.screen_.cursorPosition.column;
+  this.newLine();
+  this.setCursorColumn(column);
+};
+
+/**
+ * If autoCarriageReturn is set then newLine(), else lineFeed().
+ */
+hterm.Terminal.prototype.formFeed = function() {
+  if (this.options_.autoCarriageReturn) {
+    this.newLine();
+  } else {
+    this.lineFeed();
+  }
+};
+
+/**
+ * Move the cursor up one row, possibly inserting a blank line.
+ *
+ * The cursor column is not changed.
+ */
+hterm.Terminal.prototype.reverseLineFeed = function() {
+  var scrollTop = this.getVTScrollTop();
+  var currentRow = this.screen_.cursorPosition.row;
+
+  if (currentRow == scrollTop) {
+    this.insertLines(1);
+  } else {
+    this.setAbsoluteCursorRow(currentRow - 1);
+  }
+};
+
+/**
+ * Replace all characters to the left of the current cursor with the space
+ * character.
+ *
+ * TODO(rginda): This should probably *remove* the characters (not just replace
+ * with a space) if there are no characters at or beyond the current cursor
+ * position.
+ */
+hterm.Terminal.prototype.eraseToLeft = function() {
+  var cursor = this.saveCursor();
+  this.setCursorColumn(0);
+  const count = cursor.column + 1;
+  this.screen_.overwriteString(lib.f.getWhitespace(count), count);
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Erase a given number of characters to the right of the cursor.
+ *
+ * The cursor position is unchanged.
+ *
+ * If the current background color is not the default background color this
+ * will insert spaces rather than delete.  This is unfortunate because the
+ * trailing space will affect text selection, but it's difficult to come up
+ * with a way to style empty space that wouldn't trip up the hterm.Screen
+ * code.
+ *
+ * eraseToRight is ignored in the presence of a cursor overflow.  This deviates
+ * from xterm, but agrees with gnome-terminal and konsole, xfce4-terminal.  See
+ * crbug.com/232390 for details.
+ *
+ * @param {number} opt_count The number of characters to erase.
+ */
+hterm.Terminal.prototype.eraseToRight = function(opt_count) {
+  if (this.screen_.cursorPosition.overflow)
+    return;
+
+  var maxCount = this.screenSize.width - this.screen_.cursorPosition.column;
+  var count = opt_count ? Math.min(opt_count, maxCount) : maxCount;
+
+  if (this.screen_.textAttributes.background ===
+      this.screen_.textAttributes.DEFAULT_COLOR) {
+    var cursorRow = this.screen_.rowsArray[this.screen_.cursorPosition.row];
+    if (hterm.TextAttributes.nodeWidth(cursorRow) <=
+        this.screen_.cursorPosition.column + count) {
+      this.screen_.deleteChars(count);
+      this.clearCursorOverflow();
+      return;
+    }
+  }
+
+  var cursor = this.saveCursor();
+  this.screen_.overwriteString(lib.f.getWhitespace(count), count);
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Erase the current line.
+ *
+ * The cursor position is unchanged.
+ */
+hterm.Terminal.prototype.eraseLine = function() {
+  var cursor = this.saveCursor();
+  this.screen_.clearCursorRow();
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Erase all characters from the start of the screen to the current cursor
+ * position, regardless of scroll region.
+ *
+ * The cursor position is unchanged.
+ */
+hterm.Terminal.prototype.eraseAbove = function() {
+  var cursor = this.saveCursor();
+
+  this.eraseToLeft();
+
+  for (var i = 0; i < cursor.row; i++) {
+    this.setAbsoluteCursorPosition(i, 0);
+    this.screen_.clearCursorRow();
+  }
+
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Erase all characters from the current cursor position to the end of the
+ * screen, regardless of scroll region.
+ *
+ * The cursor position is unchanged.
+ */
+hterm.Terminal.prototype.eraseBelow = function() {
+  var cursor = this.saveCursor();
+
+  this.eraseToRight();
+
+  var bottom = this.screenSize.height - 1;
+  for (var i = cursor.row + 1; i <= bottom; i++) {
+    this.setAbsoluteCursorPosition(i, 0);
+    this.screen_.clearCursorRow();
+  }
+
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Fill the terminal with a given character.
+ *
+ * This methods does not respect the VT scroll region.
+ *
+ * @param {string} ch The character to use for the fill.
+ */
+hterm.Terminal.prototype.fill = function(ch) {
+  var cursor = this.saveCursor();
+
+  this.setAbsoluteCursorPosition(0, 0);
+  for (var row = 0; row < this.screenSize.height; row++) {
+    for (var col = 0; col < this.screenSize.width; col++) {
+      this.setAbsoluteCursorPosition(row, col);
+      this.screen_.overwriteString(ch, 1);
+    }
+  }
+
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Erase the entire display and leave the cursor at (0, 0).
+ *
+ * This does not respect the scroll region.
+ *
+ * @param {hterm.Screen} opt_screen Optional screen to operate on.  Defaults
+ *     to the current screen.
+ */
+hterm.Terminal.prototype.clearHome = function(opt_screen) {
+  var screen = opt_screen || this.screen_;
+  var bottom = screen.getHeight();
+
+  this.accessibilityReader_.clear();
+
+  if (bottom == 0) {
+    // Empty screen, nothing to do.
+    return;
+  }
+
+  for (var i = 0; i < bottom; i++) {
+    screen.setCursorPosition(i, 0);
+    screen.clearCursorRow();
+  }
+
+  screen.setCursorPosition(0, 0);
+};
+
+/**
+ * Erase the entire display without changing the cursor position.
+ *
+ * The cursor position is unchanged.  This does not respect the scroll
+ * region.
+ *
+ * @param {hterm.Screen} opt_screen Optional screen to operate on.  Defaults
+ *     to the current screen.
+ */
+hterm.Terminal.prototype.clear = function(opt_screen) {
+  var screen = opt_screen || this.screen_;
+  var cursor = screen.cursorPosition.clone();
+  this.clearHome(screen);
+  screen.setCursorPosition(cursor.row, cursor.column);
+};
+
+/**
+ * VT command to insert lines at the current cursor row.
+ *
+ * This respects the current scroll region.  Rows pushed off the bottom are
+ * lost (they won't show up in the scrollback buffer).
+ *
+ * @param {integer} count The number of lines to insert.
+ */
+hterm.Terminal.prototype.insertLines = function(count) {
+  var cursorRow = this.screen_.cursorPosition.row;
+
+  var bottom = this.getVTScrollBottom();
+  count = Math.min(count, bottom - cursorRow);
+
+  // The moveCount is the number of rows we need to relocate to make room for
+  // the new row(s).  The count is the distance to move them.
+  var moveCount = bottom - cursorRow - count + 1;
+  if (moveCount)
+    this.moveRows_(cursorRow, moveCount, cursorRow + count);
+
+  for (var i = count - 1; i >= 0; i--) {
+    this.setAbsoluteCursorPosition(cursorRow + i, 0);
+    this.screen_.clearCursorRow();
+  }
+};
+
+/**
+ * VT command to delete lines at the current cursor row.
+ *
+ * New rows are added to the bottom of scroll region to take their place.  New
+ * rows are strictly there to take up space and have no content or style.
+ *
+ * @param {number} count The number of lines to delete.
+ */
+hterm.Terminal.prototype.deleteLines = function(count) {
+  var cursor = this.saveCursor();
+
+  var top = cursor.row;
+  var bottom = this.getVTScrollBottom();
+
+  var maxCount = bottom - top + 1;
+  count = Math.min(count, maxCount);
+
+  var moveStart = bottom - count + 1;
+  if (count != maxCount)
+    this.moveRows_(top, count, moveStart);
+
+  for (var i = 0; i < count; i++) {
+    this.setAbsoluteCursorPosition(moveStart + i, 0);
+    this.screen_.clearCursorRow();
+  }
+
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Inserts the given number of spaces at the current cursor position.
+ *
+ * The cursor position is not changed.
+ *
+ * @param {number} count The number of spaces to insert.
+ */
+hterm.Terminal.prototype.insertSpace = function(count) {
+  var cursor = this.saveCursor();
+
+  var ws = lib.f.getWhitespace(count || 1);
+  this.screen_.insertString(ws, ws.length);
+  this.screen_.maybeClipCurrentRow();
+
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Forward-delete the specified number of characters starting at the cursor
+ * position.
+ *
+ * @param {integer} count The number of characters to delete.
+ */
+hterm.Terminal.prototype.deleteChars = function(count) {
+  var deleted = this.screen_.deleteChars(count);
+  if (deleted && !this.screen_.textAttributes.isDefault()) {
+    var cursor = this.saveCursor();
+    this.setCursorColumn(this.screenSize.width - deleted);
+    this.screen_.insertString(lib.f.getWhitespace(deleted));
+    this.restoreCursor(cursor);
+  }
+
+  this.clearCursorOverflow();
+};
+
+/**
+ * Shift rows in the scroll region upwards by a given number of lines.
+ *
+ * New rows are inserted at the bottom of the scroll region to fill the
+ * vacated rows.  The new rows not filled out with the current text attributes.
+ *
+ * This function does not affect the scrollback rows at all.  Rows shifted
+ * off the top are lost.
+ *
+ * The cursor position is not altered.
+ *
+ * @param {integer} count The number of rows to scroll.
+ */
+hterm.Terminal.prototype.vtScrollUp = function(count) {
+  var cursor = this.saveCursor();
+
+  this.setAbsoluteCursorRow(this.getVTScrollTop());
+  this.deleteLines(count);
+
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Shift rows below the cursor down by a given number of lines.
+ *
+ * This function respects the current scroll region.
+ *
+ * New rows are inserted at the top of the scroll region to fill the
+ * vacated rows.  The new rows not filled out with the current text attributes.
+ *
+ * This function does not affect the scrollback rows at all.  Rows shifted
+ * off the bottom are lost.
+ *
+ * @param {integer} count The number of rows to scroll.
+ */
+hterm.Terminal.prototype.vtScrollDown = function(opt_count) {
+  var cursor = this.saveCursor();
+
+  this.setAbsoluteCursorPosition(this.getVTScrollTop(), 0);
+  this.insertLines(opt_count);
+
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Enable accessibility-friendly features that have a performance impact.
+ *
+ * This will generate additional DOM nodes in an aria-live region that will
+ * cause Assitive Technology to announce the output of the terminal. It also
+ * enables other features that aid assistive technology. All the features gated
+ * behind this flag have a performance impact on the terminal which is why they
+ * are made optional.
+ *
+ * @param {boolean} enabled Whether to enable accessibility-friendly features.
+ */
+hterm.Terminal.prototype.setAccessibilityEnabled = function(enabled) {
+  this.accessibilityReader_.setAccessibilityEnabled(enabled);
+};
+
+/**
+ * Set the cursor position.
+ *
+ * The cursor row is relative to the scroll region if the terminal has
+ * 'origin mode' enabled, or relative to the addressable screen otherwise.
+ *
+ * @param {integer} row The new zero-based cursor row.
+ * @param {integer} row The new zero-based cursor column.
+ */
+hterm.Terminal.prototype.setCursorPosition = function(row, column) {
+  if (this.options_.originMode) {
+    this.setRelativeCursorPosition(row, column);
+  } else {
+    this.setAbsoluteCursorPosition(row, column);
+  }
+};
+
+/**
+ * Move the cursor relative to its current position.
+ *
+ * @param {number} row
+ * @param {number} column
+ */
+hterm.Terminal.prototype.setRelativeCursorPosition = function(row, column) {
+  var scrollTop = this.getVTScrollTop();
+  row = lib.f.clamp(row + scrollTop, scrollTop, this.getVTScrollBottom());
+  column = lib.f.clamp(column, 0, this.screenSize.width - 1);
+  this.screen_.setCursorPosition(row, column);
+};
+
+/**
+ * Move the cursor to the specified position.
+ *
+ * @param {number} row
+ * @param {number} column
+ */
+hterm.Terminal.prototype.setAbsoluteCursorPosition = function(row, column) {
+  row = lib.f.clamp(row, 0, this.screenSize.height - 1);
+  column = lib.f.clamp(column, 0, this.screenSize.width - 1);
+  this.screen_.setCursorPosition(row, column);
+};
+
+/**
+ * Set the cursor column.
+ *
+ * @param {integer} column The new zero-based cursor column.
+ */
+hterm.Terminal.prototype.setCursorColumn = function(column) {
+  this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row, column);
+};
+
+/**
+ * Return the cursor column.
+ *
+ * @return {integer} The zero-based cursor column.
+ */
+hterm.Terminal.prototype.getCursorColumn = function() {
+  return this.screen_.cursorPosition.column;
+};
+
+/**
+ * Set the cursor row.
+ *
+ * The cursor row is relative to the scroll region if the terminal has
+ * 'origin mode' enabled, or relative to the addressable screen otherwise.
+ *
+ * @param {integer} row The new cursor row.
+ */
+hterm.Terminal.prototype.setAbsoluteCursorRow = function(row) {
+  this.setAbsoluteCursorPosition(row, this.screen_.cursorPosition.column);
+};
+
+/**
+ * Return the cursor row.
+ *
+ * @return {integer} The zero-based cursor row.
+ */
+hterm.Terminal.prototype.getCursorRow = function() {
+  return this.screen_.cursorPosition.row;
+};
+
+/**
+ * Request that the ScrollPort redraw itself soon.
+ *
+ * The redraw will happen asynchronously, soon after the call stack winds down.
+ * Multiple calls will be coalesced into a single redraw.
+ */
+hterm.Terminal.prototype.scheduleRedraw_ = function() {
+  if (this.timeouts_.redraw)
+    return;
+
+  var self = this;
+  this.timeouts_.redraw = setTimeout(function() {
+      delete self.timeouts_.redraw;
+      self.scrollPort_.redraw_();
+    }, 0);
+};
+
+/**
+ * Request that the ScrollPort be scrolled to the bottom.
+ *
+ * The scroll will happen asynchronously, soon after the call stack winds down.
+ * Multiple calls will be coalesced into a single scroll.
+ *
+ * This affects the scrollbar position of the ScrollPort, and has nothing to
+ * do with the VT scroll commands.
+ */
+hterm.Terminal.prototype.scheduleScrollDown_ = function() {
+  if (this.timeouts_.scrollDown)
+    return;
+
+  var self = this;
+  this.timeouts_.scrollDown = setTimeout(function() {
+      delete self.timeouts_.scrollDown;
+      self.scrollPort_.scrollRowToBottom(self.getRowCount());
+    }, 10);
+};
+
+/**
+ * Move the cursor up a specified number of rows.
+ *
+ * @param {integer} count The number of rows to move the cursor.
+ */
+hterm.Terminal.prototype.cursorUp = function(count) {
+  return this.cursorDown(-(count || 1));
+};
+
+/**
+ * Move the cursor down a specified number of rows.
+ *
+ * @param {integer} count The number of rows to move the cursor.
+ */
+hterm.Terminal.prototype.cursorDown = function(count) {
+  count = count || 1;
+  var minHeight = (this.options_.originMode ? this.getVTScrollTop() : 0);
+  var maxHeight = (this.options_.originMode ? this.getVTScrollBottom() :
+                   this.screenSize.height - 1);
+
+  var row = lib.f.clamp(this.screen_.cursorPosition.row + count,
+                        minHeight, maxHeight);
+  this.setAbsoluteCursorRow(row);
+};
+
+/**
+ * Move the cursor left a specified number of columns.
+ *
+ * If reverse wraparound mode is enabled and the previous row wrapped into
+ * the current row then we back up through the wraparound as well.
+ *
+ * @param {integer} count The number of columns to move the cursor.
+ */
+hterm.Terminal.prototype.cursorLeft = function(count) {
+  count = count || 1;
+
+  if (count < 1)
+    return;
+
+  var currentColumn = this.screen_.cursorPosition.column;
+  if (this.options_.reverseWraparound) {
+    if (this.screen_.cursorPosition.overflow) {
+      // If this cursor is in the right margin, consume one count to get it
+      // back to the last column.  This only applies when we're in reverse
+      // wraparound mode.
+      count--;
+      this.clearCursorOverflow();
+
+      if (!count)
+        return;
+    }
+
+    var newRow = this.screen_.cursorPosition.row;
+    var newColumn = currentColumn - count;
+    if (newColumn < 0) {
+      newRow = newRow - Math.floor(count / this.screenSize.width) - 1;
+      if (newRow < 0) {
+        // xterm also wraps from row 0 to the last row.
+        newRow = this.screenSize.height + newRow % this.screenSize.height;
+      }
+      newColumn = this.screenSize.width + newColumn % this.screenSize.width;
+    }
+
+    this.setCursorPosition(Math.max(newRow, 0), newColumn);
+
+  } else {
+    var newColumn = Math.max(currentColumn - count, 0);
+    this.setCursorColumn(newColumn);
+  }
+};
+
+/**
+ * Move the cursor right a specified number of columns.
+ *
+ * @param {integer} count The number of columns to move the cursor.
+ */
+hterm.Terminal.prototype.cursorRight = function(count) {
+  count = count || 1;
+
+  if (count < 1)
+    return;
+
+  var column = lib.f.clamp(this.screen_.cursorPosition.column + count,
+                           0, this.screenSize.width - 1);
+  this.setCursorColumn(column);
+};
+
+/**
+ * Reverse the foreground and background colors of the terminal.
+ *
+ * This only affects text that was drawn with no attributes.
+ *
+ * TODO(rginda): Test xterm to see if reverse is respected for text that has
+ * been drawn with attributes that happen to coincide with the default
+ * 'no-attribute' colors.  My guess is probably not.
+ *
+ * @param {boolean} state The state to set.
+ */
+hterm.Terminal.prototype.setReverseVideo = function(state) {
+  this.options_.reverseVideo = state;
+  if (state) {
+    this.scrollPort_.setForegroundColor(this.prefs_.get('background-color'));
+    this.scrollPort_.setBackgroundColor(this.prefs_.get('foreground-color'));
+  } else {
+    this.scrollPort_.setForegroundColor(this.prefs_.get('foreground-color'));
+    this.scrollPort_.setBackgroundColor(this.prefs_.get('background-color'));
+  }
+};
+
+/**
+ * Ring the terminal bell.
+ *
+ * This will not play the bell audio more than once per second.
+ */
+hterm.Terminal.prototype.ringBell = function() {
+  this.cursorNode_.style.backgroundColor =
+      this.scrollPort_.getForegroundColor();
+
+  var self = this;
+  setTimeout(function() {
+      self.restyleCursor_();
+    }, 200);
+
+  // bellSquelchTimeout_ affects both audio and notification bells.
+  if (this.bellSquelchTimeout_)
+    return;
+
+  if (this.bellAudio_.getAttribute('src')) {
+    this.bellAudio_.play();
+    this.bellSequelchTimeout_ = setTimeout(function() {
+        delete this.bellSquelchTimeout_;
+      }.bind(this), 500);
+  } else {
+    delete this.bellSquelchTimeout_;
+  }
+
+  if (this.desktopNotificationBell_ && !this.document_.hasFocus()) {
+    var n = hterm.notify();
+    this.bellNotificationList_.push(n);
+    // TODO: Should we try to raise the window here?
+    n.onclick = function() { self.closeBellNotifications_(); };
+  }
+};
+
+/**
+ * Set the origin mode bit.
+ *
+ * If origin mode is on, certain VT cursor and scrolling commands measure their
+ * row parameter relative to the VT scroll region.  Otherwise, row 0 corresponds
+ * to the top of the addressable screen.
+ *
+ * Defaults to off.
+ *
+ * @param {boolean} state True to set origin mode, false to unset.
+ */
+hterm.Terminal.prototype.setOriginMode = function(state) {
+  this.options_.originMode = state;
+  this.setCursorPosition(0, 0);
+};
+
+/**
+ * Set the insert mode bit.
+ *
+ * If insert mode is on, existing text beyond the cursor position will be
+ * shifted right to make room for new text.  Otherwise, new text overwrites
+ * any existing text.
+ *
+ * Defaults to off.
+ *
+ * @param {boolean} state True to set insert mode, false to unset.
+ */
+hterm.Terminal.prototype.setInsertMode = function(state) {
+  this.options_.insertMode = state;
+};
+
+/**
+ * Set the auto carriage return bit.
+ *
+ * If auto carriage return is on then a formfeed character is interpreted
+ * as a newline, otherwise it's the same as a linefeed.  The difference boils
+ * down to whether or not the cursor column is reset.
+ *
+ * @param {boolean} state The state to set.
+ */
+hterm.Terminal.prototype.setAutoCarriageReturn = function(state) {
+  this.options_.autoCarriageReturn = state;
+};
+
+/**
+ * Set the wraparound mode bit.
+ *
+ * If wraparound mode is on, certain VT commands will allow the cursor to wrap
+ * to the start of the following row.  Otherwise, the cursor is clamped to the
+ * end of the screen and attempts to write past it are ignored.
+ *
+ * Defaults to on.
+ *
+ * @param {boolean} state True to set wraparound mode, false to unset.
+ */
+hterm.Terminal.prototype.setWraparound = function(state) {
+  this.options_.wraparound = state;
+};
+
+/**
+ * Set the reverse-wraparound mode bit.
+ *
+ * If wraparound mode is off, certain VT commands will allow the cursor to wrap
+ * to the end of the previous row.  Otherwise, the cursor is clamped to column
+ * 0.
+ *
+ * Defaults to off.
+ *
+ * @param {boolean} state True to set reverse-wraparound mode, false to unset.
+ */
+hterm.Terminal.prototype.setReverseWraparound = function(state) {
+  this.options_.reverseWraparound = state;
+};
+
+/**
+ * Selects between the primary and alternate screens.
+ *
+ * If alternate mode is on, the alternate screen is active.  Otherwise the
+ * primary screen is active.
+ *
+ * Swapping screens has no effect on the scrollback buffer.
+ *
+ * Each screen maintains its own cursor position.
+ *
+ * Defaults to off.
+ *
+ * @param {boolean} state True to set alternate mode, false to unset.
+ */
+hterm.Terminal.prototype.setAlternateMode = function(state) {
+  var cursor = this.saveCursor();
+  this.screen_ = state ? this.alternateScreen_ : this.primaryScreen_;
+
+  if (this.screen_.rowsArray.length &&
+      this.screen_.rowsArray[0].rowIndex != this.scrollbackRows_.length) {
+    // If the screen changed sizes while we were away, our rowIndexes may
+    // be incorrect.
+    var offset = this.scrollbackRows_.length;
+    var ary = this.screen_.rowsArray;
+    for (var i = 0; i < ary.length; i++) {
+      ary[i].rowIndex = offset + i;
+    }
+  }
+
+  this.realizeWidth_(this.screenSize.width);
+  this.realizeHeight_(this.screenSize.height);
+  this.scrollPort_.syncScrollHeight();
+  this.scrollPort_.invalidate();
+
+  this.restoreCursor(cursor);
+  this.scrollPort_.resize();
+};
+
+/**
+ * Set the cursor-blink mode bit.
+ *
+ * If cursor-blink is on, the cursor will blink when it is visible.  Otherwise
+ * a visible cursor does not blink.
+ *
+ * You should make sure to turn blinking off if you're going to dispose of a
+ * terminal, otherwise you'll leak a timeout.
+ *
+ * Defaults to on.
+ *
+ * @param {boolean} state True to set cursor-blink mode, false to unset.
+ */
+hterm.Terminal.prototype.setCursorBlink = function(state) {
+  this.options_.cursorBlink = state;
+
+  if (!state && this.timeouts_.cursorBlink) {
+    clearTimeout(this.timeouts_.cursorBlink);
+    delete this.timeouts_.cursorBlink;
+  }
+
+  if (this.options_.cursorVisible)
+    this.setCursorVisible(true);
+};
+
+/**
+ * Set the cursor-visible mode bit.
+ *
+ * If cursor-visible is on, the cursor will be visible.  Otherwise it will not.
+ *
+ * Defaults to on.
+ *
+ * @param {boolean} state True to set cursor-visible mode, false to unset.
+ */
+hterm.Terminal.prototype.setCursorVisible = function(state) {
+  this.options_.cursorVisible = state;
+
+  if (!state) {
+    if (this.timeouts_.cursorBlink) {
+      clearTimeout(this.timeouts_.cursorBlink);
+      delete this.timeouts_.cursorBlink;
+    }
+    this.cursorNode_.style.opacity = '0';
+    return;
+  }
+
+  this.syncCursorPosition_();
+
+  this.cursorNode_.style.opacity = '1';
+
+  if (this.options_.cursorBlink) {
+    if (this.timeouts_.cursorBlink)
+      return;
+
+    this.onCursorBlink_();
+  } else {
+    if (this.timeouts_.cursorBlink) {
+      clearTimeout(this.timeouts_.cursorBlink);
+      delete this.timeouts_.cursorBlink;
+    }
+  }
+};
+
+/**
+ * Synchronizes the visible cursor and document selection with the current
+ * cursor coordinates.
+ *
+ * @return {boolean} True if the cursor is onscreen and synced.
+ */
+hterm.Terminal.prototype.syncCursorPosition_ = function() {
+  var topRowIndex = this.scrollPort_.getTopRowIndex();
+  var bottomRowIndex = this.scrollPort_.getBottomRowIndex(topRowIndex);
+  var cursorRowIndex = this.scrollbackRows_.length +
+      this.screen_.cursorPosition.row;
+
+  let forceSyncSelection = false;
+  if (this.accessibilityReader_.accessibilityEnabled) {
+    // Report the new position of the cursor for accessibility purposes.
+    const cursorColumnIndex = this.screen_.cursorPosition.column;
+    const cursorLineText =
+        this.screen_.rowsArray[this.screen_.cursorPosition.row].innerText;
+    // This will force the selection to be sync'd to the cursor position if the
+    // user has pressed a key. Generally we would only sync the cursor position
+    // when selection is collapsed so that if the user has selected something
+    // we don't clear the selection by moving the selection. However when a
+    // screen reader is used, it's intuitive for entering a key to move the
+    // selection to the cursor.
+    forceSyncSelection = this.accessibilityReader_.hasUserGesture;
+    this.accessibilityReader_.afterCursorChange(
+        cursorLineText, cursorRowIndex, cursorColumnIndex);
+  }
+
+  if (cursorRowIndex > bottomRowIndex) {
+    // Cursor is scrolled off screen, move it outside of the visible area.
+    this.setCssVar('cursor-offset-row', '-1');
+    return false;
+  }
+
+  if (this.options_.cursorVisible &&
+      this.cursorNode_.style.display == 'none') {
+    // Re-display the terminal cursor if it was hidden by the mouse cursor.
+    this.cursorNode_.style.display = '';
+  }
+
+  // Position the cursor using CSS variable math.  If we do the math in JS,
+  // the float math will end up being more precise than the CSS which will
+  // cause the cursor tracking to be off.
+  this.setCssVar(
+      'cursor-offset-row',
+      `${cursorRowIndex - topRowIndex} + ` +
+      `${this.scrollPort_.visibleRowTopMargin}px`);
+  this.setCssVar('cursor-offset-col', this.screen_.cursorPosition.column);
+
+  this.cursorNode_.setAttribute('title',
+                                '(' + this.screen_.cursorPosition.column +
+                                ', ' + this.screen_.cursorPosition.row +
+                                ')');
+
+  // Update the caret for a11y purposes.
+  var selection = this.document_.getSelection();
+  if (selection && (selection.isCollapsed || forceSyncSelection)) {
+    this.screen_.syncSelectionCaret(selection);
+  }
+  return true;
+};
+
+/**
+ * Adjusts the style of this.cursorNode_ according to the current cursor shape
+ * and character cell dimensions.
+ */
+hterm.Terminal.prototype.restyleCursor_ = function() {
+  var shape = this.cursorShape_;
+
+  if (this.cursorNode_.getAttribute('focus') == 'false') {
+    // Always show a block cursor when unfocused.
+    shape = hterm.Terminal.cursorShape.BLOCK;
+  }
+
+  var style = this.cursorNode_.style;
+
+  switch (shape) {
+    case hterm.Terminal.cursorShape.BEAM:
+      style.backgroundColor = 'transparent';
+      style.borderBottomStyle = null;
+      style.borderLeftStyle = 'solid';
+      break;
+
+    case hterm.Terminal.cursorShape.UNDERLINE:
+      style.backgroundColor = 'transparent';
+      style.borderBottomStyle = 'solid';
+      style.borderLeftStyle = null;
+      break;
+
+    default:
+      style.backgroundColor = 'var(--hterm-cursor-color)';
+      style.borderBottomStyle = null;
+      style.borderLeftStyle = null;
+      break;
+  }
+};
+
+/**
+ * Synchronizes the visible cursor with the current cursor coordinates.
+ *
+ * The sync will happen asynchronously, soon after the call stack winds down.
+ * Multiple calls will be coalesced into a single sync. This should be called
+ * prior to the cursor actually changing position.
+ */
+hterm.Terminal.prototype.scheduleSyncCursorPosition_ = function() {
+  if (this.timeouts_.syncCursor)
+    return;
+
+  if (this.accessibilityReader_.accessibilityEnabled) {
+    // Report the previous position of the cursor for accessibility purposes.
+    const cursorRowIndex = this.scrollbackRows_.length +
+        this.screen_.cursorPosition.row;
+    const cursorColumnIndex = this.screen_.cursorPosition.column;
+    const cursorLineText =
+        this.screen_.rowsArray[this.screen_.cursorPosition.row].innerText;
+    this.accessibilityReader_.beforeCursorChange(
+        cursorLineText, cursorRowIndex, cursorColumnIndex);
+  }
+
+  var self = this;
+  this.timeouts_.syncCursor = setTimeout(function() {
+      self.syncCursorPosition_();
+      delete self.timeouts_.syncCursor;
+    }, 0);
+};
+
+/**
+ * Show or hide the zoom warning.
+ *
+ * The zoom warning is a message warning the user that their browser zoom must
+ * be set to 100% in order for hterm to function properly.
+ *
+ * @param {boolean} state True to show the message, false to hide it.
+ */
+hterm.Terminal.prototype.showZoomWarning_ = function(state) {
+  if (!this.zoomWarningNode_) {
+    if (!state)
+      return;
+
+    this.zoomWarningNode_ = this.document_.createElement('div');
+    this.zoomWarningNode_.id = 'hterm:zoom-warning';
+    this.zoomWarningNode_.style.cssText = (
+        'color: black;' +
+        'background-color: #ff2222;' +
+        'font-size: large;' +
+        'border-radius: 8px;' +
+        'opacity: 0.75;' +
+        'padding: 0.2em 0.5em 0.2em 0.5em;' +
+        'top: 0.5em;' +
+        'right: 1.2em;' +
+        'position: absolute;' +
+        '-webkit-text-size-adjust: none;' +
+        '-webkit-user-select: none;' +
+        '-moz-text-size-adjust: none;' +
+        '-moz-user-select: none;');
+
+    this.zoomWarningNode_.addEventListener('click', function(e) {
+      this.parentNode.removeChild(this);
+    });
+  }
+
+  this.zoomWarningNode_.textContent = lib.i18n.replaceReferences(
+      hterm.zoomWarningMessage,
+      [parseInt(this.scrollPort_.characterSize.zoomFactor * 100)]);
+
+  this.zoomWarningNode_.style.fontFamily = this.prefs_.get('font-family');
+
+  if (state) {
+    if (!this.zoomWarningNode_.parentNode)
+      this.div_.parentNode.appendChild(this.zoomWarningNode_);
+  } else if (this.zoomWarningNode_.parentNode) {
+    this.zoomWarningNode_.parentNode.removeChild(this.zoomWarningNode_);
+  }
+};
+
+/**
+ * Show the terminal overlay for a given amount of time.
+ *
+ * The terminal overlay appears in inverse video in a large font, centered
+ * over the terminal.  You should probably keep the overlay message brief,
+ * since it's in a large font and you probably aren't going to check the size
+ * of the terminal first.
+ *
+ * @param {string} msg The text (not HTML) message to display in the overlay.
+ * @param {number} opt_timeout The amount of time to wait before fading out
+ *     the overlay.  Defaults to 1.5 seconds.  Pass null to have the overlay
+ *     stay up forever (or until the next overlay).
+ */
+hterm.Terminal.prototype.showOverlay = function(msg, opt_timeout) {
+  if (!this.overlayNode_) {
+    if (!this.div_)
+      return;
+
+    this.overlayNode_ = this.document_.createElement('div');
+    this.overlayNode_.style.cssText = (
+        'border-radius: 15px;' +
+        'font-size: xx-large;' +
+        'opacity: 0.75;' +
+        'padding: 0.2em 0.5em 0.2em 0.5em;' +
+        'position: absolute;' +
+        '-webkit-user-select: none;' +
+        '-webkit-transition: opacity 180ms ease-in;' +
+        '-moz-user-select: none;' +
+        '-moz-transition: opacity 180ms ease-in;');
+
+    this.overlayNode_.addEventListener('mousedown', function(e) {
+      e.preventDefault();
+      e.stopPropagation();
+    }, true);
+  }
+
+  this.overlayNode_.style.color = this.prefs_.get('background-color');
+  this.overlayNode_.style.backgroundColor = this.prefs_.get('foreground-color');
+  this.overlayNode_.style.fontFamily = this.prefs_.get('font-family');
+
+  this.overlayNode_.textContent = msg;
+  this.overlayNode_.style.opacity = '0.75';
+
+  if (!this.overlayNode_.parentNode)
+    this.div_.appendChild(this.overlayNode_);
+
+  var divSize = hterm.getClientSize(this.div_);
+  var overlaySize = hterm.getClientSize(this.overlayNode_);
+
+  this.overlayNode_.style.top =
+      (divSize.height - overlaySize.height) / 2 + 'px';
+  this.overlayNode_.style.left = (divSize.width - overlaySize.width -
+      this.scrollPort_.currentScrollbarWidthPx) / 2 + 'px';
+
+  if (this.overlayTimeout_)
+    clearTimeout(this.overlayTimeout_);
+
+  this.accessibilityReader_.assertiveAnnounce(msg);
+
+  if (opt_timeout === null)
+    return;
+
+  this.overlayTimeout_ = setTimeout(() => {
+    this.overlayNode_.style.opacity = '0';
+    this.overlayTimeout_ = setTimeout(() => this.hideOverlay(), 200);
+  }, opt_timeout || 1500);
+};
+
+/**
+ * Hide the terminal overlay immediately.
+ *
+ * Useful when we show an overlay for an event with an unknown end time.
+ */
+hterm.Terminal.prototype.hideOverlay = function() {
+  if (this.overlayTimeout_)
+    clearTimeout(this.overlayTimeout_);
+  this.overlayTimeout_ = null;
+
+  if (this.overlayNode_.parentNode)
+    this.overlayNode_.parentNode.removeChild(this.overlayNode_);
+  this.overlayNode_.style.opacity = '0.75';
+};
+
+/**
+ * Paste from the system clipboard to the terminal.
+ */
+hterm.Terminal.prototype.paste = function() {
+  return hterm.pasteFromClipboard(this.document_);
+};
+
+/**
+ * Copy a string to the system clipboard.
+ *
+ * Note: If there is a selected range in the terminal, it'll be cleared.
+ *
+ * @param {string} str The string to copy.
+ */
+hterm.Terminal.prototype.copyStringToClipboard = function(str) {
+  if (this.prefs_.get('enable-clipboard-notice'))
+    setTimeout(this.showOverlay.bind(this, hterm.notifyCopyMessage, 500), 200);
+
+  hterm.copySelectionToClipboard(this.document_, str);
+};
+
+/**
+ * Display an image.
+ *
+ * Either URI or buffer or blob fields must be specified.
+ *
+ * @param {Object} options The image to display.
+ * @param {string=} options.name A human readable string for the image.
+ * @param {string|number=} options.size The size (in bytes).
+ * @param {boolean=} options.preserveAspectRatio Whether to preserve aspect.
+ * @param {boolean=} options.inline Whether to display the image inline.
+ * @param {string|number=} options.width The width of the image.
+ * @param {string|number=} options.height The height of the image.
+ * @param {string=} options.align Direction to align the image.
+ * @param {string=} options.uri The source URI for the image.
+ * @param {ArrayBuffer=} options.buffer The ArrayBuffer image data.
+ * @param {Blob=} options.blob The Blob image data.
+ * @param {string=} options.type The MIME type of the image data.
+ * @param {function=} onLoad Callback when loading finishes.
+ * @param {function(Event)=} onError Callback when loading fails.
+ */
+hterm.Terminal.prototype.displayImage = function(options, onLoad, onError) {
+  // Make sure we're actually given a resource to display.
+  if (options.uri === undefined && options.buffer === undefined &&
+      options.blob === undefined)
+    return;
+
+  // Set up the defaults to simplify code below.
+  if (!options.name)
+    options.name = '';
+
+  // See if the mime type is available.  If not, guess from the filename.
+  // We don't list all possible mime types because the browser can usually
+  // guess it correctly.  So list the ones that need a bit more help.
+  if (!options.type) {
+    const ary = options.name.split('.');
+    const ext = ary[ary.length - 1].trim();
+    switch (ext) {
+      case 'svg':
+      case 'svgz':
+        options.type = 'image/svg+xml';
+        break;
+    }
+  }
+
+  // Has the user approved image display yet?
+  if (this.allowImagesInline !== true) {
+    this.newLine();
+    const row = this.getRowNode(this.scrollbackRows_.length +
+                                this.getCursorRow() - 1);
+
+    if (this.allowImagesInline === false) {
+      row.textContent = hterm.msg('POPUP_INLINE_IMAGE_DISABLED', [],
+                                  'Inline Images Disabled');
+      return;
+    }
+
+    // Show a prompt.
+    let button;
+    const span = this.document_.createElement('span');
+    span.innerText = hterm.msg('POPUP_INLINE_IMAGE', [], 'Inline Images');
+    span.style.fontWeight = 'bold';
+    span.style.borderWidth = '1px';
+    span.style.borderStyle = 'dashed';
+    button = this.document_.createElement('span');
+    button.innerText = hterm.msg('BUTTON_BLOCK', [], 'block');
+    button.style.marginLeft = '1em';
+    button.style.borderWidth = '1px';
+    button.style.borderStyle = 'solid';
+    button.addEventListener('click', () => {
+      this.prefs_.set('allow-images-inline', false);
+    });
+    span.appendChild(button);
+    button = this.document_.createElement('span');
+    button.innerText = hterm.msg('BUTTON_ALLOW_SESSION', [],
+                                 'allow this session');
+    button.style.marginLeft = '1em';
+    button.style.borderWidth = '1px';
+    button.style.borderStyle = 'solid';
+    button.addEventListener('click', () => {
+      this.allowImagesInline = true;
+    });
+    span.appendChild(button);
+    button = this.document_.createElement('span');
+    button.innerText = hterm.msg('BUTTON_ALLOW_ALWAYS', [], 'always allow');
+    button.style.marginLeft = '1em';
+    button.style.borderWidth = '1px';
+    button.style.borderStyle = 'solid';
+    button.addEventListener('click', () => {
+      this.prefs_.set('allow-images-inline', true);
+    });
+    span.appendChild(button);
+
+    row.appendChild(span);
+    return;
+  }
+
+  // See if we should show this object directly, or download it.
+  if (options.inline) {
+    const io = this.io.push();
+    io.showOverlay(hterm.msg('LOADING_RESOURCE_START', [options.name],
+                             'Loading $1 ...'), null);
+
+    // While we're loading the image, eat all the user's input.
+    io.onVTKeystroke = io.sendString = () => {};
+
+    // Initialize this new image.
+    const img =
+        /** @type {!HTMLImageElement} */ (this.document_.createElement('img'));
+    if (options.uri !== undefined) {
+      img.src = options.uri;
+    } else if (options.buffer !== undefined) {
+      const blob = new Blob([options.buffer], {type: options.type});
+      img.src = URL.createObjectURL(blob);
+    } else {
+      const blob = new Blob([options.blob], {type: options.type});
+      img.src = URL.createObjectURL(options.blob);
+    }
+    img.title = img.alt = options.name;
+
+    // Attach the image to the page to let it load/render.  It won't stay here.
+    // This is needed so it's visible and the DOM can calculate the height.  If
+    // the image is hidden or not in the DOM, the height is always 0.
+    this.document_.body.appendChild(img);
+
+    // Wait for the image to finish loading before we try moving it to the
+    // right place in the terminal.
+    img.onload = () => {
+      // Now that we have the image dimensions, figure out how to show it.
+      img.style.objectFit = options.preserveAspectRatio ? 'scale-down' : 'fill';
+      img.style.maxWidth = `${this.document_.body.clientWidth}px`;
+      img.style.maxHeight = `${this.document_.body.clientHeight}px`;
+
+      // Parse a width/height specification.
+      const parseDim = (dim, maxDim, cssVar) => {
+        if (!dim || dim == 'auto')
+          return '';
+
+        const ary = dim.match(/^([0-9]+)(px|%)?$/);
+        if (ary) {
+          if (ary[2] == '%')
+            return maxDim * parseInt(ary[1]) / 100 + 'px';
+          else if (ary[2] == 'px')
+            return dim;
+          else
+            return `calc(${dim} * var(${cssVar}))`;
+        }
+
+        return '';
+      };
+      img.style.width =
+          parseDim(options.width, this.document_.body.clientWidth,
+                   '--hterm-charsize-width');
+      img.style.height =
+          parseDim(options.height,  this.document_.body.clientHeight,
+                   '--hterm-charsize-height');
+
+      // Figure out how many rows the image occupies, then add that many.
+      // XXX: This count will be inaccurate if the font size changes on us.
+      const padRows = Math.ceil(img.clientHeight /
+                                this.scrollPort_.characterSize.height);
+      for (let i = 0; i < padRows; ++i)
+        this.newLine();
+
+      // Update the max height in case the user shrinks the character size.
+      img.style.maxHeight = `calc(${padRows} * var(--hterm-charsize-height))`;
+
+      // Move the image to the last row.  This way when we scroll up, it doesn't
+      // disappear when the first row gets clipped.  It will disappear when we
+      // scroll down and the last row is clipped ...
+      this.document_.body.removeChild(img);
+      // Create a wrapper node so we can do an absolute in a relative position.
+      // This helps with rounding errors between JS & CSS counts.
+      const div = this.document_.createElement('div');
+      div.style.position = 'relative';
+      div.style.textAlign = options.align;
+      img.style.position = 'absolute';
+      img.style.bottom = 'calc(0px - var(--hterm-charsize-height))';
+      div.appendChild(img);
+      const row = this.getRowNode(this.scrollbackRows_.length +
+                                  this.getCursorRow() - 1);
+      row.appendChild(div);
+
+      // Now that the image has been read, we can revoke the source.
+      if (options.uri === undefined) {
+        URL.revokeObjectURL(img.src);
+      }
+
+      io.hideOverlay();
+      io.pop();
+
+      if (onLoad)
+        onLoad();
+    };
+
+    // If we got a malformed image, give up.
+    img.onerror = (e) => {
+      this.document_.body.removeChild(img);
+      io.showOverlay(hterm.msg('LOADING_RESOURCE_FAILED', [options.name],
+                               'Loading $1 failed'));
+      io.pop();
+
+      if (onError)
+        onError(e);
+    };
+  } else {
+    // We can't use chrome.downloads.download as that requires "downloads"
+    // permissions, and that works only in extensions, not apps.
+    const a = this.document_.createElement('a');
+    if (options.uri !== undefined) {
+      a.href = options.uri;
+    } else if (options.buffer !== undefined) {
+      const blob = new Blob([options.buffer]);
+      a.href = URL.createObjectURL(blob);
+    } else {
+      a.href = URL.createObjectURL(options.blob);
+    }
+    a.download = options.name;
+    this.document_.body.appendChild(a);
+    a.click();
+    a.remove();
+    if (options.uri === undefined) {
+      URL.revokeObjectURL(a.href);
+    }
+  }
+};
+
+/**
+ * Returns the selected text, or null if no text is selected.
+ *
+ * @return {string|null}
+ */
+hterm.Terminal.prototype.getSelectionText = function() {
+  var selection = this.scrollPort_.selection;
+  selection.sync();
+
+  if (selection.isCollapsed)
+    return null;
+
+  // Start offset measures from the beginning of the line.
+  var startOffset = selection.startOffset;
+  var node = selection.startNode;
+
+  // If an x-row isn't selected, |node| will be null.
+  if (!node)
+    return null;
+
+  if (node.nodeName != 'X-ROW') {
+    // If the selection doesn't start on an x-row node, then it must be
+    // somewhere inside the x-row.  Add any characters from previous siblings
+    // into the start offset.
+
+    if (node.nodeName == '#text' && node.parentNode.nodeName == 'SPAN') {
+      // If node is the text node in a styled span, move up to the span node.
+      node = node.parentNode;
+    }
+
+    while (node.previousSibling) {
+      node = node.previousSibling;
+      startOffset += hterm.TextAttributes.nodeWidth(node);
+    }
+  }
+
+  // End offset measures from the end of the line.
+  var endOffset = (hterm.TextAttributes.nodeWidth(selection.endNode) -
+                   selection.endOffset);
+  node = selection.endNode;
+
+  if (node.nodeName != 'X-ROW') {
+    // If the selection doesn't end on an x-row node, then it must be
+    // somewhere inside the x-row.  Add any characters from following siblings
+    // into the end offset.
+
+    if (node.nodeName == '#text' && node.parentNode.nodeName == 'SPAN') {
+      // If node is the text node in a styled span, move up to the span node.
+      node = node.parentNode;
+    }
+
+    while (node.nextSibling) {
+      node = node.nextSibling;
+      endOffset += hterm.TextAttributes.nodeWidth(node);
+    }
+  }
+
+  var rv = this.getRowsText(selection.startRow.rowIndex,
+                            selection.endRow.rowIndex + 1);
+  return lib.wc.substring(rv, startOffset, lib.wc.strWidth(rv) - endOffset);
+};
+
+/**
+ * Copy the current selection to the system clipboard, then clear it after a
+ * short delay.
+ */
+hterm.Terminal.prototype.copySelectionToClipboard = function() {
+  var text = this.getSelectionText();
+  if (text != null)
+    this.copyStringToClipboard(text);
+};
+
+hterm.Terminal.prototype.overlaySize = function() {
+  this.showOverlay(this.screenSize.width + 'x' + this.screenSize.height);
+};
+
+/**
+ * Invoked by hterm.Terminal.Keyboard when a VT keystroke is detected.
+ *
+ * @param {string} string The VT string representing the keystroke, in UTF-16.
+ */
+hterm.Terminal.prototype.onVTKeystroke = function(string) {
+  if (this.scrollOnKeystroke_)
+    this.scrollPort_.scrollRowToBottom(this.getRowCount());
+
+  this.io.onVTKeystroke(string);
+};
+
+/**
+ * Open the selected url.
+ */
+hterm.Terminal.prototype.openSelectedUrl_ = function() {
+  var str = this.getSelectionText();
+
+  // If there is no selection, try and expand wherever they clicked.
+  if (str == null) {
+    this.screen_.expandSelectionForUrl(this.document_.getSelection());
+    str = this.getSelectionText();
+
+    // If clicking in empty space, return.
+    if (str == null)
+      return;
+  }
+
+  // Make sure URL is valid before opening.
+  if (str.length > 2048 || str.search(/[\s\[\](){}<>"'\\^`]/) >= 0)
+    return;
+
+  // If the URI isn't anchored, it'll open relative to the extension.
+  // We have no way of knowing the correct schema, so assume http.
+  if (str.search('^[a-zA-Z][a-zA-Z0-9+.-]*://') < 0) {
+    // We have to whitelist a few protocols that lack authorities and thus
+    // never use the //.  Like mailto.
+    switch (str.split(':', 1)[0]) {
+      case 'mailto':
+        break;
+      default:
+        str = 'http://' + str;
+        break;
+    }
+  }
+
+  hterm.openUrl(str);
+};
+
+/**
+ * Manage the automatic mouse hiding behavior while typing.
+ *
+ * @param {boolean=} v Whether to enable automatic hiding.
+ */
+hterm.Terminal.prototype.setAutomaticMouseHiding = function(v=null) {
+  // Since Chrome OS & macOS do this by default everywhere, we don't need to.
+  // Linux & Windows seem to leave this to specific applications to manage.
+  if (v === null)
+    v = (hterm.os != 'cros' && hterm.os != 'mac');
+
+  this.mouseHideWhileTyping_ = !!v;
+};
+
+/**
+ * Handler for monitoring user keyboard activity.
+ *
+ * This isn't for processing the keystrokes directly, but for updating any
+ * state that might toggle based on the user using the keyboard at all.
+ *
+ * @param {KeyboardEvent} e The keyboard event that triggered us.
+ */
+hterm.Terminal.prototype.onKeyboardActivity_ = function(e) {
+  // When the user starts typing, hide the mouse cursor.
+  if (this.mouseHideWhileTyping_ && !this.mouseHideDelay_)
+    this.setCssVar('mouse-cursor-style', 'none');
+};
+
+/**
+ * Add the terminalRow and terminalColumn properties to mouse events and
+ * then forward on to onMouse().
+ *
+ * The terminalRow and terminalColumn properties contain the (row, column)
+ * coordinates for the mouse event.
+ *
+ * @param {Event} e The mouse event to handle.
+ */
+hterm.Terminal.prototype.onMouse_ = function(e) {
+  if (e.processedByTerminalHandler_) {
+    // We register our event handlers on the document, as well as the cursor
+    // and the scroll blocker.  Mouse events that occur on the cursor or
+    // scroll blocker will also appear on the document, but we don't want to
+    // process them twice.
+    //
+    // We can't just prevent bubbling because that has other side effects, so
+    // we decorate the event object with this property instead.
+    return;
+  }
+
+  // Consume navigation events.  Button 3 is usually "browser back" and
+  // button 4 is "browser forward" which we don't want to happen.
+  if (e.button > 2) {
+    e.preventDefault();
+    // We don't return so click events can be passed to the remote below.
+  }
+
+  var reportMouseEvents = (!this.defeatMouseReports_ &&
+      this.vt.mouseReport != this.vt.MOUSE_REPORT_DISABLED);
+
+  e.processedByTerminalHandler_ = true;
+
+  // Handle auto hiding of mouse cursor while typing.
+  if (this.mouseHideWhileTyping_ && !this.mouseHideDelay_) {
+    // Make sure the mouse cursor is visible.
+    this.syncMouseStyle();
+    // This debounce isn't perfect, but should work well enough for such a
+    // simple implementation.  If the user moved the mouse, we enabled this
+    // debounce, and then moved the mouse just before the timeout, we wouldn't
+    // debounce that later movement.
+    this.mouseHideDelay_ = setTimeout(() => this.mouseHideDelay_ = null, 1000);
+  }
+
+  // One based row/column stored on the mouse event.
+  e.terminalRow = parseInt((e.clientY - this.scrollPort_.visibleRowTopMargin) /
+                           this.scrollPort_.characterSize.height) + 1;
+  e.terminalColumn = parseInt(e.clientX /
+                              this.scrollPort_.characterSize.width) + 1;
+
+  if (e.type == 'mousedown' && e.terminalColumn > this.screenSize.width) {
+    // Mousedown in the scrollbar area.
+    return;
+  }
+
+  if (this.options_.cursorVisible && !reportMouseEvents) {
+    // If the cursor is visible and we're not sending mouse events to the
+    // host app, then we want to hide the terminal cursor when the mouse
+    // cursor is over top.  This keeps the terminal cursor from interfering
+    // with local text selection.
+    if (e.terminalRow - 1 == this.screen_.cursorPosition.row &&
+        e.terminalColumn - 1 == this.screen_.cursorPosition.column) {
+      this.cursorNode_.style.display = 'none';
+    } else if (this.cursorNode_.style.display == 'none') {
+      this.cursorNode_.style.display = '';
+    }
+  }
+
+  if (e.type == 'mousedown') {
+    this.contextMenu.hide(e);
+
+    if (e.altKey || !reportMouseEvents) {
+      // If VT mouse reporting is disabled, or has been defeated with
+      // alt-mousedown, then the mouse will act on the local selection.
+      this.defeatMouseReports_ = true;
+      this.setSelectionEnabled(true);
+    } else {
+      // Otherwise we defer ownership of the mouse to the VT.
+      this.defeatMouseReports_ = false;
+      this.document_.getSelection().collapseToEnd();
+      this.setSelectionEnabled(false);
+      e.preventDefault();
+    }
+  }
+
+  if (!reportMouseEvents) {
+    if (e.type == 'dblclick') {
+      this.screen_.expandSelection(this.document_.getSelection());
+      if (this.copyOnSelect)
+        this.copySelectionToClipboard();
+    }
+
+    if (e.type == 'click' && !e.shiftKey && (e.ctrlKey || e.metaKey)) {
+      // Debounce this event with the dblclick event.  If you try to doubleclick
+      // a URL to open it, Chrome will fire click then dblclick, but we won't
+      // have expanded the selection text at the first click event.
+      clearTimeout(this.timeouts_.openUrl);
+      this.timeouts_.openUrl = setTimeout(this.openSelectedUrl_.bind(this),
+                                          500);
+      return;
+    }
+
+    if (e.type == 'mousedown') {
+      if (e.ctrlKey && e.button == 2 /* right button */) {
+        e.preventDefault();
+        this.contextMenu.show(e, this);
+      } else if (e.button == this.mousePasteButton ||
+          (this.mouseRightClickPaste && e.button == 2 /* right button */)) {
+        if (!this.paste())
+          console.warn('Could not paste manually due to web restrictions');
+      }
+    }
+
+    if (e.type == 'mouseup' && e.button == 0 && this.copyOnSelect &&
+        !this.document_.getSelection().isCollapsed) {
+      this.copySelectionToClipboard();
+    }
+
+    if ((e.type == 'mousemove' || e.type == 'mouseup') &&
+        this.scrollBlockerNode_.engaged) {
+      // Disengage the scroll-blocker after one of these events.
+      this.scrollBlockerNode_.engaged = false;
+      this.scrollBlockerNode_.style.top = '-99px';
+    }
+
+    // Emulate arrow key presses via scroll wheel events.
+    if (this.scrollWheelArrowKeys_ && !e.shiftKey &&
+        this.keyboard.applicationCursor && !this.isPrimaryScreen()) {
+      if (e.type == 'wheel') {
+        const delta = this.scrollPort_.scrollWheelDelta(e);
+
+        // Helper to turn a wheel event delta into a series of key presses.
+        const deltaToArrows = (distance, charSize, arrowPos, arrowNeg) => {
+          if (distance == 0) {
+            return '';
+          }
+
+          // Convert the scroll distance into a number of rows/cols.
+          const cells = lib.f.smartFloorDivide(Math.abs(distance), charSize);
+          const data = '\x1bO' + (distance < 0 ? arrowNeg : arrowPos);
+          return data.repeat(cells);
+        };
+
+        // The order between up/down and left/right doesn't really matter.
+        this.io.sendString(
+            // Up/down arrow keys.
+            deltaToArrows(delta.y, this.scrollPort_.characterSize.height,
+                          'A', 'B') +
+            // Left/right arrow keys.
+            deltaToArrows(delta.x, this.scrollPort_.characterSize.width,
+                          'C', 'D')
+        );
+
+        e.preventDefault();
+      }
+    }
+  } else /* if (this.reportMouseEvents) */ {
+    if (!this.scrollBlockerNode_.engaged) {
+      if (e.type == 'mousedown') {
+        // Move the scroll-blocker into place if we want to keep the scrollport
+        // from scrolling.
+        this.scrollBlockerNode_.engaged = true;
+        this.scrollBlockerNode_.style.top = (e.clientY - 5) + 'px';
+        this.scrollBlockerNode_.style.left = (e.clientX - 5) + 'px';
+      } else if (e.type == 'mousemove') {
+        // Oh.  This means that drag-scroll was disabled AFTER the mouse down,
+        // in which case it's too late to engage the scroll-blocker.
+        this.document_.getSelection().collapseToEnd();
+        e.preventDefault();
+      }
+    }
+
+    this.onMouse(e);
+  }
+
+  if (e.type == 'mouseup' && this.document_.getSelection().isCollapsed) {
+    // Restore this on mouseup in case it was temporarily defeated with a
+    // alt-mousedown.  Only do this when the selection is empty so that
+    // we don't immediately kill the users selection.
+    this.defeatMouseReports_ = false;
+  }
+};
+
+/**
+ * Clients should override this if they care to know about mouse events.
+ *
+ * The event parameter will be a normal DOM mouse click event with additional
+ * 'terminalRow' and 'terminalColumn' properties.
+ *
+ * @param {Event} e The mouse event to handle.
+ */
+hterm.Terminal.prototype.onMouse = function(e) { };
+
+/**
+ * React when focus changes.
+ *
+ * @param {boolean} focused True if focused, false otherwise.
+ */
+hterm.Terminal.prototype.onFocusChange_ = function(focused) {
+  this.cursorNode_.setAttribute('focus', focused);
+  this.restyleCursor_();
+
+  if (this.reportFocus)
+    this.io.sendString(focused === true ? '\x1b[I' : '\x1b[O');
+
+  if (focused === true)
+    this.closeBellNotifications_();
+};
+
+/**
+ * React when the ScrollPort is scrolled.
+ */
+hterm.Terminal.prototype.onScroll_ = function() {
+  this.scheduleSyncCursorPosition_();
+};
+
+/**
+ * React when text is pasted into the scrollPort.
+ *
+ * @param {Event} e The DOM paste event to handle.
+ */
+hterm.Terminal.prototype.onPaste_ = function(e) {
+  var data = e.text.replace(/\n/mg, '\r');
+  if (this.options_.bracketedPaste) {
+    // We strip out most escape sequences as they can cause issues (like
+    // inserting an \x1b[201~ midstream).  We pass through whitespace
+    // though: 0x08:\b 0x09:\t 0x0a:\n 0x0d:\r.
+    // This matches xterm behavior.
+    const filter = (data) => data.replace(/[\x00-\x07\x0b-\x0c\x0e-\x1f]/g, '');
+    data = '\x1b[200~' + filter(data) + '\x1b[201~';
+  }
+
+  this.io.sendString(data);
+};
+
+/**
+ * React when the user tries to copy from the scrollPort.
+ *
+ * @param {Event} e The DOM copy event.
+ */
+hterm.Terminal.prototype.onCopy_ = function(e) {
+  if (!this.useDefaultWindowCopy) {
+    e.preventDefault();
+    setTimeout(this.copySelectionToClipboard.bind(this), 0);
+  }
+};
+
+/**
+ * React when the ScrollPort is resized.
+ *
+ * Note: This function should not directly contain code that alters the internal
+ * state of the terminal.  That kind of code belongs in realizeWidth or
+ * realizeHeight, so that it can be executed synchronously in the case of a
+ * programmatic width change.
+ */
+hterm.Terminal.prototype.onResize_ = function() {
+  var columnCount = Math.floor(this.scrollPort_.getScreenWidth() /
+                               this.scrollPort_.characterSize.width) || 0;
+  var rowCount = lib.f.smartFloorDivide(this.scrollPort_.getScreenHeight(),
+                            this.scrollPort_.characterSize.height) || 0;
+
+  if (columnCount <= 0 || rowCount <= 0) {
+    // We avoid these situations since they happen sometimes when the terminal
+    // gets removed from the document or during the initial load, and we can't
+    // deal with that.
+    // This can also happen if called before the scrollPort calculates the
+    // character size, meaning we dived by 0 above and default to 0 values.
+    return;
+  }
+
+  var isNewSize = (columnCount != this.screenSize.width ||
+                   rowCount != this.screenSize.height);
+
+  // We do this even if the size didn't change, just to be sure everything is
+  // in sync.
+  this.realizeSize_(columnCount, rowCount);
+  this.showZoomWarning_(this.scrollPort_.characterSize.zoomFactor != 1);
+
+  if (isNewSize)
+    this.overlaySize();
+
+  this.restyleCursor_();
+  this.scheduleSyncCursorPosition_();
+};
+
+/**
+ * Service the cursor blink timeout.
+ */
+hterm.Terminal.prototype.onCursorBlink_ = function() {
+  if (!this.options_.cursorBlink) {
+    delete this.timeouts_.cursorBlink;
+    return;
+  }
+
+  if (this.cursorNode_.getAttribute('focus') == 'false' ||
+      this.cursorNode_.style.opacity == '0') {
+    this.cursorNode_.style.opacity = '1';
+    this.timeouts_.cursorBlink = setTimeout(this.myOnCursorBlink_,
+                                            this.cursorBlinkCycle_[0]);
+  } else {
+    this.cursorNode_.style.opacity = '0';
+    this.timeouts_.cursorBlink = setTimeout(this.myOnCursorBlink_,
+                                            this.cursorBlinkCycle_[1]);
+  }
+};
+
+/**
+ * Set the scrollbar-visible mode bit.
+ *
+ * If scrollbar-visible is on, the vertical scrollbar will be visible.
+ * Otherwise it will not.
+ *
+ * Defaults to on.
+ *
+ * @param {boolean} state True to set scrollbar-visible mode, false to unset.
+ */
+hterm.Terminal.prototype.setScrollbarVisible = function(state) {
+  this.scrollPort_.setScrollbarVisible(state);
+};
+
+/**
+ * Set the scroll wheel move multiplier.  This will affect how fast the page
+ * scrolls on wheel events.
+ *
+ * Defaults to 1.
+ *
+ * @param {number} multiplier The multiplier to set.
+ */
+hterm.Terminal.prototype.setScrollWheelMoveMultipler = function(multiplier) {
+  this.scrollPort_.setScrollWheelMoveMultipler(multiplier);
+};
+
+/**
+ * Close all web notifications created by terminal bells.
+ */
+hterm.Terminal.prototype.closeBellNotifications_ = function() {
+  this.bellNotificationList_.forEach(function(n) {
+      n.close();
+    });
+  this.bellNotificationList_.length = 0;
+};
+
+/**
+ * Syncs the cursor position when the scrollport gains focus.
+ */
+hterm.Terminal.prototype.onScrollportFocus_ = function() {
+  // If the cursor is offscreen we set selection to the last row on the screen.
+  const topRowIndex = this.scrollPort_.getTopRowIndex();
+  const bottomRowIndex = this.scrollPort_.getBottomRowIndex(topRowIndex);
+  const selection = this.document_.getSelection();
+  if (!this.syncCursorPosition_() && selection) {
+    selection.collapse(this.getRowNode(bottomRowIndex));
+  }
+};
+// SOURCE FILE: hterm/js/hterm_terminal_io.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Input/Output interface used by commands to communicate with the terminal.
+ *
+ * Commands like `nassh` and `crosh` receive an instance of this class as
+ * part of their argv object.  This allows them to write to and read from the
+ * terminal without exposing them to an entire hterm.Terminal instance.
+ *
+ * The active command must override the onVTKeystroke() and sendString() methods
+ * of this class in order to receive keystrokes and send output to the correct
+ * destination.
+ *
+ * Isolating commands from the terminal provides the following benefits:
+ * - Provides a mechanism to save and restore onVTKeystroke and sendString
+ *   handlers when invoking subcommands (see the push() and pop() methods).
+ * - The isolation makes it easier to make changes in Terminal and supporting
+ *   classes without affecting commands.
+ * - In The Future commands may run in web workers where they would only be able
+ *   to talk to a Terminal instance through an IPC mechanism.
+ *
+ * @param {hterm.Terminal}
+ */
+hterm.Terminal.IO = function(terminal) {
+  this.terminal_ = terminal;
+
+  // The IO object to restore on IO.pop().
+  this.previousIO_ = null;
+
+  // Any data this object accumulated while not active.
+  this.buffered_ = '';
+
+  // Decoder to maintain UTF-8 decode state.
+  this.textDecoder_ = new TextDecoder();
+};
+
+/**
+ * Show the terminal overlay for a given amount of time.
+ *
+ * The terminal overlay appears in inverse video in a large font, centered
+ * over the terminal.  You should probably keep the overlay message brief,
+ * since it's in a large font and you probably aren't going to check the size
+ * of the terminal first.
+ *
+ * @param {string} msg The text (not HTML) message to display in the overlay.
+ * @param {number} opt_timeout The amount of time to wait before fading out
+ *     the overlay.  Defaults to 1.5 seconds.  Pass null to have the overlay
+ *     stay up forever (or until the next overlay).
+ */
+hterm.Terminal.IO.prototype.showOverlay = function(message, opt_timeout) {
+  this.terminal_.showOverlay(message, opt_timeout);
+};
+
+/**
+ * Hide the current overlay immediately.
+ *
+ * Useful when we show an overlay for an event with an unknown end time.
+ */
+hterm.Terminal.IO.prototype.hideOverlay = function() {
+  this.terminal_.hideOverlay();
+};
+
+/**
+ * Open an frame in the current terminal window, pointed to the specified
+ * url.
+ *
+ * Eventually we'll probably need size/position/decoration options.
+ * The user should also be able to move/resize the frame.
+ *
+ * @param {string} url The URL to load in the frame.
+ * @param {Object} opt_options Optional frame options.  Not implemented.
+ */
+hterm.Terminal.IO.prototype.createFrame = function(url, opt_options) {
+  return new hterm.Frame(this.terminal_, url, opt_options);
+};
+
+/**
+ * Change the preference profile for the terminal.
+ *
+ * @param profileName {string} The name of the preference profile to activate.
+ */
+hterm.Terminal.IO.prototype.setTerminalProfile = function(profileName) {
+  this.terminal_.setProfile(profileName);
+};
+
+/**
+ * Create a new hterm.Terminal.IO instance and make it active on the Terminal
+ * object associated with this instance.
+ *
+ * This is used to pass control of the terminal IO off to a subcommand.  The
+ * IO.pop() method can be used to restore control when the subcommand completes.
+ */
+hterm.Terminal.IO.prototype.push = function() {
+  var io = new hterm.Terminal.IO(this.terminal_);
+  io.keyboardCaptured_ = this.keyboardCaptured_;
+
+  io.columnCount = this.columnCount;
+  io.rowCount = this.rowCount;
+
+  io.previousIO_ = this.terminal_.io;
+  this.terminal_.io = io;
+
+  return io;
+};
+
+/**
+ * Restore the Terminal's previous IO object.
+ *
+ * We'll flush out any queued data.
+ */
+hterm.Terminal.IO.prototype.pop = function() {
+  this.terminal_.io = this.previousIO_;
+  this.previousIO_.flush();
+};
+
+/**
+ * Flush accumulated data.
+ *
+ * If we're not the active IO, the connected process might still be writing
+ * data to us, but we won't be displaying it.  Flush any buffered data now.
+ */
+hterm.Terminal.IO.prototype.flush = function() {
+  if (this.buffered_) {
+    this.terminal_.interpret(this.buffered_);
+    this.buffered_ = '';
+  }
+};
+
+/**
+ * Called when data needs to be sent to the current command.
+ *
+ * Clients should override this to receive notification of pending data.
+ *
+ * @param {string} string The data to send.
+ */
+hterm.Terminal.IO.prototype.sendString = function(string) {
+  // Override this.
+  console.log('Unhandled sendString: ' + string);
+};
+
+/**
+ * Called when a terminal keystroke is detected.
+ *
+ * Clients should override this to receive notification of keystrokes.
+ *
+ * @param {string} string The VT key sequence.
+ */
+hterm.Terminal.IO.prototype.onVTKeystroke = function(string) {
+  // Override this.
+  console.log('Unobserverd VT keystroke: ' + JSON.stringify(string));
+};
+
+hterm.Terminal.IO.prototype.onTerminalResize_ = function(width, height) {
+  var obj = this;
+  while (obj) {
+    obj.columnCount = width;
+    obj.rowCount = height;
+    obj = obj.previousIO_;
+  }
+
+  this.onTerminalResize(width, height);
+};
+
+/**
+ * Called when terminal size is changed.
+ *
+ * Clients should override this to receive notification of resize.
+ *
+ * @param {string|integer} terminal width.
+ * @param {string|integer} terminal height.
+ */
+hterm.Terminal.IO.prototype.onTerminalResize = function(width, height) {
+  // Override this.
+};
+
+/**
+ * Write a UTF-8 encoded byte string to the terminal.
+ *
+ * @param {string} string The UTF-8 encoded string to print.
+ */
+hterm.Terminal.IO.prototype.writeUTF8 = function(string) {
+  // We can't use instanceof here on string to see if it's an ArrayBuffer as it
+  // might be constructed in a different runtime context whose ArrayBuffer was
+  // not the same.  See https://crbug.com/930171#5 for more details.
+  if (typeof string == 'string') {
+    if (this.terminal_.characterEncoding != 'raw') {
+      const bytes = lib.codec.stringToCodeUnitArray(string, Uint8Array);
+      string = this.textDecoder_.decode(bytes, {stream: true});
+    }
+  } else {
+    // Handle array buffers & typed arrays by normalizing into a typed array.
+    const u8 = new Uint8Array(string);
+    if (this.terminal_.characterEncoding == 'raw') {
+      string = lib.codec.codeUnitArrayToString(u8);
+    } else {
+      string = this.textDecoder_.decode(u8, {stream: true});
+    }
+  }
+
+  this.print(string);
+};
+
+/**
+ * Write a UTF-8 encoded byte string to the terminal followed by crlf.
+ *
+ * @param {string} string The UTF-8 encoded string to print.
+ */
+hterm.Terminal.IO.prototype.writelnUTF8 = function(string) {
+  this.writeUTF8(string);
+  // We need to use writeUTF8 to make sure we flush the decoder state.
+  this.writeUTF8('\r\n');
+};
+
+/**
+ * Write a UTF-16 JavaScript string to the terminal.
+ *
+ * @param {string} string The string to print.
+ */
+hterm.Terminal.IO.prototype.print =
+hterm.Terminal.IO.prototype.writeUTF16 = function(string) {
+  // If another process has the foreground IO, buffer new data sent to this IO
+  // (since it's in the background).  When we're made the foreground IO again,
+  // we'll flush everything.
+  if (this.terminal_.io != this) {
+    this.buffered_ += string;
+    return;
+  }
+
+  this.terminal_.interpret(string);
+};
+
+/**
+ * Print a UTF-16 JavaScript string to the terminal followed by a newline.
+ *
+ * @param {string} string The string to print.
+ */
+hterm.Terminal.IO.prototype.println =
+hterm.Terminal.IO.prototype.writelnUTF16 = function(string) {
+  this.print(string + '\r\n');
+};
+// SOURCE FILE: hterm/js/hterm_text_attributes.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Constructor for TextAttribute objects.
+ *
+ * These objects manage a set of text attributes such as foreground/
+ * background color, bold, faint, italic, blink, underline, and strikethrough.
+ *
+ * TextAttribute instances can be used to construct a DOM container implementing
+ * the current attributes, or to test an existing DOM container for
+ * compatibility with the current attributes.
+ *
+ * @constructor
+ * @param {HTMLDocument} document The parent document to use when creating
+ *     new DOM containers.
+ */
+hterm.TextAttributes = function(document) {
+  this.document_ = document;
+  // These variables contain the source of the color as either:
+  // SRC_DEFAULT  (use context default)
+  // rgb(...)     (true color form)
+  // number       (representing the index from color palette to use)
+  this.foregroundSource = this.SRC_DEFAULT;
+  this.backgroundSource = this.SRC_DEFAULT;
+  this.underlineSource = this.SRC_DEFAULT;
+
+  // These properties cache the value in the color table, but foregroundSource
+  // and backgroundSource contain the canonical values.
+  this.foreground = this.DEFAULT_COLOR;
+  this.background = this.DEFAULT_COLOR;
+  this.underlineColor = this.DEFAULT_COLOR;
+
+  this.defaultForeground = 'rgb(255, 255, 255)';
+  this.defaultBackground = 'rgb(0, 0, 0)';
+
+  // Any attributes added here that do not default to falsey (e.g. undefined or
+  // null) require a bit more care.  createContainer has to always attach the
+  // attribute so matchesContainer can work correctly.
+  this.bold = false;
+  this.faint = false;
+  this.italic = false;
+  this.blink = false;
+  this.underline = false;
+  this.strikethrough = false;
+  this.inverse = false;
+  this.invisible = false;
+  this.wcNode = false;
+  this.asciiNode = true;
+  this.tileData = null;
+  this.uri = null;
+  this.uriId = null;
+
+  this.colorPalette = null;
+  this.resetColorPalette();
+};
+
+/**
+ * If false, we ignore the bold attribute.
+ *
+ * This is used for fonts that have a bold version that is a different size
+ * than the normal weight version.
+ */
+hterm.TextAttributes.prototype.enableBold = true;
+
+/**
+ * If true, use bright colors (if available) for bold text.
+ *
+ * This setting is independent of the enableBold setting.
+ */
+hterm.TextAttributes.prototype.enableBoldAsBright = true;
+
+/**
+ * A sentinel constant meaning "whatever the default color is in this context".
+ */
+hterm.TextAttributes.prototype.DEFAULT_COLOR = Symbol('DEFAULT_COLOR');
+
+/**
+ * A constant string used to specify that source color is context default.
+ */
+hterm.TextAttributes.prototype.SRC_DEFAULT = Symbol('SRC_DEFAULT');
+
+/**
+ * The document object which should own the DOM nodes created by this instance.
+ *
+ * @param {HTMLDocument} document The parent document.
+ */
+hterm.TextAttributes.prototype.setDocument = function(document) {
+  this.document_ = document;
+};
+
+/**
+ * Create a deep copy of this object.
+ *
+ * @return {hterm.TextAttributes} A deep copy of this object.
+ */
+hterm.TextAttributes.prototype.clone = function() {
+  var rv = new hterm.TextAttributes(null);
+
+  for (var key in this) {
+    rv[key] = this[key];
+  }
+
+  rv.colorPalette = this.colorPalette.concat();
+  return rv;
+};
+
+/**
+ * Reset the current set of attributes.
+ *
+ * This does not affect the palette.  Use resetColorPalette() for that.
+ * It also doesn't affect the tile data, it's not meant to.
+ */
+hterm.TextAttributes.prototype.reset = function() {
+  this.foregroundSource = this.SRC_DEFAULT;
+  this.backgroundSource = this.SRC_DEFAULT;
+  this.underlineSource = this.SRC_DEFAULT;
+  this.foreground = this.DEFAULT_COLOR;
+  this.background = this.DEFAULT_COLOR;
+  this.underlineColor = this.DEFAULT_COLOR;
+  this.bold = false;
+  this.faint = false;
+  this.italic = false;
+  this.blink = false;
+  this.underline = false;
+  this.strikethrough = false;
+  this.inverse = false;
+  this.invisible = false;
+  this.wcNode = false;
+  this.asciiNode = true;
+  this.uri = null;
+  this.uriId = null;
+};
+
+/**
+ * Reset the color palette to the default state.
+ */
+hterm.TextAttributes.prototype.resetColorPalette = function() {
+  this.colorPalette = lib.colors.colorPalette.concat();
+  this.syncColors();
+};
+
+/**
+ * Reset the color.
+ *
+ * @param {integer|string} index The color index in the palette to reset.
+ */
+hterm.TextAttributes.prototype.resetColor = function(index) {
+  index = parseInt(index, 10);
+  if (isNaN(index) || index >= this.colorPalette.length)
+    return;
+
+  this.colorPalette[index] = lib.colors.stockColorPalette[index];
+  this.syncColors();
+};
+
+/**
+ * Test if the current attributes describe unstyled text.
+ *
+ * @return {boolean} True if the current attributes describe unstyled text.
+ */
+hterm.TextAttributes.prototype.isDefault = function() {
+  return (this.foregroundSource == this.SRC_DEFAULT &&
+          this.backgroundSource == this.SRC_DEFAULT &&
+          !this.bold &&
+          !this.faint &&
+          !this.italic &&
+          !this.blink &&
+          !this.underline &&
+          !this.strikethrough &&
+          !this.inverse &&
+          !this.invisible &&
+          !this.wcNode &&
+          this.asciiNode &&
+          this.tileData == null &&
+          this.uri == null);
+};
+
+/**
+ * Create a DOM container (a span or a text node) with a style to match the
+ * current set of attributes.
+ *
+ * This method will create a plain text node if the text is unstyled, or
+ * an HTML span if the text is styled.  Due to lack of monospace wide character
+ * fonts on certain systems (e.g. Chrome OS), we need to put each wide character
+ * in a span of CSS class '.wc-node' which has double column width.
+ * Each vt_tiledata tile is also represented by a span with a single
+ * character, with CSS classes '.tile' and '.tile_<glyph number>'.
+ *
+ * @param {string} opt_textContent Optional text content for the new container.
+ * @return {HTMLNode} An HTML span or text nodes styled to match the current
+ *     attributes.
+ */
+hterm.TextAttributes.prototype.createContainer = function(opt_textContent) {
+  if (this.isDefault()) {
+    // Only attach attributes where we need an explicit default for the
+    // matchContainer logic below.
+    const node = this.document_.createTextNode(opt_textContent);
+    node.asciiNode = true;
+    return node;
+  }
+
+  var span = this.document_.createElement('span');
+  var style = span.style;
+  var classes = [];
+
+  if (this.foreground != this.DEFAULT_COLOR)
+    style.color = this.foreground;
+
+  if (this.background != this.DEFAULT_COLOR)
+    style.backgroundColor = this.background;
+
+  if (this.enableBold && this.bold)
+    style.fontWeight = 'bold';
+
+  if (this.faint)
+    span.faint = true;
+
+  if (this.italic)
+    style.fontStyle = 'italic';
+
+  if (this.blink) {
+    classes.push('blink-node');
+    span.blinkNode = true;
+  }
+
+  let textDecorationLine = '';
+  span.underline = this.underline;
+  if (this.underline) {
+    textDecorationLine += ' underline';
+    style.textDecorationStyle = this.underline;
+  }
+  if (this.underlineColor != this.DEFAULT_COLOR)
+    style.textDecorationColor = this.underlineColor;
+  if (this.strikethrough) {
+    textDecorationLine += ' line-through';
+    span.strikethrough = true;
+  }
+  if (textDecorationLine)
+    style.textDecorationLine = textDecorationLine;
+
+  if (this.wcNode) {
+    classes.push('wc-node');
+    span.wcNode = true;
+  }
+  span.asciiNode = this.asciiNode;
+
+  if (this.tileData != null) {
+    classes.push('tile');
+    classes.push('tile_' + this.tileData);
+    span.tileNode = true;
+  }
+
+  if (opt_textContent)
+    span.textContent = opt_textContent;
+
+  if (this.uri) {
+    classes.push('uri-node');
+    span.uriId = this.uriId;
+    span.title = this.uri;
+    span.addEventListener('click', hterm.openUrl.bind(this, this.uri));
+  }
+
+  if (classes.length)
+    span.className = classes.join(' ');
+
+  return span;
+};
+
+/**
+ * Tests if the provided object (string, span or text node) has the same
+ * style as this TextAttributes instance.
+ *
+ * This indicates that text with these attributes could be inserted directly
+ * into the target DOM node.
+ *
+ * For the purposes of this method, a string is considered a text node.
+ *
+ * @param {string|HTMLNode} obj The object to test.
+ * @return {boolean} True if the provided container has the same style as
+ *     this attributes instance.
+ */
+hterm.TextAttributes.prototype.matchesContainer = function(obj) {
+  if (typeof obj == 'string' || obj.nodeType == Node.TEXT_NODE)
+    return this.isDefault();
+
+  var style = obj.style;
+
+  // We don't want to put multiple characters in a wcNode or a tile.
+  // See the comments in createContainer.
+  // For attributes that default to false, we do not require that obj have them
+  // declared, so always normalize them using !! (to turn undefined into false)
+  // in the compares below.
+  return (!(this.wcNode || obj.wcNode) &&
+          this.asciiNode == obj.asciiNode &&
+          !(this.tileData != null || obj.tileNode) &&
+          this.uriId == obj.uriId &&
+          (this.foreground == this.DEFAULT_COLOR &&
+           style.color == '') &&
+          (this.background == this.DEFAULT_COLOR &&
+           style.backgroundColor == '') &&
+          (this.underlineColor == this.DEFAULT_COLOR &&
+           style.textDecorationColor == '') &&
+          (this.enableBold && this.bold) == !!style.fontWeight &&
+          this.blink == !!obj.blinkNode &&
+          this.italic == !!style.fontStyle &&
+          this.underline == obj.underline &&
+          !!this.strikethrough == !!obj.strikethrough);
+};
+
+hterm.TextAttributes.prototype.setDefaults = function(foreground, background) {
+  this.defaultForeground = foreground;
+  this.defaultBackground = background;
+
+  this.syncColors();
+};
+
+/**
+ * Updates foreground and background properties based on current indices and
+ * other state.
+ *
+ * @param {string} terminalForeground The terminal foreground color for use as
+ *     inverse text background.
+ * @param {string} terminalBackground The terminal background color for use as
+ *     inverse text foreground.
+ *
+ */
+hterm.TextAttributes.prototype.syncColors = function() {
+  function getBrightIndex(i) {
+    if (i < 8) {
+      // If the color is from the lower half of the ANSI 16, add 8.
+      return i + 8;
+    }
+
+    // If it's not from the 16 color palette, ignore bold requests.  This
+    // matches the behavior of gnome-terminal.
+    return i;
+  }
+
+  // Expand the default color as makes sense.
+  const getDefaultColor = (color, defaultColor) => {
+    return color == this.DEFAULT_COLOR ? defaultColor : color;
+  };
+
+  var foregroundSource = this.foregroundSource;
+  var backgroundSource = this.backgroundSource;
+
+  if (this.enableBoldAsBright && this.bold) {
+    if (Number.isInteger(foregroundSource)) {
+      foregroundSource = getBrightIndex(foregroundSource);
+    }
+  }
+
+  if (foregroundSource == this.SRC_DEFAULT)
+    this.foreground = this.DEFAULT_COLOR;
+  else if (Number.isInteger(foregroundSource))
+    this.foreground = this.colorPalette[foregroundSource];
+  else
+    this.foreground = foregroundSource;
+
+  if (this.faint) {
+    const colorToMakeFaint =
+        getDefaultColor(this.foreground, this.defaultForeground);
+    this.foreground = lib.colors.mix(colorToMakeFaint, 'rgb(0, 0, 0)', 0.3333);
+  }
+
+  if (backgroundSource == this.SRC_DEFAULT)
+    this.background = this.DEFAULT_COLOR;
+  else if (Number.isInteger(backgroundSource))
+    this.background = this.colorPalette[backgroundSource];
+  else
+    this.background = backgroundSource;
+
+  // Once we've processed the bold-as-bright and faint attributes, swap.
+  // This matches xterm/gnome-terminal.
+  if (this.inverse) {
+    const swp = getDefaultColor(this.foreground, this.defaultForeground);
+    this.foreground = getDefaultColor(this.background, this.defaultBackground);
+    this.background = swp;
+  }
+
+  // Process invisible settings last to keep it simple.
+  if (this.invisible)
+    this.foreground = this.background;
+
+  if (this.underlineSource == this.SRC_DEFAULT)
+    this.underlineColor = this.DEFAULT_COLOR;
+  else if (Number.isInteger(this.underlineSource))
+    this.underlineColor = this.colorPalette[this.underlineSource];
+  else
+    this.underlineColor = this.underlineSource;
+};
+
+/**
+ * Static method used to test if the provided objects (strings, spans or
+ * text nodes) have the same style.
+ *
+ * For the purposes of this method, a string is considered a text node.
+ *
+ * @param {string|HTMLNode} obj1 An object to test.
+ * @param {string|HTMLNode} obj2 Another object to test.
+ * @return {boolean} True if the containers have the same style.
+ */
+hterm.TextAttributes.containersMatch = function(obj1, obj2) {
+  if (typeof obj1 == 'string')
+    return hterm.TextAttributes.containerIsDefault(obj2);
+
+  if (obj1.nodeType != obj2.nodeType)
+    return false;
+
+  if (obj1.nodeType == Node.TEXT_NODE)
+    return true;
+
+  var style1 = obj1.style;
+  var style2 = obj2.style;
+
+  return (style1.color == style2.color &&
+          style1.backgroundColor == style2.backgroundColor &&
+          style1.backgroundColor == style2.backgroundColor &&
+          style1.fontWeight == style2.fontWeight &&
+          style1.fontStyle == style2.fontStyle &&
+          style1.textDecoration == style2.textDecoration &&
+          style1.textDecorationColor == style2.textDecorationColor &&
+          style1.textDecorationStyle == style2.textDecorationStyle &&
+          style1.textDecorationLine == style2.textDecorationLine);
+};
+
+/**
+ * Static method to test if a given DOM container represents unstyled text.
+ *
+ * For the purposes of this method, a string is considered a text node.
+ *
+ * @param {string|HTMLNode} obj1 An object to test.
+ * @return {boolean} True if the object is unstyled.
+ */
+hterm.TextAttributes.containerIsDefault = function(obj) {
+  return typeof obj == 'string'  || obj.nodeType == Node.TEXT_NODE;
+};
+
+/**
+ * Static method to get the column width of a node's textContent.
+ *
+ * @param {HTMLElement} node The HTML element to get the width of textContent
+ *     from.
+ * @return {integer} The column width of the node's textContent.
+ */
+hterm.TextAttributes.nodeWidth = function(node) {
+  if (!node.asciiNode) {
+    return lib.wc.strWidth(node.textContent);
+  } else {
+    return node.textContent.length;
+  }
+};
+
+/**
+ * Static method to get the substr of a node's textContent.  The start index
+ * and substr width are computed in column width.
+ *
+ * @param {HTMLElement} node The HTML element to get the substr of textContent
+ *     from.
+ * @param {integer} start The starting offset in column width.
+ * @param {integer} width The width to capture in column width.
+ * @return {integer} The extracted substr of the node's textContent.
+ */
+hterm.TextAttributes.nodeSubstr = function(node, start, width) {
+  if (!node.asciiNode) {
+    return lib.wc.substr(node.textContent, start, width);
+  } else {
+    return node.textContent.substr(start, width);
+  }
+};
+
+/**
+ * Static method to get the substring based of a node's textContent.  The
+ * start index of end index are computed in column width.
+ *
+ * @param {HTMLElement} node The HTML element to get the substr of textContent
+ *     from.
+ * @param {integer} start The starting offset in column width.
+ * @param {integer} end The ending offset in column width.
+ * @return {integer} The extracted substring of the node's textContent.
+ */
+hterm.TextAttributes.nodeSubstring = function(node, start, end) {
+  if (!node.asciiNode) {
+    return lib.wc.substring(node.textContent, start, end);
+  } else {
+    return node.textContent.substring(start, end);
+  }
+};
+
+/**
+ * Static method to split a string into contiguous runs of single-width
+ * characters and runs of double-width characters.
+ *
+ * @param {string} str The string to split.
+ * @return {Array} An array of objects that contain substrings of str, where
+ *     each substring is either a contiguous runs of single-width characters
+ *     or a double-width character.  For objects that contain a double-width
+ *     character, its wcNode property is set to true.  For objects that contain
+ *     only ASCII content, its asciiNode property is set to true.
+ */
+hterm.TextAttributes.splitWidecharString = function(str) {
+  const asciiRegex = new RegExp('^[\u0020-\u007f]*$');
+
+  // Optimize for printable ASCII.  This should only take ~1ms/MB, but cuts out
+  // 40ms+/MB when true.  If we're dealing with UTF8, then it's already slow.
+  if (asciiRegex.test(str)) {
+    return [{
+      str: str,
+      wcNode: false,
+      asciiNode: true,
+      wcStrWidth: str.length,
+    }];
+  }
+
+  // Iterate over each grapheme and merge them together in runs of similar
+  // strings.  We want to keep narrow and wide characters separate, and the
+  // fewer overall segments we have, the faster we'll be as processing each
+  // segment in the terminal print code is a bit slow.
+  const segmenter = new Intl.Segmenter(undefined, {type: 'grapheme'});
+  const it = segmenter.segment(str);
+
+  const rv = [];
+  let segment = it.next();
+  while (!segment.done) {
+    const grapheme = segment.value.segment;
+    const isAscii = asciiRegex.test(grapheme);
+    const strWidth = isAscii ? 1 : lib.wc.strWidth(grapheme);
+    const isWideChar =
+        isAscii ? false : (lib.wc.charWidth(grapheme.codePointAt(0)) == 2);
+
+    // Only merge non-wide characters together.  Every wide character needs to
+    // be separate so it can get a unique container.
+    const prev = rv[rv.length - 1];
+    if (prev && !isWideChar && !prev.wcNode) {
+      prev.str += grapheme;
+      prev.wcStrWidth += strWidth;
+      prev.asciiNode = prev.asciiNode && isAscii;
+    } else {
+      rv.push({
+        str: grapheme,
+        wcNode: isWideChar,
+        asciiNode: isAscii,
+        wcStrWidth: strWidth,
+      });
+    }
+
+    segment = it.next();
+  }
+
+  return rv;
+};
+// SOURCE FILE: hterm/js/hterm_vt.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Constructor for the VT escape sequence interpreter.
+ *
+ * The interpreter operates on a terminal object capable of performing cursor
+ * move operations, painting characters, etc.
+ *
+ * This interpreter is intended to be compatible with xterm, though it
+ * ignores some of the more esoteric escape sequences.
+ *
+ * Control sequences are documented in hterm/doc/ControlSequences.md.
+ *
+ * @param {hterm.Terminal} terminal Terminal to use with the interpreter.
+ */
+hterm.VT = function(terminal) {
+  /**
+   * The display terminal object associated with this virtual terminal.
+   */
+  this.terminal = terminal;
+
+  terminal.onMouse = this.onTerminalMouse_.bind(this);
+  this.mouseReport = this.MOUSE_REPORT_DISABLED;
+  this.mouseCoordinates = this.MOUSE_COORDINATES_X10;
+
+  // We only want to report mouse moves between cells, not between pixels.
+  this.lastMouseDragResponse_ = null;
+
+  // Parse state left over from the last parse.  You should use the parseState
+  // instance passed into your parse routine, rather than reading
+  // this.parseState_ directly.
+  this.parseState_ = new hterm.VT.ParseState(this.parseUnknown_);
+
+  // Any "leading modifiers" for the escape sequence, such as '?', ' ', or the
+  // other modifiers handled in this.parseCSI_.
+  this.leadingModifier_ = '';
+
+  // Any "trailing modifiers".  Same character set as a leading modifier,
+  // except these are found after the numeric arguments.
+  this.trailingModifier_ = '';
+
+  // Whether or not to respect the escape codes for setting terminal width.
+  this.allowColumnWidthChanges_ = false;
+
+  // The amount of time we're willing to wait for the end of an OSC sequence.
+  this.oscTimeLimit_ = 20000;
+
+  /**
+   * Whether to accept the 8-bit control characters.
+   *
+   * An 8-bit control character is one with the eighth bit set.  These
+   * didn't work on 7-bit terminals so they all have two byte equivalents.
+   * Most hosts still only use the two-byte versions.
+   *
+   * We ignore 8-bit control codes by default.  This is in order to avoid
+   * issues with "accidental" usage of codes that need to be terminated.
+   * The "accident" usually involves cat'ing binary data.
+   */
+  this.enable8BitControl = false;
+
+  /**
+   * Whether to allow the OSC 52 sequence to write to the system clipboard.
+   */
+  this.enableClipboardWrite = true;
+
+  /**
+   * Respect the host's attempt to change the cursor blink status using
+   * the DEC Private mode 12.
+   */
+  this.enableDec12 = false;
+
+  /**
+   * Respect the host's attempt to clear the scrollback buffer using CSI-J-3.
+   */
+  this.enableCsiJ3 = true;
+
+  /**
+   * The expected encoding method for data received from the host.
+   */
+  this.characterEncoding = 'utf-8';
+
+  /**
+   * If true, emit warnings when we encounter a control character or escape
+   * sequence that we don't recognize or explicitly ignore.
+   *
+   * We disable this by default as the console logging can be expensive when
+   * dumping binary files (e.g. `cat /dev/zero`) to the point where you can't
+   * recover w/out restarting.
+   */
+  this.warnUnimplemented = false;
+
+  /**
+   * The set of available character maps (used by G0...G3 below).
+   */
+  this.characterMaps = new hterm.VT.CharacterMaps();
+
+  /**
+   * The default G0...G3 character maps.
+   * We default to the US/ASCII map everywhere as that aligns with other
+   * terminals, and it makes it harder to accidentally switch to the graphics
+   * character map (Ctrl-N).  Any program that wants to use the graphics map
+   * will usually select it anyways since there's no guarantee what state any
+   * of the maps are in at any particular time.
+   */
+  this.G0 = this.G1 = this.G2 = this.G3 =
+      this.characterMaps.getMap('B');
+
+  /**
+   * The 7-bit visible character set.
+   *
+   * This is a mapping from inbound data to display glyph.  The GL set
+   * contains the 94 bytes from 0x21 to 0x7e.
+   *
+   * The default GL set is 'B', US ASCII.
+   */
+  this.GL = 'G0';
+
+  /**
+   * The 8-bit visible character set.
+   *
+   * This is a mapping from inbound data to display glyph.  The GR set
+   * contains the 94 bytes from 0xa1 to 0xfe.
+   */
+  this.GR = 'G0';
+
+  /**
+   * The current encoding of the terminal.
+   *
+   * We only support ECMA-35 and UTF-8, so go with a boolean here.
+   * The encoding can be locked too.
+   */
+  this.codingSystemUtf8_ = false;
+  this.codingSystemLocked_ = false;
+
+  // Construct a regular expression to match the known one-byte control chars.
+  // This is used in parseUnknown_ to quickly scan a string for the next
+  // control character.
+  this.cc1Pattern_ = null;
+  this.updateEncodingState_();
+};
+
+/**
+ * No mouse events.
+ */
+hterm.VT.prototype.MOUSE_REPORT_DISABLED = 0;
+
+/**
+ * DECSET mode 9.
+ *
+ * Report mouse down events only.
+ */
+hterm.VT.prototype.MOUSE_REPORT_PRESS = 1;
+
+/**
+ * DECSET mode 1000.
+ *
+ * Report mouse down/up events only.
+ */
+hterm.VT.prototype.MOUSE_REPORT_CLICK = 2;
+
+/**
+ * DECSET mode 1002.
+ *
+ * Report mouse down/up and movement while a button is down.
+ */
+hterm.VT.prototype.MOUSE_REPORT_DRAG = 3;
+
+/**
+ * DEC mode for X10 coorindates (the default).
+ */
+hterm.VT.prototype.MOUSE_COORDINATES_X10 = 0;
+
+/**
+ * DEC mode 1005 for UTF-8 coorindates.
+ */
+hterm.VT.prototype.MOUSE_COORDINATES_UTF8 = 1;
+
+/**
+ * DEC mode 1006 for SGR coorindates.
+ */
+hterm.VT.prototype.MOUSE_COORDINATES_SGR = 2;
+
+/**
+ * ParseState constructor.
+ *
+ * This object tracks the current state of the parse.  It has fields for the
+ * current buffer, position in the buffer, and the parse function.
+ *
+ * @param {function} defaultFunc The default parser function.
+ * @param {string} opt_buf Optional string to use as the current buffer.
+ */
+hterm.VT.ParseState = function(defaultFunction, opt_buf) {
+  this.defaultFunction = defaultFunction;
+  this.buf = opt_buf || null;
+  this.pos = 0;
+  this.func = defaultFunction;
+  this.args = [];
+  // Whether any of the arguments in the args array have subarguments.
+  // e.g. All CSI sequences are integer arguments separated by semi-colons,
+  // so subarguments are further colon separated.
+  this.subargs = null;
+};
+
+/**
+ * Reset the parser function, buffer, and position.
+ */
+hterm.VT.ParseState.prototype.reset = function(opt_buf) {
+  this.resetParseFunction();
+  this.resetBuf(opt_buf || '');
+  this.resetArguments();
+};
+
+/**
+ * Reset the parser function only.
+ */
+hterm.VT.ParseState.prototype.resetParseFunction = function() {
+  this.func = this.defaultFunction;
+};
+
+/**
+ * Reset the buffer and position only.
+ *
+ * @param {string} buf Optional new value for buf, defaults to null.
+ */
+hterm.VT.ParseState.prototype.resetBuf = function(opt_buf) {
+  this.buf = (typeof opt_buf == 'string') ? opt_buf : null;
+  this.pos = 0;
+};
+
+/**
+ * Reset the arguments list only.
+ *
+ * Typically we reset arguments before parsing a sequence that uses them rather
+ * than always trying to make sure they're in a good state.  This can lead to
+ * confusion during debugging where args from a previous sequence appear to be
+ * "sticking around" in other sequences (which in reality don't use args).
+ *
+ * @param {string} opt_arg_zero Optional initial value for args[0].
+ */
+hterm.VT.ParseState.prototype.resetArguments = function(opt_arg_zero) {
+  this.args.length = 0;
+  if (typeof opt_arg_zero != 'undefined')
+    this.args[0] = opt_arg_zero;
+};
+
+/**
+ * Parse an argument as an integer.
+ *
+ * This assumes the inputs are already in the proper format.  e.g. This won't
+ * handle non-numeric arguments.
+ *
+ * An "0" argument is treated the same as "" which means the default value will
+ * be applied.  This is what most terminal sequences expect.
+ *
+ * @param {string} argstr The argument to parse directly.
+ * @param {number=} defaultValue Default value if argstr is empty.
+ * @return {number} The parsed value.
+ */
+hterm.VT.ParseState.prototype.parseInt = function(argstr, defaultValue) {
+  if (defaultValue === undefined)
+    defaultValue = 0;
+
+  if (argstr) {
+    const ret = parseInt(argstr, 10);
+    // An argument of zero is treated as the default value.
+    return ret == 0 ? defaultValue : ret;
+  }
+  return defaultValue;
+};
+
+/**
+ * Get an argument as an integer.
+ *
+ * @param {number} argnum The argument number to retrieve.
+ * @param {number=} defaultValue Default value if the argument is empty.
+ * @return {number} The parsed value.
+ */
+hterm.VT.ParseState.prototype.iarg = function(argnum, defaultValue) {
+  return this.parseInt(this.args[argnum], defaultValue);
+};
+
+/**
+ * Check whether an argument has subarguments.
+ *
+ * @param {number} argnum The argument number to check.
+ * @return {number} Whether the argument has subarguments.
+ */
+hterm.VT.ParseState.prototype.argHasSubargs = function(argnum) {
+  return this.subargs && this.subargs[argnum];
+};
+
+/**
+ * Mark an argument as having subarguments.
+ *
+ * @param {number} argnum The argument number that has subarguments.
+ */
+hterm.VT.ParseState.prototype.argSetSubargs = function(argnum) {
+  if (this.subargs === null)
+    this.subargs = {};
+  this.subargs[argnum] = true;
+};
+
+/**
+ * Advance the parse position.
+ *
+ * @param {integer} count The number of bytes to advance.
+ */
+hterm.VT.ParseState.prototype.advance = function(count) {
+  this.pos += count;
+};
+
+/**
+ * Return the remaining portion of the buffer without affecting the parse
+ * position.
+ *
+ * @return {string} The remaining portion of the buffer.
+ */
+hterm.VT.ParseState.prototype.peekRemainingBuf = function() {
+  return this.buf.substr(this.pos);
+};
+
+/**
+ * Return the next single character in the buffer without affecting the parse
+ * position.
+ *
+ * @return {string} The next character in the buffer.
+ */
+hterm.VT.ParseState.prototype.peekChar = function() {
+  return this.buf.substr(this.pos, 1);
+};
+
+/**
+ * Return the next single character in the buffer and advance the parse
+ * position one byte.
+ *
+ * @return {string} The next character in the buffer.
+ */
+hterm.VT.ParseState.prototype.consumeChar = function() {
+  return this.buf.substr(this.pos++, 1);
+};
+
+/**
+ * Return true if the buffer is empty, or the position is past the end.
+ */
+hterm.VT.ParseState.prototype.isComplete = function() {
+  return this.buf == null || this.buf.length <= this.pos;
+};
+
+/**
+ * Reset the VT back to baseline state.
+ */
+hterm.VT.prototype.reset = function() {
+  this.G0 = this.G1 = this.G2 = this.G3 =
+      this.characterMaps.getMap('B');
+
+  this.GL = 'G0';
+  this.GR = 'G0';
+
+  this.mouseReport = this.MOUSE_REPORT_DISABLED;
+  this.mouseCoordinates = this.MOUSE_COORDINATES_X10;
+  this.lastMouseDragResponse_ = null;
+};
+
+/**
+ * Handle terminal mouse events.
+ *
+ * See the "Mouse Tracking" section of [xterm].
+ */
+hterm.VT.prototype.onTerminalMouse_ = function(e) {
+  // Short circuit a few events to avoid unnecessary processing.
+  if (this.mouseReport == this.MOUSE_REPORT_DISABLED)
+    return;
+  else if (this.mouseReport != this.MOUSE_REPORT_DRAG && e.type == 'mousemove')
+    return;
+
+  // Temporary storage for our response.
+  var response;
+
+  // Modifier key state.
+  var mod = 0;
+  if (this.mouseReport != this.MOUSE_REPORT_PRESS) {
+    if (e.shiftKey)
+      mod |= 4;
+    if (e.metaKey || (this.terminal.keyboard.altIsMeta && e.altKey))
+      mod |= 8;
+    if (e.ctrlKey)
+      mod |= 16;
+  }
+
+  // X & Y coordinate reporting.
+  let x;
+  let y;
+  // Normally X10 has a limit of 255, but since we only want to emit UTF-8 valid
+  // streams, we limit ourselves to 127 to avoid setting the 8th bit.  If we do
+  // re-enable this, we should re-enable the hterm_vt_tests.js too.
+  let limit = 127;
+  switch (this.mouseCoordinates) {
+    case this.MOUSE_COORDINATES_UTF8:
+      // UTF-8 mode is the same as X10 but with higher limits.
+      limit = 2047;
+    case this.MOUSE_COORDINATES_X10:
+      // X10 reports coordinates by encoding into strings.
+      x = String.fromCharCode(lib.f.clamp(e.terminalColumn + 32, 32, limit));
+      y = String.fromCharCode(lib.f.clamp(e.terminalRow + 32, 32, limit));
+      break;
+    case this.MOUSE_COORDINATES_SGR:
+      // SGR reports coordinates by transmitting the numbers directly.
+      x = e.terminalColumn;
+      y = e.terminalRow;
+      break;
+  }
+
+  switch (e.type) {
+    case 'wheel':
+      // Mouse wheel is treated as button 1 or 2 plus an additional 64.
+      b = (((e.deltaY * -1) > 0) ? 0 : 1) + 64;
+      b |= mod;
+      if (this.mouseCoordinates == this.MOUSE_COORDINATES_SGR) {
+        response = `\x1b[<${b};${x};${y}M`;
+      } else {
+        // X10 based modes (including UTF8) add 32 for legacy encoding reasons.
+        response = '\x1b[M' + String.fromCharCode(b + 32) + x + y;
+      }
+
+      // Keep the terminal from scrolling.
+      e.preventDefault();
+      break;
+
+    case 'mousedown':
+      // Buttons are encoded as button number.
+      var b = Math.min(e.button, 2);
+      // X10 based modes (including UTF8) add 32 for legacy encoding reasons.
+      if (this.mouseCoordinates != this.MOUSE_COORDINATES_SGR)
+        b += 32;
+
+      // And mix in the modifier keys.
+      b |= mod;
+
+      if (this.mouseCoordinates == this.MOUSE_COORDINATES_SGR)
+        response = `\x1b[<${b};${x};${y}M`;
+      else
+        response = '\x1b[M' + String.fromCharCode(b) + x + y;
+      break;
+
+    case 'mouseup':
+      if (this.mouseReport != this.MOUSE_REPORT_PRESS) {
+        if (this.mouseCoordinates == this.MOUSE_COORDINATES_SGR) {
+          // SGR mode can report the released button.
+          response = `\x1b[<${e.button};${x};${y}m`;
+        } else {
+          // X10 mode has no indication of which button was released.
+          response = '\x1b[M\x23' + x + y;
+        }
+      }
+      break;
+
+    case 'mousemove':
+      if (this.mouseReport == this.MOUSE_REPORT_DRAG && e.buttons) {
+        // Standard button bits.  The XTerm protocol only reports the first
+        // button press (e.g. if left & right are pressed, right is ignored),
+        // and it only supports the first three buttons.  If none of them are
+        // pressed, then XTerm flags it as a release.  We'll do the same.
+        // X10 based modes (including UTF8) add 32 for legacy encoding reasons.
+        b = this.mouseCoordinates == this.MOUSE_COORDINATES_SGR ? 0 : 32;
+
+        // Priority here matches XTerm: left, middle, right.
+        if (e.buttons & 0x1) {
+          // Report left button.
+          b += 0;
+        } else if (e.buttons & 0x4) {
+          // Report middle button.
+          b += 1;
+        } else if (e.buttons & 0x2) {
+          // Report right button.
+          b += 2;
+        } else {
+          // Release higher buttons.
+          b += 3;
+        }
+
+        // Add 32 to indicate mouse motion.
+        b += 32;
+
+        // And mix in the modifier keys.
+        b |= mod;
+
+        if (this.mouseCoordinates == this.MOUSE_COORDINATES_SGR)
+          response = `\x1b[<${b};${x};${y}M`;
+        else
+          response = '\x1b[M' + String.fromCharCode(b) + x + y;
+
+        // If we were going to report the same cell because we moved pixels
+        // within, suppress the report.  This is what xterm does and cuts
+        // down on duplicate messages.
+        if (this.lastMouseDragResponse_ == response)
+          response = '';
+        else
+          this.lastMouseDragResponse_ = response;
+      }
+
+      break;
+
+    case 'click':
+    case 'dblclick':
+      break;
+
+    default:
+      console.error('Unknown mouse event: ' + e.type, e);
+      break;
+  }
+
+  if (response)
+    this.terminal.io.sendString(response);
+};
+
+/**
+ * Interpret a string of characters, displaying the results on the associated
+ * terminal object.
+ *
+ * The buffer will be decoded according to the 'receive-encoding' preference.
+ */
+hterm.VT.prototype.interpret = function(buf) {
+  this.parseState_.resetBuf(buf);
+
+  while (!this.parseState_.isComplete()) {
+    var func = this.parseState_.func;
+    var pos = this.parseState_.pos;
+    var buf = this.parseState_.buf;
+
+    this.parseState_.func.call(this, this.parseState_);
+
+    if (this.parseState_.func == func && this.parseState_.pos == pos &&
+        this.parseState_.buf == buf) {
+      throw 'Parser did not alter the state!';
+    }
+  }
+};
+
+/**
+ * Set the encoding of the terminal.
+ *
+ * @param {string} encoding The name of the encoding to set.
+ */
+hterm.VT.prototype.setEncoding = function(encoding) {
+  switch (encoding) {
+    default:
+      console.warn('Invalid value for "terminal-encoding": ' + encoding);
+      // Fall through.
+    case 'iso-2022':
+      this.codingSystemUtf8_ = false;
+      this.codingSystemLocked_ = false;
+      break;
+    case 'utf-8-locked':
+      this.codingSystemUtf8_ = true;
+      this.codingSystemLocked_ = true;
+      break;
+    case 'utf-8':
+      this.codingSystemUtf8_ = true;
+      this.codingSystemLocked_ = false;
+      break;
+  }
+
+  this.updateEncodingState_();
+};
+
+/**
+ * Refresh internal state when the encoding changes.
+ */
+hterm.VT.prototype.updateEncodingState_ = function() {
+  // If we're in UTF8 mode, don't suport 8-bit escape sequences as we'll never
+  // see those -- everything should be UTF8!
+  var cc1 = Object.keys(hterm.VT.CC1)
+      .filter((e) => !this.codingSystemUtf8_ || e.charCodeAt() < 0x80)
+      .map((e) => '\\x' + lib.f.zpad(e.charCodeAt().toString(16), 2))
+      .join('');
+  this.cc1Pattern_ = new RegExp(`[${cc1}]`);
+};
+
+/**
+ * The default parse function.
+ *
+ * This will scan the string for the first 1-byte control character (C0/C1
+ * characters from [CTRL]).  Any plain text coming before the code will be
+ * printed to the terminal, then the control character will be dispatched.
+ */
+hterm.VT.prototype.parseUnknown_ = function(parseState) {
+  var self = this;
+
+  function print(str) {
+    if (!self.codingSystemUtf8_ && self[self.GL].GL)
+      str = self[self.GL].GL(str);
+
+    self.terminal.print(str);
+  }
+
+  // Search for the next contiguous block of plain text.
+  var buf = parseState.peekRemainingBuf();
+  var nextControl = buf.search(this.cc1Pattern_);
+
+  if (nextControl == 0) {
+    // We've stumbled right into a control character.
+    this.dispatch('CC1', buf.substr(0, 1), parseState);
+    parseState.advance(1);
+    return;
+  }
+
+  if (nextControl == -1) {
+    // There are no control characters in this string.
+    print(buf);
+    parseState.reset();
+    return;
+  }
+
+  print(buf.substr(0, nextControl));
+  this.dispatch('CC1', buf.substr(nextControl, 1), parseState);
+  parseState.advance(nextControl + 1);
+};
+
+/**
+ * Parse a Control Sequence Introducer code and dispatch it.
+ *
+ * See [CSI] for some useful information about these codes.
+ */
+hterm.VT.prototype.parseCSI_ = function(parseState) {
+  var ch = parseState.peekChar();
+  var args = parseState.args;
+
+  const finishParsing = () => {
+    // Resetting the arguments isn't strictly necessary, but it makes debugging
+    // less confusing (otherwise args will stick around until the next sequence
+    // that needs arguments).
+    parseState.resetArguments();
+    // We need to clear subargs since we explicitly set it.
+    parseState.subargs = null;
+    parseState.resetParseFunction();
+  };
+
+  if (ch >= '@' && ch <= '~') {
+    // This is the final character.
+    this.dispatch('CSI', this.leadingModifier_ + this.trailingModifier_ + ch,
+                  parseState);
+    finishParsing();
+
+  } else if (ch == ';') {
+    // Parameter delimiter.
+    if (this.trailingModifier_) {
+      // Parameter delimiter after the trailing modifier.  That's a paddlin'.
+      finishParsing();
+
+    } else {
+      if (!args.length) {
+        // They omitted the first param, we need to supply it.
+        args.push('');
+      }
+
+      args.push('');
+    }
+
+  } else if (ch >= '0' && ch <= '9' || ch == ':') {
+    // Next byte in the current parameter.
+
+    if (this.trailingModifier_) {
+      // Numeric parameter after the trailing modifier.  That's a paddlin'.
+      finishParsing();
+    } else {
+      if (!args.length) {
+        args[0] = ch;
+      } else {
+        args[args.length - 1] += ch;
+      }
+
+      // Possible sub-parameters.
+      if (ch == ':')
+        parseState.argSetSubargs(args.length - 1);
+    }
+
+  } else if (ch >= ' ' && ch <= '?') {
+    // Modifier character.
+    if (!args.length) {
+      this.leadingModifier_ += ch;
+    } else {
+      this.trailingModifier_ += ch;
+    }
+
+  } else if (this.cc1Pattern_.test(ch)) {
+    // Control character.
+    this.dispatch('CC1', ch, parseState);
+
+  } else {
+    // Unexpected character in sequence, bail out.
+    finishParsing();
+  }
+
+  parseState.advance(1);
+};
+
+/**
+ * Skip over the string until the next String Terminator (ST, 'ESC \') or
+ * Bell (BEL, '\x07').
+ *
+ * The string is accumulated in parseState.args[0].  Make sure to reset the
+ * arguments (with parseState.resetArguments) before starting the parse.
+ *
+ * You can detect that parsing in complete by checking that the parse
+ * function has changed back to the default parse function.
+ *
+ * @return {boolean} If true, parsing is ongoing or complete.  If false, we've
+ *     exceeded the max string sequence.
+ */
+hterm.VT.prototype.parseUntilStringTerminator_ = function(parseState) {
+  var buf = parseState.peekRemainingBuf();
+  var args = parseState.args;
+  // Since we might modify parse state buffer locally, if we want to advance
+  // the parse state buffer later on, we need to know how many chars we added.
+  let bufInserted = 0;
+
+  if (!args.length) {
+    args[0] = '';
+    args[1] = new Date();
+  } else {
+    // If our saved buffer ends with an escape, it's because we were hoping
+    // it's an ST split across two buffers.  Move it from our saved buffer
+    // to the start of our current buffer for processing anew.
+    if (args[0].slice(-1) == '\x1b') {
+      args[0] = args[0].slice(0, -1);
+      buf = '\x1b' + buf;
+      bufInserted = 1;
+    }
+  }
+
+  const nextTerminator = buf.search(/[\x1b\x07]/);
+  const terminator = buf[nextTerminator];
+  let foundTerminator;
+
+  // If the next escape we see is not a start of a ST, fall through.  This will
+  // either be invalid (embedded escape), or we'll queue it up (wait for \\).
+  if (terminator == '\x1b' && buf[nextTerminator + 1] != '\\')
+    foundTerminator = false;
+  else
+    foundTerminator = (nextTerminator != -1);
+
+  if (!foundTerminator) {
+    // No terminator here, have to wait for the next string.
+
+    args[0] += buf;
+
+    var abortReason;
+
+    // Special case: If our buffering happens to split the ST (\e\\), we have to
+    // buffer the content temporarily.  So don't reject a trailing escape here,
+    // instead we let it timeout or be rejected in the next pass.
+    if (terminator == '\x1b' && nextTerminator != buf.length - 1)
+      abortReason = 'embedded escape: ' + nextTerminator;
+
+    if (new Date() - args[1] > this.oscTimeLimit_)
+      abortReason = 'timeout expired: ' + (new Date() - args[1]);
+
+    if (abortReason) {
+      if (this.warnUnimplemented)
+        console.log('parseUntilStringTerminator_: aborting: ' + abortReason,
+                    args[0]);
+      parseState.reset(args[0]);
+      return false;
+    }
+
+    parseState.advance(buf.length - bufInserted);
+    return true;
+  }
+
+  args[0] += buf.substr(0, nextTerminator);
+
+  parseState.resetParseFunction();
+  parseState.advance(nextTerminator +
+                     (terminator == '\x1b' ? 2 : 1) - bufInserted);
+
+  return true;
+};
+
+/**
+ * Dispatch to the function that handles a given CC1, ESC, or CSI or VT52 code.
+ */
+hterm.VT.prototype.dispatch = function(type, code, parseState) {
+  var handler = hterm.VT[type][code];
+  if (!handler) {
+    if (this.warnUnimplemented)
+      console.warn('Unknown ' + type + ' code: ' + JSON.stringify(code));
+    return;
+  }
+
+  if (handler == hterm.VT.ignore) {
+    if (this.warnUnimplemented)
+      console.warn('Ignored ' + type + ' code: ' + JSON.stringify(code));
+    return;
+  }
+
+  if (parseState.subargs && !handler.supportsSubargs) {
+    if (this.warnUnimplemented)
+      console.warn('Ignored ' + type + ' code w/subargs: ' + JSON.stringify(code));
+    return;
+  }
+
+  if (type == 'CC1' && code > '\x7f' && !this.enable8BitControl) {
+    // It's kind of a hack to put this here, but...
+    //
+    // If we're dispatching a 'CC1' code, and it's got the eighth bit set,
+    // but we're not supposed to handle 8-bit codes?  Just ignore it.
+    //
+    // This prevents an errant (DCS, '\x90'), (OSC, '\x9d'), (PM, '\x9e') or
+    // (APC, '\x9f') from locking up the terminal waiting for its expected
+    // (ST, '\x9c') or (BEL, '\x07').
+    console.warn('Ignoring 8-bit control code: 0x' +
+                 code.charCodeAt(0).toString(16));
+    return;
+  }
+
+  handler.apply(this, [parseState, code]);
+};
+
+/**
+ * Set one of the ANSI defined terminal mode bits.
+ *
+ * Invoked in response to SM/RM.
+ *
+ * Unexpected and unimplemented values are silently ignored.
+ */
+hterm.VT.prototype.setANSIMode = function(code, state) {
+  if (code == 4) {  // Insert Mode (IRM)
+    this.terminal.setInsertMode(state);
+  } else if (code == 20) {  // Automatic Newline (LNM)
+    this.terminal.setAutoCarriageReturn(state);
+  } else if (this.warnUnimplemented) {
+    console.warn('Unimplemented ANSI Mode: ' + code);
+  }
+};
+
+/**
+ * Set or reset one of the DEC Private modes.
+ *
+ * Invoked in response to DECSET/DECRST.
+ */
+hterm.VT.prototype.setDECMode = function(code, state) {
+  switch (parseInt(code, 10)) {
+    case 1:  // DECCKM
+      this.terminal.keyboard.applicationCursor = state;
+      break;
+
+    case 3:  // DECCOLM
+      if (this.allowColumnWidthChanges_) {
+        this.terminal.setWidth(state ? 132 : 80);
+
+        this.terminal.clearHome();
+        this.terminal.setVTScrollRegion(null, null);
+      }
+      break;
+
+    case 5:  // DECSCNM
+      this.terminal.setReverseVideo(state);
+      break;
+
+    case 6:  // DECOM
+      this.terminal.setOriginMode(state);
+      break;
+
+    case 7:  // DECAWM
+      this.terminal.setWraparound(state);
+      break;
+
+    case 9:  // Report on mouse down events only (X10).
+      this.mouseReport = (
+          state ? this.MOUSE_REPORT_PRESS : this.MOUSE_REPORT_DISABLED);
+      this.terminal.syncMouseStyle();
+      break;
+
+    case 12:  // Start blinking cursor
+      if (this.enableDec12)
+        this.terminal.setCursorBlink(state);
+      break;
+
+    case 25:  // DECTCEM
+      this.terminal.setCursorVisible(state);
+      break;
+
+    case 30:  // Show scrollbar
+      this.terminal.setScrollbarVisible(state);
+      break;
+
+    case 40:  // Allow 80 - 132 (DECCOLM) Mode
+      this.terminal.allowColumnWidthChanges_ = state;
+      break;
+
+    case 45:  // Reverse-wraparound Mode
+      this.terminal.setReverseWraparound(state);
+      break;
+
+    case 67:  // Backarrow key sends backspace (DECBKM)
+      this.terminal.keyboard.backspaceSendsBackspace = state;
+      break;
+
+    case 1000:  // Report on mouse clicks only (X11).
+      this.mouseReport = (
+          state ? this.MOUSE_REPORT_CLICK : this.MOUSE_REPORT_DISABLED);
+      this.terminal.syncMouseStyle();
+      break;
+
+    case 1002:  // Report on mouse clicks and drags
+      this.mouseReport = (
+          state ? this.MOUSE_REPORT_DRAG : this.MOUSE_REPORT_DISABLED);
+      this.terminal.syncMouseStyle();
+      break;
+
+    case 1004:  // Report on window focus change.
+      this.terminal.reportFocus = state;
+      break;
+
+    case 1005:  // Extended coordinates in UTF-8 mode.
+      this.mouseCoordinates = (
+          state ? this.MOUSE_COORDINATES_UTF8 : this.MOUSE_COORDINATES_X10);
+      break;
+
+    case 1006:  // Extended coordinates in SGR mode.
+      this.mouseCoordinates = (
+          state ? this.MOUSE_COORDINATES_SGR : this.MOUSE_COORDINATES_X10);
+      break;
+
+    case 1007:  // Enable Alternate Scroll Mode.
+      this.terminal.scrollWheelArrowKeys_ = state;
+      break;
+
+    case 1010:  // Scroll to bottom on tty output
+      this.terminal.scrollOnOutput = state;
+      break;
+
+    case 1011:  // Scroll to bottom on key press
+      this.terminal.scrollOnKeystroke = state;
+      break;
+
+    case 1036:  // Send ESC when Meta modifies a key
+      this.terminal.keyboard.metaSendsEscape = state;
+      break;
+
+    case 1039:  // Send ESC when Alt modifies a key
+      if (state) {
+        if (!this.terminal.keyboard.previousAltSendsWhat_) {
+          this.terminal.keyboard.previousAltSendsWhat_ =
+              this.terminal.keyboard.altSendsWhat;
+          this.terminal.keyboard.altSendsWhat = 'escape';
+        }
+      } else if (this.terminal.keyboard.previousAltSendsWhat_) {
+        this.terminal.keyboard.altSendsWhat =
+            this.terminal.keyboard.previousAltSendsWhat_;
+        this.terminal.keyboard.previousAltSendsWhat_ = null;
+      }
+      break;
+
+    case 47:  // Use Alternate Screen Buffer
+    case 1047:
+      this.terminal.setAlternateMode(state);
+      break;
+
+    case 1048:  // Save cursor as in DECSC.
+      if (state)
+        this.terminal.saveCursorAndState();
+      else
+        this.terminal.restoreCursorAndState();
+      break;
+
+    case 1049:  // 1047 + 1048 + clear.
+      if (state) {
+        this.terminal.saveCursorAndState();
+        this.terminal.setAlternateMode(state);
+        this.terminal.clear();
+      } else {
+        this.terminal.setAlternateMode(state);
+        this.terminal.restoreCursorAndState();
+      }
+
+      break;
+
+    case 2004:  // Bracketed paste mode.
+      this.terminal.setBracketedPaste(state);
+      break;
+
+    default:
+      if (this.warnUnimplemented)
+        console.warn('Unimplemented DEC Private Mode: ' + code);
+      break;
+  }
+};
+
+/**
+ * Function shared by control characters and escape sequences that are
+ * ignored.
+ */
+hterm.VT.ignore = function() {};
+
+/**
+ * Collection of control characters expressed in a single byte.
+ *
+ * This includes the characters from the C0 and C1 sets (see [CTRL]) that we
+ * care about.  Two byte versions of the C1 codes are defined in the
+ * hterm.VT.ESC collection.
+ *
+ * The 'CC1' mnemonic here refers to the fact that these are one-byte Control
+ * Codes.  It's only used in this source file and not defined in any of the
+ * referenced documents.
+ */
+hterm.VT.CC1 = {};
+
+/**
+ * Collection of two-byte and three-byte sequences starting with ESC.
+ */
+hterm.VT.ESC = {};
+
+/**
+ * Collection of CSI (Control Sequence Introducer) sequences.
+ *
+ * These sequences begin with 'ESC [', and may take zero or more arguments.
+ */
+hterm.VT.CSI = {};
+
+/**
+ * Collection of OSC (Operating System Control) sequences.
+ *
+ * These sequences begin with 'ESC ]', followed by a function number and a
+ * string terminated by either ST or BEL.
+ */
+hterm.VT.OSC = {};
+
+/**
+ * Collection of VT52 sequences.
+ *
+ * When in VT52 mode, other sequences are disabled.
+ */
+hterm.VT.VT52 = {};
+
+/**
+ * Null (NUL).
+ *
+ * Silently ignored.
+ */
+hterm.VT.CC1['\x00'] = hterm.VT.ignore;
+
+/**
+ * Enquiry (ENQ).
+ *
+ * Transmit answerback message.
+ *
+ * The default answerback message in xterm is an empty string, so we just
+ * ignore this.
+ */
+hterm.VT.CC1['\x05'] = hterm.VT.ignore;
+
+/**
+ * Ring Bell (BEL).
+ */
+hterm.VT.CC1['\x07'] = function() {
+  this.terminal.ringBell();
+};
+
+/**
+ * Backspace (BS).
+ *
+ * Move the cursor to the left one character position, unless it is at the
+ * left margin, in which case no action occurs.
+ */
+hterm.VT.CC1['\x08'] = function() {
+  this.terminal.cursorLeft(1);
+};
+
+/**
+ * Horizontal Tab (HT).
+ *
+ * Move the cursor to the next tab stop, or to the right margin if no further
+ * tab stops are present on the line.
+ */
+hterm.VT.CC1['\x09'] = function() {
+  this.terminal.forwardTabStop();
+};
+
+/**
+ * Line Feed (LF).
+ *
+ * This code causes a line feed or a new line operation.  See Automatic
+ * Newline (LNM).
+ */
+hterm.VT.CC1['\x0a'] = function() {
+  this.terminal.formFeed();
+};
+
+/**
+ * Vertical Tab (VT).
+ *
+ * Interpreted as LF.
+ */
+hterm.VT.CC1['\x0b'] = hterm.VT.CC1['\x0a'];
+
+/**
+ * Form Feed (FF).
+ *
+ * Interpreted as LF.
+ */
+hterm.VT.CC1['\x0c'] = hterm.VT.CC1['\x0a'];
+
+/**
+ * Carriage Return (CR).
+ *
+ * Move cursor to the left margin on the current line.
+ */
+hterm.VT.CC1['\x0d'] = function() {
+  this.terminal.setCursorColumn(0);
+};
+
+/**
+ * Shift Out (SO), aka Lock Shift 0 (LS1).
+ *
+ * Invoke G1 character set in GL.
+ */
+hterm.VT.CC1['\x0e'] = function() {
+  this.GL = 'G1';
+};
+
+/**
+ * Shift In (SI), aka Lock Shift 0 (LS0).
+ *
+ * Invoke G0 character set in GL.
+ */
+hterm.VT.CC1['\x0f'] = function() {
+  this.GL = 'G0';
+};
+
+/**
+ * Transmit On (XON).
+ *
+ * Not currently implemented.
+ *
+ * TODO(rginda): Implement?
+ */
+hterm.VT.CC1['\x11'] = hterm.VT.ignore;
+
+/**
+ * Transmit Off (XOFF).
+ *
+ * Not currently implemented.
+ *
+ * TODO(rginda): Implement?
+ */
+hterm.VT.CC1['\x13'] = hterm.VT.ignore;
+
+/**
+ * Cancel (CAN).
+ *
+ * If sent during a control sequence, the sequence is immediately terminated
+ * and not executed.
+ *
+ * It also causes the error character to be displayed.
+ */
+hterm.VT.CC1['\x18'] = function(parseState) {
+  // If we've shifted in the G1 character set, shift it back out to
+  // the default character set.
+  if (this.GL == 'G1') {
+    this.GL = 'G0';
+  }
+  parseState.resetParseFunction();
+  this.terminal.print('?');
+};
+
+/**
+ * Substitute (SUB).
+ *
+ * Interpreted as CAN.
+ */
+hterm.VT.CC1['\x1a'] = hterm.VT.CC1['\x18'];
+
+/**
+ * Escape (ESC).
+ */
+hterm.VT.CC1['\x1b'] = function(parseState) {
+  function parseESC(parseState) {
+    var ch = parseState.consumeChar();
+
+    if (ch == '\x1b')
+      return;
+
+    this.dispatch('ESC', ch, parseState);
+
+    if (parseState.func == parseESC)
+      parseState.resetParseFunction();
+  }
+
+  parseState.func = parseESC;
+};
+
+/**
+ * Delete (DEL).
+ */
+hterm.VT.CC1['\x7f'] = hterm.VT.ignore;
+
+// 8 bit control characters and their two byte equivalents, below...
+
+/**
+ * Index (IND).
+ *
+ * Like newline, only keep the X position
+ */
+hterm.VT.CC1['\x84'] =
+hterm.VT.ESC['D'] = function() {
+  this.terminal.lineFeed();
+};
+
+/**
+ * Next Line (NEL).
+ *
+ * Like newline, but doesn't add lines.
+ */
+hterm.VT.CC1['\x85'] =
+hterm.VT.ESC['E'] = function() {
+  this.terminal.setCursorColumn(0);
+  this.terminal.cursorDown(1);
+};
+
+/**
+ * Horizontal Tabulation Set (HTS).
+ */
+hterm.VT.CC1['\x88'] =
+hterm.VT.ESC['H'] = function() {
+  this.terminal.setTabStop(this.terminal.getCursorColumn());
+};
+
+/**
+ * Reverse Index (RI).
+ *
+ * Move up one line.
+ */
+hterm.VT.CC1['\x8d'] =
+hterm.VT.ESC['M'] = function() {
+  this.terminal.reverseLineFeed();
+};
+
+/**
+ * Single Shift 2 (SS2).
+ *
+ * Select of G2 Character Set for the next character only.
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CC1['\x8e'] =
+hterm.VT.ESC['N'] = hterm.VT.ignore;
+
+/**
+ * Single Shift 3 (SS3).
+ *
+ * Select of G3 Character Set for the next character only.
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CC1['\x8f'] =
+hterm.VT.ESC['O'] = hterm.VT.ignore;
+
+/**
+ * Device Control String (DCS).
+ *
+ * Indicate a DCS sequence.  See Device-Control functions in [XTERM].
+ * Not currently implemented.
+ *
+ * TODO(rginda): Consider implementing DECRQSS, the rest don't seem applicable.
+ */
+hterm.VT.CC1['\x90'] =
+hterm.VT.ESC['P'] = function(parseState) {
+  parseState.resetArguments();
+  parseState.func = this.parseUntilStringTerminator_;
+};
+
+/**
+ * Start of Guarded Area (SPA).
+ *
+ * Will not implement.
+ */
+hterm.VT.CC1['\x96'] =
+hterm.VT.ESC['V'] = hterm.VT.ignore;
+
+/**
+ * End of Guarded Area (EPA).
+ *
+ * Will not implement.
+ */
+hterm.VT.CC1['\x97'] =
+hterm.VT.ESC['W'] = hterm.VT.ignore;
+
+/**
+ * Start of String (SOS).
+ *
+ * Will not implement.
+ */
+hterm.VT.CC1['\x98'] =
+hterm.VT.ESC['X'] = hterm.VT.ignore;
+
+/**
+ * Single Character Introducer (SCI, also DECID).
+ *
+ * Return Terminal ID.  Obsolete form of 'ESC [ c' (DA).
+ */
+hterm.VT.CC1['\x9a'] =
+hterm.VT.ESC['Z'] = function() {
+  this.terminal.io.sendString('\x1b[?1;2c');
+};
+
+/**
+ * Control Sequence Introducer (CSI).
+ *
+ * The lead into most escape sequences.  See [CSI].
+ */
+hterm.VT.CC1['\x9b'] =
+hterm.VT.ESC['['] = function(parseState) {
+  parseState.resetArguments();
+  this.leadingModifier_ = '';
+  this.trailingModifier_ = '';
+  parseState.func = this.parseCSI_;
+};
+
+/**
+ * String Terminator (ST).
+ *
+ * Used to terminate DCS/OSC/PM/APC commands which may take string arguments.
+ *
+ * We don't directly handle it here, as it's only used to terminate other
+ * sequences.  See the 'parseUntilStringTerminator_' method.
+ */
+hterm.VT.CC1['\x9c'] =
+hterm.VT.ESC['\\'] = hterm.VT.ignore;
+
+/**
+ * Operating System Command (OSC).
+ *
+ * Commands relating to the operating system.
+ */
+hterm.VT.CC1['\x9d'] =
+hterm.VT.ESC[']'] = function(parseState) {
+  parseState.resetArguments();
+
+  function parseOSC(parseState) {
+    if (!this.parseUntilStringTerminator_(parseState)) {
+      // The string sequence was too long.
+      return;
+    }
+
+    if (parseState.func == parseOSC) {
+      // We're not done parsing the string yet.
+      return;
+    }
+
+    // We're done.
+    var ary = parseState.args[0].match(/^(\d+);?(.*)$/);
+    if (ary) {
+      parseState.args[0] = ary[2];
+      this.dispatch('OSC', ary[1], parseState);
+    } else {
+      console.warn('Invalid OSC: ' + JSON.stringify(parseState.args[0]));
+    }
+
+    // Resetting the arguments isn't strictly necessary, but it makes debugging
+    // less confusing (otherwise args will stick around until the next sequence
+    // that needs arguments).
+    parseState.resetArguments();
+  }
+
+  parseState.func = parseOSC;
+};
+
+/**
+ * Privacy Message (PM).
+ *
+ * Will not implement.
+ */
+hterm.VT.CC1['\x9e'] =
+hterm.VT.ESC['^'] = function(parseState) {
+  parseState.resetArguments();
+  parseState.func = this.parseUntilStringTerminator_;
+};
+
+/**
+ * Application Program Control (APC).
+ *
+ * Will not implement.
+ */
+hterm.VT.CC1['\x9f'] =
+hterm.VT.ESC['_'] = function(parseState) {
+  parseState.resetArguments();
+  parseState.func = this.parseUntilStringTerminator_;
+};
+
+/**
+ * ESC \x20 - Unclear to me where these originated, possibly in xterm.
+ *
+ * Not currently implemented:
+ *   ESC \x20 F - Select 7 bit escape codes in responses (S7C1T).
+ *   ESC \x20 G - Select 8 bit escape codes in responses (S8C1T).
+ *                NB: We currently assume S7C1T always.
+ *
+ * Will not implement:
+ *   ESC \x20 L - Set ANSI conformance level 1.
+ *   ESC \x20 M - Set ANSI conformance level 2.
+ *   ESC \x20 N - Set ANSI conformance level 3.
+ */
+hterm.VT.ESC['\x20'] = function(parseState) {
+  parseState.func = function(parseState) {
+    var ch = parseState.consumeChar();
+    if (this.warnUnimplemented)
+      console.warn('Unimplemented sequence: ESC 0x20 ' + ch);
+    parseState.resetParseFunction();
+  };
+};
+
+/**
+ * DEC 'ESC #' sequences.
+ */
+hterm.VT.ESC['#'] = function(parseState) {
+  parseState.func = function(parseState) {
+    var ch = parseState.consumeChar();
+    if (ch == '8') {
+      // DEC Screen Alignment Test (DECALN).
+      this.terminal.setCursorPosition(0, 0);
+      this.terminal.fill('E');
+    }
+
+    parseState.resetParseFunction();
+  };
+};
+
+/**
+ * Designate Other Coding System (DOCS).
+ */
+hterm.VT.ESC['%'] = function(parseState) {
+  parseState.func = function(parseState) {
+    var ch = parseState.consumeChar();
+
+    // If we've locked the encoding, then just eat the bytes and return.
+    if (this.codingSystemLocked_) {
+      if (ch == '/')
+        parseState.consumeChar();
+      parseState.resetParseFunction();
+      return;
+    }
+
+    // Process the encoding requests.
+    switch (ch) {
+      case '@':
+        // Switch to ECMA 35.
+        this.setEncoding('iso-2022');
+        break;
+
+      case 'G':
+        // Switch to UTF-8.
+        this.setEncoding('utf-8');
+        break;
+
+      case '/':
+        // One way transition to something else.
+        ch = parseState.consumeChar();
+        switch (ch) {
+          case 'G':  // UTF-8 Level 1.
+          case 'H':  // UTF-8 Level 2.
+          case 'I':  // UTF-8 Level 3.
+            // We treat all UTF-8 levels the same.
+            this.setEncoding('utf-8-locked');
+            break;
+
+          default:
+            if (this.warnUnimplemented)
+              console.warn('Unknown ESC % / argument: ' + JSON.stringify(ch));
+            break;
+        }
+        break;
+
+      default:
+        if (this.warnUnimplemented)
+          console.warn('Unknown ESC % argument: ' + JSON.stringify(ch));
+        break;
+    }
+
+    parseState.resetParseFunction();
+  };
+};
+
+/**
+ * Character Set Selection (SCS).
+ *
+ *   ESC ( Ps - Set G0 character set (VT100).
+ *   ESC ) Ps - Set G1 character set (VT220).
+ *   ESC * Ps - Set G2 character set (VT220).
+ *   ESC + Ps - Set G3 character set (VT220).
+ *   ESC - Ps - Set G1 character set (VT300).
+ *   ESC . Ps - Set G2 character set (VT300).
+ *   ESC / Ps - Set G3 character set (VT300).
+ *
+ * All other sequences are echoed to the terminal.
+ */
+hterm.VT.ESC['('] =
+hterm.VT.ESC[')'] =
+hterm.VT.ESC['*'] =
+hterm.VT.ESC['+'] =
+hterm.VT.ESC['-'] =
+hterm.VT.ESC['.'] =
+hterm.VT.ESC['/'] = function(parseState, code) {
+  parseState.func = function(parseState) {
+    var ch = parseState.consumeChar();
+    if (ch == '\x1b') {
+      parseState.resetParseFunction();
+      parseState.func();
+      return;
+    }
+
+    var map = this.characterMaps.getMap(ch);
+    if (map !== undefined) {
+      if (code == '(') {
+        this.G0 = map;
+      } else if (code == ')' || code == '-') {
+        this.G1 = map;
+      } else if (code == '*' || code == '.') {
+        this.G2 = map;
+      } else if (code == '+' || code == '/') {
+        this.G3 = map;
+      }
+    } else if (this.warnUnimplemented) {
+      console.log('Invalid character set for "' + code + '": ' + ch);
+    }
+
+    parseState.resetParseFunction();
+  };
+};
+
+/**
+ * Back Index (DECBI).
+ *
+ * VT420 and up.  Not currently implemented.
+ */
+hterm.VT.ESC['6'] = hterm.VT.ignore;
+
+/**
+ * Save Cursor (DECSC).
+ */
+hterm.VT.ESC['7'] = function() {
+  this.terminal.saveCursorAndState();
+};
+
+/**
+ * Restore Cursor (DECRC).
+ */
+hterm.VT.ESC['8'] = function() {
+  this.terminal.restoreCursorAndState();
+};
+
+/**
+ * Forward Index (DECFI).
+ *
+ * VT210 and up.  Not currently implemented.
+ */
+hterm.VT.ESC['9'] = hterm.VT.ignore;
+
+/**
+ * Application keypad (DECKPAM).
+ */
+hterm.VT.ESC['='] = function() {
+  this.terminal.keyboard.applicationKeypad = true;
+};
+
+/**
+ * Normal keypad (DECKPNM).
+ */
+hterm.VT.ESC['>'] = function() {
+  this.terminal.keyboard.applicationKeypad = false;
+};
+
+/**
+ * Cursor to lower left corner of screen.
+ *
+ * Will not implement.
+ *
+ * This is only recognized by xterm when the hpLowerleftBugCompat resource is
+ * set.
+ */
+hterm.VT.ESC['F'] = hterm.VT.ignore;
+
+/**
+ * Full Reset (RIS).
+ */
+hterm.VT.ESC['c'] = function() {
+  this.terminal.reset();
+};
+
+/**
+ * Memory lock/unlock.
+ *
+ * Will not implement.
+ */
+hterm.VT.ESC['l'] =
+hterm.VT.ESC['m'] = hterm.VT.ignore;
+
+/**
+ * Lock Shift 2 (LS2)
+ *
+ * Invoke the G2 Character Set as GL.
+ */
+hterm.VT.ESC['n'] = function() {
+  this.GL = 'G2';
+};
+
+/**
+ * Lock Shift 3 (LS3)
+ *
+ * Invoke the G3 Character Set as GL.
+ */
+hterm.VT.ESC['o'] = function() {
+  this.GL = 'G3';
+};
+
+/**
+ * Lock Shift 2, Right (LS3R)
+ *
+ * Invoke the G3 Character Set as GR.
+ */
+hterm.VT.ESC['|'] = function() {
+  this.GR = 'G3';
+};
+
+/**
+ * Lock Shift 2, Right (LS2R)
+ *
+ * Invoke the G2 Character Set as GR.
+ */
+hterm.VT.ESC['}'] = function() {
+  this.GR = 'G2';
+};
+
+/**
+ * Lock Shift 1, Right (LS1R)
+ *
+ * Invoke the G1 Character Set as GR.
+ */
+hterm.VT.ESC['~'] = function() {
+  this.GR = 'G1';
+};
+
+/**
+ * Change icon name and window title.
+ *
+ * We only change the window title.
+ */
+hterm.VT.OSC['0'] = function(parseState) {
+  this.terminal.setWindowTitle(parseState.args[0]);
+};
+
+/**
+ * Change window title.
+ */
+hterm.VT.OSC['2'] = hterm.VT.OSC['0'];
+
+/**
+ * Set/read color palette.
+ */
+hterm.VT.OSC['4'] = function(parseState) {
+  // Args come in as a single 'index1;rgb1 ... ;indexN;rgbN' string.
+  // We split on the semicolon and iterate through the pairs.
+  var args = parseState.args[0].split(';');
+
+  var pairCount = parseInt(args.length / 2);
+  var colorPalette = this.terminal.getTextAttributes().colorPalette;
+  var responseArray = [];
+
+  for (var pairNumber = 0; pairNumber < pairCount; ++pairNumber) {
+    var colorIndex = parseInt(args[pairNumber * 2]);
+    var colorValue = args[pairNumber * 2 + 1];
+
+    if (colorIndex >= colorPalette.length)
+      continue;
+
+    if (colorValue == '?') {
+      // '?' means we should report back the current color value.
+      colorValue = lib.colors.rgbToX11(colorPalette[colorIndex]);
+      if (colorValue)
+        responseArray.push(colorIndex + ';' + colorValue);
+
+      continue;
+    }
+
+    colorValue = lib.colors.x11ToCSS(colorValue);
+    if (colorValue)
+      colorPalette[colorIndex] = colorValue;
+  }
+
+  if (responseArray.length)
+    this.terminal.io.sendString('\x1b]4;' + responseArray.join(';') + '\x07');
+};
+
+/**
+ * Hyperlinks.
+ *
+ * The first argument is optional and colon separated:
+ *   id=<id>
+ * The second argument is the link itself.
+ *
+ * Calling with a non-blank URI starts it.  A blank URI stops it.
+ *
+ * https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
+ */
+hterm.VT.OSC['8'] = function(parseState) {
+  const args = parseState.args[0].split(';');
+  let id = null;
+  let uri = null;
+
+  if (args.length != 2 || args[1].length == 0) {
+    // Reset link.
+  } else {
+    // Pull out any colon separated parameters in the first argument.
+    const params = args[0].split(':');
+    id = '';
+    params.forEach((param) => {
+      const idx = param.indexOf('=');
+      if (idx == -1)
+        return;
+
+      const key = param.slice(0, idx);
+      const value = param.slice(idx + 1);
+      switch (key) {
+        case 'id':
+          id = value;
+          break;
+        default:
+          // Ignore unknown keys.
+          break;
+      }
+    });
+
+    // The URI is in the second argument.
+    uri = args[1];
+  }
+
+  const attrs = this.terminal.getTextAttributes();
+  attrs.uri = uri;
+  attrs.uriId = id;
+};
+
+/**
+ * iTerm2 growl notifications.
+ */
+hterm.VT.OSC['9'] = function(parseState) {
+  // This just dumps the entire string as the message.
+  hterm.notify({'body': parseState.args[0]});
+};
+
+/**
+ * Change VT100 text foreground color.
+ */
+hterm.VT.OSC['10'] = function(parseState) {
+  // Args come in as a single string, but extra args will chain to the following
+  // OSC sequences.
+  var args = parseState.args[0].split(';');
+  if (!args)
+    return;
+
+  var colorArg;
+  var colorX11 = lib.colors.x11ToCSS(args.shift());
+  if (colorX11)
+    this.terminal.setForegroundColor(colorX11);
+
+  if (args.length > 0) {
+    parseState.args[0] = args.join(';');
+    hterm.VT.OSC['11'].apply(this, [parseState]);
+  }
+};
+
+/**
+ * Change VT100 text background color.
+ */
+hterm.VT.OSC['11'] = function(parseState) {
+  // Args come in as a single string, but extra args will chain to the following
+  // OSC sequences.
+  var args = parseState.args[0].split(';');
+  if (!args)
+    return;
+
+  var colorArg;
+  var colorX11 = lib.colors.x11ToCSS(args.shift());
+  if (colorX11)
+    this.terminal.setBackgroundColor(colorX11);
+
+  if (args.length > 0) {
+    parseState.args[0] = args.join(';');
+    hterm.VT.OSC['12'].apply(this, [parseState]);
+  }
+};
+
+/**
+ * Change text cursor color.
+ */
+hterm.VT.OSC['12'] = function(parseState) {
+  // Args come in as a single string, but extra args will chain to the following
+  // OSC sequences.
+  var args = parseState.args[0].split(';');
+  if (!args)
+    return;
+
+  var colorArg;
+  var colorX11 = lib.colors.x11ToCSS(args.shift());
+  if (colorX11)
+    this.terminal.setCursorColor(colorX11);
+
+  /* Note: If we support OSC 13+, we'd chain it here.
+  if (args.length > 0) {
+    parseState.args[0] = args.join(';');
+    hterm.VT.OSC['13'].apply(this, [parseState]);
+  }
+  */
+};
+
+/**
+ * Set the cursor shape.
+ *
+ * Parameter is expected to be in the form "CursorShape=number", where number is
+ * one of:
+ *
+ *   0 - Block
+ *   1 - I-Beam
+ *   2 - Underline
+ *
+ * This is a bit of a de-facto standard supported by iTerm 2 and Konsole.  See
+ * also: DECSCUSR.
+ *
+ * Invalid numbers will restore the cursor to the block shape.
+ */
+hterm.VT.OSC['50'] = function(parseState) {
+  var args = parseState.args[0].match(/CursorShape=(.)/i);
+  if (!args) {
+    console.warn('Could not parse OSC 50 args: ' + parseState.args[0]);
+    return;
+  }
+
+  switch (args[1]) {
+    case '1':  // CursorShape=1: I-Beam.
+      this.terminal.setCursorShape(hterm.Terminal.cursorShape.BEAM);
+      break;
+
+    case '2':  // CursorShape=2: Underline.
+      this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE);
+      break;
+
+    default:  // CursorShape=0: Block.
+      this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK);
+  }
+};
+
+/**
+ * Set/read system clipboard.
+ *
+ * Read is not implemented due to security considerations.  A remote app
+ * that is able to both write and read to the clipboard could essentially
+ * take over your session.
+ *
+ * The clipboard data will be decoded according to the 'receive-encoding'
+ * preference.
+ */
+hterm.VT.OSC['52'] = function(parseState) {
+  if (!this.enableClipboardWrite)
+    return;
+
+  // Args come in as a single 'clipboard;b64-data' string.  The clipboard
+  // parameter is used to select which of the X clipboards to address.  Since
+  // we're not integrating with X, we treat them all the same.
+  var args = parseState.args[0].match(/^[cps01234567]*;(.*)/);
+  if (!args)
+    return;
+
+  let data;
+  try {
+    data = window.atob(args[1]);
+  } catch (e) {
+    // If the user sent us invalid base64 content, silently ignore it.
+    return;
+  }
+  if (this.characterEncoding == 'utf-8') {
+    const decoder = new TextDecoder();
+    const bytes = lib.codec.stringToCodeUnitArray(data, Uint8Array);
+    data = decoder.decode(bytes);
+  }
+  if (data)
+    this.terminal.copyStringToClipboard(data);
+};
+
+/**
+ * Reset color palette.
+ */
+hterm.VT.OSC['104'] = function(parseState) {
+  const attrs = this.terminal.getTextAttributes();
+
+  // If there are no args, we reset the entire palette.
+  if (!parseState.args[0]) {
+    attrs.resetColorPalette();
+    return;
+  }
+
+  // Args come in as a single 'index1;index2;...;indexN' string.
+  // Split on the semicolon and iterate through the colors.
+  const args = parseState.args[0].split(';');
+  args.forEach((c) => attrs.resetColor(c));
+};
+
+/**
+ * Reset foreground color.
+ */
+hterm.VT.OSC['110'] = function(parseState) {
+  this.terminal.setForegroundColor();
+};
+
+/**
+ * Reset background color.
+ */
+hterm.VT.OSC['111'] = function(parseState) {
+  this.terminal.setBackgroundColor();
+};
+
+/**
+ * Reset text cursor color.
+ */
+hterm.VT.OSC['112'] = function(parseState) {
+  this.terminal.setCursorColor();
+};
+
+/**
+ * iTerm2 extended sequences.
+ *
+ * We only support image display atm.
+ */
+hterm.VT.OSC['1337'] = function(parseState) {
+  // Args come in as a set of key value pairs followed by data.
+  // File=name=<base64>;size=123;inline=1:<base64 data>
+  let args = parseState.args[0].match(/^File=([^:]*):([\s\S]*)$/m);
+  if (!args) {
+    if (this.warnUnimplemented)
+      console.log(`iTerm2 1337: unsupported sequence: ${args[1]}`);
+    return;
+  }
+
+  const options = {
+    name: '',
+    size: 0,
+    preserveAspectRatio: true,
+    inline: false,
+    width: 'auto',
+    height: 'auto',
+    align: 'left',
+    type: '',
+    buffer: lib.codec.stringToCodeUnitArray(atob(args[2]), Uint8Array).buffer,
+  };
+  // Walk the "key=value;" sets.
+  args[1].split(';').forEach((ele) => {
+    const kv = ele.match(/^([^=]+)=(.*)$/m);
+    if (!kv)
+      return;
+
+    // Sanitize values nicely.
+    switch (kv[1]) {
+      case 'name':
+        try {
+          options.name = window.atob(kv[2]);
+        } catch (e) {}
+        break;
+      case 'size':
+        try {
+          options.size = parseInt(kv[2]);
+        } catch (e) {}
+        break;
+      case 'width':
+        options.width = kv[2];
+        break;
+      case 'height':
+        options.height = kv[2];
+        break;
+      case 'preserveAspectRatio':
+        options.preserveAspectRatio = !(kv[2] == '0');
+        break;
+      case 'inline':
+        options.inline = !(kv[2] == '0');
+        break;
+      // hterm-specific keys.
+      case 'align':
+        options.align = kv[2];
+        break;
+      case 'type':
+        options.type = kv[2];
+        break;
+      default:
+        // Ignore unknown keys.  Don't want remote stuffing our JS env.
+        break;
+    }
+  });
+
+  // This is a bit of a hack.  If the buffer has data following the image, we
+  // need to delay processing of it until after we've finished with the image.
+  // Otherwise while we wait for the the image to load asynchronously, the new
+  // text data will intermingle with the image.
+  if (options.inline) {
+    const io = this.terminal.io;
+    const queued = parseState.peekRemainingBuf();
+    parseState.advance(queued.length);
+    this.terminal.displayImage(options);
+    io.print(queued);
+  } else
+    this.terminal.displayImage(options);
+};
+
+/**
+ * URxvt perl modules.
+ *
+ * This is the escape system used by rxvt-unicode and its perl modules.
+ * Obviously we don't support perl or custom modules, so we list a few common
+ * ones that we find useful.
+ *
+ * Technically there is no format here, but most modules obey:
+ * <module name>;<module args, usually ; delimited>
+ */
+hterm.VT.OSC['777'] = function(parseState) {
+  var ary;
+  var urxvtMod = parseState.args[0].split(';', 1)[0];
+
+  switch (urxvtMod) {
+    case 'notify':
+      // Format:
+      // notify;title;message
+      var title, message;
+      ary = parseState.args[0].match(/^[^;]+;([^;]*)(;([\s\S]*))?$/);
+      if (ary) {
+        title = ary[1];
+        message = ary[3];
+      }
+      hterm.notify({'title': title, 'body': message});
+      break;
+
+    default:
+      console.warn('Unknown urxvt module: ' + parseState.args[0]);
+      break;
+  }
+};
+
+/**
+ * Insert (blank) characters (ICH).
+ */
+hterm.VT.CSI['@'] = function(parseState) {
+  this.terminal.insertSpace(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Up (CUU).
+ */
+hterm.VT.CSI['A'] = function(parseState) {
+  this.terminal.cursorUp(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Down (CUD).
+ */
+hterm.VT.CSI['B'] = function(parseState) {
+  this.terminal.cursorDown(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Forward (CUF).
+ */
+hterm.VT.CSI['C'] = function(parseState) {
+  this.terminal.cursorRight(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Backward (CUB).
+ */
+hterm.VT.CSI['D'] = function(parseState) {
+  this.terminal.cursorLeft(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Next Line (CNL).
+ *
+ * This is like Cursor Down, except the cursor moves to the beginning of the
+ * line as well.
+ */
+hterm.VT.CSI['E'] = function(parseState) {
+  this.terminal.cursorDown(parseState.iarg(0, 1));
+  this.terminal.setCursorColumn(0);
+};
+
+/**
+ * Cursor Preceding Line (CPL).
+ *
+ * This is like Cursor Up, except the cursor moves to the beginning of the
+ * line as well.
+ */
+hterm.VT.CSI['F'] = function(parseState) {
+  this.terminal.cursorUp(parseState.iarg(0, 1));
+  this.terminal.setCursorColumn(0);
+};
+
+/**
+ * Cursor Horizontal Absolute (CHA).
+ *
+ * Xterm calls this Cursor Character Absolute.
+ */
+hterm.VT.CSI['G'] = function(parseState) {
+  this.terminal.setCursorColumn(parseState.iarg(0, 1) - 1);
+};
+
+/**
+ * Cursor Position (CUP).
+ */
+hterm.VT.CSI['H'] = function(parseState) {
+  this.terminal.setCursorPosition(parseState.iarg(0, 1) - 1,
+                                  parseState.iarg(1, 1) - 1);
+};
+
+/**
+ * Cursor Forward Tabulation (CHT).
+ */
+hterm.VT.CSI['I'] = function(parseState) {
+  var count = parseState.iarg(0, 1);
+  count = lib.f.clamp(count, 1, this.terminal.screenSize.width);
+  for (var i = 0; i < count; i++) {
+    this.terminal.forwardTabStop();
+  }
+};
+
+/**
+ * Erase in Display (ED, DECSED).
+ */
+hterm.VT.CSI['J'] =
+hterm.VT.CSI['?J'] = function(parseState, code) {
+  var arg = parseState.args[0];
+
+  if (!arg || arg == 0) {
+    this.terminal.eraseBelow();
+  } else if (arg == 1) {
+    this.terminal.eraseAbove();
+  } else if (arg == 2) {
+    this.terminal.clear();
+  } else if (arg == 3) {
+    if (this.enableCsiJ3) {
+      this.terminal.clearScrollback();
+    }
+  }
+};
+
+/**
+ * Erase in line (EL, DECSEL).
+ */
+hterm.VT.CSI['K'] =
+hterm.VT.CSI['?K'] = function(parseState, code) {
+  var arg = parseState.args[0];
+
+  if (!arg || arg == 0) {
+    this.terminal.eraseToRight();
+  } else if (arg == 1) {
+    this.terminal.eraseToLeft();
+  } else if (arg == 2) {
+    this.terminal.eraseLine();
+  }
+};
+
+/**
+ * Insert Lines (IL).
+ */
+hterm.VT.CSI['L'] = function(parseState) {
+  this.terminal.insertLines(parseState.iarg(0, 1));
+};
+
+/**
+ * Delete Lines (DL).
+ */
+hterm.VT.CSI['M'] = function(parseState) {
+  this.terminal.deleteLines(parseState.iarg(0, 1));
+};
+
+/**
+ * Delete Characters (DCH).
+ *
+ * This command shifts the line contents left, starting at the cursor position.
+ */
+hterm.VT.CSI['P'] = function(parseState) {
+  this.terminal.deleteChars(parseState.iarg(0, 1));
+};
+
+/**
+ * Scroll Up (SU).
+ */
+hterm.VT.CSI['S'] = function(parseState) {
+  this.terminal.vtScrollUp(parseState.iarg(0, 1));
+};
+
+/**
+ * Scroll Down (SD).
+ * Also 'Initiate highlight mouse tracking'.  Will not implement this part.
+ */
+hterm.VT.CSI['T'] = function(parseState) {
+  if (parseState.args.length <= 1)
+    this.terminal.vtScrollDown(parseState.iarg(0, 1));
+};
+
+/**
+ * Reset one or more features of the title modes to the default value.
+ *
+ *   ESC [ > Ps T
+ *
+ * Normally, "reset" disables the feature. It is possible to disable the
+ * ability to reset features by compiling a different default for the title
+ * modes into xterm.
+ *
+ * Ps values:
+ *   0 - Do not set window/icon labels using hexadecimal.
+ *   1 - Do not query window/icon labels using hexadecimal.
+ *   2 - Do not set window/icon labels using UTF-8.
+ *   3 - Do not query window/icon labels using UTF-8.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['>T'] = hterm.VT.ignore;
+
+/**
+ * Erase Characters (ECH).
+ */
+hterm.VT.CSI['X'] = function(parseState) {
+  this.terminal.eraseToRight(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Backward Tabulation (CBT).
+ */
+hterm.VT.CSI['Z'] = function(parseState) {
+  var count = parseState.iarg(0, 1);
+  count = lib.f.clamp(count, 1, this.terminal.screenSize.width);
+  for (var i = 0; i < count; i++) {
+    this.terminal.backwardTabStop();
+  }
+};
+
+/**
+ * Character Position Absolute (HPA).
+ *
+ * Same as Cursor Horizontal Absolute (CHA).
+ */
+hterm.VT.CSI['`'] = hterm.VT.CSI['G'];
+
+/**
+ * Character Position Relative (HPR).
+ */
+hterm.VT.CSI['a'] = function(parseState) {
+  this.terminal.setCursorColumn(this.terminal.getCursorColumn() +
+                                parseState.iarg(0, 1));
+};
+
+/**
+ * Repeat the preceding graphic character.
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['b'] = hterm.VT.ignore;
+
+/**
+ * Send Device Attributes (Primary DA).
+ *
+ * TODO(rginda): This is hardcoded to send back 'VT100 with Advanced Video
+ * Option', but it may be more correct to send a VT220 response once
+ * we fill out the 'Not currently implemented' parts.
+ */
+hterm.VT.CSI['c'] = function(parseState) {
+  if (!parseState.args[0] || parseState.args[0] == 0) {
+    this.terminal.io.sendString('\x1b[?1;2c');
+  }
+};
+
+/**
+ * Send Device Attributes (Secondary DA).
+ *
+ * TODO(rginda): This is hardcoded to send back 'VT100' but it may be more
+ * correct to send a VT220 response once we fill out more 'Not currently
+ * implemented' parts.
+ */
+hterm.VT.CSI['>c'] = function(parseState) {
+  this.terminal.io.sendString('\x1b[>0;256;0c');
+};
+
+/**
+ * Line Position Absolute (VPA).
+ */
+hterm.VT.CSI['d'] = function(parseState) {
+  this.terminal.setAbsoluteCursorRow(parseState.iarg(0, 1) - 1);
+};
+
+/**
+ * Horizontal and Vertical Position (HVP).
+ *
+ * Same as Cursor Position (CUP).
+ */
+hterm.VT.CSI['f'] = hterm.VT.CSI['H'];
+
+/**
+ * Tab Clear (TBC).
+ */
+hterm.VT.CSI['g'] = function(parseState) {
+  if (!parseState.args[0] || parseState.args[0] == 0) {
+    // Clear tab stop at cursor.
+    this.terminal.clearTabStopAtCursor(false);
+  } else if (parseState.args[0] == 3) {
+    // Clear all tab stops.
+    this.terminal.clearAllTabStops();
+  }
+};
+
+/**
+ * Set Mode (SM).
+ */
+hterm.VT.CSI['h'] = function(parseState) {
+  for (var i = 0; i < parseState.args.length; i++) {
+    this.setANSIMode(parseState.args[i], true);
+  }
+};
+
+/**
+ * DEC Private Mode Set (DECSET).
+ */
+hterm.VT.CSI['?h'] = function(parseState) {
+  for (var i = 0; i < parseState.args.length; i++) {
+    this.setDECMode(parseState.args[i], true);
+  }
+};
+
+/**
+ * Media Copy (MC).
+ * Media Copy (MC, DEC Specific).
+ *
+ * These commands control the printer.  Will not implement.
+ */
+hterm.VT.CSI['i'] =
+hterm.VT.CSI['?i'] = hterm.VT.ignore;
+
+/**
+ * Reset Mode (RM).
+ */
+hterm.VT.CSI['l'] = function(parseState) {
+  for (var i = 0; i < parseState.args.length; i++) {
+    this.setANSIMode(parseState.args[i], false);
+  }
+};
+
+/**
+ * DEC Private Mode Reset (DECRST).
+ */
+hterm.VT.CSI['?l'] = function(parseState) {
+  for (var i = 0; i < parseState.args.length; i++) {
+    this.setDECMode(parseState.args[i], false);
+  }
+};
+
+/**
+ * Parse extended SGR 38/48 sequences.
+ *
+ * This deals with the various ISO 8613-6 forms, and with legacy xterm forms
+ * that are common in the wider application world.
+ *
+ * @param {hterm.VT.ParseState} parseState The current input state.
+ * @param {number} i The argument in parseState to start processing.
+ * @param {hterm.TextAttributes} attrs The current text attributes.
+ * @return {Object} The skipCount member defines how many arguments to skip
+ *     (i.e. how many were processed), and the color member is the color that
+ *     was successfully processed, or undefined if not.
+ */
+hterm.VT.prototype.parseSgrExtendedColors = function(parseState, i, attrs) {
+  let ary;
+  let usedSubargs;
+
+  if (parseState.argHasSubargs(i)) {
+    // The ISO 8613-6 compliant form.
+    // e.g. 38:[color choice]:[arg1]:[arg2]:...
+    ary = parseState.args[i].split(':');
+    ary.shift();  // Remove "38".
+    usedSubargs = true;
+  } else if (parseState.argHasSubargs(i + 1)) {
+    // The xterm form which isn't ISO 8613-6 compliant.  Not many emulators
+    // support this, and others actively do not want to.  We'll ignore it so
+    // at least the rest of the stream works correctly.  e.g. 38;2:R:G:B
+    // We return 0 here so we only skip the "38" ... we can't be confident the
+    // next arg is actually supposed to be part of it vs a typo where the next
+    // arg is legit.
+    return {skipCount: 0};
+  } else {
+    // The xterm form which isn't ISO 8613-6 compliant, but many emulators
+    // support, and many applications rely on.
+    // e.g. 38;2;R;G;B
+    ary = parseState.args.slice(i + 1);
+    usedSubargs = false;
+  }
+
+  // Figure out which form to parse.
+  switch (parseInt(ary[0])) {
+    default:  // Unknown.
+    case 0:  // Implementation defined.  We ignore it.
+      return {skipCount: 0};
+
+    case 1: {  // Transparent color.
+      // Require ISO 8613-6 form.
+      if (!usedSubargs)
+        return {skipCount: 0};
+
+      return {
+        color: 'rgba(0, 0, 0, 0)',
+        skipCount: 0,
+      };
+    }
+
+    case 2: {  // RGB color.
+      // Skip over the color space identifier, if it exists.
+      let start;
+      if (usedSubargs) {
+        // The ISO 8613-6 compliant form:
+        //   38:2:<color space id>:R:G:B[:...]
+        // The xterm form isn't ISO 8613-6 compliant.
+        //   38:2:R:G:B
+        // Since the ISO 8613-6 form requires at least 5 arguments,
+        // we can still support the xterm form unambiguously.
+        if (ary.length == 4)
+          start = 1;
+        else
+          start = 2;
+      } else {
+        // The legacy xterm form: 38;2;R;G;B
+        start = 1;
+      }
+
+      // We need at least 3 args for RGB.  If we don't have them, assume this
+      // sequence is corrupted, so don't eat anything more.
+      // We ignore more than 3 args on purpose since ISO 8613-6 defines some,
+      // and we don't care about them.
+      if (ary.length < start + 3)
+        return {skipCount: 0};
+
+      const r = parseState.parseInt(ary[start + 0]);
+      const g = parseState.parseInt(ary[start + 1]);
+      const b = parseState.parseInt(ary[start + 2]);
+      return {
+        color: `rgb(${r}, ${g}, ${b})`,
+        skipCount: usedSubargs ? 0 : 4,
+      };
+    }
+
+    case 3: {  // CMY color.
+      // No need to support xterm/legacy forms as xterm doesn't support CMY.
+      if (!usedSubargs)
+        return {skipCount: 0};
+
+      // We need at least 4 args for CMY.  If we don't have them, assume
+      // this sequence is corrupted.  We ignore the color space identifier,
+      // tolerance, etc...
+      if (ary.length < 4)
+        return {skipCount: 0};
+
+      // TODO: See CMYK below.
+      const c = parseState.parseInt(ary[1]);
+      const m = parseState.parseInt(ary[2]);
+      const y = parseState.parseInt(ary[3]);
+      return {skipCount: 0};
+    }
+
+    case 4: {  // CMYK color.
+      // No need to support xterm/legacy forms as xterm doesn't support CMYK.
+      if (!usedSubargs)
+        return {skipCount: 0};
+
+      // We need at least 5 args for CMYK.  If we don't have them, assume
+      // this sequence is corrupted.  We ignore the color space identifier,
+      // tolerance, etc...
+      if (ary.length < 5)
+        return {skipCount: 0};
+
+      // TODO: Implement this.
+      // Might wait until CSS4 is adopted for device-cmyk():
+      // https://www.w3.org/TR/css-color-4/#cmyk-colors
+      // Or normalize it to RGB ourselves:
+      // https://www.w3.org/TR/css-color-4/#cmyk-rgb
+      const c = parseState.parseInt(ary[1]);
+      const m = parseState.parseInt(ary[2]);
+      const y = parseState.parseInt(ary[3]);
+      const k = parseState.parseInt(ary[4]);
+      return {skipCount: 0};
+    }
+
+    case 5: {  // Color palette index.
+      // If we're short on args, assume this sequence is corrupted, so don't
+      // eat anything more.
+      if (ary.length < 2)
+        return {skipCount: 0};
+
+      // Support 38:5:P (ISO 8613-6) and 38;5;P (xterm/legacy).
+      // We also ignore extra args with 38:5:P:[...], but more for laziness.
+      const ret = {
+        skipCount: usedSubargs ? 0 : 2,
+      };
+      const color = parseState.parseInt(ary[1]);
+      if (color < attrs.colorPalette.length)
+        ret.color = color;
+      return ret;
+    }
+  }
+};
+
+/**
+ * Character Attributes (SGR).
+ *
+ * Iterate through the list of arguments, applying the attribute changes based
+ * on the argument value...
+ */
+hterm.VT.CSI['m'] = function(parseState) {
+  var attrs = this.terminal.getTextAttributes();
+
+  if (!parseState.args.length) {
+    attrs.reset();
+    return;
+  }
+
+  for (var i = 0; i < parseState.args.length; i++) {
+    // If this argument has subargs (i.e. it has args followed by colons),
+    // the iarg logic will implicitly truncate that off for us.
+    var arg = parseState.iarg(i, 0);
+
+    if (arg < 30) {
+      if (arg == 0) {  // Normal (default).
+        attrs.reset();
+      } else if (arg == 1) {  // Bold.
+        attrs.bold = true;
+      } else if (arg == 2) {  // Faint.
+        attrs.faint = true;
+      } else if (arg == 3) {  // Italic.
+        attrs.italic = true;
+      } else if (arg == 4) {  // Underline.
+        if (parseState.argHasSubargs(i)) {
+          const uarg = parseState.args[i].split(':')[1];
+          if (uarg == 0)
+            attrs.underline = false;
+          else if (uarg == 1)
+            attrs.underline = 'solid';
+          else if (uarg == 2)
+            attrs.underline = 'double';
+          else if (uarg == 3)
+            attrs.underline = 'wavy';
+          else if (uarg == 4)
+            attrs.underline = 'dotted';
+          else if (uarg == 5)
+            attrs.underline = 'dashed';
+        } else {
+          attrs.underline = 'solid';
+        }
+      } else if (arg == 5) {  // Blink.
+        attrs.blink = true;
+      } else if (arg == 7) {  // Inverse.
+        attrs.inverse = true;
+      } else if (arg == 8) {  // Invisible.
+        attrs.invisible = true;
+      } else if (arg == 9) {  // Crossed out.
+        attrs.strikethrough = true;
+      } else if (arg == 21) {  // Double underlined.
+        attrs.underline = 'double';
+      } else if (arg == 22) {  // Not bold & not faint.
+        attrs.bold = false;
+        attrs.faint = false;
+      } else if (arg == 23) {  // Not italic.
+        attrs.italic = false;
+      } else if (arg == 24) {  // Not underlined.
+        attrs.underline = false;
+      } else if (arg == 25) {  // Not blink.
+        attrs.blink = false;
+      } else if (arg == 27) {  // Steady.
+        attrs.inverse = false;
+      } else if (arg == 28) {  // Visible.
+        attrs.invisible = false;
+      } else if (arg == 29) {  // Not crossed out.
+        attrs.strikethrough = false;
+      }
+
+    } else if (arg < 50) {
+      // Select fore/background color from bottom half of 16 color palette
+      // or from the 256 color palette or alternative specify color in fully
+      // qualified rgb(r, g, b) form.
+      if (arg < 38) {
+        attrs.foregroundSource = arg - 30;
+
+      } else if (arg == 38) {
+        const result = this.parseSgrExtendedColors(parseState, i, attrs);
+        if (result.color !== undefined)
+          attrs.foregroundSource = result.color;
+        i += result.skipCount;
+
+      } else if (arg == 39) {
+        attrs.foregroundSource = attrs.SRC_DEFAULT;
+
+      } else if (arg < 48) {
+        attrs.backgroundSource = arg - 40;
+
+      } else if (arg == 48) {
+        const result = this.parseSgrExtendedColors(parseState, i, attrs);
+        if (result.color !== undefined)
+          attrs.backgroundSource = result.color;
+        i += result.skipCount;
+
+      } else {
+        attrs.backgroundSource = attrs.SRC_DEFAULT;
+      }
+
+    } else if (arg == 58) {  // Underline coloring.
+      const result = this.parseSgrExtendedColors(parseState, i, attrs);
+      if (result.color !== undefined)
+        attrs.underlineSource = result.color;
+      i += result.skipCount;
+
+    } else if (arg == 59) {  // Disable underline coloring.
+      attrs.underlineSource = attrs.SRC_DEFAULT;
+
+    } else if (arg >= 90 && arg <= 97) {
+      attrs.foregroundSource = arg - 90 + 8;
+
+    } else if (arg >= 100 && arg <= 107) {
+      attrs.backgroundSource = arg - 100 + 8;
+    }
+  }
+
+  attrs.setDefaults(this.terminal.getForegroundColor(),
+                    this.terminal.getBackgroundColor());
+};
+
+// SGR calls can handle subargs.
+hterm.VT.CSI['m'].supportsSubargs = true;
+
+/**
+ * Set xterm-specific keyboard modes.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['>m'] = hterm.VT.ignore;
+
+/**
+ * Device Status Report (DSR, DEC Specific).
+ *
+ * 5 - Status Report. Result (OK) is CSI 0 n
+ * 6 - Report Cursor Position (CPR) [row;column]. Result is CSI r ; c R
+ */
+hterm.VT.CSI['n'] = function(parseState) {
+  if (parseState.args[0] == 5) {
+    this.terminal.io.sendString('\x1b0n');
+  } else if (parseState.args[0] == 6) {
+    var row = this.terminal.getCursorRow() + 1;
+    var col = this.terminal.getCursorColumn() + 1;
+    this.terminal.io.sendString('\x1b[' + row + ';' + col + 'R');
+  }
+};
+
+/**
+ * Disable modifiers which may be enabled via CSI['>m'].
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['>n'] = hterm.VT.ignore;
+
+/**
+ * Device Status Report (DSR, DEC Specific).
+ *
+ * 6  - Report Cursor Position (CPR) [row;column] as CSI ? r ; c R
+ * 15 - Report Printer status as CSI ? 1 0 n (ready) or
+ *      CSI ? 1 1 n (not ready).
+ * 25 - Report UDK status as CSI ? 2 0 n (unlocked) or CSI ? 2 1 n (locked).
+ * 26 - Report Keyboard status as CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).
+ *      The last two parameters apply to VT400 & up, and denote keyboard ready
+ *      and LK01 respectively.
+ * 53 - Report Locator status as CSI ? 5 3 n Locator available, if compiled-in,
+ *      or CSI ? 5 0 n No Locator, if not.
+ */
+hterm.VT.CSI['?n'] = function(parseState) {
+  if (parseState.args[0] == 6) {
+    var row = this.terminal.getCursorRow() + 1;
+    var col = this.terminal.getCursorColumn() + 1;
+    this.terminal.io.sendString('\x1b[' + row + ';' + col + 'R');
+  } else if (parseState.args[0] == 15) {
+    this.terminal.io.sendString('\x1b[?11n');
+  } else if (parseState.args[0] == 25) {
+    this.terminal.io.sendString('\x1b[?21n');
+  } else if (parseState.args[0] == 26) {
+    this.terminal.io.sendString('\x1b[?12;1;0;0n');
+  } else if (parseState.args[0] == 53) {
+    this.terminal.io.sendString('\x1b[?50n');
+  }
+};
+
+/**
+ * This is used by xterm to decide whether to hide the pointer cursor as the
+ * user types.
+ *
+ * Valid values for the parameter:
+ *   0 - Never hide the pointer.
+ *   1 - Hide if the mouse tracking mode is not enabled.
+ *   2 - Always hide the pointer.
+ *
+ * If no parameter is given, xterm uses the default, which is 1.
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['>p'] = hterm.VT.ignore;
+
+/**
+ * Soft terminal reset (DECSTR).
+ */
+hterm.VT.CSI['!p'] = function() {
+  this.terminal.softReset();
+};
+
+/**
+ * Request ANSI Mode (DECRQM).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['$p'] = hterm.VT.ignore;
+hterm.VT.CSI['?$p'] = hterm.VT.ignore;
+
+/**
+ * Set conformance level (DECSCL).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['"p'] = hterm.VT.ignore;
+
+/**
+ * Load LEDs (DECLL).
+ *
+ * Not currently implemented.  Could be implemented as virtual LEDs overlaying
+ * the terminal if anyone cares.
+ */
+hterm.VT.CSI['q'] = hterm.VT.ignore;
+
+/**
+ * Set cursor style (DECSCUSR, VT520).
+ */
+hterm.VT.CSI[' q'] = function(parseState) {
+  var arg = parseState.args[0];
+
+  if (arg == 0 || arg == 1) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK);
+    this.terminal.setCursorBlink(true);
+  } else if (arg == 2) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK);
+    this.terminal.setCursorBlink(false);
+  } else if (arg == 3) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE);
+    this.terminal.setCursorBlink(true);
+  } else if (arg == 4) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE);
+    this.terminal.setCursorBlink(false);
+  } else if (arg == 5) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.BEAM);
+    this.terminal.setCursorBlink(true);
+  } else if (arg == 6) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.BEAM);
+    this.terminal.setCursorBlink(false);
+  } else {
+    console.warn('Unknown cursor style: ' + arg);
+  }
+};
+
+/**
+ * Select character protection attribute (DECSCA).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['"q'] = hterm.VT.ignore;
+
+/**
+ * Set Scrolling Region (DECSTBM).
+ */
+hterm.VT.CSI['r'] = function(parseState) {
+  var args = parseState.args;
+  var scrollTop = args[0] ? parseInt(args[0], 10) -1 : null;
+  var scrollBottom = args[1] ? parseInt(args[1], 10) - 1 : null;
+  this.terminal.setVTScrollRegion(scrollTop, scrollBottom);
+  this.terminal.setCursorPosition(0, 0);
+};
+
+/**
+ * Restore DEC Private Mode Values.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['?r'] = hterm.VT.ignore;
+
+/**
+ * Change Attributes in Rectangular Area (DECCARA)
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$r'] = hterm.VT.ignore;
+
+/**
+ * Save cursor (ANSI.SYS)
+ */
+hterm.VT.CSI['s'] = function() {
+  this.terminal.saveCursorAndState();
+};
+
+/**
+ * Save DEC Private Mode Values.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['?s'] = hterm.VT.ignore;
+
+/**
+ * Window manipulation (from dtterm, as well as extensions).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['t'] = hterm.VT.ignore;
+
+/**
+ * Reverse Attributes in Rectangular Area (DECRARA).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$t'] = hterm.VT.ignore;
+
+/**
+ * Set one or more features of the title modes.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['>t'] = hterm.VT.ignore;
+
+/**
+ * Set warning-bell volume (DECSWBV, VT520).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI[' t'] = hterm.VT.ignore;
+
+/**
+ * Restore cursor (ANSI.SYS).
+ */
+hterm.VT.CSI['u'] = function() {
+  this.terminal.restoreCursorAndState();
+};
+
+/**
+ * Set margin-bell volume (DECSMBV, VT520).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI[' u'] = hterm.VT.ignore;
+
+/**
+ * Copy Rectangular Area (DECCRA, VT400 and up).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$v'] = hterm.VT.ignore;
+
+/**
+ * Enable Filter Rectangle (DECEFR).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['\'w'] = hterm.VT.ignore;
+
+/**
+ * Request Terminal Parameters (DECREQTPARM).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['x'] = hterm.VT.ignore;
+
+/**
+ * Select Attribute Change Extent (DECSACE).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['*x'] = hterm.VT.ignore;
+
+/**
+ * Fill Rectangular Area (DECFRA), VT420 and up.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$x'] = hterm.VT.ignore;
+
+/**
+ * vt_tiledata (as used by NAOhack and UnNetHack)
+ * (see https://nethackwiki.com/wiki/Vt_tiledata for more info)
+ *
+ * Implemented as far as we care (start a glyph and end a glyph).
+ */
+hterm.VT.CSI['z'] = function(parseState) {
+  if (parseState.args.length < 1)
+    return;
+  var arg = parseState.args[0];
+  if (arg == 0) {
+    // Start a glyph (one parameter, the glyph number).
+    if (parseState.args.length < 2)
+      return;
+    this.terminal.getTextAttributes().tileData = parseState.args[1];
+  } else if (arg == 1) {
+    // End a glyph.
+    this.terminal.getTextAttributes().tileData = null;
+  }
+};
+
+/**
+ * Enable Locator Reporting (DECELR).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['\'z'] = hterm.VT.ignore;
+
+/**
+ * Erase Rectangular Area (DECERA), VT400 and up.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$z'] = hterm.VT.ignore;
+
+/**
+ * Select Locator Events (DECSLE).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['\'{'] = hterm.VT.ignore;
+
+/**
+ * Request Locator Position (DECRQLP).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['\'|'] = hterm.VT.ignore;
+
+/**
+ * Insert Columns (DECIC), VT420 and up.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['\'}'] = hterm.VT.ignore;
+
+/**
+ * Delete P s Columns (DECDC), VT420 and up.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['\'~'] = hterm.VT.ignore;
+// SOURCE FILE: hterm/js/hterm_vt_character_map.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Character map object.
+ *
+ * Mapping from received to display character, used depending on the active
+ * VT character set.
+ *
+ * GR maps are not currently supported.
+ *
+ * @param {string} description A human readable description of this map.
+ * @param {Object} glmap The GL mapping from input to output characters.
+ */
+hterm.VT.CharacterMap = function(description, glmap) {
+  /**
+   * Short description for this character set, useful for debugging.
+   */
+  this.description = description;
+
+  /**
+   * The function to call to when this map is installed in GL.
+   */
+  this.GL = null;
+
+  // Always keep an unmodified reference to the map.
+  // This allows us to sanely reset back to the original state.
+  this.glmapBase_ = glmap;
+
+  // Now sync the internal state as needed.
+  this.sync_();
+};
+
+/**
+ * Internal helper for resyncing internal state.
+ *
+ * Used when the mappings change.
+ *
+ * @param {Object?} opt_glmap Additional mappings to overlay on top of the
+ *     base mapping.
+ */
+hterm.VT.CharacterMap.prototype.sync_ = function(opt_glmap) {
+  // If there are no maps, then reset the state back.
+  if (!this.glmapBase_ && !opt_glmap) {
+    this.GL = null;
+    delete this.glmap_;
+    delete this.glre_;
+    return;
+  }
+
+  // Set the the GL mapping.  If we're given a custom mapping, then create a
+  // new object to hold the merged map.  This way we can cleanly reset back.
+  if (opt_glmap)
+    this.glmap_ = Object.assign({}, this.glmapBase_, opt_glmap);
+  else
+    this.glmap_ = this.glmapBase_;
+
+  var glchars = Object.keys(this.glmap_).map((key) =>
+      '\\x' + lib.f.zpad(key.charCodeAt(0).toString(16)));
+  this.glre_ = new RegExp('[' + glchars.join('') + ']', 'g');
+
+  this.GL = (str) => str.replace(this.glre_, (ch) => this.glmap_[ch]);
+};
+
+/**
+ * Reset map back to original mappings (discarding runtime updates).
+ *
+ * Specifically, any calls to setOverrides will be discarded.
+ */
+hterm.VT.CharacterMap.prototype.reset = function() {
+  // If we haven't been given a custom mapping, then there's nothing to reset.
+  if (this.glmap_ !== this.glmapBase_)
+    this.sync_();
+};
+
+/**
+ * Merge custom changes to this map.
+ *
+ * The input map need not duplicate the existing mappings as it is merged with
+ * the existing base map (what was created with).  Subsequent calls to this
+ * will throw away previous override settings.
+ *
+ * @param {Object} glmap The custom map to override existing mappings.
+ */
+hterm.VT.CharacterMap.prototype.setOverrides = function(glmap) {
+  this.sync_(glmap);
+};
+
+/**
+ * Return a copy of this mapping.
+ *
+ * @return {hterm.VT.CharacterMap} A new hterm.VT.CharacterMap instance.
+ */
+hterm.VT.CharacterMap.prototype.clone = function() {
+  var map = new hterm.VT.CharacterMap(this.description, this.glmapBase_);
+  if (this.glmap_ !== this.glmapBase_)
+    map.setOverrides(this.glmap_);
+  return map;
+};
+
+/**
+ * Table of character maps.
+ */
+hterm.VT.CharacterMaps = function() {
+  this.maps_ = hterm.VT.CharacterMaps.DefaultMaps;
+
+  // Always keep an unmodified reference to the map.
+  // This allows us to sanely reset back to the original state.
+  this.mapsBase_ = this.maps_;
+};
+
+/**
+ * Look up a previously registered map.
+ *
+ * @param {String} name The name of the map to lookup.
+ * @return {hterm.VT.CharacterMap} The map, if it's been registered.
+ */
+hterm.VT.CharacterMaps.prototype.getMap = function(name) {
+  if (this.maps_.hasOwnProperty(name))
+    return this.maps_[name];
+  else
+    return undefined;
+};
+
+/**
+ * Register a new map.
+ *
+ * Any previously registered maps by this name will be discarded.
+ *
+ * @param {String} name The name of the map.
+ * @param {hterm.VT.CharacterMap} map The map to register.
+ */
+hterm.VT.CharacterMaps.prototype.addMap = function(name, map) {
+  if (this.maps_ === this.mapsBase_)
+    this.maps_ = Object.assign({}, this.mapsBase_);
+  this.maps_[name] = map;
+};
+
+/**
+ * Reset the table and all its maps back to original state.
+ */
+hterm.VT.CharacterMaps.prototype.reset = function() {
+  if (this.maps_ !== hterm.VT.CharacterMaps.DefaultMaps)
+    this.maps_ = hterm.VT.CharacterMaps.DefaultMaps;
+};
+
+/**
+ * Merge custom changes to this table.
+ *
+ * @param {Object} maps A set of hterm.VT.CharacterMap objects.
+ */
+hterm.VT.CharacterMaps.prototype.setOverrides = function(maps) {
+  if (this.maps_ === this.mapsBase_)
+    this.maps_ = Object.assign({}, this.mapsBase_);
+
+  for (var name in maps) {
+    var map = this.getMap(name);
+    if (map !== undefined) {
+      this.maps_[name] = map.clone();
+      this.maps_[name].setOverrides(maps[name]);
+    } else
+      this.addMap(name, new hterm.VT.CharacterMap('user ' + name, maps[name]));
+  }
+};
+
+/**
+ * The default set of supported character maps.
+ */
+hterm.VT.CharacterMaps.DefaultMaps = {};
+
+/**
+ * VT100 Graphic character map.
+ * http://vt100.net/docs/vt220-rm/table2-4.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['0'] = new hterm.VT.CharacterMap(
+    'graphic', {
+      '\x60':'\u25c6',  // ` -> diamond
+      '\x61':'\u2592',  // a -> grey-box
+      '\x62':'\u2409',  // b -> h/t
+      '\x63':'\u240c',  // c -> f/f
+      '\x64':'\u240d',  // d -> c/r
+      '\x65':'\u240a',  // e -> l/f
+      '\x66':'\u00b0',  // f -> degree
+      '\x67':'\u00b1',  // g -> +/-
+      '\x68':'\u2424',  // h -> n/l
+      '\x69':'\u240b',  // i -> v/t
+      '\x6a':'\u2518',  // j -> bottom-right
+      '\x6b':'\u2510',  // k -> top-right
+      '\x6c':'\u250c',  // l -> top-left
+      '\x6d':'\u2514',  // m -> bottom-left
+      '\x6e':'\u253c',  // n -> line-cross
+      '\x6f':'\u23ba',  // o -> scan1
+      '\x70':'\u23bb',  // p -> scan3
+      '\x71':'\u2500',  // q -> scan5
+      '\x72':'\u23bc',  // r -> scan7
+      '\x73':'\u23bd',  // s -> scan9
+      '\x74':'\u251c',  // t -> left-tee
+      '\x75':'\u2524',  // u -> right-tee
+      '\x76':'\u2534',  // v -> bottom-tee
+      '\x77':'\u252c',  // w -> top-tee
+      '\x78':'\u2502',  // x -> vertical-line
+      '\x79':'\u2264',  // y -> less-equal
+      '\x7a':'\u2265',  // z -> greater-equal
+      '\x7b':'\u03c0',  // { -> pi
+      '\x7c':'\u2260',  // | -> not-equal
+      '\x7d':'\u00a3',  // } -> british-pound
+      '\x7e':'\u00b7',  // ~ -> dot
+    });
+
+/**
+ * British character map.
+ * http://vt100.net/docs/vt220-rm/table2-5.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['A'] = new hterm.VT.CharacterMap(
+    'british', {
+      '\x23': '\u00a3',  // # -> british-pound
+    });
+
+/**
+ * US ASCII map, no changes.
+ */
+hterm.VT.CharacterMaps.DefaultMaps['B'] = new hterm.VT.CharacterMap(
+    'us', null);
+
+/**
+ * Dutch character map.
+ * http://vt100.net/docs/vt220-rm/table2-6.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['4'] = new hterm.VT.CharacterMap(
+    'dutch', {
+      '\x23': '\u00a3',  // # -> british-pound
+
+      '\x40': '\u00be',  // @ -> 3/4
+
+      '\x5b': '\u0132',  // [ -> 'ij' ligature (xterm goes with \u00ff?)
+      '\x5c': '\u00bd',  // \ -> 1/2
+      '\x5d': '\u007c',  // ] -> vertical bar
+
+      '\x7b': '\u00a8',  // { -> two dots
+      '\x7c': '\u0066',  // | -> f
+      '\x7d': '\u00bc',  // } -> 1/4
+      '\x7e': '\u00b4',  // ~ -> acute
+    });
+
+/**
+ * Finnish character map.
+ * http://vt100.net/docs/vt220-rm/table2-7.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['C'] =
+hterm.VT.CharacterMaps.DefaultMaps['5'] = new hterm.VT.CharacterMap(
+    'finnish', {
+      '\x5b': '\u00c4',  // [ -> 'A' umlaut
+      '\x5c': '\u00d6',  // \ -> 'O' umlaut
+      '\x5d': '\u00c5',  // ] -> 'A' ring
+      '\x5e': '\u00dc',  // ~ -> 'u' umlaut
+
+      '\x60': '\u00e9',  // ` -> 'e' acute
+
+      '\x7b': '\u00e4',  // { -> 'a' umlaut
+      '\x7c': '\u00f6',  // | -> 'o' umlaut
+      '\x7d': '\u00e5',  // } -> 'a' ring
+      '\x7e': '\u00fc',  // ~ -> 'u' umlaut
+    });
+
+/**
+ * French character map.
+ * http://vt100.net/docs/vt220-rm/table2-8.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['R'] = new hterm.VT.CharacterMap(
+    'french', {
+      '\x23': '\u00a3',  // # -> british-pound
+
+      '\x40': '\u00e0',  // @ -> 'a' grave
+
+      '\x5b': '\u00b0',  // [ -> ring
+      '\x5c': '\u00e7',  // \ -> 'c' cedilla
+      '\x5d': '\u00a7',  // ] -> section symbol (double s)
+
+      '\x7b': '\u00e9',  // { -> 'e' acute
+      '\x7c': '\u00f9',  // | -> 'u' grave
+      '\x7d': '\u00e8',  // } -> 'e' grave
+      '\x7e': '\u00a8',  // ~ -> umlaut
+    });
+
+/**
+ * French Canadian character map.
+ * http://vt100.net/docs/vt220-rm/table2-9.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['Q'] = new hterm.VT.CharacterMap(
+    'french canadian', {
+      '\x40': '\u00e0',  // @ -> 'a' grave
+
+      '\x5b': '\u00e2',  // [ -> 'a' circumflex
+      '\x5c': '\u00e7',  // \ -> 'c' cedilla
+      '\x5d': '\u00ea',  // ] -> 'e' circumflex
+      '\x5e': '\u00ee',  // ^ -> 'i' circumflex
+
+      '\x60': '\u00f4',  // ` -> 'o' circumflex
+
+      '\x7b': '\u00e9',  // { -> 'e' acute
+      '\x7c': '\u00f9',  // | -> 'u' grave
+      '\x7d': '\u00e8',  // } -> 'e' grave
+      '\x7e': '\u00fb',  // ~ -> 'u' circumflex
+    });
+
+/**
+ * German character map.
+ * http://vt100.net/docs/vt220-rm/table2-10.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['K'] = new hterm.VT.CharacterMap(
+    'german', {
+      '\x40': '\u00a7',  // @ -> section symbol (double s)
+
+      '\x5b': '\u00c4',  // [ -> 'A' umlaut
+      '\x5c': '\u00d6',  // \ -> 'O' umlaut
+      '\x5d': '\u00dc',  // ] -> 'U' umlaut
+
+      '\x7b': '\u00e4',  // { -> 'a' umlaut
+      '\x7c': '\u00f6',  // | -> 'o' umlaut
+      '\x7d': '\u00fc',  // } -> 'u' umlaut
+      '\x7e': '\u00df',  // ~ -> eszett
+    });
+
+/**
+ * Italian character map.
+ * http://vt100.net/docs/vt220-rm/table2-11.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['Y'] = new hterm.VT.CharacterMap(
+    'italian', {
+      '\x23': '\u00a3',  // # -> british-pound
+
+      '\x40': '\u00a7',  // @ -> section symbol (double s)
+
+      '\x5b': '\u00b0',  // [ -> ring
+      '\x5c': '\u00e7',  // \ -> 'c' cedilla
+      '\x5d': '\u00e9',  // ] -> 'e' acute
+
+      '\x60': '\u00f9',  // ` -> 'u' grave
+
+      '\x7b': '\u00e0',  // { -> 'a' grave
+      '\x7c': '\u00f2',  // | -> 'o' grave
+      '\x7d': '\u00e8',  // } -> 'e' grave
+      '\x7e': '\u00ec',  // ~ -> 'i' grave
+    });
+
+/**
+ * Norwegian/Danish character map.
+ * http://vt100.net/docs/vt220-rm/table2-12.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['E'] =
+hterm.VT.CharacterMaps.DefaultMaps['6'] = new hterm.VT.CharacterMap(
+    'norwegian/danish', {
+      '\x40': '\u00c4',  // @ -> 'A' umlaut
+
+      '\x5b': '\u00c6',  // [ -> 'AE' ligature
+      '\x5c': '\u00d8',  // \ -> 'O' stroke
+      '\x5d': '\u00c5',  // ] -> 'A' ring
+      '\x5e': '\u00dc',  // ^ -> 'U' umlaut
+
+      '\x60': '\u00e4',  // ` -> 'a' umlaut
+
+      '\x7b': '\u00e6',  // { -> 'ae' ligature
+      '\x7c': '\u00f8',  // | -> 'o' stroke
+      '\x7d': '\u00e5',  // } -> 'a' ring
+      '\x7e': '\u00fc',  // ~ -> 'u' umlaut
+    });
+
+/**
+ * Spanish character map.
+ * http://vt100.net/docs/vt220-rm/table2-13.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['Z'] = new hterm.VT.CharacterMap(
+    'spanish', {
+      '\x23': '\u00a3',  // # -> british-pound
+
+      '\x40': '\u00a7',  // @ -> section symbol (double s)
+
+      '\x5b': '\u00a1',  // [ -> '!' inverted
+      '\x5c': '\u00d1',  // \ -> 'N' tilde
+      '\x5d': '\u00bf',  // ] -> '?' inverted
+
+      '\x7b': '\u00b0',  // { -> ring
+      '\x7c': '\u00f1',  // | -> 'n' tilde
+      '\x7d': '\u00e7',  // } -> 'c' cedilla
+    });
+
+/**
+ * Swedish character map.
+ * http://vt100.net/docs/vt220-rm/table2-14.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['7'] =
+hterm.VT.CharacterMaps.DefaultMaps['H'] = new hterm.VT.CharacterMap(
+    'swedish', {
+      '\x40': '\u00c9',  // @ -> 'E' acute
+
+      '\x5b': '\u00c4',  // [ -> 'A' umlaut
+      '\x5c': '\u00d6',  // \ -> 'O' umlaut
+      '\x5d': '\u00c5',  // ] -> 'A' ring
+      '\x5e': '\u00dc',  // ^ -> 'U' umlaut
+
+      '\x60': '\u00e9',  // ` -> 'e' acute
+
+      '\x7b': '\u00e4',  // { -> 'a' umlaut
+      '\x7c': '\u00f6',  // | -> 'o' umlaut
+      '\x7d': '\u00e5',  // } -> 'a' ring
+      '\x7e': '\u00fc',  // ~ -> 'u' umlaut
+    });
+
+/**
+ * Swiss character map.
+ * http://vt100.net/docs/vt220-rm/table2-15.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['='] = new hterm.VT.CharacterMap(
+    'swiss', {
+      '\x23': '\u00f9',  // # -> 'u' grave
+
+      '\x40': '\u00e0',  // @ -> 'a' grave
+
+      '\x5b': '\u00e9',  // [ -> 'e' acute
+      '\x5c': '\u00e7',  // \ -> 'c' cedilla
+      '\x5d': '\u00ea',  // ] -> 'e' circumflex
+      '\x5e': '\u00ee',  // ^ -> 'i' circumflex
+      '\x5f': '\u00e8',  // _ -> 'e' grave
+
+      '\x60': '\u00f4',  // ` -> 'o' circumflex
+
+      '\x7b': '\u00e4',  // { -> 'a' umlaut
+      '\x7c': '\u00f6',  // | -> 'o' umlaut
+      '\x7d': '\u00fc',  // } -> 'u' umlaut
+      '\x7e': '\u00fb',  // ~ -> 'u' circumflex
+    });
+lib.resource.add('hterm/audio/bell', 'audio/ogg;base64',
+'T2dnUwACAAAAAAAAAADhqW5KAAAAAMFvEjYBHgF2b3JiaXMAAAAAAYC7AAAAAAAAAHcBAAAAAAC4' +
+'AU9nZ1MAAAAAAAAAAAAA4aluSgEAAAAAesI3EC3//////////////////8kDdm9yYmlzHQAAAFhp' +
+'cGguT3JnIGxpYlZvcmJpcyBJIDIwMDkwNzA5AAAAAAEFdm9yYmlzKUJDVgEACAAAADFMIMWA0JBV' +
+'AAAQAABgJCkOk2ZJKaWUoSh5mJRISSmllMUwiZiUicUYY4wxxhhjjDHGGGOMIDRkFQAABACAKAmO' +
+'o+ZJas45ZxgnjnKgOWlOOKcgB4pR4DkJwvUmY26mtKZrbs4pJQgNWQUAAAIAQEghhRRSSCGFFGKI' +
+'IYYYYoghhxxyyCGnnHIKKqigggoyyCCDTDLppJNOOumoo4466ii00EILLbTSSkwx1VZjrr0GXXxz' +
+'zjnnnHPOOeecc84JQkNWAQAgAAAEQgYZZBBCCCGFFFKIKaaYcgoyyIDQkFUAACAAgAAAAABHkRRJ' +
+'sRTLsRzN0SRP8ixREzXRM0VTVE1VVVVVdV1XdmXXdnXXdn1ZmIVbuH1ZuIVb2IVd94VhGIZhGIZh' +
+'GIZh+H3f933f930gNGQVACABAKAjOZbjKaIiGqLiOaIDhIasAgBkAAAEACAJkiIpkqNJpmZqrmmb' +
+'tmirtm3LsizLsgyEhqwCAAABAAQAAAAAAKBpmqZpmqZpmqZpmqZpmqZpmqZpmmZZlmVZlmVZlmVZ' +
+'lmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZQGjIKgBAAgBAx3Ecx3EkRVIkx3IsBwgNWQUAyAAA' +
+'CABAUizFcjRHczTHczzHczxHdETJlEzN9EwPCA1ZBQAAAgAIAAAAAABAMRzFcRzJ0SRPUi3TcjVX' +
+'cz3Xc03XdV1XVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVYHQkFUAAAQAACGdZpZq' +
+'gAgzkGEgNGQVAIAAAAAYoQhDDAgNWQUAAAQAAIih5CCa0JrzzTkOmuWgqRSb08GJVJsnuamYm3PO' +
+'OeecbM4Z45xzzinKmcWgmdCac85JDJqloJnQmnPOeRKbB62p0ppzzhnnnA7GGWGcc85p0poHqdlY' +
+'m3POWdCa5qi5FJtzzomUmye1uVSbc84555xzzjnnnHPOqV6czsE54Zxzzonam2u5CV2cc875ZJzu' +
+'zQnhnHPOOeecc84555xzzglCQ1YBAEAAAARh2BjGnYIgfY4GYhQhpiGTHnSPDpOgMcgppB6NjkZK' +
+'qYNQUhknpXSC0JBVAAAgAACEEFJIIYUUUkghhRRSSCGGGGKIIaeccgoqqKSSiirKKLPMMssss8wy' +
+'y6zDzjrrsMMQQwwxtNJKLDXVVmONteaec645SGultdZaK6WUUkoppSA0ZBUAAAIAQCBkkEEGGYUU' +
+'UkghhphyyimnoIIKCA1ZBQAAAgAIAAAA8CTPER3RER3RER3RER3RER3P8RxREiVREiXRMi1TMz1V' +
+'VFVXdm1Zl3Xbt4Vd2HXf133f141fF4ZlWZZlWZZlWZZlWZZlWZZlCUJDVgEAIAAAAEIIIYQUUkgh' +
+'hZRijDHHnINOQgmB0JBVAAAgAIAAAAAAR3EUx5EcyZEkS7IkTdIszfI0T/M00RNFUTRNUxVd0RV1' +
+'0xZlUzZd0zVl01Vl1XZl2bZlW7d9WbZ93/d93/d93/d93/d939d1IDRkFQAgAQCgIzmSIimSIjmO' +
+'40iSBISGrAIAZAAABACgKI7iOI4jSZIkWZImeZZniZqpmZ7pqaIKhIasAgAAAQAEAAAAAACgaIqn' +
+'mIqniIrniI4oiZZpiZqquaJsyq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7rukBo' +
+'yCoAQAIAQEdyJEdyJEVSJEVyJAcIDVkFAMgAAAgAwDEcQ1Ikx7IsTfM0T/M00RM90TM9VXRFFwgN' +
+'WQUAAAIACAAAAAAAwJAMS7EczdEkUVIt1VI11VItVVQ9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV' +
+'VVVVVVVVVVVV1TRN0zSB0JCVAAAZAAAjQQYZhBCKcpBCbj1YCDHmJAWhOQahxBiEpxAzDDkNInSQ' +
+'QSc9uJI5wwzz4FIoFURMg40lN44gDcKmXEnlOAhCQ1YEAFEAAIAxyDHEGHLOScmgRM4xCZ2UyDkn' +
+'pZPSSSktlhgzKSWmEmPjnKPSScmklBhLip2kEmOJrQAAgAAHAIAAC6HQkBUBQBQAAGIMUgophZRS' +
+'zinmkFLKMeUcUko5p5xTzjkIHYTKMQadgxAppRxTzinHHITMQeWcg9BBKAAAIMABACDAQig0ZEUA' +
+'ECcA4HAkz5M0SxQlSxNFzxRl1xNN15U0zTQ1UVRVyxNV1VRV2xZNVbYlTRNNTfRUVRNFVRVV05ZN' +
+'VbVtzzRl2VRV3RZV1bZl2xZ+V5Z13zNNWRZV1dZNVbV115Z9X9ZtXZg0zTQ1UVRVTRRV1VRV2zZV' +
+'17Y1UXRVUVVlWVRVWXZlWfdVV9Z9SxRV1VNN2RVVVbZV2fVtVZZ94XRVXVdl2fdVWRZ+W9eF4fZ9' +
+'4RhV1dZN19V1VZZ9YdZlYbd13yhpmmlqoqiqmiiqqqmqtm2qrq1bouiqoqrKsmeqrqzKsq+rrmzr' +
+'miiqrqiqsiyqqiyrsqz7qizrtqiquq3KsrCbrqvrtu8LwyzrunCqrq6rsuz7qizruq3rxnHrujB8' +
+'pinLpqvquqm6um7runHMtm0co6rqvirLwrDKsu/rui+0dSFRVXXdlF3jV2VZ921fd55b94WybTu/' +
+'rfvKceu60vg5z28cubZtHLNuG7+t+8bzKz9hOI6lZ5q2baqqrZuqq+uybivDrOtCUVV9XZVl3zdd' +
+'WRdu3zeOW9eNoqrquirLvrDKsjHcxm8cuzAcXds2jlvXnbKtC31jyPcJz2vbxnH7OuP2daOvDAnH' +
+'jwAAgAEHAIAAE8pAoSErAoA4AQAGIecUUxAqxSB0EFLqIKRUMQYhc05KxRyUUEpqIZTUKsYgVI5J' +
+'yJyTEkpoKZTSUgehpVBKa6GU1lJrsabUYu0gpBZKaS2U0lpqqcbUWowRYxAy56RkzkkJpbQWSmkt' +
+'c05K56CkDkJKpaQUS0otVsxJyaCj0kFIqaQSU0mptVBKa6WkFktKMbYUW24x1hxKaS2kEltJKcYU' +
+'U20txpojxiBkzknJnJMSSmktlNJa5ZiUDkJKmYOSSkqtlZJSzJyT0kFIqYOOSkkptpJKTKGU1kpK' +
+'sYVSWmwx1pxSbDWU0lpJKcaSSmwtxlpbTLV1EFoLpbQWSmmttVZraq3GUEprJaUYS0qxtRZrbjHm' +
+'GkppraQSW0mpxRZbji3GmlNrNabWam4x5hpbbT3WmnNKrdbUUo0txppjbb3VmnvvIKQWSmktlNJi' +
+'ai3G1mKtoZTWSiqxlZJabDHm2lqMOZTSYkmpxZJSjC3GmltsuaaWamwx5ppSi7Xm2nNsNfbUWqwt' +
+'xppTS7XWWnOPufVWAADAgAMAQIAJZaDQkJUAQBQAAEGIUs5JaRByzDkqCULMOSepckxCKSlVzEEI' +
+'JbXOOSkpxdY5CCWlFksqLcVWaykptRZrLQAAoMABACDABk2JxQEKDVkJAEQBACDGIMQYhAYZpRiD' +
+'0BikFGMQIqUYc05KpRRjzknJGHMOQioZY85BKCmEUEoqKYUQSkklpQIAAAocAAACbNCUWByg0JAV' +
+'AUAUAABgDGIMMYYgdFQyKhGETEonqYEQWgutddZSa6XFzFpqrbTYQAithdYySyXG1FpmrcSYWisA' +
+'AOzAAQDswEIoNGQlAJAHAEAYoxRjzjlnEGLMOegcNAgx5hyEDirGnIMOQggVY85BCCGEzDkIIYQQ' +
+'QuYchBBCCKGDEEIIpZTSQQghhFJK6SCEEEIppXQQQgihlFIKAAAqcAAACLBRZHOCkaBCQ1YCAHkA' +
+'AIAxSjkHoZRGKcYglJJSoxRjEEpJqXIMQikpxVY5B6GUlFrsIJTSWmw1dhBKaS3GWkNKrcVYa64h' +
+'pdZirDXX1FqMteaaa0otxlprzbkAANwFBwCwAxtFNicYCSo0ZCUAkAcAgCCkFGOMMYYUYoox55xD' +
+'CCnFmHPOKaYYc84555RijDnnnHOMMeecc845xphzzjnnHHPOOeecc44555xzzjnnnHPOOeecc845' +
+'55xzzgkAACpwAAAIsFFkc4KRoEJDVgIAqQAAABFWYowxxhgbCDHGGGOMMUYSYowxxhhjbDHGGGOM' +
+'McaYYowxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHG' +
+'GFtrrbXWWmuttdZaa6211lprrQBAvwoHAP8HG1ZHOCkaCyw0ZCUAEA4AABjDmHOOOQYdhIYp6KSE' +
+'DkIIoUNKOSglhFBKKSlzTkpKpaSUWkqZc1JSKiWlllLqIKTUWkottdZaByWl1lJqrbXWOgiltNRa' +
+'a6212EFIKaXWWostxlBKSq212GKMNYZSUmqtxdhirDGk0lJsLcYYY6yhlNZaazHGGGstKbXWYoy1' +
+'xlprSam11mKLNdZaCwDgbnAAgEiwcYaVpLPC0eBCQ1YCACEBAARCjDnnnHMQQgghUoox56CDEEII' +
+'IURKMeYcdBBCCCGEjDHnoIMQQgghhJAx5hx0EEIIIYQQOucchBBCCKGEUkrnHHQQQgghlFBC6SCE' +
+'EEIIoYRSSikdhBBCKKGEUkopJYQQQgmllFJKKaWEEEIIoYQSSimllBBCCKWUUkoppZQSQgghlFJK' +
+'KaWUUkIIoZRQSimllFJKCCGEUkoppZRSSgkhhFBKKaWUUkopIYQSSimllFJKKaUAAIADBwCAACPo' +
+'JKPKImw04cIDUGjISgCADAAAcdhq6ynWyCDFnISWS4SQchBiLhFSijlHsWVIGcUY1ZQxpRRTUmvo' +
+'nGKMUU+dY0oxw6yUVkookYLScqy1dswBAAAgCAAwECEzgUABFBjIAIADhAQpAKCwwNAxXAQE5BIy' +
+'CgwKx4Rz0mkDABCEyAyRiFgMEhOqgaJiOgBYXGDIB4AMjY20iwvoMsAFXdx1IIQgBCGIxQEUkICD' +
+'E2544g1PuMEJOkWlDgIAAAAA4AAAHgAAkg0gIiKaOY4Ojw+QEJERkhKTE5QAAAAAALABgA8AgCQF' +
+'iIiIZo6jw+MDJERkhKTE5AQlAAAAAAAAAAAACAgIAAAAAAAEAAAACAhPZ2dTAAQYOwAAAAAAAOGp' +
+'bkoCAAAAmc74DRgyNjM69TAzOTk74dnLubewsbagmZiNp4d0KbsExSY/I3XUTwJgkeZdn1HY4zoj' +
+'33/q9DFtv3Ui1/jmx7lCUtPt18/sYf9MkgAsAGRBd3gMGP4sU+qCPYBy9VrA3YqJosW3W2/ef1iO' +
+'/u3cg8ZG/57jU+pPmbGEJUgkfnaI39DbPqxddZphbMRmCc5rKlkUMkyx8iIoug5dJv1OYH9a59c+' +
+'3Gevqc7Z2XFdDjL/qHztRfjWEWxJ/aiGezjohu9HsCZdQBKbiH0VtU/3m85lDG2T/+xkZcYnX+E+' +
+'aqzv/xTgOoTFG+x7SNqQ4N+oAABSxuVXw77Jd5bmmTmuJakX7509HH0kGYKvARPpwfOSAPySPAc2' +
+'EkneDwB2HwAAJlQDYK5586N79GJCjx4+p6aDUd27XSvRyXLJkIC5YZ1jLv5lpOhZTz0s+DmnF1di' +
+'ptrnM6UDgIW11Xh8cHTd0/SmbgOAdxcyWwMAAGIrZ3fNSfZbzKiYrK4+tPqtnMVLOeWOG2kVvUY+' +
+'p2PJ/hkCl5aFRO4TLGYPZcIU3vYM1hohS4jHFlnyW/2T5J7kGsShXWT8N05V+3C/GPqJ1QdWisGP' +
+'xEzHqXISBPIinWDUt7IeJv/f5OtzBxpTzZZQ+CYEhHXfqG4aABQli72GJhN4oJv+hXcApAJSErAW' +
+'8G2raAX4NUcABnVt77CzZAB+LsHcVe+Q4h+QB1wh/ZrJTPxSBdI8mgTeAdTsQOoFUEng9BHcVPhx' +
+'SRRYkKWZJXOFYP6V4AEripJoEjXgA2wJRZHSExmJDm8F0A6gEXsg5a4ZsALItrMB7+fh7UKLvYWS' +
+'dtsDwFf1mzYzS1F82N1h2Oyt2e76B1QdS0SAsQigLPMOgJS9JRC7hFXA6kUsLFNKD5cA5cTRvgSq' +
+'Pc3Fl99xW3QTi/MHR8DEm6WnvaVQATwRqRKjywQ9BrrhugR2AKTsPQeQckrAOgDOhbTESyrXQ50C' +
+'kNpXdtWjW7W2/3UjeX3U95gIdalfRAoAmqUEiwp53hCdcCwlg47fcbfzlmQMAgaBkh7c+fcDgF+i' +
+'fwDXfzegLPcLYJsAAJQArTXjnh/uXGy3v1Hk3pV6/3t5ruW81f6prfbM2Q3WNVy98BwUtbCwhFhA' +
+'WuPev6Oe/4ZaFQUcgKrVs4defzh1TADA1DEh5b3VlDaECw5b+bPfkKos3tIAue3vJZOih3ga3l6O' +
+'3PSfIkrLv0PAS86PPdL7g8oc2KteNFKKzKRehOv2gJoFLBPXmaXvPBQILgJon0bbWBszrYZYYwE7' +
+'jl2j+vTdU7Vpk21LiU0QajPkywAAHqbUC0/YsYOdb4e6BOp7E0cCi04Ao/TgD8ZVAMid6h/A8IeB' +
+'Nkp6/xsAACZELEYIk+yvI6Qz1NN6lIftB/6IMWjWJNOqPTMedAmyaj6Es0QBklJpiSWWHnQ2CoYb' +
+'GWAmt+0gLQBFKCBnp2QUUQZ/1thtZDBJUpFWY82z34ocorB62oX7qB5y0oPAv/foxH25wVmgIHf2' +
+'xFOr8leZcBq1Kx3ZvCq9Bga639AxuHuPNL/71YCF4EywJpqHFAX6XF0sjVbuANnvvdLcrufYwOM/' +
+'iDa6iA468AYAAB6mNBMXcgTD8HSRqJ4vw8CjAlCEPACASlX/APwPOJKl9xQAAAPmnev2eWp33Xgy' +
+'w3Dvfz6myGk3oyP8YTKsCOvzAgALQi0o1c6Nzs2O2Pg2h4ACIJAgAGP0aNn5x0BDgVfH7u2TtyfD' +
+'cRIuYAyQhBF/lvSRAttgA6TPbWZA9gaUrZWAUEAA+Dx47Q3/r87HxUUqZmB0BmUuMlojFjHt1gDu' +
+'nnvuX8MImsjSq5WkzSzGS62OEIlOufWWezxWpv6FBgDgJVltfXFYtNAAnqU0xQoD0YLiXo5cF5QV' +
+'4CnY1tBLAkZCOABAhbk/AM+/AwSCCdlWAAAMcFjS7owb8GVDzveDiZvznbt2tF4bL5odN1YKl88T' +
+'AEABCZvufq9YCTBtMwVAQUEAwGtNltzSaHvADYC3TxLVjqiRA+OZAMhzcqEgRcAOwoCgvdTxsTHL' +
+'QEF6+oOb2+PAI8ciPQcXg7pOY+LjxQSv2fjmFuj34gGwz310/bGK6z3xgT887eomWULEaDd04wHe' +
+'tYxdjcgV2SxvSwn0VoZXJRqkRC5ASQ/muVoAUsX7AgAQMBNaVwAAlABRxT/1PmfqLqSRNDbhXb07' +
+'berpB3b94jpuWEZjBCD2OcdXFpCKEgCDfcFPMw8AAADUwT4lnUm50lmwrpMMhPQIKj6u0E8fr2vG' +
+'BngMNdIlrZsigjahljud6AFVg+tzXwUnXL3TJLpajaWKA4VAAAAMiFfqJgKAZ08XrtS3dxtQNYcp' +
+'PvYEG8ClvrQRJgBephwnNWJjtGqmp6VEPSvBe7EBiU3qgJbQAwD4Le8LAMDMhHbNAAAlgK+tFs5O' +
+'+YyJc9yCnJa3rxLPulGnxwsXV9Fsk2k4PisCAHC8FkwbGE9gJQAAoMnyksj0CdFMZLLgoz8M+Fxz' +
+'iwYBgIx+zHiCBAKAlBKNpF1sO9JpVcyEi9ar15YlHgrut5fPJnkdJ6vEwZPyAHQBIEDUrlMcBAAd' +
+'2KAS0Qq+JwRsE4AJZtMnAD6GnOYwYlOIZvtzUNdjreB7fiMkWI0CmBB6AIAKc38A9osEFlTSGECB' +
+'+cbeRDC0aRpLHqNPplcK/76Lxn2rpmqyXsYJWRi/FQAAAKBQk9MCAOibrQBQADCDsqpooPutd+05' +
+'Ce9g6iEdiYXgVmQAI4+4wskEBEiBloNQ6Ki0/KTQ0QjWfjxzi+AeuXKoMjEVfQOZzr0y941qLgM2' +
+'AExvbZOqcxZ6J6krlrj4y2j9AdgKDx6GnJsVLhbc42uq584+ouSdNBpoCiCVHrz+WzUA/DDtD8AT' +
+'gA3h0lMCAAzcFv+S+fSSNkeYWlTpb34mf2RfmqqJeMeklhHAfu7VoAEACgAApKRktL+KkQDWMwYC' +
+'UAAAAHCKsp80xhp91UjqQBw3x45cetqkjQEyu3G9B6N+R650Uq8OVig7wOm6Wun0ea4lKDPoabJs' +
+'6aLqgbhPzpv4KR4iODilw88ZpY7q1IOMcbASAOAVtmcCnobcrkG4KGS7/ZnskVWRNF9J0RUHKOnB' +
+'yy9WA8Dv6L4AAARMCQUA4GritfVM2lcZfH3Q3T/vZ47J2YHhcmBazjfdyuV25gLAzrc0cwAAAAAY' +
+'Ch6PdwAAAGyWjFW4yScjaWa2mGcofHxWxewKALglWBpLUvwwk+UOh5eNGyUOs1/EF+pZr+ud5Ozo' +
+'GwYdAABg2p52LiSgAY/ZVlOmilEgHn6G3OcwYjzI7vOj1t6xsx4S3lBY96EUQBF6AIBAmPYH4PoG' +
+'YCoJAADWe+OZJZi7/x76/yH7Lzf9M5XzRKnFPmveMsilQHwVAAAAAKB3LQD8PCIAAADga0QujBLy' +
+'wzeJ4a6Z/ERVBAUlAEDqvoM7BQBAuAguzFqILtmjH3Kd4wfKobnOhA3z85qWoRPm9hwoOHoDAAlC' +
+'bwDAA56FHAuXflHo3fe2ttG9XUDeA9YmYCBQ0oPr/1QC8IvuCwAAApbUAQCK22MmE3O78VAbHQT9' +
+'PIPNoT9zNc3l2Oe7TAVLANBufT8MAQAAAGzT4PS8AQAAoELGHb2uaCwwEv1EWhFriUkbAaAZ27/f' +
+'VZnTZXbWz3BwWpjUaMZKRj7dZ0J//gUeTdpVEwAAZOFsNxKAjQSgA+ABPoY8Jj5y2wje81jsXc/1' +
+'TOQWTDYZBmAkNDiqVwuA2NJ9AQAAEBKAt9Vrsfs/2N19MO91S9rd8EHTZHnzC5MYmfQEACy/FBcA' +
+'AADA5c4gi4z8RANs/m6FNXVo9DV46JG1BBDukqlw/Va5G7QbuGVSI+2aZaoLXJrdVj2zlC9Z5QEA' +
+'EFz/5QzgVZwAAAAA/oXcxyC6WfTu+09Ve/c766J4VTAGUFmA51+VANKi/QPoPwYgYAkA715OH4S0' +
+'s5KDHvj99MMq8TPFc3roKZnGOoT1bmIhVgc7XAMBAAAAAMAW1VbQw3gapzOpJd+Kd2fc4iSO62fJ' +
+'v9+movui1wUNPAj059N3OVxzk4gV73PmE8FIA2F5mRq37Evc76vLXfF4rD5UJJAw46hW6LZCb5sN' +
+'Ldx+kzMCAAB+hfy95+965ZCLP7B3/VlTHCvDEKtQhTm4KiCgAEAbrfbWTPssAAAAXpee1tVrozYY' +
+'n41wD1aeYtkKfswN5/SXPO0JDnhO/4laUortv/s412fybe/nONdncoCHnBVliu0CQGBWlPY/5Kwo' +
+'m2L/kruPM6Q7oz4tvDQy+bZ3HzOi+gNHA4DZEgA='
+);
+
+lib.resource.add('hterm/images/icon-96', 'image/png;base64',
+'iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAStklEQVR42u1dBXjrupL+RzIGmjIf' +
+'vAcu42NmZub3lpmZmZmZmRkuMzPDYaYyJG0Sa9b2p2z1eQtp7bzefpv/nKnkkSw7Gg1IshNsDtpo' +
+'o4022mijDWp/tlTgzbpJSqYvMoFTC9vjRD5JLb9RYaRkpk22SS28P8pacAaPdZ41KYMCI89YB6wN' +
+'3JzQJM3UIGqurfTlKQTAZtqENid5SlNdU804VmbbWQtA6HMkAAdADsBeAJ7mxwIhIhFSXJ9iRPw4' +
+'JYDEcqmGWEp1HhCI8gAtpXF7scB1ZRH9E3HObANCNy1AoGTegNDnCdE41tfQDH2t+CINQEpJ9Xp9' +
+'7oUDh3+nXK48DYAMIWQmANIkNTn6vP69e3d/zctfeu0nXNexmVn3F0gDAMxMlBoHuht0qnsEEekC' +
+'42SdGHmNxgVjgk4bPN04Yui8bhc534cQBH35RKrPN9sGdLnB1/Wuv+HW4f+6/tZvBHAaAJvmKr0A' +
+'jJGvyQMw8pLrrvqeT378Ax8UwrKeevoFgEhfjcGGO2JO+iuTt1SW5DHzyraDExyTlWwHjCQ/CAJc' +
+'ecU+XHn5xWDmVCGQFAKljsLbx8Ynvv3Bhx7/EQCzurimU04jADLsvK3r73/7W1//g1/6hU++uVqt' +
+'0X/dcBcKxRIsy9Ji34DPow2et6FzgcXFKk6fOY83vu4VEFKkDiYHB3roSz73sc+Oj08eOHzk+B9o' +
+'MyQABGk0gCIyOt9xHPvaD3/wnT/5VV/+meumpmbwD/98A0qdvVEBNhvMDCJaVXtM01GtVlEs+LBt' +
+'C1ngzW98tX/m7Llv/emf+83HarX6vbrfGECQRgBmlLP9Ix961499+zd/5XVj45P407/8FxQ7uiGl' +
+'QK1Ww1ZCvR6gXq3AsgQ8zwYzUkMIgXe+/Q1Dd9x5/6duv/P+R7QjprQaIHQd/8orLvnCJz/2/pfm' +
+'cj7+6rf+DK5XgOu6sT3dQtBawqjW6lhYXIRlSTAjE/T39eLSS/ZeEwqgE8CiYUV4vQIgTULTyFve' +
+'9Or3WJZN/3n9HTh3fgrFjhJmZmawFaGUwkJlEffc9xh83wMYqcFg7Noxinw+l9OBikirAabz7eju' +
+'6sxJKTE7W4bn5+D7PrYmtI/gAFJasCwb4IzaBMHzXE8LgBJC4I1GQRKAa4Xo6upEsZiH53nIRYLe' +
+'olDMCIIq+nq70dFRAGckgFKpAD+UgBaAgfRRkGvbliwUcoh8ABHFYSfWMnBrxOzL12PwKufzSvV5' +
+'5Tpmi5a0IASBQCgWcujs7ABn5AQic+b5rhNlAVAmTliTEwnA990wIxEEdUQYnxjHidMnAUIcBYAB' +
+'RqNDdC7BM8t0VtfTnGRd8FKdRIjJcVlCsAbPPA5UAK4rXLJjP7aNbkO9XoPrOrEQWHEm69Kua0ca' +
+'YEspvCBQ5toSp9EASCkt27ZF1PlCxBOZOPo5feY0Xpg8jHe/7V3YNjhqjDRac3mMVl1Oo40vtREt' +
+'W+2FYwdw/S03YHJ6EkODQ1hcXIQUcaeBlUIWsCwZ+QDLdZxcubKAtBpgNmzZliUa6yLMKiRGoBR2' +
+'79yN6666FlJYABgvRhAIncUSHn/iCdQrAZjjSAiKFQQRVEhZIRJASJEACICmlAKQUtqhBETjw5ij' +
+'uFqr4oWjBwHmF7/jVUHc6aRNXxAoZA3PdYXruvlldJfTaIATaQA4KU/CzNwMDp84DOYXf+hZXiij' +
+'hJz+DK0QAEd+RYTOOAcgMw0g24oskNYAIoCXxDpbnsOxM8fB5qacwKZD+3WQcS+VxQrYYXNVNGMh' +
+'I1odiIRQSHb8BmbCpgZYjmVLYi0ANmxQNKpOj50FFOB3WnDzEpOnFkGbuOXPimG5Ap0jLqZOLiKo' +
+'MyIsVhfB9lLEpFSQ+S26jh2Fo/n0YagRCUlLRhpAAIMIyWl9vBinAkbfoIPXf+0wnrlxAs/dPInK' +
+'VB1CUOsFkdhD6Nnp49oP98EvWfjvnzqGak0hVlwwFJsaoADK9vq2Y0eOOKUGJLTAjjQgFgBAy/gT' +
+'vbGIyXC0nX66jJd+YgC7X1nCo39/AccfmUVQU1F5y0d9rsvGJW/txuXv7oGqMx7+2/OoVxWIzE5S' +
+'OkfaBBGyhGPHc4G8YYjT+wDLDgUgJbQPWDGuL0/VcefvnMLRB2dw3Uf78dZv345D90zjsX++gPGj' +
+'C7peC8yNI7DjpSVcE476rlEPB++awmP/dCEaEMtqbAP1Fqzkhn0VaUAegMzABJkaIMG8epNEiE3R' +
+'0funce75Mi4NR+MV7+3B6NUFPPnvY3jupslISJkKoW9PDld/sA+7Xt6B8SMV3Pjzx3Di0TkENQaJ' +
+'5A1qM8VRljKPgpg58pcNHyCz0ADSTnhNDTBBglCZruPhvz+PY4/M4Jqwg6772AB2vqwDd/zmKYwd' +
+'WQAJpMalb+vGSz81AA6Ah/76HJ69KfI7tej6K7RPUKwaWQT1FmiAlJEJykXZZh5cE02FoaEJkpYE' +
+'wGsKwNQGAnDhQAUP/915TJ5YwPCleZSG3WwWvwgYvryAYr8Tm5wn/2Mc5cm481c9RzXWobQPyBpS' +
+'ikgDGgJAVvMARzY0AARwc7Y5Ckn3vK4TV7+/D5YncN+fnsWpJ+cgsnDICnj0n85DSOCSUBO6Rl08' +
+'8g8XcObZ+VgjSKweKRG1xgcIEQnA9QE46aMgwwlHAmBuOFFepeMRd8rI1cU4FBzYn8exh2bw6D9e' +
+'wNihCjgrR0wI21vAzb9yIrT/pfha7/y+nXj+5gk8EWrDzJlF/WxQUgMUwEtREGW/5RlpgJdaABq0' +
+'pAGicYFVFaBzxMGV7+vFvtd3YfpsFbf+6ok4KqovxqFoph+YBBAsMg7cPonTT83jsnd247J39IQR' +
+'UUcceR28cxrVcrBUX2sAa1Nar7dCAwhevCkDN7UADB9gSyEBaBVYYeT37PTw9u/aAbcg8Pi/XMAz' +
+'109gfqLhFAktgX46LbrOg395DscemAnD0X68+suGQ+3L4Y7fOhVHRA00nDBRa3wAEGuAA8DbqABI' +
+'kyEA2xFSrBHHM2xf4Ozz82HIOb5kbgSh1TDv69wLZdz0S8dxUTgRHLwkD2HRkgCIdBi6NBPmVpgg' +
+'L7krBkrnA6xIA0Qjfl4x9Bw7XInDzHo1hblJbZYoNkvP3zqFw/fPIKgqGNC7aNoEtUQDEJkg23Ec' +
+'v1qtrhkFiWYeTYzCUCEEeI15QDTSgjpnMerTmyUB1CsKrGACyvABQb1VAnAt13V8NAHRxGqotEMI' +
+'QUbJFgGtMhNuqQa4Ui9HbEgDKFknioKIhC4kbGUwFBhsOGHO/AqhCxAh5dOsBZFBMoqCGhpARJv7' +
+'ihul35oEt84E6U0ZCv1APp0T1tACsIhEpquZQhJsT2C9UAGjtqA2vDnPzOD/NUEqymcOJ94TcPJZ' +
+'zYSFHYKIjHlA+iXk/kvyeO1XDENYtK6J16kn53H375+OBbFukBkFtWoewHAdJ1qQKwAQWcyEtQaQ' +
+'4QPSmk6KZ6gXDlVAcn0x9vTpxTSjdhkBcOYmSO+KNTZlKK0GWHYoASJkZoJIABPHFnDbb5zEFxts' +
+'hqEtMkG2rfcEtAZsJAoimBpgGRqg062KVmsAmBH2V2NfWKZ1woxYAyIBwFABXma+nE30wytV4rU/' +
+'OK9xLWaGUmpJAHE+awEDUsrGnoCERsooyJYALfPaOEHNByBl7BGwKQsy8kYLUZ1kOTXyZprgUYJH' +
+'SBzrctLHDZ6huflCLt61qtWDWAMawsgOWgCe5+v+JYN4vT6AtAbIpSCIGuEcRoaG8TrXRcwzCeZ7' +
+'u2gcm4QIZn0QEudC5wGYdYxUt2PyjRSAyWsc6mvW6hW0CnpXzAdgQ6NZAdByJsgKBQAQGCp+oQFQ' +
+'8ePdhUIBxWJxXfrJYKQHNRUMMK9kuwhzc3O4eO+eeLQqpbLfFfMaAgAnhdDccrSpAZYtAUApxujI' +
+'EN725lfg3//7bvT19cOyLJhg44/ZCTo1y40yI79qmT4/5un2jTx0+XLtmAOAlUJXVx6ve83LdFkr' +
+'dsWMTZkUTpikjFyAJUxHFr6oDc918cDDT6KyMB8xzVFpmBpAGGZHiCgVZgoRphSlQkCQTvXxEhFk' +
+'lMolXnyseY28NMtlIjXaCzsHO7aPoFDIQ6nWCMDzXS2AdJvybMl4HiaSLyK89S2vxRte/wrU6vXG' +
+'IFrzOxdWTZcaMNtCgq15a9vNtWyTMjUncwEguSu2ISesO3vp3YDkE2ZSypiyQMO0JO331gTFryoJ' +
+'IXylVLrFOCtEpAHmaG5jbQ3Qb8r45XKFN2qCOCJpSUsxi/n5SlOP8rXB0WpoUgC8HgGwQYqI7AMH' +
+'j1G9zk2Ea20wgI5iPhqs8dMk6/26GrOyiqharc16nlffvn3EaWtAc/BcBw8+/Ojc+PjkKaMvuWkN' +
+'ME+YnZ17+rnnDxweHOi9iCM+gzbLOXLrG8piu46JIO5/4NHD9XpwbEPfEqjJ01R0XecDYcz8lvhF' +
+'MSEkwJIBaU76AZA+SsST5oHOmidqvsHQieYk6ya/ucysT/pPon6yLum/5tXN4uV45ocAKHEeWFdQ' +
+'YcpKKb4wNnH/xMTUjwGYArBofLHfuhfjeO+eXbu+/ms+946JyWl16NAxWmV80AZGImW+M0z/dxWU' +
+'NbvJNQzaqNK4ro13v/NN9C//doP4gz/+mxKAWWNQb2hHzL/s0n1XDfT3W3fe8wRAVmLytCE56HM3' +
+'LL/E+bRqb+niFZ9rSvD0nnHzd2Y+M3vs5Ckwc/S9QQMABgGc0cvS9fU8migi0uUDey7asfvQ4eMQ' +
+'louuzs74Am0sL4TZQhHHTpzG8FB/qdRR3DU9M/sUgJqmphfjhJaa9H1v9/Ztw/1PPn0QtWoNs7Oz' +
+'WBltATiOixMnzuCS/bvtgTBwCQXg6s5fNLdTmnkuSAKww0WrS7q6St7E5Ax6egbWWHpow3EcnDs/' +
+'EX8v6fDw4J4XDhzxASwAEOvSAF2Wu2j3jssAQqVSQ6+ULTQ/W3+pQy/dYHauEi9Sbhsd2gGgqB2x' +
+'BEDN+gCpy3rCCGjP5OQ0FHO0idGeDTexHRkoxvjEJHZsGxkE0APgnO5TYc6x1hKAIKJtu3dtGzp1' +
+'+hyKxY5oB6wpDWibIRenTp3D6OhQl5RyMAiC5w0TRCtpACW+rM8aGR7cPzTYX3ziqQPw/dzmm4gt' +
+'YOaYGZ7n4cTJs3jVK67xw++l23723AVtURLhaFIDEuGnG47+S33fo8mpWZQ6XUxPT6ONtfeD7dgR' +
+'j6NQyNHQ0MCOUAA2ANmMBpAhhGJo//eFy6lgFsjn823zsw6cnhyHUhw74kcfe8ozfMCKAkjOAYb2' +
+'7tk5cubsBTiuF3v35h1w2xwpRmgxZrBj+/AIgA4AY7pfsZYGyIi6uzv3hHOArocefQbMwNTUVFsD' +
+'mjdDIUmcDgfv6OhwH4CIjie0gJfVAF3J2bVjWzgB65TnL0ygs7NrnROwthZUqzWcPHUOV1y2txiu' +
+'JA/Pzc0/spYJEob5ye/Zs/NiZka5XEVPr4821gfP9xAN3nA9yB4c6Nt+cG5eLvPGDCdNUKNS7769' +
+'u3ZGX1NfqwfR+s//C/PDnH5TRq+kxun8fBkdxQJGhgd2Hjx01BBAwgQl7L/I5fyd4RJE3+TUdNjI' +
+'PKSc0AJg/T+JxNNnK5Uly3VuterJOpzh3hmts5DWKExy3/j6l2J4eAAjI4PbjG9UF6YQrMaBWRCu' +
+'fu4fHRn0Bvp7USzkUS4vmD9as+IP3cSHWL5eXGTUizk6v/IDubodM7+++qs+ENbsg2RxLlE/5pr1' +
+'Ew8H25aFnp6u2CFvGx0e0JHQGdMEJTWgkTo7d4xe3NfXg1KpiLe86TWg9ONtc3eKuVX3yatei5m1' +
+'AIa6pRT9QaCeb2YporBzx7Zd0chnRkgKbaSLsMLZcK6/rzecU53n5TSAEkw/HPkFy86BpJtq3LRB' +
+'IK6jq7NDhPOqPi0A0+cuuxq6EMas5bGJaVQWFWgTbrqVTdEX9f4ZvmfB9/3Il5bW2hNmnZbDB4om' +
+'Lpw/h7n5RYCa+3E0ToY4Jp9XiGSYk/WMvHmlxDEn7yN5ffN4mTzrM808G+0leJqVbG81njbfjFJH' +
+'Hr4no4lZ3fjRT06GoWxQ+eFHn7rTz/1Tv5QSrBQpZrAmfVMaQJyNOXHOPESjztJfs54uxFJWl5q1' +
+'zYuZRzD+RzAPEufoJFln2TyMv8axwUheJPGRVSMFEHe4ZckqMy8cOXLin5f7xVUyyPypwhKAHp13' +
+'IjJCVW4iHGAz30Q5mmx3I+dwyvbWE36x0ck1AFW9Gb+g06qmWkMQVuLEQEtuVldyjR/vFJqyjxNb' +
+'6+mTA6DV96HMvkx0ej2pAZZxoBL5QJ8oDKIW3jxnfA5twj1xUhPMjjd9wGpOOEgIgUzaxFG8RZ4F' +
+'Tgxos9N1atajtd+S1LytA26p8NKbQE7/0+BtpNakNtpoo4022vgf7lRPtKCE39oAAAAASUVORK5C' +
+'YII='
+);
+
+lib.resource.add('hterm/concat/date', 'text/plain',
+'Thu, 05 Dec 2019 19:54:18 +0000'
+);
+
+lib.resource.add('hterm/changelog/version', 'text/plain',
+'1.85'
+);
+
+lib.resource.add('hterm/changelog/date', 'text/plain',
+'2019-06-17'
+);
+
+lib.resource.add('hterm/git/HEAD', 'text/plain',
+'530691a7e349cc0038ef14f1eb2a7c6ce8971e73'
+);
+
diff --git a/htdocs/dist/1.86/hterm_all.js b/htdocs/dist/1.86/hterm_all.js
new file mode 100644
index 0000000..66f85b6
--- /dev/null
+++ b/htdocs/dist/1.86/hterm_all.js
@@ -0,0 +1,19984 @@
+// This file was generated by libdot/bin/concat.sh.
+// It has been marked read-only for your safety.  Rather than
+// edit it directly, please modify one of these source files.
+//
+// libdot/js/lib.js
+// libdot/js/lib_polyfill.js
+// libdot/js/lib_array.js
+// libdot/js/lib_codec.js
+// libdot/js/lib_colors.js
+// libdot/js/lib_f.js
+// libdot/js/lib_i18n.js
+// libdot/js/lib_message_manager.js
+// libdot/js/lib_preference_manager.js
+// libdot/js/lib_resource.js
+// libdot/js/lib_storage.js
+// libdot/js/lib_storage_chrome.js
+// libdot/js/lib_storage_local.js
+// libdot/js/lib_storage_memory.js
+// libdot/third_party/fast-text-encoding/text.js
+// libdot/third_party/intl-segmenter/intl-segmenter.js
+// libdot/third_party/wcwidth/lib_wc.js
+// hterm/js/hterm.js
+// hterm/js/hterm_accessibility_reader.js
+// hterm/js/hterm_contextmenu.js
+// hterm/js/hterm_frame.js
+// hterm/js/hterm_keyboard.js
+// hterm/js/hterm_keyboard_bindings.js
+// hterm/js/hterm_keyboard_keymap.js
+// hterm/js/hterm_keyboard_keypattern.js
+// hterm/js/hterm_options.js
+// hterm/js/hterm_parser.js
+// hterm/js/hterm_parser_identifiers.js
+// hterm/js/hterm_preference_manager.js
+// hterm/js/hterm_pubsub.js
+// hterm/js/hterm_screen.js
+// hterm/js/hterm_scrollport.js
+// hterm/js/hterm_terminal.js
+// hterm/js/hterm_terminal_io.js
+// hterm/js/hterm_text_attributes.js
+// hterm/js/hterm_vt.js
+// hterm/js/hterm_vt_character_map.js
+// hterm/audio/bell.ogg
+// hterm/images/icon-96.png
+
+'use strict';
+
+// SOURCE FILE: libdot/js/lib.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+const lib = {};
+
+// Export for node environments.
+if (typeof exports !== 'undefined') {
+  module.exports = lib;
+}
+
+/**
+ * List of functions that need to be invoked during library initialization.
+ *
+ * Each element in the initCallbacks_ array is itself a two-element array.
+ * Element 0 is a short string describing the owner of the init routine, useful
+ * for debugging.  Element 1 is the callback function.
+ */
+lib.initCallbacks_ = [];
+
+/**
+ * Register an initialization function.
+ *
+ * The initialization functions are invoked in registration order when
+ * lib.init() is invoked.  Each function will receive a single parameter, which
+ * is a function to be invoked when it completes its part of the initialization.
+ *
+ * @param {string} name A short descriptive name of the init routine useful for
+ *     debugging.
+ * @param {function(function)} callback The initialization function to register.
+ * @return {function} The callback parameter.
+ */
+lib.registerInit = function(name, callback) {
+  lib.initCallbacks_.push([name, callback]);
+  return callback;
+};
+
+/**
+ * Initialize the library.
+ *
+ * This will ensure that all registered runtime dependencies are met, and
+ * invoke any registered initialization functions.
+ *
+ * Initialization is asynchronous.  The library is not ready for use until
+ * the onInit function is invoked.
+ *
+ * @param {function()} onInit The function to invoke when initialization is
+ *     complete.
+ * @param {function(*)} opt_logFunction An optional function to send
+ *     initialization related log messages to.
+ */
+lib.init = function(onInit, opt_logFunction) {
+  var ary = lib.initCallbacks_;
+
+  var initNext = function() {
+    if (ary.length) {
+      var rec = ary.shift();
+      if (opt_logFunction)
+        opt_logFunction('init: ' + rec[0]);
+      rec[1](initNext);
+    } else {
+      onInit();
+    }
+  };
+
+  if (typeof onInit != 'function')
+    throw new Error('Missing or invalid argument: onInit');
+
+  setTimeout(initNext, 0);
+};
+// SOURCE FILE: libdot/js/lib_polyfill.js
+// Copyright 2017 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Polyfills for ES2016+ features we want to use.
+ */
+
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
+if (!String.prototype.padStart) {
+  String.prototype.padStart = function(targetLength, padString) {
+    // If the string is already long enough, nothing to do!
+    targetLength -= this.length;
+    if (targetLength <= 0)
+      return String(this);
+
+    if (padString === undefined)
+      padString = ' ';
+
+    // In case the pad is multiple chars long.
+    if (targetLength > padString.length)
+      padString = padString.repeat((targetLength / padString.length) + 1);
+
+    return padString.slice(0, targetLength) + String(this);
+  };
+}
+
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
+if (!String.prototype.padEnd) {
+  String.prototype.padEnd = function(targetLength, padString) {
+    // If the string is already long enough, nothing to do!
+    targetLength -= this.length;
+    if (targetLength <= 0)
+      return String(this);
+
+    if (padString === undefined)
+      padString = ' ';
+
+    // In case the pad is multiple chars long.
+    if (targetLength > padString.length)
+      padString = padString.repeat((targetLength / padString.length) + 1);
+
+    return String(this) + padString.slice(0, targetLength);
+  };
+}
+
+// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Object/values
+// https://github.com/tc39/proposal-object-values-entries/blob/master/polyfill.js
+if (!Object.values || !Object.entries) {
+  const reduce = Function.bind.call(Function.call, Array.prototype.reduce);
+  const isEnumerable = Function.bind.call(Function.call,
+      Object.prototype.propertyIsEnumerable);
+  const concat = Function.bind.call(Function.call, Array.prototype.concat);
+
+  if (!Object.values) {
+    Object.values = function values(O) {
+      return reduce(Reflect.ownKeys(O), (v, k) => concat(v,
+          typeof k === 'string' && isEnumerable(O, k) ? [O[k]] : []), []);
+    };
+  }
+
+  if (!Object.entries) {
+    Object.entries = function entries(O) {
+      return reduce(Reflect.ownKeys(O), (e, k) => concat(e,
+          typeof k === 'string' && isEnumerable(O, k) ? [[k, O[k]]] : []), []);
+    };
+  }
+}
+
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally
+// https://github.com/tc39/proposal-promise-finally/blob/master/polyfill.js
+if (typeof Promise.prototype.finally !== 'function') {
+  const speciesConstructor = function(O, defaultConstructor) {
+    if (!O || (typeof O !== 'object' && typeof O !== 'function')) {
+      throw new TypeError('Assertion failed: Type(O) is not Object');
+    }
+    const C = O.constructor;
+    if (typeof C === 'undefined') {
+      return defaultConstructor;
+    }
+    if (!C || (typeof C !== 'object' && typeof C !== 'function')) {
+      throw new TypeError('O.constructor is not an Object');
+    }
+    const S =
+        typeof Symbol === 'function' && typeof Symbol.species === 'symbol' ?
+        C[Symbol.species] : undefined;
+    if (S == null) {
+      return defaultConstructor;
+    }
+    if (typeof S === 'function' && S.prototype) {
+      return S;
+    }
+    throw new TypeError('no constructor found');
+  };
+
+  const shim = {
+    finally(onFinally) {
+      const promise = this;
+      if (typeof promise !== 'object' || promise === null) {
+        throw new TypeError('"this" value is not an Object');
+      }
+      const C = speciesConstructor(promise, Promise);
+      if (typeof onFinally !== 'function') {
+        return Promise.prototype.then.call(promise, onFinally, onFinally);
+      }
+      return Promise.prototype.then.call(
+        promise,
+        x => new C(resolve => resolve(onFinally())).then(() => x),
+        e => new C(resolve => resolve(onFinally())).then(() => { throw e; })
+      );
+    }
+  };
+  Object.defineProperty(Promise.prototype, 'finally', {
+    configurable: true, writable: true, value: shim.finally,
+  });
+}
+// SOURCE FILE: libdot/js/lib_array.js
+// Copyright 2017 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Helper functions for (typed) arrays.
+ */
+
+lib.array = {};
+
+/**
+ * Concatenate an arbitrary number of typed arrays of the same type into a new
+ * typed array of this type.
+ *
+ * @template TYPED_ARRAY
+ * @param {...!TYPED_ARRAY} arrays
+ * @returns {!TYPED_ARRAY}
+ */
+lib.array.concatTyped = function(...arrays) {
+  let resultLength = 0;
+  for (const array of arrays) {
+    resultLength += array.length;
+  }
+  const result = new arrays[0].constructor(resultLength);
+  let pos = 0;
+  for (const array of arrays) {
+    result.set(array, pos);
+    pos += array.length;
+  }
+  return result;
+};
+
+/**
+ * Compare two array-like objects entrywise.
+ *
+ * @template ARRAY_LIKE
+ * @param {?ARRAY_LIKE} a
+ * @param {?ARRAY_LIKE} b
+ * @returns {!boolean} true if both arrays are null or they agree entrywise;
+ *     false otherwise.
+ */
+lib.array.compare = function(a, b) {
+  if (a === null || b === null) {
+    return a === null && b === null;
+  }
+
+  if (a.length !== b.length) {
+    return false;
+  }
+
+  for (let i = 0; i < a.length; i++) {
+    if (a[i] !== b[i]) {
+      return false;
+    }
+  }
+  return true;
+};
+// SOURCE FILE: libdot/js/lib_codec.js
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+lib.codec = {};
+
+/**
+ * Join an array of code units to a string.
+ *
+ * The code units must not be larger than 65535.  The individual code units may
+ * be for UTF-8 or UTF-16 -- it doesn't matter since UTF-16 can handle all UTF-8
+ * code units.
+ *
+ * The input array type may be an Array or a typed Array (e.g. Uint8Array).
+ *
+ * @param {Array<number>} array The code units to generate for the string.
+ * @return {string} A UTF-16 encoded string.
+ */
+lib.codec.codeUnitArrayToString = function(array) {
+  // String concat is faster than Array.join.
+  //
+  // String.fromCharCode.apply is faster than this if called less frequently
+  // and with smaller array sizes (like <32K).  But it's a recursive call so
+  // larger arrays will blow the stack and fail.  We also seem to be faster
+  // (or at least more constant time) when called frequently.
+  let ret = '';
+  for (let i = 0; i < array.length; ++i) {
+    ret += String.fromCharCode(array[i]);
+  }
+  return ret;
+};
+
+/**
+ * Create an array of code units from a UTF-16 encoded string.
+ *
+ * @param {string} str The string to extract code units from.
+ * @param {type=} type The type of the return value.
+ * @return {Array<number>} The array of code units.
+ */
+lib.codec.stringToCodeUnitArray = function(str, type=Array) {
+  // Indexing string directly is faster than Array.map.
+  const ret = new type(str.length);
+  for (let i = 0; i < str.length; ++i) {
+    ret[i] = str.charCodeAt(i);
+  }
+  return ret;
+};
+// SOURCE FILE: libdot/js/lib_colors.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Namespace for color utilities.
+ */
+lib.colors = {};
+
+/**
+ * First, some canned regular expressions we're going to use in this file.
+ *
+ *
+ *                              BRACE YOURSELF
+ *
+ *                                 ,~~~~.
+ *                                 |>_< ~~
+ *                                3`---'-/.
+ *                                3:::::\v\
+ *                               =o=:::::\,\
+ *                                | :::::\,,\
+ *
+ *                        THE REGULAR EXPRESSIONS
+ *                               ARE COMING.
+ *
+ * There's no way to break long RE literals in JavaScript.  Fix that why don't
+ * you?  Oh, and also there's no way to write a string that doesn't interpret
+ * escapes.
+ *
+ * Instead, we stoop to this .replace() trick.
+ */
+lib.colors.re_ = {
+  // CSS hex color, #RGB.
+  hex16: /#([a-f0-9])([a-f0-9])([a-f0-9])/i,
+
+  // CSS hex color, #RRGGBB.
+  hex24: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/i,
+
+  // CSS rgb color, rgb(rrr,ggg,bbb).
+  rgb: new RegExp(
+      ('^/s*rgb/s*/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*,' +
+       '/s*(/d{1,3})/s*/)/s*$'
+       ).replace(/\//g, '\\'), 'i'),
+
+  // CSS rgb color, rgb(rrr,ggg,bbb,aaa).
+  rgba: new RegExp(
+      ('^/s*rgba/s*' +
+       '/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*,/s*(/d{1,3})/s*' +
+       '(?:,/s*(/d+(?:/./d+)?)/s*)/)/s*$'
+       ).replace(/\//g, '\\'), 'i'),
+
+  // Either RGB or RGBA.
+  rgbx: new RegExp(
+      ('^/s*rgba?/s*' +
+       '/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*,/s*(/d{1,3})/s*' +
+       '(?:,/s*(/d+(?:/./d+)?)/s*)?/)/s*$'
+       ).replace(/\//g, '\\'), 'i'),
+
+  // An X11 "rgb:dddd/dddd/dddd" value.
+  x11rgb: /^\s*rgb:([a-f0-9]{1,4})\/([a-f0-9]{1,4})\/([a-f0-9]{1,4})\s*$/i,
+
+  // English color name.
+  name: /[a-z][a-z0-9\s]+/,
+};
+
+/**
+ * Convert a CSS rgb(ddd,ddd,ddd) color value into an X11 color value.
+ *
+ * Other CSS color values are ignored to ensure sanitary data handling.
+ *
+ * Each 'ddd' component is a one byte value specified in decimal.
+ *
+ * @param {string} value The CSS color value to convert.
+ * @return {string} The X11 color value or null if the value could not be
+ *     converted.
+ */
+lib.colors.rgbToX11 = function(value) {
+  function scale(v) {
+    v = (Math.min(v, 255) * 257).toString(16);
+    return lib.f.zpad(v, 4);
+  }
+
+  var ary = value.match(lib.colors.re_.rgbx);
+  if (!ary)
+    return null;
+
+  return 'rgb:' + scale(ary[1]) + '/' + scale(ary[2]) + '/' + scale(ary[3]);
+};
+
+/**
+ * Convert a legacy X11 colover value into an CSS rgb(...) color value.
+ *
+ * They take the form:
+ * 12 bit: #RGB          -> #R000G000B000
+ * 24 bit: #RRGGBB       -> #RR00GG00BB00
+ * 36 bit: #RRRGGGBBB    -> #RRR0GGG0BBB0
+ * 48 bit: #RRRRGGGGBBBB
+ * These are the most significant bits.
+ *
+ * Truncate values back down to 24 bit since that's all CSS supports.
+ */
+lib.colors.x11HexToCSS = function(v) {
+  if (!v.startsWith('#'))
+    return null;
+  // Strip the leading # off.
+  v = v.substr(1);
+
+  // Reject unknown sizes.
+  if ([3, 6, 9, 12].indexOf(v.length) == -1)
+    return null;
+
+  // Reject non-hex values.
+  if (v.match(/[^a-f0-9]/i))
+    return null;
+
+  // Split the colors out.
+  var size = v.length / 3;
+  var r = v.substr(0, size);
+  var g = v.substr(size, size);
+  var b = v.substr(size + size, size);
+
+  // Normalize to 16 bits.
+  function norm16(v) {
+    v = parseInt(v, 16);
+    return size == 2 ? v :         // 16 bit
+           size == 1 ? v << 4 :    // 8 bit
+           v >> (4 * (size - 2));  // 24 or 32 bit
+  }
+  return lib.colors.arrayToRGBA([r, g, b].map(norm16));
+};
+
+/**
+ * Convert an X11 color value into an CSS rgb(...) color value.
+ *
+ * The X11 value may be an X11 color name, or an RGB value of the form
+ * rgb:hhhh/hhhh/hhhh.  If a component value is less than 4 digits it is
+ * padded out to 4, then scaled down to fit in a single byte.
+ *
+ * @param {string} value The X11 color value to convert.
+ * @return {string} The CSS color value or null if the value could not be
+ *     converted.
+ */
+lib.colors.x11ToCSS = function(v) {
+  function scale(v) {
+    // Pad out values with less than four digits.  This padding (probably)
+    // matches xterm.  It's difficult to say for sure since xterm seems to
+    // arrive at a padded value and then perform some combination of
+    // gamma correction, color space transformation, and quantization.
+
+    if (v.length == 1) {
+      // Single digits pad out to four by repeating the character.  "f" becomes
+      // "ffff".  Scaling down a hex value of this pattern by 257 is the same
+      // as cutting off one byte.  We skip the middle step and just double
+      // the character.
+      return parseInt(v + v, 16);
+    }
+
+    if (v.length == 2) {
+      // Similar deal here.  X11 pads two digit values by repeating the
+      // byte (or scale up by 257).  Since we're going to scale it back
+      // down anyway, we can just return the original value.
+      return parseInt(v, 16);
+    }
+
+    if (v.length == 3) {
+      // Three digit values seem to be padded by repeating the final digit.
+      // e.g. 10f becomes 10ff.
+      v = v + v.substr(2);
+    }
+
+    // Scale down the 2 byte value.
+    return Math.round(parseInt(v, 16) / 257);
+  }
+
+  var ary = v.match(lib.colors.re_.x11rgb);
+  if (!ary) {
+    // Handle the legacy format.
+    if (v.startsWith('#'))
+      return lib.colors.x11HexToCSS(v);
+    else
+      return lib.colors.nameToRGB(v);
+  }
+
+  ary.splice(0, 1);
+  return lib.colors.arrayToRGBA(ary.map(scale));
+};
+
+/**
+ * Converts one or more CSS '#RRGGBB' color values into their rgb(...)
+ * form.
+ *
+ * Arrays are converted in place. If a value cannot be converted, it is
+ * replaced with null.
+ *
+ * @param {string|Array.<string>} A single RGB value or array of RGB values to
+ *     convert.
+ * @return {string|Array.<string>} The converted value or values.
+ */
+lib.colors.hexToRGB = function(arg) {
+  var hex16 = lib.colors.re_.hex16;
+  var hex24 = lib.colors.re_.hex24;
+
+  function convert(hex) {
+    if (hex.length == 4) {
+      hex = hex.replace(hex16, function(h, r, g, b) {
+        return "#" + r + r + g + g + b + b;
+      });
+    }
+    var ary = hex.match(hex24);
+    if (!ary)
+      return null;
+
+    return 'rgb(' + parseInt(ary[1], 16) + ', ' +
+        parseInt(ary[2], 16) + ', ' +
+        parseInt(ary[3], 16) + ')';
+  }
+
+  if (arg instanceof Array) {
+    for (var i = 0; i < arg.length; i++) {
+      arg[i] = convert(arg[i]);
+    }
+  } else {
+    arg = convert(arg);
+  }
+
+  return arg;
+};
+
+/**
+ * Converts one or more CSS rgb(...) forms into their '#RRGGBB' color values.
+ *
+ * If given an rgba(...) form, the alpha field is thrown away.
+ *
+ * Arrays are converted in place. If a value cannot be converted, it is
+ * replaced with null.
+ *
+ * @param {string|Array.<string>} A single rgb(...) value or array of rgb(...)
+ *     values to convert.
+ * @return {string|Array.<string>} The converted value or values.
+ */
+lib.colors.rgbToHex = function(arg) {
+  function convert(rgb) {
+    var ary = lib.colors.crackRGB(rgb);
+    if (!ary)
+      return null;
+    return '#' + lib.f.zpad(((parseInt(ary[0]) << 16) |
+                             (parseInt(ary[1]) <<  8) |
+                             (parseInt(ary[2]) <<  0)).toString(16), 6);
+  }
+
+  if (arg instanceof Array) {
+    for (var i = 0; i < arg.length; i++) {
+      arg[i] = convert(arg[i]);
+    }
+  } else {
+    arg = convert(arg);
+  }
+
+  return arg;
+};
+
+/**
+ * Take any valid css color definition and turn it into an rgb or rgba value.
+ *
+ * Returns null if the value could not be normalized.
+ */
+lib.colors.normalizeCSS = function(def) {
+  if (def.startsWith('#'))
+    return lib.colors.hexToRGB(def);
+
+  if (lib.colors.re_.rgbx.test(def))
+    return def;
+
+  return lib.colors.nameToRGB(def);
+};
+
+/**
+ * Convert a 3 or 4 element array into an rgba(...) string.
+ */
+lib.colors.arrayToRGBA = function(ary) {
+  var alpha = (ary.length > 3) ? ary[3] : 1;
+  return 'rgba(' + ary[0] + ', ' + ary[1] + ', ' + ary[2] + ', ' + alpha + ')';
+};
+
+/**
+ * Overwrite the alpha channel of an rgb/rgba color.
+ */
+lib.colors.setAlpha = function(rgb, alpha) {
+  var ary = lib.colors.crackRGB(rgb);
+  ary[3] = alpha;
+  return lib.colors.arrayToRGBA(ary);
+};
+
+/**
+ * Mix a percentage of a tint color into a base color.
+ */
+lib.colors.mix = function(base, tint, percent) {
+  var ary1 = lib.colors.crackRGB(base);
+  var ary2 = lib.colors.crackRGB(tint);
+
+  for (var i = 0; i < 4; ++i) {
+    var diff = ary2[i] - ary1[i];
+    ary1[i] = Math.round(parseInt(ary1[i]) + diff * percent);
+  }
+
+  return lib.colors.arrayToRGBA(ary1);
+};
+
+/**
+ * Split an rgb/rgba color into an array of its components.
+ *
+ * On success, a 4 element array will be returned.  For rgb values, the alpha
+ * will be set to 1.
+ */
+lib.colors.crackRGB = function(color) {
+  if (color.startsWith('rgba')) {
+    var ary = color.match(lib.colors.re_.rgba);
+    if (ary) {
+      ary.shift();
+      return Array.from(ary);
+    }
+  } else {
+    var ary = color.match(lib.colors.re_.rgb);
+    if (ary) {
+      ary.shift();
+      ary.push('1');
+      return Array.from(ary);
+    }
+  }
+
+  console.error('Couldn\'t crack: ' + color);
+  return null;
+};
+
+/**
+ * Convert an X11 color name into a CSS rgb(...) value.
+ *
+ * Names are stripped of spaces and converted to lowercase.  If the name is
+ * unknown, null is returned.
+ *
+ * This list of color name to RGB mapping is derived from the stock X11
+ * rgb.txt file.
+ *
+ * @param {string} name The color name to convert.
+ * @return {string} The corresponding CSS rgb(...) value.
+ */
+lib.colors.nameToRGB = function(name) {
+  if (name in lib.colors.colorNames)
+    return lib.colors.colorNames[name];
+
+  name = name.toLowerCase();
+  if (name in lib.colors.colorNames)
+    return lib.colors.colorNames[name];
+
+  name = name.replace(/\s+/g, '');
+  if (name in lib.colors.colorNames)
+    return lib.colors.colorNames[name];
+
+  return null;
+};
+
+/**
+ * The stock color palette.
+ */
+lib.colors.stockColorPalette = lib.colors.hexToRGB
+  ([// The "ANSI 16"...
+    '#000000', '#CC0000', '#4E9A06', '#C4A000',
+    '#3465A4', '#75507B', '#06989A', '#D3D7CF',
+    '#555753', '#EF2929', '#00BA13', '#FCE94F',
+    '#729FCF', '#F200CB', '#00B5BD', '#EEEEEC',
+
+    // The 6x6 color cubes...
+    '#000000', '#00005F', '#000087', '#0000AF', '#0000D7', '#0000FF',
+    '#005F00', '#005F5F', '#005F87', '#005FAF', '#005FD7', '#005FFF',
+    '#008700', '#00875F', '#008787', '#0087AF', '#0087D7', '#0087FF',
+    '#00AF00', '#00AF5F', '#00AF87', '#00AFAF', '#00AFD7', '#00AFFF',
+    '#00D700', '#00D75F', '#00D787', '#00D7AF', '#00D7D7', '#00D7FF',
+    '#00FF00', '#00FF5F', '#00FF87', '#00FFAF', '#00FFD7', '#00FFFF',
+
+    '#5F0000', '#5F005F', '#5F0087', '#5F00AF', '#5F00D7', '#5F00FF',
+    '#5F5F00', '#5F5F5F', '#5F5F87', '#5F5FAF', '#5F5FD7', '#5F5FFF',
+    '#5F8700', '#5F875F', '#5F8787', '#5F87AF', '#5F87D7', '#5F87FF',
+    '#5FAF00', '#5FAF5F', '#5FAF87', '#5FAFAF', '#5FAFD7', '#5FAFFF',
+    '#5FD700', '#5FD75F', '#5FD787', '#5FD7AF', '#5FD7D7', '#5FD7FF',
+    '#5FFF00', '#5FFF5F', '#5FFF87', '#5FFFAF', '#5FFFD7', '#5FFFFF',
+
+    '#870000', '#87005F', '#870087', '#8700AF', '#8700D7', '#8700FF',
+    '#875F00', '#875F5F', '#875F87', '#875FAF', '#875FD7', '#875FFF',
+    '#878700', '#87875F', '#878787', '#8787AF', '#8787D7', '#8787FF',
+    '#87AF00', '#87AF5F', '#87AF87', '#87AFAF', '#87AFD7', '#87AFFF',
+    '#87D700', '#87D75F', '#87D787', '#87D7AF', '#87D7D7', '#87D7FF',
+    '#87FF00', '#87FF5F', '#87FF87', '#87FFAF', '#87FFD7', '#87FFFF',
+
+    '#AF0000', '#AF005F', '#AF0087', '#AF00AF', '#AF00D7', '#AF00FF',
+    '#AF5F00', '#AF5F5F', '#AF5F87', '#AF5FAF', '#AF5FD7', '#AF5FFF',
+    '#AF8700', '#AF875F', '#AF8787', '#AF87AF', '#AF87D7', '#AF87FF',
+    '#AFAF00', '#AFAF5F', '#AFAF87', '#AFAFAF', '#AFAFD7', '#AFAFFF',
+    '#AFD700', '#AFD75F', '#AFD787', '#AFD7AF', '#AFD7D7', '#AFD7FF',
+    '#AFFF00', '#AFFF5F', '#AFFF87', '#AFFFAF', '#AFFFD7', '#AFFFFF',
+
+    '#D70000', '#D7005F', '#D70087', '#D700AF', '#D700D7', '#D700FF',
+    '#D75F00', '#D75F5F', '#D75F87', '#D75FAF', '#D75FD7', '#D75FFF',
+    '#D78700', '#D7875F', '#D78787', '#D787AF', '#D787D7', '#D787FF',
+    '#D7AF00', '#D7AF5F', '#D7AF87', '#D7AFAF', '#D7AFD7', '#D7AFFF',
+    '#D7D700', '#D7D75F', '#D7D787', '#D7D7AF', '#D7D7D7', '#D7D7FF',
+    '#D7FF00', '#D7FF5F', '#D7FF87', '#D7FFAF', '#D7FFD7', '#D7FFFF',
+
+    '#FF0000', '#FF005F', '#FF0087', '#FF00AF', '#FF00D7', '#FF00FF',
+    '#FF5F00', '#FF5F5F', '#FF5F87', '#FF5FAF', '#FF5FD7', '#FF5FFF',
+    '#FF8700', '#FF875F', '#FF8787', '#FF87AF', '#FF87D7', '#FF87FF',
+    '#FFAF00', '#FFAF5F', '#FFAF87', '#FFAFAF', '#FFAFD7', '#FFAFFF',
+    '#FFD700', '#FFD75F', '#FFD787', '#FFD7AF', '#FFD7D7', '#FFD7FF',
+    '#FFFF00', '#FFFF5F', '#FFFF87', '#FFFFAF', '#FFFFD7', '#FFFFFF',
+
+    // The greyscale ramp...
+    '#080808', '#121212', '#1C1C1C', '#262626', '#303030', '#3A3A3A',
+    '#444444', '#4E4E4E', '#585858', '#626262', '#6C6C6C', '#767676',
+    '#808080', '#8A8A8A', '#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2',
+    '#BCBCBC', '#C6C6C6', '#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE'
+   ]);
+
+/**
+ * The current color palette, possibly with user changes.
+ */
+lib.colors.colorPalette = lib.colors.stockColorPalette;
+
+/**
+ * Named colors according to the stock X11 rgb.txt file.
+ */
+lib.colors.colorNames = {
+  "aliceblue": "rgb(240, 248, 255)",
+  "antiquewhite": "rgb(250, 235, 215)",
+  "antiquewhite1": "rgb(255, 239, 219)",
+  "antiquewhite2": "rgb(238, 223, 204)",
+  "antiquewhite3": "rgb(205, 192, 176)",
+  "antiquewhite4": "rgb(139, 131, 120)",
+  "aquamarine": "rgb(127, 255, 212)",
+  "aquamarine1": "rgb(127, 255, 212)",
+  "aquamarine2": "rgb(118, 238, 198)",
+  "aquamarine3": "rgb(102, 205, 170)",
+  "aquamarine4": "rgb(69, 139, 116)",
+  "azure": "rgb(240, 255, 255)",
+  "azure1": "rgb(240, 255, 255)",
+  "azure2": "rgb(224, 238, 238)",
+  "azure3": "rgb(193, 205, 205)",
+  "azure4": "rgb(131, 139, 139)",
+  "beige": "rgb(245, 245, 220)",
+  "bisque": "rgb(255, 228, 196)",
+  "bisque1": "rgb(255, 228, 196)",
+  "bisque2": "rgb(238, 213, 183)",
+  "bisque3": "rgb(205, 183, 158)",
+  "bisque4": "rgb(139, 125, 107)",
+  "black": "rgb(0, 0, 0)",
+  "blanchedalmond": "rgb(255, 235, 205)",
+  "blue": "rgb(0, 0, 255)",
+  "blue1": "rgb(0, 0, 255)",
+  "blue2": "rgb(0, 0, 238)",
+  "blue3": "rgb(0, 0, 205)",
+  "blue4": "rgb(0, 0, 139)",
+  "blueviolet": "rgb(138, 43, 226)",
+  "brown": "rgb(165, 42, 42)",
+  "brown1": "rgb(255, 64, 64)",
+  "brown2": "rgb(238, 59, 59)",
+  "brown3": "rgb(205, 51, 51)",
+  "brown4": "rgb(139, 35, 35)",
+  "burlywood": "rgb(222, 184, 135)",
+  "burlywood1": "rgb(255, 211, 155)",
+  "burlywood2": "rgb(238, 197, 145)",
+  "burlywood3": "rgb(205, 170, 125)",
+  "burlywood4": "rgb(139, 115, 85)",
+  "cadetblue": "rgb(95, 158, 160)",
+  "cadetblue1": "rgb(152, 245, 255)",
+  "cadetblue2": "rgb(142, 229, 238)",
+  "cadetblue3": "rgb(122, 197, 205)",
+  "cadetblue4": "rgb(83, 134, 139)",
+  "chartreuse": "rgb(127, 255, 0)",
+  "chartreuse1": "rgb(127, 255, 0)",
+  "chartreuse2": "rgb(118, 238, 0)",
+  "chartreuse3": "rgb(102, 205, 0)",
+  "chartreuse4": "rgb(69, 139, 0)",
+  "chocolate": "rgb(210, 105, 30)",
+  "chocolate1": "rgb(255, 127, 36)",
+  "chocolate2": "rgb(238, 118, 33)",
+  "chocolate3": "rgb(205, 102, 29)",
+  "chocolate4": "rgb(139, 69, 19)",
+  "coral": "rgb(255, 127, 80)",
+  "coral1": "rgb(255, 114, 86)",
+  "coral2": "rgb(238, 106, 80)",
+  "coral3": "rgb(205, 91, 69)",
+  "coral4": "rgb(139, 62, 47)",
+  "cornflowerblue": "rgb(100, 149, 237)",
+  "cornsilk": "rgb(255, 248, 220)",
+  "cornsilk1": "rgb(255, 248, 220)",
+  "cornsilk2": "rgb(238, 232, 205)",
+  "cornsilk3": "rgb(205, 200, 177)",
+  "cornsilk4": "rgb(139, 136, 120)",
+  "cyan": "rgb(0, 255, 255)",
+  "cyan1": "rgb(0, 255, 255)",
+  "cyan2": "rgb(0, 238, 238)",
+  "cyan3": "rgb(0, 205, 205)",
+  "cyan4": "rgb(0, 139, 139)",
+  "darkblue": "rgb(0, 0, 139)",
+  "darkcyan": "rgb(0, 139, 139)",
+  "darkgoldenrod": "rgb(184, 134, 11)",
+  "darkgoldenrod1": "rgb(255, 185, 15)",
+  "darkgoldenrod2": "rgb(238, 173, 14)",
+  "darkgoldenrod3": "rgb(205, 149, 12)",
+  "darkgoldenrod4": "rgb(139, 101, 8)",
+  "darkgray": "rgb(169, 169, 169)",
+  "darkgreen": "rgb(0, 100, 0)",
+  "darkgrey": "rgb(169, 169, 169)",
+  "darkkhaki": "rgb(189, 183, 107)",
+  "darkmagenta": "rgb(139, 0, 139)",
+  "darkolivegreen": "rgb(85, 107, 47)",
+  "darkolivegreen1": "rgb(202, 255, 112)",
+  "darkolivegreen2": "rgb(188, 238, 104)",
+  "darkolivegreen3": "rgb(162, 205, 90)",
+  "darkolivegreen4": "rgb(110, 139, 61)",
+  "darkorange": "rgb(255, 140, 0)",
+  "darkorange1": "rgb(255, 127, 0)",
+  "darkorange2": "rgb(238, 118, 0)",
+  "darkorange3": "rgb(205, 102, 0)",
+  "darkorange4": "rgb(139, 69, 0)",
+  "darkorchid": "rgb(153, 50, 204)",
+  "darkorchid1": "rgb(191, 62, 255)",
+  "darkorchid2": "rgb(178, 58, 238)",
+  "darkorchid3": "rgb(154, 50, 205)",
+  "darkorchid4": "rgb(104, 34, 139)",
+  "darkred": "rgb(139, 0, 0)",
+  "darksalmon": "rgb(233, 150, 122)",
+  "darkseagreen": "rgb(143, 188, 143)",
+  "darkseagreen1": "rgb(193, 255, 193)",
+  "darkseagreen2": "rgb(180, 238, 180)",
+  "darkseagreen3": "rgb(155, 205, 155)",
+  "darkseagreen4": "rgb(105, 139, 105)",
+  "darkslateblue": "rgb(72, 61, 139)",
+  "darkslategray": "rgb(47, 79, 79)",
+  "darkslategray1": "rgb(151, 255, 255)",
+  "darkslategray2": "rgb(141, 238, 238)",
+  "darkslategray3": "rgb(121, 205, 205)",
+  "darkslategray4": "rgb(82, 139, 139)",
+  "darkslategrey": "rgb(47, 79, 79)",
+  "darkturquoise": "rgb(0, 206, 209)",
+  "darkviolet": "rgb(148, 0, 211)",
+  "debianred": "rgb(215, 7, 81)",
+  "deeppink": "rgb(255, 20, 147)",
+  "deeppink1": "rgb(255, 20, 147)",
+  "deeppink2": "rgb(238, 18, 137)",
+  "deeppink3": "rgb(205, 16, 118)",
+  "deeppink4": "rgb(139, 10, 80)",
+  "deepskyblue": "rgb(0, 191, 255)",
+  "deepskyblue1": "rgb(0, 191, 255)",
+  "deepskyblue2": "rgb(0, 178, 238)",
+  "deepskyblue3": "rgb(0, 154, 205)",
+  "deepskyblue4": "rgb(0, 104, 139)",
+  "dimgray": "rgb(105, 105, 105)",
+  "dimgrey": "rgb(105, 105, 105)",
+  "dodgerblue": "rgb(30, 144, 255)",
+  "dodgerblue1": "rgb(30, 144, 255)",
+  "dodgerblue2": "rgb(28, 134, 238)",
+  "dodgerblue3": "rgb(24, 116, 205)",
+  "dodgerblue4": "rgb(16, 78, 139)",
+  "firebrick": "rgb(178, 34, 34)",
+  "firebrick1": "rgb(255, 48, 48)",
+  "firebrick2": "rgb(238, 44, 44)",
+  "firebrick3": "rgb(205, 38, 38)",
+  "firebrick4": "rgb(139, 26, 26)",
+  "floralwhite": "rgb(255, 250, 240)",
+  "forestgreen": "rgb(34, 139, 34)",
+  "gainsboro": "rgb(220, 220, 220)",
+  "ghostwhite": "rgb(248, 248, 255)",
+  "gold": "rgb(255, 215, 0)",
+  "gold1": "rgb(255, 215, 0)",
+  "gold2": "rgb(238, 201, 0)",
+  "gold3": "rgb(205, 173, 0)",
+  "gold4": "rgb(139, 117, 0)",
+  "goldenrod": "rgb(218, 165, 32)",
+  "goldenrod1": "rgb(255, 193, 37)",
+  "goldenrod2": "rgb(238, 180, 34)",
+  "goldenrod3": "rgb(205, 155, 29)",
+  "goldenrod4": "rgb(139, 105, 20)",
+  "gray": "rgb(190, 190, 190)",
+  "gray0": "rgb(0, 0, 0)",
+  "gray1": "rgb(3, 3, 3)",
+  "gray10": "rgb(26, 26, 26)",
+  "gray100": "rgb(255, 255, 255)",
+  "gray11": "rgb(28, 28, 28)",
+  "gray12": "rgb(31, 31, 31)",
+  "gray13": "rgb(33, 33, 33)",
+  "gray14": "rgb(36, 36, 36)",
+  "gray15": "rgb(38, 38, 38)",
+  "gray16": "rgb(41, 41, 41)",
+  "gray17": "rgb(43, 43, 43)",
+  "gray18": "rgb(46, 46, 46)",
+  "gray19": "rgb(48, 48, 48)",
+  "gray2": "rgb(5, 5, 5)",
+  "gray20": "rgb(51, 51, 51)",
+  "gray21": "rgb(54, 54, 54)",
+  "gray22": "rgb(56, 56, 56)",
+  "gray23": "rgb(59, 59, 59)",
+  "gray24": "rgb(61, 61, 61)",
+  "gray25": "rgb(64, 64, 64)",
+  "gray26": "rgb(66, 66, 66)",
+  "gray27": "rgb(69, 69, 69)",
+  "gray28": "rgb(71, 71, 71)",
+  "gray29": "rgb(74, 74, 74)",
+  "gray3": "rgb(8, 8, 8)",
+  "gray30": "rgb(77, 77, 77)",
+  "gray31": "rgb(79, 79, 79)",
+  "gray32": "rgb(82, 82, 82)",
+  "gray33": "rgb(84, 84, 84)",
+  "gray34": "rgb(87, 87, 87)",
+  "gray35": "rgb(89, 89, 89)",
+  "gray36": "rgb(92, 92, 92)",
+  "gray37": "rgb(94, 94, 94)",
+  "gray38": "rgb(97, 97, 97)",
+  "gray39": "rgb(99, 99, 99)",
+  "gray4": "rgb(10, 10, 10)",
+  "gray40": "rgb(102, 102, 102)",
+  "gray41": "rgb(105, 105, 105)",
+  "gray42": "rgb(107, 107, 107)",
+  "gray43": "rgb(110, 110, 110)",
+  "gray44": "rgb(112, 112, 112)",
+  "gray45": "rgb(115, 115, 115)",
+  "gray46": "rgb(117, 117, 117)",
+  "gray47": "rgb(120, 120, 120)",
+  "gray48": "rgb(122, 122, 122)",
+  "gray49": "rgb(125, 125, 125)",
+  "gray5": "rgb(13, 13, 13)",
+  "gray50": "rgb(127, 127, 127)",
+  "gray51": "rgb(130, 130, 130)",
+  "gray52": "rgb(133, 133, 133)",
+  "gray53": "rgb(135, 135, 135)",
+  "gray54": "rgb(138, 138, 138)",
+  "gray55": "rgb(140, 140, 140)",
+  "gray56": "rgb(143, 143, 143)",
+  "gray57": "rgb(145, 145, 145)",
+  "gray58": "rgb(148, 148, 148)",
+  "gray59": "rgb(150, 150, 150)",
+  "gray6": "rgb(15, 15, 15)",
+  "gray60": "rgb(153, 153, 153)",
+  "gray61": "rgb(156, 156, 156)",
+  "gray62": "rgb(158, 158, 158)",
+  "gray63": "rgb(161, 161, 161)",
+  "gray64": "rgb(163, 163, 163)",
+  "gray65": "rgb(166, 166, 166)",
+  "gray66": "rgb(168, 168, 168)",
+  "gray67": "rgb(171, 171, 171)",
+  "gray68": "rgb(173, 173, 173)",
+  "gray69": "rgb(176, 176, 176)",
+  "gray7": "rgb(18, 18, 18)",
+  "gray70": "rgb(179, 179, 179)",
+  "gray71": "rgb(181, 181, 181)",
+  "gray72": "rgb(184, 184, 184)",
+  "gray73": "rgb(186, 186, 186)",
+  "gray74": "rgb(189, 189, 189)",
+  "gray75": "rgb(191, 191, 191)",
+  "gray76": "rgb(194, 194, 194)",
+  "gray77": "rgb(196, 196, 196)",
+  "gray78": "rgb(199, 199, 199)",
+  "gray79": "rgb(201, 201, 201)",
+  "gray8": "rgb(20, 20, 20)",
+  "gray80": "rgb(204, 204, 204)",
+  "gray81": "rgb(207, 207, 207)",
+  "gray82": "rgb(209, 209, 209)",
+  "gray83": "rgb(212, 212, 212)",
+  "gray84": "rgb(214, 214, 214)",
+  "gray85": "rgb(217, 217, 217)",
+  "gray86": "rgb(219, 219, 219)",
+  "gray87": "rgb(222, 222, 222)",
+  "gray88": "rgb(224, 224, 224)",
+  "gray89": "rgb(227, 227, 227)",
+  "gray9": "rgb(23, 23, 23)",
+  "gray90": "rgb(229, 229, 229)",
+  "gray91": "rgb(232, 232, 232)",
+  "gray92": "rgb(235, 235, 235)",
+  "gray93": "rgb(237, 237, 237)",
+  "gray94": "rgb(240, 240, 240)",
+  "gray95": "rgb(242, 242, 242)",
+  "gray96": "rgb(245, 245, 245)",
+  "gray97": "rgb(247, 247, 247)",
+  "gray98": "rgb(250, 250, 250)",
+  "gray99": "rgb(252, 252, 252)",
+  "green": "rgb(0, 255, 0)",
+  "green1": "rgb(0, 255, 0)",
+  "green2": "rgb(0, 238, 0)",
+  "green3": "rgb(0, 205, 0)",
+  "green4": "rgb(0, 139, 0)",
+  "greenyellow": "rgb(173, 255, 47)",
+  "grey": "rgb(190, 190, 190)",
+  "grey0": "rgb(0, 0, 0)",
+  "grey1": "rgb(3, 3, 3)",
+  "grey10": "rgb(26, 26, 26)",
+  "grey100": "rgb(255, 255, 255)",
+  "grey11": "rgb(28, 28, 28)",
+  "grey12": "rgb(31, 31, 31)",
+  "grey13": "rgb(33, 33, 33)",
+  "grey14": "rgb(36, 36, 36)",
+  "grey15": "rgb(38, 38, 38)",
+  "grey16": "rgb(41, 41, 41)",
+  "grey17": "rgb(43, 43, 43)",
+  "grey18": "rgb(46, 46, 46)",
+  "grey19": "rgb(48, 48, 48)",
+  "grey2": "rgb(5, 5, 5)",
+  "grey20": "rgb(51, 51, 51)",
+  "grey21": "rgb(54, 54, 54)",
+  "grey22": "rgb(56, 56, 56)",
+  "grey23": "rgb(59, 59, 59)",
+  "grey24": "rgb(61, 61, 61)",
+  "grey25": "rgb(64, 64, 64)",
+  "grey26": "rgb(66, 66, 66)",
+  "grey27": "rgb(69, 69, 69)",
+  "grey28": "rgb(71, 71, 71)",
+  "grey29": "rgb(74, 74, 74)",
+  "grey3": "rgb(8, 8, 8)",
+  "grey30": "rgb(77, 77, 77)",
+  "grey31": "rgb(79, 79, 79)",
+  "grey32": "rgb(82, 82, 82)",
+  "grey33": "rgb(84, 84, 84)",
+  "grey34": "rgb(87, 87, 87)",
+  "grey35": "rgb(89, 89, 89)",
+  "grey36": "rgb(92, 92, 92)",
+  "grey37": "rgb(94, 94, 94)",
+  "grey38": "rgb(97, 97, 97)",
+  "grey39": "rgb(99, 99, 99)",
+  "grey4": "rgb(10, 10, 10)",
+  "grey40": "rgb(102, 102, 102)",
+  "grey41": "rgb(105, 105, 105)",
+  "grey42": "rgb(107, 107, 107)",
+  "grey43": "rgb(110, 110, 110)",
+  "grey44": "rgb(112, 112, 112)",
+  "grey45": "rgb(115, 115, 115)",
+  "grey46": "rgb(117, 117, 117)",
+  "grey47": "rgb(120, 120, 120)",
+  "grey48": "rgb(122, 122, 122)",
+  "grey49": "rgb(125, 125, 125)",
+  "grey5": "rgb(13, 13, 13)",
+  "grey50": "rgb(127, 127, 127)",
+  "grey51": "rgb(130, 130, 130)",
+  "grey52": "rgb(133, 133, 133)",
+  "grey53": "rgb(135, 135, 135)",
+  "grey54": "rgb(138, 138, 138)",
+  "grey55": "rgb(140, 140, 140)",
+  "grey56": "rgb(143, 143, 143)",
+  "grey57": "rgb(145, 145, 145)",
+  "grey58": "rgb(148, 148, 148)",
+  "grey59": "rgb(150, 150, 150)",
+  "grey6": "rgb(15, 15, 15)",
+  "grey60": "rgb(153, 153, 153)",
+  "grey61": "rgb(156, 156, 156)",
+  "grey62": "rgb(158, 158, 158)",
+  "grey63": "rgb(161, 161, 161)",
+  "grey64": "rgb(163, 163, 163)",
+  "grey65": "rgb(166, 166, 166)",
+  "grey66": "rgb(168, 168, 168)",
+  "grey67": "rgb(171, 171, 171)",
+  "grey68": "rgb(173, 173, 173)",
+  "grey69": "rgb(176, 176, 176)",
+  "grey7": "rgb(18, 18, 18)",
+  "grey70": "rgb(179, 179, 179)",
+  "grey71": "rgb(181, 181, 181)",
+  "grey72": "rgb(184, 184, 184)",
+  "grey73": "rgb(186, 186, 186)",
+  "grey74": "rgb(189, 189, 189)",
+  "grey75": "rgb(191, 191, 191)",
+  "grey76": "rgb(194, 194, 194)",
+  "grey77": "rgb(196, 196, 196)",
+  "grey78": "rgb(199, 199, 199)",
+  "grey79": "rgb(201, 201, 201)",
+  "grey8": "rgb(20, 20, 20)",
+  "grey80": "rgb(204, 204, 204)",
+  "grey81": "rgb(207, 207, 207)",
+  "grey82": "rgb(209, 209, 209)",
+  "grey83": "rgb(212, 212, 212)",
+  "grey84": "rgb(214, 214, 214)",
+  "grey85": "rgb(217, 217, 217)",
+  "grey86": "rgb(219, 219, 219)",
+  "grey87": "rgb(222, 222, 222)",
+  "grey88": "rgb(224, 224, 224)",
+  "grey89": "rgb(227, 227, 227)",
+  "grey9": "rgb(23, 23, 23)",
+  "grey90": "rgb(229, 229, 229)",
+  "grey91": "rgb(232, 232, 232)",
+  "grey92": "rgb(235, 235, 235)",
+  "grey93": "rgb(237, 237, 237)",
+  "grey94": "rgb(240, 240, 240)",
+  "grey95": "rgb(242, 242, 242)",
+  "grey96": "rgb(245, 245, 245)",
+  "grey97": "rgb(247, 247, 247)",
+  "grey98": "rgb(250, 250, 250)",
+  "grey99": "rgb(252, 252, 252)",
+  "honeydew": "rgb(240, 255, 240)",
+  "honeydew1": "rgb(240, 255, 240)",
+  "honeydew2": "rgb(224, 238, 224)",
+  "honeydew3": "rgb(193, 205, 193)",
+  "honeydew4": "rgb(131, 139, 131)",
+  "hotpink": "rgb(255, 105, 180)",
+  "hotpink1": "rgb(255, 110, 180)",
+  "hotpink2": "rgb(238, 106, 167)",
+  "hotpink3": "rgb(205, 96, 144)",
+  "hotpink4": "rgb(139, 58, 98)",
+  "indianred": "rgb(205, 92, 92)",
+  "indianred1": "rgb(255, 106, 106)",
+  "indianred2": "rgb(238, 99, 99)",
+  "indianred3": "rgb(205, 85, 85)",
+  "indianred4": "rgb(139, 58, 58)",
+  "ivory": "rgb(255, 255, 240)",
+  "ivory1": "rgb(255, 255, 240)",
+  "ivory2": "rgb(238, 238, 224)",
+  "ivory3": "rgb(205, 205, 193)",
+  "ivory4": "rgb(139, 139, 131)",
+  "khaki": "rgb(240, 230, 140)",
+  "khaki1": "rgb(255, 246, 143)",
+  "khaki2": "rgb(238, 230, 133)",
+  "khaki3": "rgb(205, 198, 115)",
+  "khaki4": "rgb(139, 134, 78)",
+  "lavender": "rgb(230, 230, 250)",
+  "lavenderblush": "rgb(255, 240, 245)",
+  "lavenderblush1": "rgb(255, 240, 245)",
+  "lavenderblush2": "rgb(238, 224, 229)",
+  "lavenderblush3": "rgb(205, 193, 197)",
+  "lavenderblush4": "rgb(139, 131, 134)",
+  "lawngreen": "rgb(124, 252, 0)",
+  "lemonchiffon": "rgb(255, 250, 205)",
+  "lemonchiffon1": "rgb(255, 250, 205)",
+  "lemonchiffon2": "rgb(238, 233, 191)",
+  "lemonchiffon3": "rgb(205, 201, 165)",
+  "lemonchiffon4": "rgb(139, 137, 112)",
+  "lightblue": "rgb(173, 216, 230)",
+  "lightblue1": "rgb(191, 239, 255)",
+  "lightblue2": "rgb(178, 223, 238)",
+  "lightblue3": "rgb(154, 192, 205)",
+  "lightblue4": "rgb(104, 131, 139)",
+  "lightcoral": "rgb(240, 128, 128)",
+  "lightcyan": "rgb(224, 255, 255)",
+  "lightcyan1": "rgb(224, 255, 255)",
+  "lightcyan2": "rgb(209, 238, 238)",
+  "lightcyan3": "rgb(180, 205, 205)",
+  "lightcyan4": "rgb(122, 139, 139)",
+  "lightgoldenrod": "rgb(238, 221, 130)",
+  "lightgoldenrod1": "rgb(255, 236, 139)",
+  "lightgoldenrod2": "rgb(238, 220, 130)",
+  "lightgoldenrod3": "rgb(205, 190, 112)",
+  "lightgoldenrod4": "rgb(139, 129, 76)",
+  "lightgoldenrodyellow": "rgb(250, 250, 210)",
+  "lightgray": "rgb(211, 211, 211)",
+  "lightgreen": "rgb(144, 238, 144)",
+  "lightgrey": "rgb(211, 211, 211)",
+  "lightpink": "rgb(255, 182, 193)",
+  "lightpink1": "rgb(255, 174, 185)",
+  "lightpink2": "rgb(238, 162, 173)",
+  "lightpink3": "rgb(205, 140, 149)",
+  "lightpink4": "rgb(139, 95, 101)",
+  "lightsalmon": "rgb(255, 160, 122)",
+  "lightsalmon1": "rgb(255, 160, 122)",
+  "lightsalmon2": "rgb(238, 149, 114)",
+  "lightsalmon3": "rgb(205, 129, 98)",
+  "lightsalmon4": "rgb(139, 87, 66)",
+  "lightseagreen": "rgb(32, 178, 170)",
+  "lightskyblue": "rgb(135, 206, 250)",
+  "lightskyblue1": "rgb(176, 226, 255)",
+  "lightskyblue2": "rgb(164, 211, 238)",
+  "lightskyblue3": "rgb(141, 182, 205)",
+  "lightskyblue4": "rgb(96, 123, 139)",
+  "lightslateblue": "rgb(132, 112, 255)",
+  "lightslategray": "rgb(119, 136, 153)",
+  "lightslategrey": "rgb(119, 136, 153)",
+  "lightsteelblue": "rgb(176, 196, 222)",
+  "lightsteelblue1": "rgb(202, 225, 255)",
+  "lightsteelblue2": "rgb(188, 210, 238)",
+  "lightsteelblue3": "rgb(162, 181, 205)",
+  "lightsteelblue4": "rgb(110, 123, 139)",
+  "lightyellow": "rgb(255, 255, 224)",
+  "lightyellow1": "rgb(255, 255, 224)",
+  "lightyellow2": "rgb(238, 238, 209)",
+  "lightyellow3": "rgb(205, 205, 180)",
+  "lightyellow4": "rgb(139, 139, 122)",
+  "limegreen": "rgb(50, 205, 50)",
+  "linen": "rgb(250, 240, 230)",
+  "magenta": "rgb(255, 0, 255)",
+  "magenta1": "rgb(255, 0, 255)",
+  "magenta2": "rgb(238, 0, 238)",
+  "magenta3": "rgb(205, 0, 205)",
+  "magenta4": "rgb(139, 0, 139)",
+  "maroon": "rgb(176, 48, 96)",
+  "maroon1": "rgb(255, 52, 179)",
+  "maroon2": "rgb(238, 48, 167)",
+  "maroon3": "rgb(205, 41, 144)",
+  "maroon4": "rgb(139, 28, 98)",
+  "mediumaquamarine": "rgb(102, 205, 170)",
+  "mediumblue": "rgb(0, 0, 205)",
+  "mediumorchid": "rgb(186, 85, 211)",
+  "mediumorchid1": "rgb(224, 102, 255)",
+  "mediumorchid2": "rgb(209, 95, 238)",
+  "mediumorchid3": "rgb(180, 82, 205)",
+  "mediumorchid4": "rgb(122, 55, 139)",
+  "mediumpurple": "rgb(147, 112, 219)",
+  "mediumpurple1": "rgb(171, 130, 255)",
+  "mediumpurple2": "rgb(159, 121, 238)",
+  "mediumpurple3": "rgb(137, 104, 205)",
+  "mediumpurple4": "rgb(93, 71, 139)",
+  "mediumseagreen": "rgb(60, 179, 113)",
+  "mediumslateblue": "rgb(123, 104, 238)",
+  "mediumspringgreen": "rgb(0, 250, 154)",
+  "mediumturquoise": "rgb(72, 209, 204)",
+  "mediumvioletred": "rgb(199, 21, 133)",
+  "midnightblue": "rgb(25, 25, 112)",
+  "mintcream": "rgb(245, 255, 250)",
+  "mistyrose": "rgb(255, 228, 225)",
+  "mistyrose1": "rgb(255, 228, 225)",
+  "mistyrose2": "rgb(238, 213, 210)",
+  "mistyrose3": "rgb(205, 183, 181)",
+  "mistyrose4": "rgb(139, 125, 123)",
+  "moccasin": "rgb(255, 228, 181)",
+  "navajowhite": "rgb(255, 222, 173)",
+  "navajowhite1": "rgb(255, 222, 173)",
+  "navajowhite2": "rgb(238, 207, 161)",
+  "navajowhite3": "rgb(205, 179, 139)",
+  "navajowhite4": "rgb(139, 121, 94)",
+  "navy": "rgb(0, 0, 128)",
+  "navyblue": "rgb(0, 0, 128)",
+  "oldlace": "rgb(253, 245, 230)",
+  "olivedrab": "rgb(107, 142, 35)",
+  "olivedrab1": "rgb(192, 255, 62)",
+  "olivedrab2": "rgb(179, 238, 58)",
+  "olivedrab3": "rgb(154, 205, 50)",
+  "olivedrab4": "rgb(105, 139, 34)",
+  "orange": "rgb(255, 165, 0)",
+  "orange1": "rgb(255, 165, 0)",
+  "orange2": "rgb(238, 154, 0)",
+  "orange3": "rgb(205, 133, 0)",
+  "orange4": "rgb(139, 90, 0)",
+  "orangered": "rgb(255, 69, 0)",
+  "orangered1": "rgb(255, 69, 0)",
+  "orangered2": "rgb(238, 64, 0)",
+  "orangered3": "rgb(205, 55, 0)",
+  "orangered4": "rgb(139, 37, 0)",
+  "orchid": "rgb(218, 112, 214)",
+  "orchid1": "rgb(255, 131, 250)",
+  "orchid2": "rgb(238, 122, 233)",
+  "orchid3": "rgb(205, 105, 201)",
+  "orchid4": "rgb(139, 71, 137)",
+  "palegoldenrod": "rgb(238, 232, 170)",
+  "palegreen": "rgb(152, 251, 152)",
+  "palegreen1": "rgb(154, 255, 154)",
+  "palegreen2": "rgb(144, 238, 144)",
+  "palegreen3": "rgb(124, 205, 124)",
+  "palegreen4": "rgb(84, 139, 84)",
+  "paleturquoise": "rgb(175, 238, 238)",
+  "paleturquoise1": "rgb(187, 255, 255)",
+  "paleturquoise2": "rgb(174, 238, 238)",
+  "paleturquoise3": "rgb(150, 205, 205)",
+  "paleturquoise4": "rgb(102, 139, 139)",
+  "palevioletred": "rgb(219, 112, 147)",
+  "palevioletred1": "rgb(255, 130, 171)",
+  "palevioletred2": "rgb(238, 121, 159)",
+  "palevioletred3": "rgb(205, 104, 137)",
+  "palevioletred4": "rgb(139, 71, 93)",
+  "papayawhip": "rgb(255, 239, 213)",
+  "peachpuff": "rgb(255, 218, 185)",
+  "peachpuff1": "rgb(255, 218, 185)",
+  "peachpuff2": "rgb(238, 203, 173)",
+  "peachpuff3": "rgb(205, 175, 149)",
+  "peachpuff4": "rgb(139, 119, 101)",
+  "peru": "rgb(205, 133, 63)",
+  "pink": "rgb(255, 192, 203)",
+  "pink1": "rgb(255, 181, 197)",
+  "pink2": "rgb(238, 169, 184)",
+  "pink3": "rgb(205, 145, 158)",
+  "pink4": "rgb(139, 99, 108)",
+  "plum": "rgb(221, 160, 221)",
+  "plum1": "rgb(255, 187, 255)",
+  "plum2": "rgb(238, 174, 238)",
+  "plum3": "rgb(205, 150, 205)",
+  "plum4": "rgb(139, 102, 139)",
+  "powderblue": "rgb(176, 224, 230)",
+  "purple": "rgb(160, 32, 240)",
+  "purple1": "rgb(155, 48, 255)",
+  "purple2": "rgb(145, 44, 238)",
+  "purple3": "rgb(125, 38, 205)",
+  "purple4": "rgb(85, 26, 139)",
+  "red": "rgb(255, 0, 0)",
+  "red1": "rgb(255, 0, 0)",
+  "red2": "rgb(238, 0, 0)",
+  "red3": "rgb(205, 0, 0)",
+  "red4": "rgb(139, 0, 0)",
+  "rosybrown": "rgb(188, 143, 143)",
+  "rosybrown1": "rgb(255, 193, 193)",
+  "rosybrown2": "rgb(238, 180, 180)",
+  "rosybrown3": "rgb(205, 155, 155)",
+  "rosybrown4": "rgb(139, 105, 105)",
+  "royalblue": "rgb(65, 105, 225)",
+  "royalblue1": "rgb(72, 118, 255)",
+  "royalblue2": "rgb(67, 110, 238)",
+  "royalblue3": "rgb(58, 95, 205)",
+  "royalblue4": "rgb(39, 64, 139)",
+  "saddlebrown": "rgb(139, 69, 19)",
+  "salmon": "rgb(250, 128, 114)",
+  "salmon1": "rgb(255, 140, 105)",
+  "salmon2": "rgb(238, 130, 98)",
+  "salmon3": "rgb(205, 112, 84)",
+  "salmon4": "rgb(139, 76, 57)",
+  "sandybrown": "rgb(244, 164, 96)",
+  "seagreen": "rgb(46, 139, 87)",
+  "seagreen1": "rgb(84, 255, 159)",
+  "seagreen2": "rgb(78, 238, 148)",
+  "seagreen3": "rgb(67, 205, 128)",
+  "seagreen4": "rgb(46, 139, 87)",
+  "seashell": "rgb(255, 245, 238)",
+  "seashell1": "rgb(255, 245, 238)",
+  "seashell2": "rgb(238, 229, 222)",
+  "seashell3": "rgb(205, 197, 191)",
+  "seashell4": "rgb(139, 134, 130)",
+  "sienna": "rgb(160, 82, 45)",
+  "sienna1": "rgb(255, 130, 71)",
+  "sienna2": "rgb(238, 121, 66)",
+  "sienna3": "rgb(205, 104, 57)",
+  "sienna4": "rgb(139, 71, 38)",
+  "skyblue": "rgb(135, 206, 235)",
+  "skyblue1": "rgb(135, 206, 255)",
+  "skyblue2": "rgb(126, 192, 238)",
+  "skyblue3": "rgb(108, 166, 205)",
+  "skyblue4": "rgb(74, 112, 139)",
+  "slateblue": "rgb(106, 90, 205)",
+  "slateblue1": "rgb(131, 111, 255)",
+  "slateblue2": "rgb(122, 103, 238)",
+  "slateblue3": "rgb(105, 89, 205)",
+  "slateblue4": "rgb(71, 60, 139)",
+  "slategray": "rgb(112, 128, 144)",
+  "slategray1": "rgb(198, 226, 255)",
+  "slategray2": "rgb(185, 211, 238)",
+  "slategray3": "rgb(159, 182, 205)",
+  "slategray4": "rgb(108, 123, 139)",
+  "slategrey": "rgb(112, 128, 144)",
+  "snow": "rgb(255, 250, 250)",
+  "snow1": "rgb(255, 250, 250)",
+  "snow2": "rgb(238, 233, 233)",
+  "snow3": "rgb(205, 201, 201)",
+  "snow4": "rgb(139, 137, 137)",
+  "springgreen": "rgb(0, 255, 127)",
+  "springgreen1": "rgb(0, 255, 127)",
+  "springgreen2": "rgb(0, 238, 118)",
+  "springgreen3": "rgb(0, 205, 102)",
+  "springgreen4": "rgb(0, 139, 69)",
+  "steelblue": "rgb(70, 130, 180)",
+  "steelblue1": "rgb(99, 184, 255)",
+  "steelblue2": "rgb(92, 172, 238)",
+  "steelblue3": "rgb(79, 148, 205)",
+  "steelblue4": "rgb(54, 100, 139)",
+  "tan": "rgb(210, 180, 140)",
+  "tan1": "rgb(255, 165, 79)",
+  "tan2": "rgb(238, 154, 73)",
+  "tan3": "rgb(205, 133, 63)",
+  "tan4": "rgb(139, 90, 43)",
+  "thistle": "rgb(216, 191, 216)",
+  "thistle1": "rgb(255, 225, 255)",
+  "thistle2": "rgb(238, 210, 238)",
+  "thistle3": "rgb(205, 181, 205)",
+  "thistle4": "rgb(139, 123, 139)",
+  "tomato": "rgb(255, 99, 71)",
+  "tomato1": "rgb(255, 99, 71)",
+  "tomato2": "rgb(238, 92, 66)",
+  "tomato3": "rgb(205, 79, 57)",
+  "tomato4": "rgb(139, 54, 38)",
+  "turquoise": "rgb(64, 224, 208)",
+  "turquoise1": "rgb(0, 245, 255)",
+  "turquoise2": "rgb(0, 229, 238)",
+  "turquoise3": "rgb(0, 197, 205)",
+  "turquoise4": "rgb(0, 134, 139)",
+  "violet": "rgb(238, 130, 238)",
+  "violetred": "rgb(208, 32, 144)",
+  "violetred1": "rgb(255, 62, 150)",
+  "violetred2": "rgb(238, 58, 140)",
+  "violetred3": "rgb(205, 50, 120)",
+  "violetred4": "rgb(139, 34, 82)",
+  "wheat": "rgb(245, 222, 179)",
+  "wheat1": "rgb(255, 231, 186)",
+  "wheat2": "rgb(238, 216, 174)",
+  "wheat3": "rgb(205, 186, 150)",
+  "wheat4": "rgb(139, 126, 102)",
+  "white": "rgb(255, 255, 255)",
+  "whitesmoke": "rgb(245, 245, 245)",
+  "yellow": "rgb(255, 255, 0)",
+  "yellow1": "rgb(255, 255, 0)",
+  "yellow2": "rgb(238, 238, 0)",
+  "yellow3": "rgb(205, 205, 0)",
+  "yellow4": "rgb(139, 139, 0)",
+  "yellowgreen": "rgb(154, 205, 50)"
+};
+// SOURCE FILE: libdot/js/lib_f.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Grab bag of utility functions.
+ */
+lib.f = {};
+
+/**
+ * Replace variable references in a string.
+ *
+ * Variables are of the form %FUNCTION(VARNAME).  FUNCTION is an optional
+ * escape function to apply to the value.
+ *
+ * For example
+ *   lib.f.replaceVars("%(greeting), %encodeURIComponent(name)",
+ *                     { greeting: "Hello",
+ *                       name: "Google+" });
+ *
+ * Will result in "Hello, Google%2B".
+ */
+lib.f.replaceVars = function(str, vars) {
+  return str.replace(/%([a-z]*)\(([^\)]+)\)/gi, function(match, fn, varname) {
+      if (typeof vars[varname] == 'undefined')
+        throw 'Unknown variable: ' + varname;
+
+      var rv = vars[varname];
+
+      if (fn in lib.f.replaceVars.functions) {
+        rv = lib.f.replaceVars.functions[fn](rv);
+      } else if (fn) {
+        throw 'Unknown escape function: ' + fn;
+      }
+
+      return rv;
+    });
+};
+
+/**
+ * Functions that can be used with replaceVars.
+ *
+ * Clients can add to this list to extend lib.f.replaceVars().
+ */
+lib.f.replaceVars.functions = {
+  encodeURI: encodeURI,
+  encodeURIComponent: encodeURIComponent,
+  escapeHTML: function(str) {
+    var map = {
+      '<': '&lt;',
+      '>': '&gt;',
+      '&': '&amp;',
+      '"': '&quot;',
+      "'": '&#39;'
+    };
+
+    return str.replace(/[<>&\"\']/g, (m) => map[m]);
+  }
+};
+
+lib.f.getURL = function(path) {
+  if (lib.f.getURL.chromeSupported())
+    return chrome.runtime.getURL(path);
+
+  return path;
+};
+
+lib.f.getURL.chromeSupported = function() {
+  return window.chrome && chrome.runtime && chrome.runtime.getURL;
+};
+
+/**
+ * Clamp a given integer to a specified range.
+ *
+ * @param {integer} v The value to be clamped.
+ * @param {integer} min The minimum acceptable value.
+ * @param {integer} max The maximum acceptable value.
+ */
+lib.f.clamp = function(v, min, max) {
+  if (v < min)
+    return min;
+  if (v > max)
+    return max;
+  return v;
+};
+
+/**
+ * Left pad a number to a given length with leading zeros.
+ *
+ * @param {string|integer} number The number to pad.
+ * @param {integer} length The desired length.
+ * @return {string} The padded number as a string.
+ */
+lib.f.zpad = function(number, length) {
+  return String(number).padStart(length, '0');
+};
+
+/**
+ * Return the current call stack after skipping a given number of frames.
+ *
+ * This method is intended to be used for debugging only.  It returns an
+ * Object instead of an Array, because the console stringifies arrays by
+ * default and that's not what we want.
+ *
+ * A typical call might look like...
+ *
+ *    console.log('Something wicked this way came', lib.f.getStack());
+ *    //                         Notice the comma ^
+ *
+ * This would print the message to the js console, followed by an object
+ * which can be clicked to reveal the stack.
+ *
+ * @param {number=} ignoreFrames How many inner stack frames to ignore.  The
+ *     innermost 'getStack' call is always ignored.
+ * @param {number=} count How many frames to return.
+ */
+lib.f.getStack = function(ignoreFrames = 0, count = undefined) {
+  const stackArray = (new Error()).stack.split('\n');
+
+  // Always ignore the Error() object and getStack call itself.
+  // [0] = 'Error'
+  // [1] = '    at Object.lib.f.getStack (file:///.../lib_f.js:267:23)'
+  ignoreFrames += 2;
+
+  const max = stackArray.length - ignoreFrames;
+  if (count === undefined)
+    count = max;
+  else
+    count = lib.f.clamp(count, 0, max);
+
+  // Remove the leading spaces and "at" from each line:
+  // '    at window.onload (file:///.../lib_test.js:11:18)'
+  const stackObject = new Array();
+  for (let i = ignoreFrames; i < count + ignoreFrames; ++i)
+    stackObject.push(stackArray[i].replace(/^\s*at\s+/, ''));
+
+  return stackObject;
+};
+
+/**
+ * Divides the two numbers and floors the results, unless the remainder is less
+ * than an incredibly small value, in which case it returns the ceiling.
+ * This is useful when the number are truncated approximations of longer
+ * values, and so doing division with these numbers yields a result incredibly
+ * close to a whole number.
+ *
+ * @param {number} numerator
+ * @param {number} denominator
+ * @return {number}
+ */
+lib.f.smartFloorDivide = function(numerator,  denominator) {
+  var val = numerator / denominator;
+  var ceiling = Math.ceil(val);
+  if (ceiling - val < .0001) {
+    return ceiling;
+  } else {
+    return Math.floor(val);
+  }
+};
+
+/**
+ * Get a random integer in a range (inclusive).
+ *
+ * @param {number} min The lowest integer in the range.
+ * @param {number} max The highest integer in the range.
+ * @return {number} A random number between min & max.
+ */
+lib.f.randomInt = function(min, max) {
+  return Math.floor(Math.random() * (max - min + 1)) + min;
+};
+
+/**
+ * Get the current OS.
+ *
+ * @return {Promise<string>} A promise that resolves to a constant in
+ *     runtime.PlatformOs.
+ */
+lib.f.getOs = function() {
+  // Try the brower extensions API.
+  if (window.browser && browser.runtime && browser.runtime.getPlatformInfo)
+    return browser.runtime.getPlatformInfo().then((info) => info.os);
+
+  // Use the native Chrome API if available.
+  if (window.chrome && chrome.runtime && chrome.runtime.getPlatformInfo) {
+    return new Promise((resolve, reject) =>
+        chrome.runtime.getPlatformInfo((info) => resolve(info.os)));
+  }
+
+  // Fallback logic.  Capture the major OS's.  The rest should support the
+  // browser API above.
+  if (window.navigator && navigator.userAgent) {
+    const ua = navigator.userAgent;
+    if (ua.includes('Mac OS X'))
+      return Promise.resolve('mac');
+    else if (ua.includes('CrOS'))
+      return Promise.resolve('cros');
+    else if (ua.includes('Linux'))
+      return Promise.resolve('linux');
+    else if (ua.includes('Android'))
+      return Promise.resolve('android');
+    else if (ua.includes('Windows'))
+      return Promise.resolve('windows');
+  }
+
+  // Probe node environment.
+  if (typeof process != 'undefined') {
+    return Promise.resolve('node');
+  }
+
+  // Still here?  No idea.
+  return Promise.reject(null);
+};
+
+/**
+ * Get the current Chrome milestone version.
+ *
+ * @return {number} The milestone number if we're running on Chrome, else NaN.
+ */
+lib.f.getChromeMilestone = function() {
+  if (window.navigator && navigator.userAgent) {
+    const ary = navigator.userAgent.match(/\sChrome\/(\d+)/);
+    if (ary)
+      return parseInt(ary[1]);
+  }
+
+  // Returning NaN will make all number comparisons fail.
+  return NaN;
+};
+
+/**
+ * Return the lastError string in the browser.
+ *
+ * This object might live in different locations, and it isn't always defined
+ * (if there hasn't been a "last error").  Wrap all that ugliness here.
+ *
+ * @param {string=} defaultMsg The default message if no error is found.
+ * @return {string} The last error message from the browser.
+ */
+lib.f.lastError = function(defaultMsg = null) {
+  let lastError;
+  if (window.browser && browser.runtime)
+    lastError = browser.runtime.lastError;
+  else if (window.chrome && chrome.runtime)
+    lastError = chrome.runtime.lastError;
+
+  if (lastError && lastError.message)
+    return lastError.message;
+  else
+    return defaultMsg;
+};
+
+/**
+ * Just like window.open, but enforce noopener.
+ *
+ * If we're not careful, the website we open will have access to use via its
+ * window.opener field.  Newer browser support putting 'noopener' into the
+ * features argument, but there are many which still don't.  So hack it.
+ *
+ * @param {string=} url The URL to point the new window to.
+ * @param {string=} name The name of the new window.
+ * @param {string=} features The window features to enable.
+ * @return {Window} The newly opened window.
+ */
+lib.f.openWindow = function(url, name=undefined, features=undefined) {
+  // We create the window first without the URL loaded.
+  const win = window.open(undefined, name, features);
+
+  // If the system is blocking window.open, don't crash.
+  if (win !== null) {
+    // Clear the opener setting before redirecting.
+    win.opener = null;
+
+    // Now it's safe to redirect.  Skip this step if the url is not set so we
+    // mimic the window.open behavior more precisely.
+    if (url) {
+      win.location = url;
+    }
+  }
+
+  return win;
+};
+// SOURCE FILE: libdot/js/lib_i18n.js
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Wrappers over the browser i18n helpers.
+ *
+ * Arguably some of these functions should be l10n, but oh well.
+ */
+lib.i18n = {};
+
+/**
+ * Convenience shortcut to the browser i18n object.
+ */
+lib.i18n.browser_ =
+    window.browser && browser.i18n ? browser.i18n :
+    window.chrome && chrome.i18n ? chrome.i18n :
+    null;
+
+/**
+ * Get the list of accepted UI languages.
+ *
+ * https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/i18n/getAcceptLanguages
+ *
+ * @param {function(Array)} callback Function to invoke with the results.  The
+ *     parameter is a list of locale names.
+ */
+lib.i18n.getAcceptLanguages = function(callback) {
+  if (lib.i18n.browser_) {
+    lib.i18n.browser_.getAcceptLanguages(callback);
+  } else {
+    setTimeout(function() {
+        callback([navigator.language.replace(/-/g, '_')]);
+      }, 0);
+  }
+};
+
+/**
+ * Get a message by name, optionally replacing arguments too.
+ *
+ * https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/i18n/getMessage
+ *
+ * @param {string} msgname The id for this localized string.
+ * @param {string[]=} substitutions Any replacements in the string.
+ * @param {string=} fallback Translation if the message wasn't found.
+ * @return {string} The translated message.
+ */
+lib.i18n.getMessage = function(msgname, substitutions = [], fallback = '') {
+  // First let the native browser APIs handle everything for us.
+  if (lib.i18n.browser_) {
+    const message = lib.i18n.browser_.getMessage(msgname, substitutions);
+    if (message)
+      return message;
+  }
+
+  // Do our best to get something reasonable.
+  return lib.i18n.replaceReferences(fallback, substitutions);
+};
+
+/**
+ * Replace $1...$n references with the elements of the args array.
+ *
+ * This largely behaves like Chrome's getMessage helper.  The $# references are
+ * always replaced/removed regardless of the specified substitutions.
+ *
+ * @param {string} msg String containing the message and argument references.
+ * @param {string[]=} args Array containing the argument values.
+ * @return {string} The message with replacements expanded.
+ */
+lib.i18n.replaceReferences = function(msg, args = []) {
+  // The Chrome API allows a single substitution as a string rather than array.
+  if (args === null) {
+    args = [];
+  }
+  if (!(args instanceof Array)) {
+    args = [args];
+  }
+
+  return msg.replace(/\$(\d+)/g, (m, index) => {
+    return index <= args.length ? args[index - 1] : '';
+  });
+};
+// SOURCE FILE: libdot/js/lib_message_manager.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * MessageManager class handles internationalized strings.
+ *
+ * Note: chrome.i18n isn't sufficient because...
+ *     1. There's a bug in chrome that makes it unavailable in iframes:
+ *        https://crbug.com/130200
+ *     2. The client code may not be packaged in a Chrome extension.
+ *     3. The client code may be part of a library packaged in a third-party
+ *        Chrome extension.
+ *
+ * @param {Array} languages List of languages to load, in the order they
+ *     should be loaded.  Newer messages replace older ones.  'en' is
+ *     automatically added as the first language if it is not already present.
+ */
+lib.MessageManager = function(languages) {
+  this.languages_ = languages.map((el) => el.replace(/-/g, '_'));
+
+  if (this.languages_.indexOf('en') == -1)
+    this.languages_.unshift('en');
+
+  this.messages = {};
+};
+
+/**
+ * Add message definitions to the message manager.
+ *
+ * This takes an object of the same format of a Chrome messages.json file.  See
+ * <https://developer.chrome.com/extensions/i18n-messages>.
+ */
+lib.MessageManager.prototype.addMessages = function(defs) {
+  for (var key in defs) {
+    var def = defs[key];
+
+    if (!def.placeholders) {
+      this.messages[key] = def.message;
+    } else {
+      // Replace "$NAME$" placeholders with "$1", etc.
+      this.messages[key] = def.message.replace(
+          /\$([a-z][^\s\$]+)\$/ig,
+          function(m, name) {
+            return defs[key].placeholders[name.toLowerCase()].content;
+          });
+    }
+  }
+};
+
+/**
+ * Load the first available language message bundle.
+ *
+ * @param {string} pattern A url pattern containing a "$1" where the locale
+ *     name should go.
+ * @param {function(Array,Array)} onComplete Function to be called when loading
+ *     is complete.  The two arrays are the list of successful and failed
+ *     locale names.  If the first parameter is length 0, no locales were
+ *     loaded.
+ */
+lib.MessageManager.prototype.findAndLoadMessages = function(
+    pattern, onComplete) {
+  var languages = this.languages_.concat();
+  var loaded = [];
+  var failed = [];
+
+  function onLanguageComplete(state) {
+    if (state) {
+      loaded = languages.shift();
+    } else {
+      failed = languages.shift();
+    }
+
+    if (languages.length) {
+      tryNextLanguage();
+    } else {
+      onComplete(loaded, failed);
+    }
+  }
+
+  var tryNextLanguage = function() {
+    this.loadMessages(this.replaceReferences(pattern, languages),
+                      onLanguageComplete.bind(this, true),
+                      onLanguageComplete.bind(this, false));
+  }.bind(this);
+
+  tryNextLanguage();
+};
+
+/**
+ * Load messages from a messages.json file.
+ */
+lib.MessageManager.prototype.loadMessages = function(
+    url, onSuccess, opt_onError) {
+  var xhr = new XMLHttpRequest();
+
+  xhr.onload = () => {
+    this.addMessages(JSON.parse(xhr.responseText));
+    onSuccess();
+  };
+  if (opt_onError)
+    xhr.onerror = () => opt_onError(xhr);
+
+  xhr.open('GET', url);
+  xhr.send();
+};
+
+/**
+ * Per-instance copy of replaceReferences.
+ */
+lib.MessageManager.prototype.replaceReferences = lib.i18n.replaceReferences;
+
+/**
+ * Get a message by name, optionally replacing arguments too.
+ *
+ * @param {string} msgname String containing the name of the message to get.
+ * @param {Array} opt_args Optional array containing the argument values.
+ * @param {string} opt_default Optional value to return if the msgname is not
+ *     found.  Returns the message name by default.
+ */
+lib.MessageManager.prototype.get = function(msgname, opt_args, opt_default) {
+  // First try the integrated browser getMessage.  We prefer that over any
+  // registered messages as only the browser supports translations.
+  let message = lib.i18n.getMessage(msgname, opt_args);
+  if (message)
+    return message;
+
+  // Look it up in the registered cache next.
+  message = this.messages[msgname];
+  if (!message) {
+    console.warn('Unknown message: ' + msgname);
+    message = opt_default === undefined ? msgname : opt_default;
+    // Register the message with the default to avoid multiple warnings.
+    this.messages[msgname] = message;
+  }
+
+  return this.replaceReferences(message, opt_args);
+};
+
+/**
+ * Process all of the "i18n" html attributes found in a given dom fragment.
+ *
+ * The real work happens in processI18nAttribute.
+ */
+lib.MessageManager.prototype.processI18nAttributes = function(dom) {
+  var nodes = dom.querySelectorAll('[i18n]');
+
+  for (var i = 0; i < nodes.length; i++)
+    this.processI18nAttribute(nodes[i]);
+};
+
+/**
+ * Process the "i18n" attribute in the specified node.
+ *
+ * The i18n attribute should contain a JSON object.  The keys are taken to
+ * be attribute names, and the values are message names.
+ *
+ * If the JSON object has a "_" (underscore) key, its value is used as the
+ * textContent of the element.
+ *
+ * Message names can refer to other attributes on the same element with by
+ * prefixing with a dollar sign.  For example...
+ *
+ *   <button id='send-button'
+ *           i18n='{"aria-label": "$id", "_": "SEND_BUTTON_LABEL"}'
+ *           ></button>
+ *
+ * The aria-label message name will be computed as "SEND_BUTTON_ARIA_LABEL".
+ * Notice that the "id" attribute was appended to the target attribute, and
+ * the result converted to UPPER_AND_UNDER style.
+ */
+lib.MessageManager.prototype.processI18nAttribute = function(node) {
+  // Convert the "lower-and-dashes" attribute names into
+  // "UPPER_AND_UNDER" style.
+  const thunk = (str) => str.replace(/-/g, '_').toUpperCase();
+
+  var i18n = node.getAttribute('i18n');
+  if (!i18n)
+    return;
+
+  try {
+    i18n = JSON.parse(i18n);
+  } catch (ex) {
+    console.error('Can\'t parse ' + node.tagName + '#' + node.id + ': ' + i18n);
+    throw ex;
+  }
+
+  // Load all the messages specified in the i18n attributes.
+  for (var key in i18n) {
+    // The node attribute we'll be setting.
+    var attr = key;
+
+    var msgname = i18n[key];
+    // For "=foo", re-use the referenced message name.
+    if (msgname.startsWith('=')) {
+      key = msgname.substr(1);
+      msgname = i18n[key];
+    }
+
+    // For "$foo", calculate the message name.
+    if (msgname.startsWith('$'))
+      msgname = thunk(node.getAttribute(msgname.substr(1)) + '_' + key);
+
+    // Finally load the message.
+    var msg = this.get(msgname);
+    if (attr == '_')
+      node.textContent = msg;
+    else
+      node.setAttribute(attr, msg);
+  }
+};
+// SOURCE FILE: libdot/js/lib_preference_manager.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Constructor for lib.PreferenceManager objects.
+ *
+ * These objects deal with persisting changes to stable storage and notifying
+ * consumers when preferences change.
+ *
+ * It is intended that the backing store could be something other than HTML5
+ * storage, but there aren't any use cases at the moment.  In the future there
+ * may be a chrome api to store sync-able name/value pairs, and we'd want
+ * that.
+ *
+ * @param {lib.Storage.*} storage The storage object to use as a backing
+ *     store.
+ * @param {string} opt_prefix The optional prefix to be used for all preference
+ *     names.  The '/' character should be used to separate levels of hierarchy,
+ *     if you're going to have that kind of thing.  If provided, the prefix
+ *     should start with a '/'.  If not provided, it defaults to '/'.
+ */
+lib.PreferenceManager = function(storage, opt_prefix) {
+  this.storage = storage;
+  this.storageObserver_ = this.onStorageChange_.bind(this);
+
+  this.isActive_ = false;
+  this.activate();
+
+  this.trace = false;
+
+  var prefix = opt_prefix || '/';
+  if (!prefix.endsWith('/'))
+    prefix += '/';
+
+  this.prefix = prefix;
+
+  // Internal state for when we're doing a bulk import from JSON and we want
+  // to elide redundant storage writes (for quota reasons).
+  this.isImportingJson_ = false;
+
+  this.prefRecords_ = {};
+  this.globalObservers_ = [];
+
+  this.childFactories_ = {};
+
+  // Map of list-name to {map of child pref managers}
+  // As in...
+  //
+  //  this.childLists_ = {
+  //    'profile-ids': {
+  //      'one': PreferenceManager,
+  //      'two': PreferenceManager,
+  //      ...
+  //    },
+  //
+  //    'frob-ids': {
+  //      ...
+  //    }
+  //  }
+  this.childLists_ = {};
+};
+
+/**
+ * Used internally to indicate that the current value of the preference should
+ * be taken from the default value defined with the preference.
+ *
+ * Equality tests against this value MUST use '===' or '!==' to be accurate.
+ */
+lib.PreferenceManager.prototype.DEFAULT_VALUE = Symbol('DEFAULT_VALUE');
+
+/**
+ * An individual preference.
+ *
+ * These objects are managed by the PreferenceManager, you shouldn't need to
+ * handle them directly.
+ */
+lib.PreferenceManager.Record = function(name, defaultValue) {
+  this.name = name;
+  this.defaultValue = defaultValue;
+  this.currentValue = this.DEFAULT_VALUE;
+  this.observers = [];
+};
+
+/**
+ * A local copy of the DEFAULT_VALUE constant to make it less verbose.
+ */
+lib.PreferenceManager.Record.prototype.DEFAULT_VALUE =
+    lib.PreferenceManager.prototype.DEFAULT_VALUE;
+
+/**
+ * Register a callback to be invoked when this preference changes.
+ *
+ * @param {function(value, string, lib.PreferenceManager} observer The function
+ *     to invoke.  It will receive the new value, the name of the preference,
+ *     and a reference to the PreferenceManager as parameters.
+ */
+lib.PreferenceManager.Record.prototype.addObserver = function(observer) {
+  this.observers.push(observer);
+};
+
+/**
+ * Unregister an observer callback.
+ *
+ * @param {function} observer A previously registered callback.
+ */
+lib.PreferenceManager.Record.prototype.removeObserver = function(observer) {
+  var i = this.observers.indexOf(observer);
+  if (i >= 0)
+    this.observers.splice(i, 1);
+};
+
+/**
+ * Fetch the value of this preference.
+ */
+lib.PreferenceManager.Record.prototype.get = function() {
+  if (this.currentValue === this.DEFAULT_VALUE) {
+    if (/^(string|number)$/.test(typeof this.defaultValue))
+      return this.defaultValue;
+
+    if (typeof this.defaultValue == 'object') {
+      // We want to return a COPY of the default value so that users can
+      // modify the array or object without changing the default value.
+      return JSON.parse(JSON.stringify(this.defaultValue));
+    }
+
+    return this.defaultValue;
+  }
+
+  return this.currentValue;
+};
+
+/**
+ * Stop this preference manager from tracking storage changes.
+ *
+ * Call this if you're going to swap out one preference manager for another so
+ * that you don't get notified about irrelevant changes.
+ */
+lib.PreferenceManager.prototype.deactivate = function() {
+  if (!this.isActive_)
+    throw new Error('Not activated');
+
+  this.isActive_ = false;
+  this.storage.removeObserver(this.storageObserver_);
+};
+
+/**
+ * Start tracking storage changes.
+ *
+ * If you previously deactivated this preference manager, you can reactivate it
+ * with this method.  You don't need to call this at initialization time, as
+ * it's automatically called as part of the constructor.
+ */
+lib.PreferenceManager.prototype.activate = function() {
+  if (this.isActive_)
+    throw new Error('Already activated');
+
+  this.isActive_ = true;
+  this.storage.addObserver(this.storageObserver_);
+};
+
+/**
+ * Read the backing storage for these preferences.
+ *
+ * You should do this once at initialization time to prime the local cache
+ * of preference values.  The preference manager will monitor the backing
+ * storage for changes, so you should not need to call this more than once.
+ *
+ * This function recursively reads storage for all child preference managers as
+ * well.
+ *
+ * This function is asynchronous, if you need to read preference values, you
+ * *must* wait for the callback.
+ *
+ * @param {function()} opt_callback Optional function to invoke when the read
+ *     has completed.
+ */
+lib.PreferenceManager.prototype.readStorage = function(opt_callback) {
+  var pendingChildren = 0;
+
+  function onChildComplete() {
+    if (--pendingChildren == 0 && opt_callback)
+      opt_callback();
+  }
+
+  var keys = Object.keys(this.prefRecords_).map((el) => this.prefix + el);
+
+  if (this.trace)
+    console.log('Preferences read: ' + this.prefix);
+
+  this.storage.getItems(keys, function(items) {
+      var prefixLength = this.prefix.length;
+
+      for (var key in items) {
+        var value = items[key];
+        var name = key.substr(prefixLength);
+        var needSync = (name in this.childLists_ &&
+                        (JSON.stringify(value) !=
+                         JSON.stringify(this.prefRecords_[name].currentValue)));
+
+        this.prefRecords_[name].currentValue = value;
+
+        if (needSync) {
+          pendingChildren++;
+          this.syncChildList(name, onChildComplete);
+        }
+      }
+
+      if (pendingChildren == 0 && opt_callback)
+        setTimeout(opt_callback);
+    }.bind(this));
+};
+
+/**
+ * Define a preference.
+ *
+ * This registers a name, default value, and onChange handler for a preference.
+ *
+ * @param {string} name The name of the preference.  This will be prefixed by
+ *     the prefix of this PreferenceManager before written to local storage.
+ * @param {string|number|boolean|Object|Array|null} value The default value of
+ *     this preference.  Anything that can be represented in JSON is a valid
+ *     default value.
+ * @param {function(value, string, lib.PreferenceManager} opt_observer A
+ *     function to invoke when the preference changes.  It will receive the new
+ *     value, the name of the preference, and a reference to the
+ *     PreferenceManager as parameters.
+ */
+lib.PreferenceManager.prototype.definePreference = function(
+    name, value, opt_onChange) {
+
+  var record = this.prefRecords_[name];
+  if (record) {
+    this.changeDefault(name, value);
+  } else {
+    record = this.prefRecords_[name] =
+        new lib.PreferenceManager.Record(name, value);
+  }
+
+  if (opt_onChange)
+    record.addObserver(opt_onChange);
+};
+
+/**
+ * Define multiple preferences with a single function call.
+ *
+ * @param {Array} defaults An array of 3-element arrays.  Each three element
+ *     array should contain the [key, value, onChange] parameters for a
+ *     preference.
+ */
+lib.PreferenceManager.prototype.definePreferences = function(defaults) {
+  for (var i = 0; i < defaults.length; i++) {
+    this.definePreference(defaults[i][0], defaults[i][1], defaults[i][2]);
+  }
+};
+
+/**
+ * Define an ordered list of child preferences.
+ *
+ * Child preferences are different from just storing an array of JSON objects
+ * in that each child is an instance of a preference manager.  This means you
+ * can observe changes to individual child preferences, and get some validation
+ * that you're not reading or writing to an undefined child preference value.
+ *
+ * @param {string} listName A name for the list of children.  This must be
+ *     unique in this preference manager.  The listName will become a
+ *     preference on this PreferenceManager used to store the ordered list of
+ *     child ids.  It is also used in get/add/remove operations to identify the
+ *     list of children to operate on.
+ * @param {function} childFactory A function that will be used to generate
+ *     instances of these children.  The factory function will receive the
+ *     parent lib.PreferenceManager object and a unique id for the new child
+ *     preferences.
+ */
+lib.PreferenceManager.prototype.defineChildren = function(
+    listName, childFactory) {
+
+  // Define a preference to hold the ordered list of child ids.
+  this.definePreference(listName, [],
+                        this.onChildListChange_.bind(this, listName));
+  this.childFactories_[listName] = childFactory;
+  this.childLists_[listName] = {};
+};
+
+/**
+ * Register to observe preference changes.
+ *
+ * @param {Function} global A callback that will happen for every preference.
+ *     Pass null if you don't need one.
+ * @param {Object} map A map of preference specific callbacks.  Pass null if
+ *     you don't need any.
+ */
+lib.PreferenceManager.prototype.addObservers = function(global, map) {
+  if (global && typeof global != 'function')
+    throw new Error('Invalid param: globals');
+
+  if (global)
+    this.globalObservers_.push(global);
+
+  if (!map)
+    return;
+
+  for (var name in map) {
+    if (!(name in this.prefRecords_))
+      throw new Error('Unknown preference: ' + name);
+
+    this.prefRecords_[name].addObserver(map[name]);
+  }
+};
+
+/**
+ * Dispatch the change observers for all known preferences.
+ *
+ * It may be useful to call this after readStorage completes, in order to
+ * get application state in sync with user preferences.
+ *
+ * This can be used if you've changed a preference manager out from under
+ * a live object, for example when switching to a different prefix.
+ */
+lib.PreferenceManager.prototype.notifyAll = function() {
+  for (var name in this.prefRecords_) {
+    this.notifyChange_(name);
+  }
+};
+
+/**
+ * Notify the change observers for a given preference.
+ *
+ * @param {string} name The name of the preference that changed.
+ */
+lib.PreferenceManager.prototype.notifyChange_ = function(name) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  var currentValue = record.get();
+
+  for (var i = 0; i < this.globalObservers_.length; i++)
+    this.globalObservers_[i](name, currentValue);
+
+  for (var i = 0; i < record.observers.length; i++) {
+    record.observers[i](currentValue, name, this);
+  }
+};
+
+/**
+ * Create a new child PreferenceManager for the given child list.
+ *
+ * The optional hint parameter is an opaque prefix added to the auto-generated
+ * unique id for this child.  Your child factory can parse out the prefix
+ * and use it.
+ *
+ * @param {string} listName The child list to create the new instance from.
+ * @param {string} opt_hint Optional hint to include in the child id.
+ * @param {string} opt_id Optional id to override the generated id.
+ */
+lib.PreferenceManager.prototype.createChild = function(listName, opt_hint,
+                                                       opt_id) {
+  var ids = this.get(listName);
+  var id;
+
+  if (opt_id) {
+    id = opt_id;
+    if (ids.indexOf(id) != -1)
+      throw new Error('Duplicate child: ' + listName + ': ' + id);
+
+  } else {
+    // Pick a random, unique 4-digit hex identifier for the new profile.
+    while (!id || ids.indexOf(id) != -1) {
+      id = lib.f.randomInt(1, 0xffff).toString(16);
+      id = lib.f.zpad(id, 4);
+      if (opt_hint)
+        id = opt_hint + ':' + id;
+    }
+  }
+
+  var childManager = this.childFactories_[listName](this, id);
+  childManager.trace = this.trace;
+  childManager.resetAll();
+
+  this.childLists_[listName][id] = childManager;
+
+  ids.push(id);
+  this.set(listName, ids, undefined, !this.isImportingJson_);
+
+  return childManager;
+};
+
+/**
+ * Remove a child preferences instance.
+ *
+ * Removes a child preference manager and clears any preferences stored in it.
+ *
+ * @param {string} listName The name of the child list containing the child to
+ *     remove.
+ * @param {string} id The child ID.
+ */
+lib.PreferenceManager.prototype.removeChild = function(listName, id) {
+  var prefs = this.getChild(listName, id);
+  prefs.resetAll();
+
+  var ids = this.get(listName);
+  var i = ids.indexOf(id);
+  if (i != -1) {
+    ids.splice(i, 1);
+    this.set(listName, ids, undefined, !this.isImportingJson_);
+  }
+
+  delete this.childLists_[listName][id];
+};
+
+/**
+ * Return a child PreferenceManager instance for a given id.
+ *
+ * If the child list or child id is not known this will return the specified
+ * default value or throw an exception if no default value is provided.
+ *
+ * @param {string} listName The child list to look in.
+ * @param {string} id The child ID.
+ * @param {*} opt_default The optional default value to return if the child
+ *     is not found.
+ */
+lib.PreferenceManager.prototype.getChild = function(listName, id, opt_default) {
+  if (!(listName in this.childLists_))
+    throw new Error('Unknown child list: ' + listName);
+
+  var childList = this.childLists_[listName];
+  if (!(id in childList)) {
+    if (typeof opt_default == 'undefined')
+      throw new Error('Unknown "' + listName + '" child: ' + id);
+
+    return opt_default;
+  }
+
+  return childList[id];
+};
+
+/**
+ * Calculate the difference between two lists of child ids.
+ *
+ * Given two arrays of child ids, this function will return an object
+ * with "added", "removed", and "common" properties.  Each property is
+ * a map of child-id to `true`.  For example, given...
+ *
+ *    a = ['child-x', 'child-y']
+ *    b = ['child-y']
+ *
+ *    diffChildLists(a, b) =>
+ *      { added: { 'child-x': true }, removed: {}, common: { 'child-y': true } }
+ *
+ * The added/removed properties assume that `a` is the current list.
+ *
+ * @param {Array[string]} a The most recent list of child ids.
+ * @param {Array[string]} b An older list of child ids.
+ * @return {Object} An object with added/removed/common properties.
+ */
+lib.PreferenceManager.diffChildLists = function(a, b) {
+  var rv = {
+    added: {},
+    removed: {},
+    common: {},
+  };
+
+  for (var i = 0; i < a.length; i++) {
+    if (b.indexOf(a[i]) != -1) {
+      rv.common[a[i]] = true;
+    } else {
+      rv.added[a[i]] = true;
+    }
+  }
+
+  for (var i = 0; i < b.length; i++) {
+    if ((b[i] in rv.added) || (b[i] in rv.common))
+      continue;
+
+    rv.removed[b[i]] = true;
+  }
+
+  return rv;
+};
+
+/**
+ * Synchronize a list of child PreferenceManagers instances with the current
+ * list stored in prefs.
+ *
+ * This will instantiate any missing managers and read current preference values
+ * from storage.  Any active managers that no longer appear in preferences will
+ * be deleted.
+ *
+ * @param {string} listName The child list to synchronize.
+ * @param {function()} opt_callback Optional function to invoke when the sync
+ *     is complete.
+ */
+lib.PreferenceManager.prototype.syncChildList = function(
+    listName, opt_callback) {
+
+  var pendingChildren = 0;
+  function onChildStorage() {
+    if (--pendingChildren == 0 && opt_callback)
+      opt_callback();
+  }
+
+  // The list of child ids that we *should* have a manager for.
+  var currentIds = this.get(listName);
+
+  // The known managers at the start of the sync.  Any manager still in this
+  // list at the end should be discarded.
+  var oldIds = Object.keys(this.childLists_[listName]);
+
+  var rv = lib.PreferenceManager.diffChildLists(currentIds, oldIds);
+
+  for (var i = 0; i < currentIds.length; i++) {
+    var id = currentIds[i];
+
+    var managerIndex = oldIds.indexOf(id);
+    if (managerIndex >= 0)
+      oldIds.splice(managerIndex, 1);
+
+    if (!this.childLists_[listName][id]) {
+      var childManager = this.childFactories_[listName](this, id);
+      if (!childManager) {
+        console.warn('Unable to restore child: ' + listName + ': ' + id);
+        continue;
+      }
+
+      childManager.trace = this.trace;
+      this.childLists_[listName][id] = childManager;
+      pendingChildren++;
+      childManager.readStorage(onChildStorage);
+    }
+  }
+
+  for (var i = 0; i < oldIds.length; i++) {
+    delete this.childLists_[listName][oldIds[i]];
+  }
+
+  if (!pendingChildren && opt_callback)
+    setTimeout(opt_callback);
+};
+
+/**
+ * Reset a preference to its default state.
+ *
+ * This will dispatch the onChange handler if the preference value actually
+ * changes.
+ *
+ * @param {string} name The preference to reset.
+ */
+lib.PreferenceManager.prototype.reset = function(name) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  this.storage.removeItem(this.prefix + name);
+
+  if (record.currentValue !== this.DEFAULT_VALUE) {
+    record.currentValue = this.DEFAULT_VALUE;
+    this.notifyChange_(name);
+  }
+};
+
+/**
+ * Reset all preferences back to their default state.
+ */
+lib.PreferenceManager.prototype.resetAll = function() {
+  var changed = [];
+
+  for (var listName in this.childLists_) {
+    var childList = this.childLists_[listName];
+    for (var id in childList) {
+      childList[id].resetAll();
+    }
+  }
+
+  for (var name in this.prefRecords_) {
+    if (this.prefRecords_[name].currentValue !== this.DEFAULT_VALUE) {
+      this.prefRecords_[name].currentValue = this.DEFAULT_VALUE;
+      changed.push(name);
+    }
+  }
+
+  var keys = Object.keys(this.prefRecords_).map(function(el) {
+      return this.prefix + el;
+  }.bind(this));
+
+  this.storage.removeItems(keys);
+
+  changed.forEach(this.notifyChange_.bind(this));
+};
+
+/**
+ * Return true if two values should be considered not-equal.
+ *
+ * If both values are the same scalar type and compare equal this function
+ * returns false (no difference), otherwise return true.
+ *
+ * This is used in places where we want to check if a preference has changed.
+ * Rather than take the time to compare complex values we just consider them
+ * to always be different.
+ *
+ * @param {*} a A value to compare.
+ * @param {*} b A value to compare.
+ */
+lib.PreferenceManager.prototype.diff = function(a, b) {
+  // If the types are different.
+  if ((typeof a) !== (typeof b)) {
+    return true;
+  }
+
+  // Or if the type is not a simple primitive one.
+  if (!(/^(undefined|boolean|number|string)$/.test(typeof a))) {
+    // Special case the null object.
+    if (a === null && b === null) {
+      return false;
+    } else {
+      return true;
+    }
+  }
+
+  // Do a normal compare for primitive types.
+  return a !== b;
+};
+
+/**
+ * Change the default value of a preference.
+ *
+ * This is useful when subclassing preference managers.
+ *
+ * The function does not alter the current value of the preference, unless
+ * it has the old default value.  When that happens, the change observers
+ * will be notified.
+ *
+ * @param {string} name The name of the parameter to change.
+ * @param {*} newValue The new default value for the preference.
+ */
+lib.PreferenceManager.prototype.changeDefault = function(name, newValue) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  if (!this.diff(record.defaultValue, newValue)) {
+    // Default value hasn't changed.
+    return;
+  }
+
+  if (record.currentValue !== this.DEFAULT_VALUE) {
+    // This pref has a specific value, just change the default and we're done.
+    record.defaultValue = newValue;
+    return;
+  }
+
+  record.defaultValue = newValue;
+
+  this.notifyChange_(name);
+};
+
+/**
+ * Change the default value of multiple preferences.
+ *
+ * @param {Object} map A map of name -> value pairs specifying the new default
+ *     values.
+ */
+lib.PreferenceManager.prototype.changeDefaults = function(map) {
+  for (var key in map) {
+    this.changeDefault(key, map[key]);
+  }
+};
+
+/**
+ * Set a preference to a specific value.
+ *
+ * This will dispatch the onChange handler if the preference value actually
+ * changes.
+ *
+ * @param {string} name The preference to set.
+ * @param {*} newValue The value to set.  Anything that can be represented in
+ *     JSON is a valid value.
+ * @param {function()=} onComplete Callback when the set call completes.
+ * @param {boolean=} saveToStorage Whether to commit the change to the backing
+ *     storage or only the in-memory record copy.
+ */
+lib.PreferenceManager.prototype.set = function(
+    name, newValue, onComplete=undefined, saveToStorage=true) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  var oldValue = record.get();
+
+  if (!this.diff(oldValue, newValue))
+    return;
+
+  if (this.diff(record.defaultValue, newValue)) {
+    record.currentValue = newValue;
+    if (saveToStorage)
+      this.storage.setItem(this.prefix + name, newValue, onComplete);
+  } else {
+    record.currentValue = this.DEFAULT_VALUE;
+    if (saveToStorage)
+      this.storage.removeItem(this.prefix + name, onComplete);
+  }
+
+  // We need to manually send out the notification on this instance.  If we
+  // The storage event won't fire a notification because we've already changed
+  // the currentValue, so it won't see a difference.  If we delayed changing
+  // currentValue until the storage event, a pref read immediately after a write
+  // would return the previous value.
+  //
+  // The notification is in a timeout so clients don't accidentally depend on
+  // a synchronous notification.
+  setTimeout(this.notifyChange_.bind(this, name), 0);
+};
+
+/**
+ * Get the value of a preference.
+ *
+ * @param {string} key The preference to get.
+ */
+lib.PreferenceManager.prototype.get = function(name) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  return record.get();
+};
+
+/**
+ * Return all non-default preferences as a JSON object.
+ *
+ * This includes any nested preference managers as well.
+ */
+lib.PreferenceManager.prototype.exportAsJson = function() {
+  var rv = {};
+
+  for (var name in this.prefRecords_) {
+    if (name in this.childLists_) {
+      rv[name] = [];
+      var childIds = this.get(name);
+      for (var i = 0; i < childIds.length; i++) {
+        var id = childIds[i];
+        rv[name].push({id: id, json: this.getChild(name, id).exportAsJson()});
+      }
+
+    } else {
+      var record = this.prefRecords_[name];
+      if (record.currentValue != this.DEFAULT_VALUE)
+        rv[name] = record.currentValue;
+    }
+  }
+
+  return rv;
+};
+
+/**
+ * Import a JSON blob of preferences previously generated with exportAsJson.
+ *
+ * This will create nested preference managers as well.
+ */
+lib.PreferenceManager.prototype.importFromJson = function(json, opt_onComplete) {
+  this.isImportingJson_ = true;
+
+  let pendingWrites = 0;
+  const onWriteStorage = () => {
+    if (--pendingWrites < 1) {
+      if (opt_onComplete)
+        opt_onComplete();
+
+      // We've delayed updates to the child arrays, so flush them now.
+      for (let name in json)
+        if (name in this.childLists_)
+          this.set(name, this.get(name));
+
+      this.isImportingJson_ = false;
+    }
+  };
+
+  for (var name in json) {
+    if (name in this.childLists_) {
+      var childList = json[name];
+      for (var i = 0; i < childList.length; i++) {
+        var id = childList[i].id;
+
+        var childPrefManager = this.childLists_[name][id];
+        if (!childPrefManager)
+          childPrefManager = this.createChild(name, null, id);
+
+        childPrefManager.importFromJson(childList[i].json, onWriteStorage);
+        pendingWrites++;
+      }
+
+    } else {
+      // The set is synchronous.
+      this.set(name, json[name]);
+    }
+  }
+
+  // If we didn't update any children, no async work has been queued, so make
+  // the completion callback directly.
+  if (pendingWrites == 0 && opt_onComplete)
+    opt_onComplete();
+};
+
+/**
+ * Called when one of the child list preferences changes.
+ */
+lib.PreferenceManager.prototype.onChildListChange_ = function(listName) {
+  this.syncChildList(listName);
+};
+
+/**
+ * Called when a key in the storage changes.
+ */
+lib.PreferenceManager.prototype.onStorageChange_ = function(map) {
+  for (var key in map) {
+    if (this.prefix) {
+      if (key.lastIndexOf(this.prefix, 0) != 0)
+        continue;
+    }
+
+    var name = key.substr(this.prefix.length);
+
+    if (!(name in this.prefRecords_)) {
+      // Sometimes we'll get notified about prefs that are no longer defined.
+      continue;
+    }
+
+    var record = this.prefRecords_[name];
+
+    var newValue = map[key].newValue;
+    var currentValue = record.currentValue;
+    if (currentValue === record.DEFAULT_VALUE)
+      currentValue = (void 0);
+
+    if (this.diff(currentValue, newValue)) {
+      if (typeof newValue == 'undefined' || newValue === null) {
+        record.currentValue = record.DEFAULT_VALUE;
+      } else {
+        record.currentValue = newValue;
+      }
+
+      this.notifyChange_(name);
+    }
+  }
+};
+// SOURCE FILE: libdot/js/lib_resource.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Storage for canned resources.
+ *
+ * These are usually non-JavaScript things that are collected during a build
+ * step and converted into a series of 'lib.resource.add(...)' calls.  See
+ * the "@resource" directive from libdot/bin/concat for the canonical use
+ * case.
+ *
+ * This is global storage, so you should prefix your resource names to avoid
+ * collisions.
+ */
+lib.resource = {
+  resources_: {}
+};
+
+/**
+ * Add a resource.
+ *
+ * @param {string} name A name for the resource.  You should prefix this to
+ *   avoid collisions with resources from a shared library.
+ * @param {string} type A mime type for the resource, or "raw" if not
+ *   applicable.
+ * @param {*} data The value of the resource.
+ */
+lib.resource.add = function(name, type, data) {
+  lib.resource.resources_[name] = {
+    type: type,
+    name: name,
+    data: data
+  };
+};
+
+/**
+ * Retrieve a resource record.
+ *
+ * The resource data is stored on the "data" property of the returned object.
+ *
+ * @param {string} name The name of the resource to get.
+ * @param {*} opt_defaultValue The optional value to return if the resource is
+ *   not defined.
+ * @return {object} An object with "type", "name", and "data" properties.
+ */
+lib.resource.get = function(name, opt_defaultValue) {
+  if (!(name in lib.resource.resources_)) {
+    if (typeof opt_defaultValue == 'undefined')
+      throw 'Unknown resource: ' + name;
+
+    return opt_defaultValue;
+  }
+
+  return lib.resource.resources_[name];
+};
+
+/**
+ * Retrieve resource data.
+ *
+ * @param {string} name The name of the resource to get.
+ * @param {*} opt_defaultValue The optional value to return if the resource is
+ *   not defined.
+ * @return {*} The resource data.
+ */
+lib.resource.getData = function(name, opt_defaultValue) {
+  if (!(name in lib.resource.resources_)) {
+    if (typeof opt_defaultValue == 'undefined')
+      throw 'Unknown resource: ' + name;
+
+    return opt_defaultValue;
+  }
+
+  return lib.resource.resources_[name].data;
+};
+
+/**
+ * Retrieve resource as a data: url.
+ *
+ * @param {string} name The name of the resource to get.
+ * @param {*} opt_defaultValue The optional value to return if the resource is
+ *   not defined.
+ * @return {*} A data: url encoded version of the resource.
+ */
+lib.resource.getDataUrl = function(name, opt_defaultValue) {
+  var resource = lib.resource.get(name, opt_defaultValue);
+  return 'data:' + resource.type + ',' + resource.data;
+};
+// SOURCE FILE: libdot/js/lib_storage.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Namespace for implementations of persistent, possibly cloud-backed
+ * storage.
+ */
+lib.Storage = new Object();
+// SOURCE FILE: libdot/js/lib_storage_chrome.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * chrome.storage based class with an async interface that is interchangeable
+ * with other lib.Storage.* implementations.
+ */
+lib.Storage.Chrome = function(storage) {
+  this.storage_ = storage;
+  this.observers_ = [];
+
+  chrome.storage.onChanged.addListener(this.onChanged_.bind(this));
+};
+
+/**
+ * Called by the storage implementation when the storage is modified.
+ */
+lib.Storage.Chrome.prototype.onChanged_ = function(changes, areaname) {
+  if (chrome.storage[areaname] != this.storage_)
+    return;
+
+  for (var i = 0; i < this.observers_.length; i++) {
+    this.observers_[i](changes);
+  }
+};
+
+/**
+ * Register a function to observe storage changes.
+ *
+ * @param {function(map)} callback The function to invoke when the storage
+ *     changes.
+ */
+lib.Storage.Chrome.prototype.addObserver = function(callback) {
+  this.observers_.push(callback);
+};
+
+/**
+ * Unregister a change observer.
+ *
+ * @param {function} observer A previously registered callback.
+ */
+lib.Storage.Chrome.prototype.removeObserver = function(callback) {
+  var i = this.observers_.indexOf(callback);
+  if (i != -1)
+    this.observers_.splice(i, 1);
+};
+
+/**
+ * Delete everything in this storage.
+ *
+ * @param {function(map)} callback The function to invoke when the delete
+ *     has completed.
+ */
+lib.Storage.Chrome.prototype.clear = function(opt_callback) {
+  this.storage_.clear();
+
+  if (opt_callback)
+    setTimeout(opt_callback, 0);
+};
+
+/**
+ * Return the current value of a storage item.
+ *
+ * @param {string} key The key to look up.
+ * @param {function(value) callback The function to invoke when the value has
+ *     been retrieved.
+ */
+lib.Storage.Chrome.prototype.getItem = function(key, callback) {
+  this.storage_.get(key, callback);
+};
+/**
+ * Fetch the values of multiple storage items.
+ *
+ * @param {Array} keys The keys to look up.
+ * @param {function(map) callback The function to invoke when the values have
+ *     been retrieved.
+ */
+
+lib.Storage.Chrome.prototype.getItems = function(keys, callback) {
+  this.storage_.get(keys, callback);
+};
+
+/**
+ * Set a value in storage.
+ *
+ * @param {string} key The key for the value to be stored.
+ * @param {*} value The value to be stored.  Anything that can be serialized
+ *     with JSON is acceptable.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     set is complete.  You don't have to wait for the set to complete in order
+ *     to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Chrome.prototype.setItem = function(key, value, opt_callback) {
+  const onComplete = () => {
+    const err = lib.f.lastError();
+    if (err) {
+      // Doesn't seem to be any better way of handling this.
+      // https://crbug.com/764759
+      if (err.indexOf('MAX_WRITE_OPERATIONS')) {
+        console.warn(`Will retry save of ${key} after exceeding quota: ${err}`);
+        setTimeout(() => this.setItem(key, value, onComplete), 1000);
+        return;
+      } else {
+        console.error(`Unknown runtime error: ${err}`);
+      }
+    }
+
+    if (opt_callback)
+      opt_callback();
+  };
+
+  var obj = {};
+  obj[key] = value;
+  this.storage_.set(obj, onComplete);
+};
+
+/**
+ * Set multiple values in storage.
+ *
+ * @param {Object} map A map of key/values to set in storage.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     set is complete.  You don't have to wait for the set to complete in order
+ *     to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Chrome.prototype.setItems = function(obj, opt_callback) {
+  this.storage_.set(obj, opt_callback);
+};
+
+/**
+ * Remove an item from storage.
+ *
+ * @param {string} key The key to be removed.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     remove is complete.  You don't have to wait for the set to complete in
+ *     order to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Chrome.prototype.removeItem = function(key, opt_callback) {
+  this.storage_.remove(key, opt_callback);
+};
+
+/**
+ * Remove multiple items from storage.
+ *
+ * @param {Array} keys The keys to be removed.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     remove is complete.  You don't have to wait for the set to complete in
+ *     order to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Chrome.prototype.removeItems = function(keys, opt_callback) {
+  this.storage_.remove(keys, opt_callback);
+};
+// SOURCE FILE: libdot/js/lib_storage_local.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * window.localStorage based class with an async interface that is
+ * interchangeable with other lib.Storage.* implementations.
+ */
+lib.Storage.Local = function() {
+  this.observers_ = [];
+  this.storage_ = window.localStorage;
+  window.addEventListener('storage', this.onStorage_.bind(this));
+};
+
+/**
+ * Called by the storage implementation when the storage is modified.
+ */
+lib.Storage.Local.prototype.onStorage_ = function(e) {
+  if (e.storageArea != this.storage_)
+    return;
+
+  // JS throws an exception if JSON.parse is given an empty string. So here we
+  // only parse if the value is truthy. This mean the empty string, undefined
+  // and null will not be parsed.
+  var prevValue = e.oldValue ? JSON.parse(e.oldValue) : e.oldValue;
+  var curValue = e.newValue ? JSON.parse(e.newValue) : e.newValue;
+  var o = {};
+  o[e.key] = {
+    oldValue: prevValue,
+    newValue: curValue
+  };
+
+  for (var i = 0; i < this.observers_.length; i++) {
+    this.observers_[i](o);
+  }
+};
+
+/**
+ * Register a function to observe storage changes.
+ *
+ * @param {function(map)} callback The function to invoke when the storage
+ *     changes.
+ */
+lib.Storage.Local.prototype.addObserver = function(callback) {
+  this.observers_.push(callback);
+};
+
+/**
+ * Unregister a change observer.
+ *
+ * @param {function} observer A previously registered callback.
+ */
+lib.Storage.Local.prototype.removeObserver = function(callback) {
+  var i = this.observers_.indexOf(callback);
+  if (i != -1)
+    this.observers_.splice(i, 1);
+};
+
+/**
+ * Delete everything in this storage.
+ *
+ * @param {function(map)} callback The function to invoke when the delete
+ *     has completed.
+ */
+lib.Storage.Local.prototype.clear = function(opt_callback) {
+  this.storage_.clear();
+
+  if (opt_callback)
+    setTimeout(opt_callback, 0);
+};
+
+/**
+ * Return the current value of a storage item.
+ *
+ * @param {string} key The key to look up.
+ * @param {function(value) callback The function to invoke when the value has
+ *     been retrieved.
+ */
+lib.Storage.Local.prototype.getItem = function(key, callback) {
+  var value = this.storage_.getItem(key);
+
+  if (typeof value == 'string') {
+    try {
+      value = JSON.parse(value);
+    } catch (e) {
+      // If we can't parse the value, just return it unparsed.
+    }
+  }
+
+  setTimeout(callback.bind(null, value), 0);
+};
+
+/**
+ * Fetch the values of multiple storage items.
+ *
+ * @param {Array} keys The keys to look up.
+ * @param {function(map) callback The function to invoke when the values have
+ *     been retrieved.
+ */
+lib.Storage.Local.prototype.getItems = function(keys, callback) {
+  var rv = {};
+
+  for (var i = keys.length - 1; i >= 0; i--) {
+    var key = keys[i];
+    var value = this.storage_.getItem(key);
+    if (typeof value == 'string') {
+      try {
+        rv[key] = JSON.parse(value);
+      } catch (e) {
+        // If we can't parse the value, just return it unparsed.
+        rv[key] = value;
+      }
+    } else {
+      keys.splice(i, 1);
+    }
+  }
+
+  setTimeout(callback.bind(null, rv), 0);
+};
+
+/**
+ * Set a value in storage.
+ *
+ * @param {string} key The key for the value to be stored.
+ * @param {*} value The value to be stored.  Anything that can be serialized
+ *     with JSON is acceptable.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     set is complete.  You don't have to wait for the set to complete in order
+ *     to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Local.prototype.setItem = function(key, value, opt_callback) {
+  this.storage_.setItem(key, JSON.stringify(value));
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+
+/**
+ * Set multiple values in storage.
+ *
+ * @param {Object} map A map of key/values to set in storage.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     set is complete.  You don't have to wait for the set to complete in order
+ *     to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Local.prototype.setItems = function(obj, opt_callback) {
+  for (var key in obj) {
+    this.storage_.setItem(key, JSON.stringify(obj[key]));
+  }
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+
+/**
+ * Remove an item from storage.
+ *
+ * @param {string} key The key to be removed.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     remove is complete.  You don't have to wait for the set to complete in
+ *     order to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Local.prototype.removeItem = function(key, opt_callback) {
+  this.storage_.removeItem(key);
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+
+/**
+ * Remove multiple items from storage.
+ *
+ * @param {Array} keys The keys to be removed.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     remove is complete.  You don't have to wait for the set to complete in
+ *     order to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Local.prototype.removeItems = function(ary, opt_callback) {
+  for (var i = 0; i < ary.length; i++) {
+    this.storage_.removeItem(ary[i]);
+  }
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+// SOURCE FILE: libdot/js/lib_storage_memory.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * In-memory storage class with an async interface that is interchangeable with
+ * other lib.Storage.* implementations.
+ */
+lib.Storage.Memory = function() {
+  this.observers_ = [];
+  this.storage_ = {};
+};
+
+/**
+ * Register a function to observe storage changes.
+ *
+ * @param {function(map)} callback The function to invoke when the storage
+ *     changes.
+ */
+lib.Storage.Memory.prototype.addObserver = function(callback) {
+  this.observers_.push(callback);
+};
+
+/**
+ * Unregister a change observer.
+ *
+ * @param {function} observer A previously registered callback.
+ */
+lib.Storage.Memory.prototype.removeObserver = function(callback) {
+  var i = this.observers_.indexOf(callback);
+  if (i != -1)
+    this.observers_.splice(i, 1);
+};
+
+/**
+ * Delete everything in this storage.
+ *
+ * @param {function(map)} callback The function to invoke when the delete
+ *     has completed.
+ */
+lib.Storage.Memory.prototype.clear = function(opt_callback) {
+  var e = {};
+  for (var key in this.storage_) {
+    e[key] = {oldValue: this.storage_[key], newValue: (void 0)};
+  }
+
+  this.storage_ = {};
+
+  setTimeout(function() {
+    for (var i = 0; i < this.observers_.length; i++) {
+      this.observers_[i](e);
+    }
+  }.bind(this), 0);
+
+  if (opt_callback)
+    setTimeout(opt_callback, 0);
+};
+
+/**
+ * Return the current value of a storage item.
+ *
+ * @param {string} key The key to look up.
+ * @param {function(value) callback The function to invoke when the value has
+ *     been retrieved.
+ */
+lib.Storage.Memory.prototype.getItem = function(key, callback) {
+  var value = this.storage_[key];
+
+  if (typeof value == 'string') {
+    try {
+      value = JSON.parse(value);
+    } catch (e) {
+      // If we can't parse the value, just return it unparsed.
+    }
+  }
+
+  setTimeout(callback.bind(null, value), 0);
+};
+
+/**
+ * Fetch the values of multiple storage items.
+ *
+ * @param {Array} keys The keys to look up.
+ * @param {function(map) callback The function to invoke when the values have
+ *     been retrieved.
+ */
+lib.Storage.Memory.prototype.getItems = function(keys, callback) {
+  var rv = {};
+
+  for (var i = keys.length - 1; i >= 0; i--) {
+    var key = keys[i];
+    var value = this.storage_[key];
+    if (typeof value == 'string') {
+      try {
+        rv[key] = JSON.parse(value);
+      } catch (e) {
+        // If we can't parse the value, just return it unparsed.
+        rv[key] = value;
+      }
+    } else {
+      keys.splice(i, 1);
+    }
+  }
+
+  setTimeout(callback.bind(null, rv), 0);
+};
+
+/**
+ * Set a value in storage.
+ *
+ * @param {string} key The key for the value to be stored.
+ * @param {*} value The value to be stored.  Anything that can be serialized
+ *     with JSON is acceptable.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     set is complete.  You don't have to wait for the set to complete in order
+ *     to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Memory.prototype.setItem = function(key, value, opt_callback) {
+  var oldValue = this.storage_[key];
+  this.storage_[key] = JSON.stringify(value);
+
+  var e = {};
+  e[key] = {oldValue: oldValue, newValue: value};
+
+  setTimeout(function() {
+    for (var i = 0; i < this.observers_.length; i++) {
+      this.observers_[i](e);
+    }
+  }.bind(this), 0);
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+
+/**
+ * Set multiple values in storage.
+ *
+ * @param {Object} map A map of key/values to set in storage.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     set is complete.  You don't have to wait for the set to complete in order
+ *     to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Memory.prototype.setItems = function(obj, opt_callback) {
+  var e = {};
+
+  for (var key in obj) {
+    e[key] = {oldValue: this.storage_[key], newValue: obj[key]};
+    this.storage_[key] = JSON.stringify(obj[key]);
+  }
+
+  setTimeout(function() {
+    for (var i = 0; i < this.observers_.length; i++) {
+      this.observers_[i](e);
+    }
+  }.bind(this));
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+
+/**
+ * Remove an item from storage.
+ *
+ * @param {string} key The key to be removed.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     remove is complete.  You don't have to wait for the set to complete in
+ *     order to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Memory.prototype.removeItem = function(key, opt_callback) {
+  delete this.storage_[key];
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+
+/**
+ * Remove multiple items from storage.
+ *
+ * @param {Array} keys The keys to be removed.
+ * @param {function()} opt_callback Optional function to invoke when the
+ *     remove is complete.  You don't have to wait for the set to complete in
+ *     order to read the value, since the local cache is updated synchronously.
+ */
+lib.Storage.Memory.prototype.removeItems = function(ary, opt_callback) {
+  for (var i = 0; i < ary.length; i++) {
+    delete this.storage_[ary[i]];
+  }
+
+  if (opt_callback)
+  setTimeout(opt_callback, 0);
+};
+// SOURCE FILE: libdot/third_party/fast-text-encoding/text.js
+/*
+ * Copyright 2017 Sam Thorogood. All rights reserved.
+ *
+ * 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
+ *
+ *     https://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.
+ */
+
+/**
+ * @fileoverview Polyfill for TextEncoder and TextDecoder.
+ *
+ * You probably want `text.min.js`, and not this file directly.
+ */
+
+(function(scope) {
+'use strict';
+
+// fail early
+if (scope['TextEncoder'] && scope['TextDecoder']) {
+  return false;
+}
+
+/**
+ * @constructor
+ * @param {string=} utfLabel
+ */
+function FastTextEncoder(utfLabel='utf-8') {
+  if (utfLabel !== 'utf-8') {
+    throw new RangeError(
+      `Failed to construct 'TextEncoder': The encoding label provided ('${utfLabel}') is invalid.`);
+  }
+}
+
+Object.defineProperty(FastTextEncoder.prototype, 'encoding', {value: 'utf-8'});
+
+/**
+ * @param {string} string
+ * @param {{stream: boolean}=} options
+ * @return {!Uint8Array}
+ */
+FastTextEncoder.prototype.encode = function(string, options={stream: false}) {
+  if (options.stream) {
+    throw new Error(`Failed to encode: the 'stream' option is unsupported.`);
+  }
+
+  let pos = 0;
+  const len = string.length;
+  const out = [];
+
+  let at = 0;  // output position
+  let tlen = Math.max(32, len + (len >> 1) + 7);  // 1.5x size
+  let target = new Uint8Array((tlen >> 3) << 3);  // ... but at 8 byte offset
+
+  while (pos < len) {
+    let value = string.charCodeAt(pos++);
+    if (value >= 0xd800 && value <= 0xdbff) {
+      // high surrogate
+      if (pos < len) {
+        const extra = string.charCodeAt(pos);
+        if ((extra & 0xfc00) === 0xdc00) {
+          ++pos;
+          value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
+        }
+      }
+      if (value >= 0xd800 && value <= 0xdbff) {
+        continue;  // drop lone surrogate
+      }
+    }
+
+    // expand the buffer if we couldn't write 4 bytes
+    if (at + 4 > target.length) {
+      tlen += 8;  // minimum extra
+      tlen *= (1.0 + (pos / string.length) * 2);  // take 2x the remaining
+      tlen = (tlen >> 3) << 3;  // 8 byte offset
+
+      const update = new Uint8Array(tlen);
+      update.set(target);
+      target = update;
+    }
+
+    if ((value & 0xffffff80) === 0) {  // 1-byte
+      target[at++] = value;  // ASCII
+      continue;
+    } else if ((value & 0xfffff800) === 0) {  // 2-byte
+      target[at++] = ((value >>  6) & 0x1f) | 0xc0;
+    } else if ((value & 0xffff0000) === 0) {  // 3-byte
+      target[at++] = ((value >> 12) & 0x0f) | 0xe0;
+      target[at++] = ((value >>  6) & 0x3f) | 0x80;
+    } else if ((value & 0xffe00000) === 0) {  // 4-byte
+      target[at++] = ((value >> 18) & 0x07) | 0xf0;
+      target[at++] = ((value >> 12) & 0x3f) | 0x80;
+      target[at++] = ((value >>  6) & 0x3f) | 0x80;
+    } else {
+      // FIXME: do we care
+      continue;
+    }
+
+    target[at++] = (value & 0x3f) | 0x80;
+  }
+
+  return target.slice(0, at);
+}
+
+/**
+ * @constructor
+ * @param {string=} utfLabel
+ * @param {{fatal: boolean}=} options
+ */
+function FastTextDecoder(utfLabel='utf-8', options={fatal: false}) {
+  if (utfLabel !== 'utf-8') {
+    throw new RangeError(
+      `Failed to construct 'TextDecoder': The encoding label provided ('${utfLabel}') is invalid.`);
+  }
+  if (options.fatal) {
+    throw new Error(`Failed to construct 'TextDecoder': the 'fatal' option is unsupported.`);
+  }
+}
+
+Object.defineProperty(FastTextDecoder.prototype, 'encoding', {value: 'utf-8'});
+
+Object.defineProperty(FastTextDecoder.prototype, 'fatal', {value: false});
+
+Object.defineProperty(FastTextDecoder.prototype, 'ignoreBOM', {value: false});
+
+/**
+ * @param {(!ArrayBuffer|!ArrayBufferView)} buffer
+ * @param {{stream: boolean}=} options
+ */
+FastTextDecoder.prototype.decode = function(buffer, options={stream: false}) {
+  if (options['stream']) {
+    throw new Error(`Failed to decode: the 'stream' option is unsupported.`);
+  }
+
+  const bytes = new Uint8Array(buffer);
+  let pos = 0;
+  const len = bytes.length;
+  const out = [];
+
+  while (pos < len) {
+    const byte1 = bytes[pos++];
+    if (byte1 === 0) {
+      break;  // NULL
+    }
+
+    if ((byte1 & 0x80) === 0) {  // 1-byte
+      out.push(byte1);
+    } else if ((byte1 & 0xe0) === 0xc0) {  // 2-byte
+      const byte2 = bytes[pos++] & 0x3f;
+      out.push(((byte1 & 0x1f) << 6) | byte2);
+    } else if ((byte1 & 0xf0) === 0xe0) {
+      const byte2 = bytes[pos++] & 0x3f;
+      const byte3 = bytes[pos++] & 0x3f;
+      out.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);
+    } else if ((byte1 & 0xf8) === 0xf0) {
+      const byte2 = bytes[pos++] & 0x3f;
+      const byte3 = bytes[pos++] & 0x3f;
+      const byte4 = bytes[pos++] & 0x3f;
+
+      // this can be > 0xffff, so possibly generate surrogates
+      let codepoint = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
+      if (codepoint > 0xffff) {
+        // codepoint &= ~0x10000;
+        codepoint -= 0x10000;
+        out.push((codepoint >>> 10) & 0x3ff | 0xd800)
+        codepoint = 0xdc00 | codepoint & 0x3ff;
+      }
+      out.push(codepoint);
+    } else {
+      // FIXME: we're ignoring this
+    }
+  }
+
+  return String.fromCharCode.apply(null, out);
+}
+
+scope['TextEncoder'] = FastTextEncoder;
+scope['TextDecoder'] = FastTextDecoder;
+
+}(typeof window !== 'undefined' ? window : (typeof global !== 'undefined' ? global : this)));
+// SOURCE FILE: libdot/third_party/intl-segmenter/intl-segmenter.js
+// Rough polyfill for Intl.Segmenter proposal
+//
+// https://github.com/tc39/proposal-intl-segmenter/blob/master/README.md
+//
+// Caveats and Limitations
+//  * granularity: 'line': 'strictness' option is not supported (ignored)
+//  * In Chrome, uses v8BreakIterator
+//  * Otherwise, uses very simplistic rules
+//    * Ignores locale; only "usable" on English
+//    * granularity: 'grapheme' does not understand combining characters
+//    * granularity: 'sentence' does not understand decimals
+
+(function(global) {
+  if ('Intl' in global && 'Segmenter' in global.Intl)
+    return;
+
+  global.Intl = global.Intl || {};
+
+  const GRANULARITIES = ['grapheme', 'word','sentence', 'line'];
+
+  // TODO: Implement https://www.unicode.org/reports/tr29/
+  const RULES = {
+    grapheme: {
+      grapheme: /^(.|\n)/
+    },
+    word: {
+      letter: /^[a-z](?:'?[a-z])*/i,
+      number: /^\d+([,.]\d+)*/
+    },
+    sentence: {
+      terminator: /^[^.?!\r\n]+[.?!]+[\r\n]?/,
+      separator: /^[^.?!\r\n]+[\r\n]?/
+    },
+    line: {
+      hard: /^\S*[\r\n]/,
+      soft: /^\S*\s*/
+    }
+  };
+
+  // Work around bug in v8BreakIterator where ICU's UWordBreak enum is
+  // used even if granularity is not "word". See the code in
+  // Runtime_BreakIteratorBreakType in runtime/runtime-i18n.cc for
+  // details.
+  function fixBreakType(value, granularity) {
+    // Undo the mapping of UWordBreak to string
+    const ruleStatus = {
+      none: 0, // UBRK_WORD_NONE
+      number: 100, // UBRK_WORD_NUMBER
+      letter: 200, // UBRK_WORD_LETTER
+      kana: 300, // UBRK_WORD_KANA
+      ideo: 400, // UBRK_WORD_IDEO
+      unknown: -1
+    }[value] || 0;
+
+
+    switch (granularity) {
+    case 'character':
+      return undefined;
+    case 'word':
+      return value;
+    case 'sentence':
+      // Map ULineBreakTag rule status to string.
+      return {
+        0: 'terminator',
+        100: 'separator'
+      }[ruleStatus] || value;
+    case 'line':
+      // Map ULineBreakTag rule status to string.
+      return {
+        0: 'soft',
+        100: 'hard'
+      }[ruleStatus] || value;
+    default:
+      return value;
+    }
+  }
+
+  function segment(locale, granularity, string) {
+    const breaks = [];
+    if ('v8BreakIterator' in global.Intl) {
+      if (granularity === 'grapheme')
+        granularity = 'character';
+      const vbi = new global.Intl.v8BreakIterator(locale, {type: granularity});
+      vbi.adoptText(string);
+      let last = 0;
+      let pos = vbi.next();
+      while (pos !== -1) {
+        breaks.push({
+          pos: vbi.current(),
+          segment: string.slice(last, pos),
+          breakType: fixBreakType(vbi.breakType(), granularity)
+        });
+        last = pos;
+        pos = vbi.next();
+      }
+    } else {
+      const rules = RULES[granularity];
+      let pos = 0;
+      while (pos < string.length) {
+        let found = false;
+        for (let rule of Object.keys(rules)) {
+          const re = rules[rule];
+          const m = string.slice(pos).match(re);
+          if (m) {
+            pos += m[0].length;
+            breaks.push({
+              pos: pos,
+              segment: m[0],
+              breakType: granularity === 'grapheme' ? undefined : rule
+            });
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          breaks.push({
+            pos: pos + 1,
+            segment: string.slice(pos, ++pos),
+            breakType: 'none'
+          });
+        }
+      }
+    }
+    breaks.initial = 0;
+    return breaks;
+  }
+
+  class $SegmentIterator$ {
+    constructor(string, breaks) {
+      this._cur = -1;
+      this._type = undefined;
+      this._breaks = breaks;
+    }
+
+    [Symbol.iterator]() { return this; }
+
+    next() {
+      if (this._cur < this._breaks.length)
+        ++this._cur;
+
+      if (this._cur >= this._breaks.length) {
+        this._type = undefined;
+        return {done: true, value: undefined};
+      }
+
+      this._type = this._breaks[this._cur].breakType;
+      return {
+        done: false,
+        value: {
+          segment: this._breaks[this._cur].segment,
+          breakType: this._breaks[this._cur].breakType
+        }
+      };
+    }
+
+    following(index = undefined) {
+      if (!this._breaks.length)
+        return true;
+      if (index === undefined) {
+        if (this._cur < this._breaks.length)
+          ++this._cur;
+      } else {
+        // TODO: binary search
+        for (this._cur = 0;
+             this._cur < this._breaks.length
+             && this._breaks[this._cur].pos < index;
+             ++this._cur) {}
+      }
+
+      this._type = this._cur < this._breaks.length
+        ? this._breaks[this._cur].breakType : undefined;
+      return this._cur + 1 >= this._breaks.length;
+    }
+
+    preceding(index = undefined) {
+      if (!this._breaks.length)
+        return true;
+      if (index === undefined) {
+        if (this._cur >= this._breaks.length)
+          --this._cur;
+        if (this._cur >= 0)
+          --this._cur;
+      } else {
+        // TODO: binary search
+        for (this._cur = this._breaks.length - 1;
+             this._cur >= 0
+             && this._breaks[this._cur].pos >= index;
+             --this._cur) {}
+      }
+
+      this._type =
+        this._cur + 1 >= this._breaks.length ? undefined :
+        this._breaks[this._cur + 1].breakType;
+      return this._cur < 0;
+    }
+
+    get position() {
+      if (this._cur < 0 || !this._breaks.length)
+        return this._breaks.initial;
+      if (this._cur >= this._breaks.length)
+        return this._breaks[this._breaks.length - 1].pos;
+      return this._breaks[this._cur].pos;
+    }
+
+    get breakType() {
+      return this._type;
+    }
+  }
+
+  global.Intl.Segmenter = class Segmenter {
+    constructor(locale, options) {
+      this._locale = Array.isArray(locale)
+        ? locale.map(s => String(s)) : String(locale || navigator.language);
+      options = Object.assign({granularity: 'grapheme'}, options);
+      this._granularity = GRANULARITIES.includes(options.granularity)
+        ? options.granularity : 'grapheme';
+    }
+
+    segment(string) {
+      return new $SegmentIterator$(
+        string, segment(this._locale, this._granularity, string));
+    }
+  };
+}(typeof window !== 'undefined' ? window : (typeof global !== 'undefined' ? global : this)));
+// SOURCE FILE: libdot/third_party/wcwidth/lib_wc.js
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of lib.wc source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * This JavaScript library is ported from the wcwidth.js module of node.js.
+ * The original implementation can be found at:
+ * https://npmjs.org/package/wcwidth.js
+ */
+
+/**
+ * JavaScript porting of Markus Kuhn's wcwidth() implementation
+ *
+ * The following explanation comes from the original C implementation:
+ *
+ * This is an implementation of wcwidth() and wcswidth() (defined in
+ * IEEE Std 1002.1-2001) for Unicode.
+ *
+ * https://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
+ * https://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
+ *
+ * In fixed-width output devices, Latin characters all occupy a single
+ * "cell" position of equal width, whereas ideographic CJK characters
+ * occupy two such cells. Interoperability between terminal-line
+ * applications and (teletype-style) character terminals using the
+ * UTF-8 encoding requires agreement on which character should advance
+ * the cursor by how many cell positions. No established formal
+ * standards exist at present on which Unicode character shall occupy
+ * how many cell positions on character terminals. These routines are
+ * a first attempt of defining such behavior based on simple rules
+ * applied to data provided by the Unicode Consortium.
+ *
+ * For some graphical characters, the Unicode standard explicitly
+ * defines a character-cell width via the definition of the East Asian
+ * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
+ * In all these cases, there is no ambiguity about which width a
+ * terminal shall use. For characters in the East Asian Ambiguous (A)
+ * class, the width choice depends purely on a preference of backward
+ * compatibility with either historic CJK or Western practice.
+ * Choosing single-width for these characters is easy to justify as
+ * the appropriate long-term solution, as the CJK practice of
+ * displaying these characters as double-width comes from historic
+ * implementation simplicity (8-bit encoded characters were displayed
+ * single-width and 16-bit ones double-width, even for Greek,
+ * Cyrillic, etc.) and not any typographic considerations.
+ *
+ * Much less clear is the choice of width for the Not East Asian
+ * (Neutral) class. Existing practice does not dictate a width for any
+ * of these characters. It would nevertheless make sense
+ * typographically to allocate two character cells to characters such
+ * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
+ * represented adequately with a single-width glyph. The following
+ * routines at present merely assign a single-cell width to all
+ * neutral characters, in the interest of simplicity. This is not
+ * entirely satisfactory and should be reconsidered before
+ * establishing a formal standard in lib.wc area. At the moment, the
+ * decision which Not East Asian (Neutral) characters should be
+ * represented by double-width glyphs cannot yet be answered by
+ * applying a simple rule from the Unicode database content. Setting
+ * up a proper standard for the behavior of UTF-8 character terminals
+ * will require a careful analysis not only of each Unicode character,
+ * but also of each presentation form, something the author of these
+ * routines has avoided to do so far.
+ *
+ * https://www.unicode.org/unicode/reports/tr11/
+ *
+ * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
+ *
+ * Permission to use, copy, modify, and distribute lib.wc software
+ * for any purpose and without fee is hereby granted. The author
+ * disclaims all warranties with regard to lib.wc software.
+ *
+ * Latest version: https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
+ */
+
+/**
+ * The following function defines the column width of an ISO 10646 character
+ * as follows:
+ *
+ *  - The null character (U+0000) has a column width of 0.
+ *  - Other C0/C1 control characters and DEL will lead to a return value of -1.
+ *  - Non-spacing and enclosing combining characters (general category code Mn
+ *    or Me in the Unicode database) have a column width of 0.
+ *  - SOFT HYPHEN (U+00AD) has a column width of 1.
+ *  - Other format characters (general category code Cf in the Unicode database)
+ *    and ZERO WIDTH SPACE (U+200B) have a column width of 0.
+ *  - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) have a
+ *    column width of 0.
+ *  - Spacing characters in the East Asian Wide (W) or East Asian Full-width (F)
+ *    category as defined in Unicode Technical Report #11 have a column width of
+ *    2.
+ *  - East Asian Ambiguous characters are taken into account if
+ *    regardCjkAmbiguous flag is enabled. They have a column width of 2.
+ *  - All remaining characters (including all printable ISO 8859-1 and WGL4
+ *    characters, Unicode control characters, etc.) have a column width of 1.
+ *
+ * This implementation assumes that characters are encoded in ISO 10646.
+ */
+
+lib.wc = {};
+
+// Width of a nul character.
+lib.wc.nulWidth = 0;
+
+// Width of a control character.
+lib.wc.controlWidth = 0;
+
+// Flag whether to consider East Asian Ambiguous characters.
+lib.wc.regardCjkAmbiguous = false;
+
+// Width of an East Asian Ambiguous character.
+lib.wc.cjkAmbiguousWidth = 2;
+
+// Sorted list of non-overlapping intervals of non-spacing characters
+// generated by the `./ranges.py` helper.
+lib.wc.combining = [
+    [0x00ad, 0x00ad], [0x0300, 0x036f], [0x0483, 0x0489],
+    [0x0591, 0x05bd], [0x05bf, 0x05bf], [0x05c1, 0x05c2],
+    [0x05c4, 0x05c5], [0x05c7, 0x05c7], [0x0610, 0x061a],
+    [0x061c, 0x061c], [0x064b, 0x065f], [0x0670, 0x0670],
+    [0x06d6, 0x06dc], [0x06df, 0x06e4], [0x06e7, 0x06e8],
+    [0x06ea, 0x06ed], [0x0711, 0x0711], [0x0730, 0x074a],
+    [0x07a6, 0x07b0], [0x07eb, 0x07f3], [0x07fd, 0x07fd],
+    [0x0816, 0x0819], [0x081b, 0x0823], [0x0825, 0x0827],
+    [0x0829, 0x082d], [0x0859, 0x085b], [0x08d3, 0x08e1],
+    [0x08e3, 0x0902], [0x093a, 0x093a], [0x093c, 0x093c],
+    [0x0941, 0x0948], [0x094d, 0x094d], [0x0951, 0x0957],
+    [0x0962, 0x0963], [0x0981, 0x0981], [0x09bc, 0x09bc],
+    [0x09c1, 0x09c4], [0x09cd, 0x09cd], [0x09e2, 0x09e3],
+    [0x09fe, 0x09fe], [0x0a01, 0x0a02], [0x0a3c, 0x0a3c],
+    [0x0a41, 0x0a42], [0x0a47, 0x0a48], [0x0a4b, 0x0a4d],
+    [0x0a51, 0x0a51], [0x0a70, 0x0a71], [0x0a75, 0x0a75],
+    [0x0a81, 0x0a82], [0x0abc, 0x0abc], [0x0ac1, 0x0ac5],
+    [0x0ac7, 0x0ac8], [0x0acd, 0x0acd], [0x0ae2, 0x0ae3],
+    [0x0afa, 0x0aff], [0x0b01, 0x0b01], [0x0b3c, 0x0b3c],
+    [0x0b3f, 0x0b3f], [0x0b41, 0x0b44], [0x0b4d, 0x0b4d],
+    [0x0b56, 0x0b56], [0x0b62, 0x0b63], [0x0b82, 0x0b82],
+    [0x0bc0, 0x0bc0], [0x0bcd, 0x0bcd], [0x0c00, 0x0c00],
+    [0x0c04, 0x0c04], [0x0c3e, 0x0c40], [0x0c46, 0x0c48],
+    [0x0c4a, 0x0c4d], [0x0c55, 0x0c56], [0x0c62, 0x0c63],
+    [0x0c81, 0x0c81], [0x0cbc, 0x0cbc], [0x0cbf, 0x0cbf],
+    [0x0cc6, 0x0cc6], [0x0ccc, 0x0ccd], [0x0ce2, 0x0ce3],
+    [0x0d00, 0x0d01], [0x0d3b, 0x0d3c], [0x0d41, 0x0d44],
+    [0x0d4d, 0x0d4d], [0x0d62, 0x0d63], [0x0dca, 0x0dca],
+    [0x0dd2, 0x0dd4], [0x0dd6, 0x0dd6], [0x0e31, 0x0e31],
+    [0x0e34, 0x0e3a], [0x0e47, 0x0e4e], [0x0eb1, 0x0eb1],
+    [0x0eb4, 0x0ebc], [0x0ec8, 0x0ecd], [0x0f18, 0x0f19],
+    [0x0f35, 0x0f35], [0x0f37, 0x0f37], [0x0f39, 0x0f39],
+    [0x0f71, 0x0f7e], [0x0f80, 0x0f84], [0x0f86, 0x0f87],
+    [0x0f8d, 0x0f97], [0x0f99, 0x0fbc], [0x0fc6, 0x0fc6],
+    [0x102d, 0x1030], [0x1032, 0x1037], [0x1039, 0x103a],
+    [0x103d, 0x103e], [0x1058, 0x1059], [0x105e, 0x1060],
+    [0x1071, 0x1074], [0x1082, 0x1082], [0x1085, 0x1086],
+    [0x108d, 0x108d], [0x109d, 0x109d], [0x1160, 0x11ff],
+    [0x135d, 0x135f], [0x1712, 0x1714], [0x1732, 0x1734],
+    [0x1752, 0x1753], [0x1772, 0x1773], [0x17b4, 0x17b5],
+    [0x17b7, 0x17bd], [0x17c6, 0x17c6], [0x17c9, 0x17d3],
+    [0x17dd, 0x17dd], [0x180b, 0x180e], [0x1885, 0x1886],
+    [0x18a9, 0x18a9], [0x1920, 0x1922], [0x1927, 0x1928],
+    [0x1932, 0x1932], [0x1939, 0x193b], [0x1a17, 0x1a18],
+    [0x1a1b, 0x1a1b], [0x1a56, 0x1a56], [0x1a58, 0x1a5e],
+    [0x1a60, 0x1a60], [0x1a62, 0x1a62], [0x1a65, 0x1a6c],
+    [0x1a73, 0x1a7c], [0x1a7f, 0x1a7f], [0x1ab0, 0x1abe],
+    [0x1b00, 0x1b03], [0x1b34, 0x1b34], [0x1b36, 0x1b3a],
+    [0x1b3c, 0x1b3c], [0x1b42, 0x1b42], [0x1b6b, 0x1b73],
+    [0x1b80, 0x1b81], [0x1ba2, 0x1ba5], [0x1ba8, 0x1ba9],
+    [0x1bab, 0x1bad], [0x1be6, 0x1be6], [0x1be8, 0x1be9],
+    [0x1bed, 0x1bed], [0x1bef, 0x1bf1], [0x1c2c, 0x1c33],
+    [0x1c36, 0x1c37], [0x1cd0, 0x1cd2], [0x1cd4, 0x1ce0],
+    [0x1ce2, 0x1ce8], [0x1ced, 0x1ced], [0x1cf4, 0x1cf4],
+    [0x1cf8, 0x1cf9], [0x1dc0, 0x1df9], [0x1dfb, 0x1dff],
+    [0x200b, 0x200f], [0x202a, 0x202e], [0x2060, 0x2064],
+    [0x2066, 0x206f], [0x20d0, 0x20f0], [0x2cef, 0x2cf1],
+    [0x2d7f, 0x2d7f], [0x2de0, 0x2dff], [0x302a, 0x302d],
+    [0x3099, 0x309a], [0xa66f, 0xa672], [0xa674, 0xa67d],
+    [0xa69e, 0xa69f], [0xa6f0, 0xa6f1], [0xa802, 0xa802],
+    [0xa806, 0xa806], [0xa80b, 0xa80b], [0xa825, 0xa826],
+    [0xa8c4, 0xa8c5], [0xa8e0, 0xa8f1], [0xa8ff, 0xa8ff],
+    [0xa926, 0xa92d], [0xa947, 0xa951], [0xa980, 0xa982],
+    [0xa9b3, 0xa9b3], [0xa9b6, 0xa9b9], [0xa9bc, 0xa9bd],
+    [0xa9e5, 0xa9e5], [0xaa29, 0xaa2e], [0xaa31, 0xaa32],
+    [0xaa35, 0xaa36], [0xaa43, 0xaa43], [0xaa4c, 0xaa4c],
+    [0xaa7c, 0xaa7c], [0xaab0, 0xaab0], [0xaab2, 0xaab4],
+    [0xaab7, 0xaab8], [0xaabe, 0xaabf], [0xaac1, 0xaac1],
+    [0xaaec, 0xaaed], [0xaaf6, 0xaaf6], [0xabe5, 0xabe5],
+    [0xabe8, 0xabe8], [0xabed, 0xabed], [0xfb1e, 0xfb1e],
+    [0xfe00, 0xfe0f], [0xfe20, 0xfe2f], [0xfeff, 0xfeff],
+    [0xfff9, 0xfffb], [0x101fd, 0x101fd], [0x102e0, 0x102e0],
+    [0x10376, 0x1037a], [0x10a01, 0x10a03], [0x10a05, 0x10a06],
+    [0x10a0c, 0x10a0f], [0x10a38, 0x10a3a], [0x10a3f, 0x10a3f],
+    [0x10ae5, 0x10ae6], [0x10d24, 0x10d27], [0x10f46, 0x10f50],
+    [0x11001, 0x11001], [0x11038, 0x11046], [0x1107f, 0x11081],
+    [0x110b3, 0x110b6], [0x110b9, 0x110ba], [0x11100, 0x11102],
+    [0x11127, 0x1112b], [0x1112d, 0x11134], [0x11173, 0x11173],
+    [0x11180, 0x11181], [0x111b6, 0x111be], [0x111c9, 0x111cc],
+    [0x1122f, 0x11231], [0x11234, 0x11234], [0x11236, 0x11237],
+    [0x1123e, 0x1123e], [0x112df, 0x112df], [0x112e3, 0x112ea],
+    [0x11300, 0x11301], [0x1133b, 0x1133c], [0x11340, 0x11340],
+    [0x11366, 0x1136c], [0x11370, 0x11374], [0x11438, 0x1143f],
+    [0x11442, 0x11444], [0x11446, 0x11446], [0x1145e, 0x1145e],
+    [0x114b3, 0x114b8], [0x114ba, 0x114ba], [0x114bf, 0x114c0],
+    [0x114c2, 0x114c3], [0x115b2, 0x115b5], [0x115bc, 0x115bd],
+    [0x115bf, 0x115c0], [0x115dc, 0x115dd], [0x11633, 0x1163a],
+    [0x1163d, 0x1163d], [0x1163f, 0x11640], [0x116ab, 0x116ab],
+    [0x116ad, 0x116ad], [0x116b0, 0x116b5], [0x116b7, 0x116b7],
+    [0x1171d, 0x1171f], [0x11722, 0x11725], [0x11727, 0x1172b],
+    [0x1182f, 0x11837], [0x11839, 0x1183a], [0x119d4, 0x119d7],
+    [0x119da, 0x119db], [0x119e0, 0x119e0], [0x11a01, 0x11a0a],
+    [0x11a33, 0x11a38], [0x11a3b, 0x11a3e], [0x11a47, 0x11a47],
+    [0x11a51, 0x11a56], [0x11a59, 0x11a5b], [0x11a8a, 0x11a96],
+    [0x11a98, 0x11a99], [0x11c30, 0x11c36], [0x11c38, 0x11c3d],
+    [0x11c3f, 0x11c3f], [0x11c92, 0x11ca7], [0x11caa, 0x11cb0],
+    [0x11cb2, 0x11cb3], [0x11cb5, 0x11cb6], [0x11d31, 0x11d36],
+    [0x11d3a, 0x11d3a], [0x11d3c, 0x11d3d], [0x11d3f, 0x11d45],
+    [0x11d47, 0x11d47], [0x11d90, 0x11d91], [0x11d95, 0x11d95],
+    [0x11d97, 0x11d97], [0x11ef3, 0x11ef4], [0x13430, 0x13438],
+    [0x16af0, 0x16af4], [0x16b30, 0x16b36], [0x16f4f, 0x16f4f],
+    [0x16f8f, 0x16f92], [0x1bc9d, 0x1bc9e], [0x1bca0, 0x1bca3],
+    [0x1d167, 0x1d169], [0x1d173, 0x1d182], [0x1d185, 0x1d18b],
+    [0x1d1aa, 0x1d1ad], [0x1d242, 0x1d244], [0x1da00, 0x1da36],
+    [0x1da3b, 0x1da6c], [0x1da75, 0x1da75], [0x1da84, 0x1da84],
+    [0x1da9b, 0x1da9f], [0x1daa1, 0x1daaf], [0x1e000, 0x1e006],
+    [0x1e008, 0x1e018], [0x1e01b, 0x1e021], [0x1e023, 0x1e024],
+    [0x1e026, 0x1e02a], [0x1e130, 0x1e136], [0x1e2ec, 0x1e2ef],
+    [0x1e8d0, 0x1e8d6], [0x1e944, 0x1e94a], [0xe0001, 0xe0001],
+    [0xe0020, 0xe007f], [0xe0100, 0xe01ef],
+];
+
+// Sorted list of non-overlapping intervals of East Asian Ambiguous characters
+// generated by the `./ranges.py` helper.
+lib.wc.ambiguous = [
+    [0x00a1, 0x00a1], [0x00a4, 0x00a4], [0x00a7, 0x00a8],
+    [0x00aa, 0x00aa], [0x00ad, 0x00ae], [0x00b0, 0x00b4],
+    [0x00b6, 0x00ba], [0x00bc, 0x00bf], [0x00c6, 0x00c6],
+    [0x00d0, 0x00d0], [0x00d7, 0x00d8], [0x00de, 0x00e1],
+    [0x00e6, 0x00e6], [0x00e8, 0x00ea], [0x00ec, 0x00ed],
+    [0x00f0, 0x00f0], [0x00f2, 0x00f3], [0x00f7, 0x00fa],
+    [0x00fc, 0x00fc], [0x00fe, 0x00fe], [0x0101, 0x0101],
+    [0x0111, 0x0111], [0x0113, 0x0113], [0x011b, 0x011b],
+    [0x0126, 0x0127], [0x012b, 0x012b], [0x0131, 0x0133],
+    [0x0138, 0x0138], [0x013f, 0x0142], [0x0144, 0x0144],
+    [0x0148, 0x014b], [0x014d, 0x014d], [0x0152, 0x0153],
+    [0x0166, 0x0167], [0x016b, 0x016b], [0x01ce, 0x01ce],
+    [0x01d0, 0x01d0], [0x01d2, 0x01d2], [0x01d4, 0x01d4],
+    [0x01d6, 0x01d6], [0x01d8, 0x01d8], [0x01da, 0x01da],
+    [0x01dc, 0x01dc], [0x0251, 0x0251], [0x0261, 0x0261],
+    [0x02c4, 0x02c4], [0x02c7, 0x02c7], [0x02c9, 0x02cb],
+    [0x02cd, 0x02cd], [0x02d0, 0x02d0], [0x02d8, 0x02db],
+    [0x02dd, 0x02dd], [0x02df, 0x02df], [0x0300, 0x036f],
+    [0x0391, 0x03a1], [0x03a3, 0x03a9], [0x03b1, 0x03c1],
+    [0x03c3, 0x03c9], [0x0401, 0x0401], [0x0410, 0x044f],
+    [0x0451, 0x0451], [0x1100, 0x115f], [0x2010, 0x2010],
+    [0x2013, 0x2016], [0x2018, 0x2019], [0x201c, 0x201d],
+    [0x2020, 0x2022], [0x2024, 0x2027], [0x2030, 0x2030],
+    [0x2032, 0x2033], [0x2035, 0x2035], [0x203b, 0x203b],
+    [0x203e, 0x203e], [0x2074, 0x2074], [0x207f, 0x207f],
+    [0x2081, 0x2084], [0x20ac, 0x20ac], [0x2103, 0x2103],
+    [0x2105, 0x2105], [0x2109, 0x2109], [0x2113, 0x2113],
+    [0x2116, 0x2116], [0x2121, 0x2122], [0x2126, 0x2126],
+    [0x212b, 0x212b], [0x2153, 0x2154], [0x215b, 0x215e],
+    [0x2160, 0x216b], [0x2170, 0x2179], [0x2189, 0x2189],
+    [0x2190, 0x2199], [0x21b8, 0x21b9], [0x21d2, 0x21d2],
+    [0x21d4, 0x21d4], [0x21e7, 0x21e7], [0x2200, 0x2200],
+    [0x2202, 0x2203], [0x2207, 0x2208], [0x220b, 0x220b],
+    [0x220f, 0x220f], [0x2211, 0x2211], [0x2215, 0x2215],
+    [0x221a, 0x221a], [0x221d, 0x2220], [0x2223, 0x2223],
+    [0x2225, 0x2225], [0x2227, 0x222c], [0x222e, 0x222e],
+    [0x2234, 0x2237], [0x223c, 0x223d], [0x2248, 0x2248],
+    [0x224c, 0x224c], [0x2252, 0x2252], [0x2260, 0x2261],
+    [0x2264, 0x2267], [0x226a, 0x226b], [0x226e, 0x226f],
+    [0x2282, 0x2283], [0x2286, 0x2287], [0x2295, 0x2295],
+    [0x2299, 0x2299], [0x22a5, 0x22a5], [0x22bf, 0x22bf],
+    [0x2312, 0x2312], [0x231a, 0x231b], [0x2329, 0x232a],
+    [0x23e9, 0x23ec], [0x23f0, 0x23f0], [0x23f3, 0x23f3],
+    [0x2460, 0x24e9], [0x24eb, 0x254b], [0x2550, 0x2573],
+    [0x2580, 0x258f], [0x2592, 0x2595], [0x25a0, 0x25a1],
+    [0x25a3, 0x25a9], [0x25b2, 0x25b3], [0x25b6, 0x25b7],
+    [0x25bc, 0x25bd], [0x25c0, 0x25c1], [0x25c6, 0x25c8],
+    [0x25cb, 0x25cb], [0x25ce, 0x25d1], [0x25e2, 0x25e5],
+    [0x25ef, 0x25ef], [0x25fd, 0x25fe], [0x2605, 0x2606],
+    [0x2609, 0x2609], [0x260e, 0x260f], [0x2614, 0x2615],
+    [0x261c, 0x261c], [0x261e, 0x261e], [0x2640, 0x2640],
+    [0x2642, 0x2642], [0x2648, 0x2653], [0x2660, 0x2661],
+    [0x2663, 0x2665], [0x2667, 0x266a], [0x266c, 0x266d],
+    [0x266f, 0x266f], [0x267f, 0x267f], [0x2693, 0x2693],
+    [0x269e, 0x269f], [0x26a1, 0x26a1], [0x26aa, 0x26ab],
+    [0x26bd, 0x26bf], [0x26c4, 0x26e1], [0x26e3, 0x26e3],
+    [0x26e8, 0x26ff], [0x2705, 0x2705], [0x270a, 0x270b],
+    [0x2728, 0x2728], [0x273d, 0x273d], [0x274c, 0x274c],
+    [0x274e, 0x274e], [0x2753, 0x2755], [0x2757, 0x2757],
+    [0x2776, 0x277f], [0x2795, 0x2797], [0x27b0, 0x27b0],
+    [0x27bf, 0x27bf], [0x2b1b, 0x2b1c], [0x2b50, 0x2b50],
+    [0x2b55, 0x2b59], [0x2e80, 0x2fdf], [0x2ff0, 0x303e],
+    [0x3040, 0x4dbf], [0x4e00, 0xa4cf], [0xa960, 0xa97f],
+    [0xac00, 0xd7a3], [0xe000, 0xfaff], [0xfe00, 0xfe19],
+    [0xfe30, 0xfe6f], [0xff01, 0xff60], [0xffe0, 0xffe6],
+    [0xfffd, 0xfffd], [0x16fe0, 0x16fe3], [0x17000, 0x18aff],
+    [0x1b000, 0x1b12f], [0x1b150, 0x1b152], [0x1b164, 0x1b167],
+    [0x1b170, 0x1b2ff], [0x1f004, 0x1f004], [0x1f0cf, 0x1f0cf],
+    [0x1f100, 0x1f10a], [0x1f110, 0x1f12d], [0x1f130, 0x1f169],
+    [0x1f170, 0x1f1ac], [0x1f200, 0x1f202], [0x1f210, 0x1f23b],
+    [0x1f240, 0x1f248], [0x1f250, 0x1f251], [0x1f260, 0x1f265],
+    [0x1f300, 0x1f320], [0x1f32d, 0x1f335], [0x1f337, 0x1f37c],
+    [0x1f37e, 0x1f393], [0x1f3a0, 0x1f3ca], [0x1f3cf, 0x1f3d3],
+    [0x1f3e0, 0x1f3f0], [0x1f3f4, 0x1f3f4], [0x1f3f8, 0x1f43e],
+    [0x1f440, 0x1f440], [0x1f442, 0x1f4fc], [0x1f4ff, 0x1f53d],
+    [0x1f54b, 0x1f54e], [0x1f550, 0x1f567], [0x1f57a, 0x1f57a],
+    [0x1f595, 0x1f596], [0x1f5a4, 0x1f5a4], [0x1f5fb, 0x1f64f],
+    [0x1f680, 0x1f6c5], [0x1f6cc, 0x1f6cc], [0x1f6d0, 0x1f6d2],
+    [0x1f6d5, 0x1f6d5], [0x1f6eb, 0x1f6ec], [0x1f6f4, 0x1f6fa],
+    [0x1f7e0, 0x1f7eb], [0x1f90d, 0x1f971], [0x1f973, 0x1f976],
+    [0x1f97a, 0x1f9a2], [0x1f9a5, 0x1f9aa], [0x1f9ae, 0x1f9ca],
+    [0x1f9cd, 0x1f9ff], [0x1fa70, 0x1fa73], [0x1fa78, 0x1fa7a],
+    [0x1fa80, 0x1fa82], [0x1fa90, 0x1fa95], [0x20000, 0x2fffd],
+    [0x30000, 0x3fffd], [0xe0100, 0xe01ef], [0xf0000, 0xffffd],
+    [0x100000, 0x10fffd],
+];
+
+// Sorted list of non-overlapping intervals of East Asian Unambiguous characters
+// generated by the `./ranges.py` helper.
+lib.wc.unambiguous = [
+    [0x1100, 0x115f], [0x231a, 0x231b], [0x2329, 0x232a],
+    [0x23e9, 0x23ec], [0x23f0, 0x23f0], [0x23f3, 0x23f3],
+    [0x25fd, 0x25fe], [0x2614, 0x2615], [0x2648, 0x2653],
+    [0x267f, 0x267f], [0x2693, 0x2693], [0x26a1, 0x26a1],
+    [0x26aa, 0x26ab], [0x26bd, 0x26be], [0x26c4, 0x26c5],
+    [0x26ce, 0x26ce], [0x26d4, 0x26d4], [0x26ea, 0x26ea],
+    [0x26f2, 0x26f3], [0x26f5, 0x26f5], [0x26fa, 0x26fa],
+    [0x26fd, 0x26fd], [0x2705, 0x2705], [0x270a, 0x270b],
+    [0x2728, 0x2728], [0x274c, 0x274c], [0x274e, 0x274e],
+    [0x2753, 0x2755], [0x2757, 0x2757], [0x2795, 0x2797],
+    [0x27b0, 0x27b0], [0x27bf, 0x27bf], [0x2b1b, 0x2b1c],
+    [0x2b50, 0x2b50], [0x2b55, 0x2b55], [0x2e80, 0x2fdf],
+    [0x2ff0, 0x303e], [0x3040, 0x3247], [0x3250, 0x4dbf],
+    [0x4e00, 0xa4cf], [0xa960, 0xa97f], [0xac00, 0xd7a3],
+    [0xf900, 0xfaff], [0xfe10, 0xfe19], [0xfe30, 0xfe6f],
+    [0xff01, 0xff60], [0xffe0, 0xffe6], [0x16fe0, 0x16fe3],
+    [0x17000, 0x18aff], [0x1b000, 0x1b12f], [0x1b150, 0x1b152],
+    [0x1b164, 0x1b167], [0x1b170, 0x1b2ff], [0x1f004, 0x1f004],
+    [0x1f0cf, 0x1f0cf], [0x1f18e, 0x1f18e], [0x1f191, 0x1f19a],
+    [0x1f200, 0x1f202], [0x1f210, 0x1f23b], [0x1f240, 0x1f248],
+    [0x1f250, 0x1f251], [0x1f260, 0x1f265], [0x1f300, 0x1f320],
+    [0x1f32d, 0x1f335], [0x1f337, 0x1f37c], [0x1f37e, 0x1f393],
+    [0x1f3a0, 0x1f3ca], [0x1f3cf, 0x1f3d3], [0x1f3e0, 0x1f3f0],
+    [0x1f3f4, 0x1f3f4], [0x1f3f8, 0x1f43e], [0x1f440, 0x1f440],
+    [0x1f442, 0x1f4fc], [0x1f4ff, 0x1f53d], [0x1f54b, 0x1f54e],
+    [0x1f550, 0x1f567], [0x1f57a, 0x1f57a], [0x1f595, 0x1f596],
+    [0x1f5a4, 0x1f5a4], [0x1f5fb, 0x1f64f], [0x1f680, 0x1f6c5],
+    [0x1f6cc, 0x1f6cc], [0x1f6d0, 0x1f6d2], [0x1f6d5, 0x1f6d5],
+    [0x1f6eb, 0x1f6ec], [0x1f6f4, 0x1f6fa], [0x1f7e0, 0x1f7eb],
+    [0x1f90d, 0x1f971], [0x1f973, 0x1f976], [0x1f97a, 0x1f9a2],
+    [0x1f9a5, 0x1f9aa], [0x1f9ae, 0x1f9ca], [0x1f9cd, 0x1f9ff],
+    [0x1fa70, 0x1fa73], [0x1fa78, 0x1fa7a], [0x1fa80, 0x1fa82],
+    [0x1fa90, 0x1fa95], [0x20000, 0x2fffd], [0x30000, 0x3fffd],
+];
+
+/**
+ * Binary search to check if the given unicode character is in the table.
+ *
+ * @param {integer} ucs A unicode character code.
+ * @param {Object} table A sorted list of internals to match against.
+ * @return {boolean} True if the given character is in the table.
+ */
+lib.wc.binaryTableSearch_ = function(ucs, table) {
+  var min = 0, max = table.length - 1;
+  var mid;
+
+  if (ucs < table[min][0] || ucs > table[max][1])
+    return false;
+  while (max >= min) {
+    mid = Math.floor((min + max) / 2);
+    if (ucs > table[mid][1]) {
+      min = mid + 1;
+    } else if (ucs < table[mid][0]) {
+      max = mid - 1;
+    } else {
+      return true;
+    }
+  }
+
+  return false;
+};
+
+/**
+ * Binary search to check if the given unicode character is a space character.
+ *
+ * @param {integer} ucs A unicode character code.
+ *
+ * @return {boolean} True if the given character is a space character; false
+ *     otherwise.
+ */
+lib.wc.isSpace = function(ucs) {
+  return lib.wc.binaryTableSearch_(ucs, lib.wc.combining);
+};
+
+/**
+ * Auxiliary function for checking if the given unicode character is a East
+ * Asian Ambiguous character.
+ *
+ * @param {integer} ucs A unicode character code.
+ *
+ * @return {boolean} True if the given character is a East Asian Ambiguous
+ * character.
+ */
+lib.wc.isCjkAmbiguous = function(ucs) {
+  return lib.wc.binaryTableSearch_(ucs, lib.wc.ambiguous);
+};
+
+/**
+ * Determine the column width of the given character.
+ *
+ * @param {integer} ucs A unicode character code.
+ *
+ * @return {integer} The column width of the given character.
+ */
+lib.wc.charWidth = function(ucs) {
+  if (lib.wc.regardCjkAmbiguous) {
+    return lib.wc.charWidthRegardAmbiguous(ucs);
+  } else {
+    return lib.wc.charWidthDisregardAmbiguous(ucs);
+  }
+};
+
+/**
+ * Determine the column width of the given character without considering East
+ * Asian Ambiguous characters.
+ *
+ * @param {integer} ucs A unicode character code.
+ *
+ * @return {integer} The column width of the given character.
+ */
+lib.wc.charWidthDisregardAmbiguous = function(ucs) {
+  // Optimize for ASCII characters.
+  if (ucs < 0x7f) {
+    if (ucs >= 0x20)
+      return 1;
+    else if (ucs == 0)
+      return lib.wc.nulWidth;
+    else /* if (ucs < 0x20) */
+      return lib.wc.controlWidth;
+  }
+
+  // Test for 8-bit control characters.
+  if (ucs < 0xa0)
+    return lib.wc.controlWidth;
+
+  // Binary search in table of non-spacing characters.
+  if (lib.wc.isSpace(ucs))
+    return 0;
+
+  // Binary search in table of wide characters.
+  return lib.wc.binaryTableSearch_(ucs, lib.wc.unambiguous) ? 2 : 1;
+};
+
+/**
+ * Determine the column width of the given character considering East Asian
+ * Ambiguous characters.
+ *
+ * @param {integer} ucs A unicode character code.
+ *
+ * @return {integer} The column width of the given character.
+ */
+lib.wc.charWidthRegardAmbiguous = function(ucs) {
+  if (lib.wc.isCjkAmbiguous(ucs))
+    return lib.wc.cjkAmbiguousWidth;
+
+  return lib.wc.charWidthDisregardAmbiguous(ucs);
+};
+
+/**
+ * Determine the column width of the given string.
+ *
+ * @param {string} str A string.
+ *
+ * @return {integer} The column width of the given string.
+ */
+lib.wc.strWidth = function(str) {
+  var width, rv = 0;
+
+  for (var i = 0; i < str.length;) {
+    var codePoint = str.codePointAt(i);
+    width = lib.wc.charWidth(codePoint);
+    if (width < 0)
+      return -1;
+    rv += width;
+    i += (codePoint <= 0xffff) ? 1 : 2;
+  }
+
+  return rv;
+};
+
+/**
+ * Get the substring at the given column offset of the given column width.
+ *
+ * @param {string} str The string to get substring from.
+ * @param {integer} start The starting column offset to get substring.
+ * @param {integer} opt_width The column width of the substring.
+ *
+ * @return {string} The substring.
+ */
+lib.wc.substr = function(str, start, opt_width) {
+  var startIndex = 0;
+  var endIndex, width;
+
+  // Fun edge case: Normally we associate zero width codepoints (like combining
+  // characters) with the previous codepoint, so we skip any leading ones while
+  // including trailing ones.  However, if there are zero width codepoints at
+  // the start of the string, and the substring starts at 0, lets include them
+  // in the result.  This also makes for a simple optimization for a common
+  // request.
+  if (start) {
+    for (width = 0; startIndex < str.length;) {
+      const codePoint = str.codePointAt(startIndex);
+      width += lib.wc.charWidth(codePoint);
+      if (width > start)
+        break;
+      startIndex += (codePoint <= 0xffff) ? 1 : 2;
+    }
+  }
+
+  if (opt_width != undefined) {
+    for (endIndex = startIndex, width = 0; endIndex < str.length;) {
+      const codePoint = str.codePointAt(endIndex);
+      width += lib.wc.charWidth(codePoint);
+      if (width > opt_width)
+        break;
+      endIndex += (codePoint <= 0xffff) ? 1 : 2;
+    }
+    return str.substring(startIndex, endIndex);
+  }
+
+  return str.substr(startIndex);
+};
+
+/**
+ * Get substring at the given start and end column offset.
+ *
+ * @param {string} str The string to get substring from.
+ * @param {integer} start The starting column offset.
+ * @param {integer} end The ending column offset.
+ *
+ * @return {string} The substring.
+ */
+lib.wc.substring = function(str, start, end) {
+  return lib.wc.substr(str, start, end - start);
+};
+lib.resource.add('libdot/changelog/version', 'text/plain',
+'3.0.0'
+);
+
+lib.resource.add('libdot/changelog/date', 'text/plain',
+'2019-08-06'
+);
+
+// SOURCE FILE: hterm/js/hterm.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Declares the hterm.* namespace and some basic shared utilities
+ * that are too small to deserve dedicated files.
+ */
+var hterm = {};
+
+/**
+ * The type of window hosting hterm.
+ *
+ * This is set as part of hterm.init().  The value is invalid until
+ * initialization completes.
+ */
+hterm.windowType = null;
+
+/**
+ * The OS we're running under.
+ *
+ * Used when setting up OS-specific behaviors.
+ *
+ * This is set as part of hterm.init().  The value is invalid until
+ * initialization completes.
+ */
+hterm.os = null;
+
+/**
+ * Warning message to display in the terminal when browser zoom is enabled.
+ *
+ * You can replace it with your own localized message.
+ */
+hterm.zoomWarningMessage = 'ZOOM != 100%';
+
+/**
+ * Brief overlay message displayed when text is copied to the clipboard.
+ *
+ * By default it is the unicode BLACK SCISSORS character, but you can
+ * replace it with your own localized message.
+ *
+ * This is only displayed when the 'enable-clipboard-notice' preference
+ * is enabled.
+ */
+hterm.notifyCopyMessage = '\u2702';
+
+
+/**
+ * Text shown in a desktop notification for the terminal
+ * bell.  \u226a is a unicode EIGHTH NOTE, %(title) will
+ * be replaced by the terminal title.
+ */
+hterm.desktopNotificationTitle = '\u266A %(title) \u266A';
+
+/**
+ * The hterm init function, registered with lib.registerInit().
+ *
+ * This is called during lib.init().
+ *
+ * @param {function} onInit The function lib.init() wants us to invoke when
+ *     initialization is complete.
+ */
+lib.registerInit('hterm', function(onInit) {
+  function initOs(os) {
+    hterm.os = os;
+
+    onInit();
+  }
+
+  function initMessageManager() {
+    lib.i18n.getAcceptLanguages((languages) => {
+      if (!hterm.messageManager)
+        hterm.messageManager = new lib.MessageManager(languages);
+
+      // If OS detection fails, then we'll still set the value to something.
+      // The OS logic in hterm tends to be best effort anyways.
+      lib.f.getOs().then(initOs).catch(initOs);
+    });
+  }
+
+  function onWindow(window) {
+    hterm.windowType = window.type;
+    initMessageManager();
+  }
+
+  function onTab(tab) {
+    if (tab && window.chrome) {
+      chrome.windows.get(tab.windowId, null, onWindow);
+    } else {
+      // TODO(rginda): This is where we end up for a v1 app's background page.
+      // Maybe windowType = 'none' would be more appropriate, or something.
+      hterm.windowType = 'normal';
+      initMessageManager();
+    }
+  }
+
+  if (!hterm.defaultStorage) {
+    if (window.chrome && chrome.storage && chrome.storage.sync) {
+      hterm.defaultStorage = new lib.Storage.Chrome(chrome.storage.sync);
+    } else {
+      hterm.defaultStorage = new lib.Storage.Local();
+    }
+  }
+
+  // The chrome.tabs API is not supported in packaged apps, and detecting if
+  // you're a packaged app is a little awkward.
+  var isPackagedApp = false;
+  if (window.chrome && chrome.runtime && chrome.runtime.getManifest) {
+    var manifest = chrome.runtime.getManifest();
+    isPackagedApp = manifest.app && manifest.app.background;
+  }
+
+  if (isPackagedApp) {
+    // Packaged apps are never displayed in browser tabs.
+    setTimeout(onWindow.bind(null, {type: 'popup'}), 0);
+  } else {
+    if (window.chrome && chrome.tabs) {
+      // The getCurrent method gets the tab that is "currently running", not the
+      // topmost or focused tab.
+      chrome.tabs.getCurrent(onTab);
+    } else {
+      setTimeout(onWindow.bind(null, {type: 'normal'}), 0);
+    }
+  }
+});
+
+/**
+ * Return decimal { width, height } for a given dom node.
+ */
+hterm.getClientSize = function(dom) {
+  return dom.getBoundingClientRect();
+};
+
+/**
+ * Return decimal width for a given dom node.
+ */
+hterm.getClientWidth = function(dom) {
+  return dom.getBoundingClientRect().width;
+};
+
+/**
+ * Return decimal height for a given dom node.
+ */
+hterm.getClientHeight = function(dom) {
+  return dom.getBoundingClientRect().height;
+};
+
+/**
+ * Copy the specified text to the system clipboard.
+ *
+ * We'll create selections on demand based on the content to copy.
+ *
+ * @param {HTMLDocument} document The document with the selection to copy.
+ * @param {string} str The string data to copy out.
+ */
+hterm.copySelectionToClipboard = function(document, str) {
+  // Request permission if need be.
+  const requestPermission = () => {
+    // Use the Permissions API if available.
+    if (navigator.permissions && navigator.permissions.query) {
+      return navigator.permissions.query({name: 'clipboard-write'})
+        .then((status) => {
+          const checkState = (resolve, reject) => {
+            switch (status.state) {
+              case 'granted':
+                return resolve();
+              case 'denied':
+                return reject();
+              default:
+                // Wait for the user to approve/disprove.
+                return new Promise((resolve, reject) => {
+                  status.onchange = () => checkState(resolve, reject);
+                });
+            }
+          };
+
+          return new Promise(checkState);
+        })
+        // If the platform doesn't support "clipboard-write", or is denied,
+        // we move on to the copying step anyways.
+        .catch(() => Promise.resolve());
+    } else {
+      // No permissions API, so resolve right away.
+      return Promise.resolve();
+    }
+  };
+
+  // Write to the clipboard.
+  const writeClipboard = () => {
+    // Use the Clipboard API if available.
+    if (navigator.clipboard && navigator.clipboard.writeText) {
+      // If this fails (perhaps due to focus changing windows), fallback to the
+      // legacy copy method.
+      return navigator.clipboard.writeText(str)
+        .catch(execCommand);
+    } else {
+      // No Clipboard API, so use the old execCommand style.
+      return execCommand();
+    }
+  };
+
+  // Write to the clipboard using the legacy execCommand method.
+  // TODO: Once we can rely on the Clipboard API everywhere, we can simplify
+  // this a lot by deleting the custom selection logic.
+  const execCommand = () => {
+    const copySource = document.createElement('pre');
+    copySource.id = 'hterm:copy-to-clipboard-source';
+    copySource.textContent = str;
+    copySource.style.cssText = (
+        '-webkit-user-select: text;' +
+        '-moz-user-select: text;' +
+        'position: absolute;' +
+        'top: -99px');
+
+    document.body.appendChild(copySource);
+
+    const selection = document.getSelection();
+    const anchorNode = selection.anchorNode;
+    const anchorOffset = selection.anchorOffset;
+    const focusNode = selection.focusNode;
+    const focusOffset = selection.focusOffset;
+
+    // FF sometimes throws NS_ERROR_FAILURE exceptions when we make this call.
+    // Catch it because a failure here leaks the copySource node.
+    // https://bugzilla.mozilla.org/show_bug.cgi?id=1178676
+    try {
+      selection.selectAllChildren(copySource);
+    } catch (ex) {}
+
+    try {
+      document.execCommand('copy');
+    } catch (firefoxException) {
+      // Ignore this. FF throws an exception if there was an error, even
+      // though the spec says just return false.
+    }
+
+    // IE doesn't support selection.extend.  This means that the selection won't
+    // return on IE.
+    if (selection.extend) {
+      // When running in the test harness, we won't have any related nodes.
+      if (anchorNode) {
+        selection.collapse(anchorNode, anchorOffset);
+      }
+      if (focusNode) {
+        selection.extend(focusNode, focusOffset);
+      }
+    }
+
+    copySource.parentNode.removeChild(copySource);
+
+    // Since execCommand is synchronous, resolve right away.
+    return Promise.resolve();
+  };
+
+  // Kick it all off!
+  return requestPermission().then(writeClipboard);
+};
+
+/**
+ * Paste the system clipboard into the element with focus.
+ *
+ * Note: In Chrome/Firefox app/extension environments, you'll need the
+ * "clipboardRead" permission.  In other environments, this might always
+ * fail as the browser frequently blocks access for security reasons.
+ *
+ * @param {HTMLDocument} The document to paste into.
+ * @return {boolean} True if the paste succeeded.
+ */
+hterm.pasteFromClipboard = function(document) {
+  try {
+    return document.execCommand('paste');
+  } catch (firefoxException) {
+    // Ignore this.  FF 40 and older would incorrectly throw an exception if
+    // there was an error instead of returning false.
+    return false;
+  }
+};
+
+/**
+ * Return a formatted message in the current locale.
+ *
+ * @param {string} name The name of the message to return.
+ * @param {Array<string>=} args The message arguments, if required.
+ * @param {string=} string The default message text.
+ * @return {string} The localized message.
+ */
+hterm.msg = function(name, args = [], string) {
+  return hterm.messageManager.get('HTERM_' + name, args, string);
+};
+
+/**
+ * Create a new notification.
+ *
+ * @param {Object} params Various parameters for the notification.
+ * @param {string} params.title The title (defaults to the window's title).
+ * @param {string} params.body The message body (main text).
+ */
+hterm.notify = function(params) {
+  var def = (curr, fallback) => curr !== undefined ? curr : fallback;
+  if (params === undefined || params === null)
+    params = {};
+
+  // Merge the user's choices with the default settings.  We don't take it
+  // directly in case it was stuffed with excess junk.
+  var options = {
+      'body': params.body,
+      'icon': def(params.icon, lib.resource.getDataUrl('hterm/images/icon-96')),
+  };
+
+  var title = def(params.title, window.document.title);
+  if (!title)
+    title = 'hterm';
+  title = lib.f.replaceVars(hterm.desktopNotificationTitle, {'title': title});
+
+  var n = new Notification(title, options);
+  n.onclick = function() {
+    window.focus();
+    this.close();
+  };
+  return n;
+};
+
+/**
+ * Launches url in a new tab.
+ *
+ * @param {string} url URL to launch in a new tab.
+ */
+hterm.openUrl = function(url) {
+  if (window.chrome && chrome.browser && chrome.browser.openTab) {
+    // For Chrome v2 apps, we need to use this API to properly open windows.
+    chrome.browser.openTab({'url': url});
+  } else {
+    const win = lib.f.openWindow(url, '_blank');
+    win.focus();
+  }
+};
+
+/**
+ * Constructor for a hterm.Size record.
+ *
+ * Instances of this class have public read/write members for width and height.
+ *
+ * @param {integer} width The width of this record.
+ * @param {integer} height The height of this record.
+ */
+hterm.Size = function(width, height) {
+  this.width = width;
+  this.height = height;
+};
+
+/**
+ * Adjust the width and height of this record.
+ *
+ * @param {integer} width The new width of this record.
+ * @param {integer} height The new height of this record.
+ */
+hterm.Size.prototype.resize = function(width, height) {
+  this.width = width;
+  this.height = height;
+};
+
+/**
+ * Return a copy of this record.
+ *
+ * @return {hterm.Size} A new hterm.Size instance with the same width and
+ * height.
+ */
+hterm.Size.prototype.clone = function() {
+  return new hterm.Size(this.width, this.height);
+};
+
+/**
+ * Set the height and width of this instance based on another hterm.Size.
+ *
+ * @param {hterm.Size} that The object to copy from.
+ */
+hterm.Size.prototype.setTo = function(that) {
+  this.width = that.width;
+  this.height = that.height;
+};
+
+/**
+ * Test if another hterm.Size instance is equal to this one.
+ *
+ * @param {hterm.Size} that The other hterm.Size instance.
+ * @return {boolean} True if both instances have the same width/height, false
+ *     otherwise.
+ */
+hterm.Size.prototype.equals = function(that) {
+  return this.width == that.width && this.height == that.height;
+};
+
+/**
+ * Return a string representation of this instance.
+ *
+ * @return {string} A string that identifies the width and height of this
+ *     instance.
+ */
+hterm.Size.prototype.toString = function() {
+  return '[hterm.Size: ' + this.width + ', ' + this.height + ']';
+};
+
+/**
+ * Constructor for a hterm.RowCol record.
+ *
+ * Instances of this class have public read/write members for row and column.
+ *
+ * This class includes an 'overflow' bit which is use to indicate that an
+ * attempt has been made to move the cursor column passed the end of the
+ * screen.  When this happens we leave the cursor column set to the last column
+ * of the screen but set the overflow bit.  In this state cursor movement
+ * happens normally, but any attempt to print new characters causes a cr/lf
+ * first.
+ *
+ * @param {integer} row The row of this record.
+ * @param {integer} column The column of this record.
+ * @param {boolean} opt_overflow Optional boolean indicating that the RowCol
+ *     has overflowed.
+ */
+hterm.RowCol = function(row, column, opt_overflow) {
+  this.row = row;
+  this.column = column;
+  this.overflow = !!opt_overflow;
+};
+
+/**
+ * Adjust the row and column of this record.
+ *
+ * @param {integer} row The new row of this record.
+ * @param {integer} column The new column of this record.
+ * @param {boolean} opt_overflow Optional boolean indicating that the RowCol
+ *     has overflowed.
+ */
+hterm.RowCol.prototype.move = function(row, column, opt_overflow) {
+  this.row = row;
+  this.column = column;
+  this.overflow = !!opt_overflow;
+};
+
+/**
+ * Return a copy of this record.
+ *
+ * @return {hterm.RowCol} A new hterm.RowCol instance with the same row and
+ * column.
+ */
+hterm.RowCol.prototype.clone = function() {
+  return new hterm.RowCol(this.row, this.column, this.overflow);
+};
+
+/**
+ * Set the row and column of this instance based on another hterm.RowCol.
+ *
+ * @param {hterm.RowCol} that The object to copy from.
+ */
+hterm.RowCol.prototype.setTo = function(that) {
+  this.row = that.row;
+  this.column = that.column;
+  this.overflow = that.overflow;
+};
+
+/**
+ * Test if another hterm.RowCol instance is equal to this one.
+ *
+ * @param {hterm.RowCol} that The other hterm.RowCol instance.
+ * @return {boolean} True if both instances have the same row/column, false
+ *     otherwise.
+ */
+hterm.RowCol.prototype.equals = function(that) {
+  return (this.row == that.row && this.column == that.column &&
+          this.overflow == that.overflow);
+};
+
+/**
+ * Return a string representation of this instance.
+ *
+ * @return {string} A string that identifies the row and column of this
+ *     instance.
+ */
+hterm.RowCol.prototype.toString = function() {
+  return ('[hterm.RowCol: ' + this.row + ', ' + this.column + ', ' +
+          this.overflow + ']');
+};
+// SOURCE FILE: hterm/js/hterm_accessibility_reader.js
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * AccessibilityReader responsible for rendering command output for AT.
+ *
+ * Renders command output for Assistive Technology using a live region. We don't
+ * use the visible rows of the terminal for rendering command output to the
+ * screen reader because the rendered content may be different from what we want
+ * read out by a screen reader. For example, we may not actually render every
+ * row of a large piece of output to the screen as it wouldn't be performant.
+ * But we want the screen reader to read it all out in order.
+ *
+ * @param {HTMLDivElement} div The div element where the live region should be
+ *     added.
+ */
+hterm.AccessibilityReader = function(div) {
+  this.document_ = div.ownerDocument;
+
+  // The live region element to add text to.
+  const liveRegion = this.document_.createElement('div');
+  liveRegion.id = 'hterm:accessibility-live-region';
+  liveRegion.style.cssText = `position: absolute;
+                              width: 0; height: 0;
+                              overflow: hidden;
+                              left: 0; top: 0;`;
+  div.appendChild(liveRegion);
+
+  // Whether command output should be rendered for Assistive Technology.
+  // This isn't always enabled because it has an impact on performance.
+  this.accessibilityEnabled = false;
+
+  // This live element is used for command output.
+  this.liveElement_ = this.document_.createElement('p');
+  this.liveElement_.setAttribute('aria-live', 'polite');
+  this.liveElement_.setAttribute('aria-label', '');
+  liveRegion.appendChild(this.liveElement_);
+
+  // This live element is used for speaking out the current screen when
+  // navigating through the scrollback buffer. It will interrupt existing
+  // announcements.
+  this.assertiveLiveElement_ = this.document_.createElement('p');
+  this.assertiveLiveElement_.setAttribute('aria-live', 'assertive');
+  this.assertiveLiveElement_.setAttribute('aria-label', '');
+  liveRegion.appendChild(this.assertiveLiveElement_);
+
+  // A queue of updates to announce.
+  this.queue_ = [];
+
+  // A timer which tracks when next to add items to the live region. null when
+  // not running. This is used to combine updates that occur in a small window,
+  // as well as to avoid too much output being added to the live region in one
+  // go which can cause the renderer to hang.
+  this.nextReadTimer_ = null;
+
+  // This is set to true if the cursor is about to update position on the
+  // screen. i.e. beforeCursorChange has been called but not afterCursorChange.
+  this.cursorIsChanging_ = false;
+
+  // This tracks changes that would be added to queue_ while the cursor is
+  // changing. This is done so that we can decide to discard these changes if
+  // we announce something as a result of the cursor change.
+  this.cursorChangeQueue_ = [];
+
+  // The string of text on the row that the cursor was last on. Only valid while
+  // cursorIsChanging_ is true.
+  this.lastCursorRowString_ = null;
+
+  // The row that the cursor was last on. Only valid while cursorIsChanging_ is
+  // true.
+  this.lastCursorRow_ = null;
+
+  // The column that the cursor was last on. Only valid while cursorIsChanging_
+  // is true.
+  this.lastCursorColumn_ = null;
+
+  // True if a keypress has been performed since the last cursor change.
+  this.hasUserGesture = false;
+};
+
+/**
+ * Delay in ms to use for merging strings to output.
+ *
+ * We merge strings together to avoid hanging the terminal and to ensure that
+ * aria updates make it to the screen reader. We want this to be short so
+ * there's not a big delay between typing/executing commands and hearing output.
+ *
+ * @constant
+ * @type {integer}
+ */
+hterm.AccessibilityReader.DELAY = 50;
+
+/**
+ * Enable accessibility-friendly features that have a performance impact.
+ *
+ * @param {boolean} enabled Whether to enable accessibility-friendly features.
+ */
+hterm.AccessibilityReader.prototype.setAccessibilityEnabled =
+    function(enabled) {
+  if (!enabled) {
+    this.clear();
+  }
+
+  this.accessibilityEnabled = enabled;
+};
+
+/**
+ * Decorate the document where the terminal <x-screen> resides. This is needed
+ * for listening to keystrokes on the screen.
+ *
+ * @param {HTMLDocument} doc The document where the <x-screen> resides.
+ */
+hterm.AccessibilityReader.prototype.decorate = function(doc) {
+  const handlers = ['keydown', 'keypress', 'keyup', 'textInput'];
+  handlers.forEach((handler) => {
+    doc.addEventListener(handler, () => { this.hasUserGesture = true; });
+  });
+};
+
+/**
+ * This should be called before the cursor on the screen is about to get
+ * updated. This allows cursor changes to be tracked and related notifications
+ * to be announced.
+ *
+ * @param {string} cursorRowString The text in the row that the cursor is
+ *     currently on.
+ * @param {integer} cursorRow The index of the row that the cursor is currently
+ *     on, including rows in the scrollback buffer.
+ * @param {integer} cursorColumn The index of the column that the cursor is
+ *     currently on.
+ */
+hterm.AccessibilityReader.prototype.beforeCursorChange =
+    function(cursorRowString, cursorRow, cursorColumn) {
+  // If accessibility is enabled we don't announce selection changes as these
+  // can have a performance impact.
+  if (!this.accessibilityEnabled) {
+    return;
+  }
+
+  // If there is no user gesture that can be tied to the cursor change, we
+  // don't want to announce anything.
+  if (!this.hasUserGesture || this.cursorIsChanging_) {
+    return;
+  }
+
+  this.cursorIsChanging_ = true;
+  this.lastCursorRowString_ = cursorRowString;
+  this.lastCursorRow_ = cursorRow;
+  this.lastCursorColumn_ = cursorColumn;
+};
+
+/**
+ * This should be called after the cursor on the screen has been updated. Note
+ * that several updates to the cursor may have happened between
+ * beforeCursorChange and afterCursorChange.
+ *
+ * This allows cursor changes to be tracked and related notifications to be
+ * announced.
+ *
+ * @param {string} cursorRowString The text in the row that the cursor is
+ *     currently on.
+ * @param {integer} cursorRow The index of the row that the cursor is currently
+ *     on, including rows in the scrollback buffer.
+ * @param {integer} cursorColumn The index of the column that the cursor is
+ *     currently on.
+ */
+hterm.AccessibilityReader.prototype.afterCursorChange =
+    function(cursorRowString, cursorRow, cursorColumn) {
+  // This can happen if clear() is called midway through a cursor change.
+  if (!this.cursorIsChanging_) {
+    return;
+  }
+  this.cursorIsChanging_ = false;
+
+  if (!this.announceAction_(cursorRowString, cursorRow, cursorColumn)) {
+    // If we don't announce a special action, we re-queue all the output that
+    // was queued during the selection change.
+    for (let i = 0; i < this.cursorChangeQueue_.length; ++i) {
+      this.announce(this.cursorChangeQueue_[i]);
+    }
+  }
+
+  this.cursorChangeQueue_ = [];
+  this.lastCursorRowString_ = null;
+  this.lastCursorRow_ = null;
+  this.lastCursorColumn_ = null;
+  this.hasUserGesture = false;
+};
+
+/**
+ * Announce the command output.
+ *
+ * @param {string} str The string to announce using a live region.
+ */
+hterm.AccessibilityReader.prototype.announce = function(str) {
+  if (!this.accessibilityEnabled) {
+    return;
+  }
+
+  // If the cursor is in the middle of changing, we queue up the output
+  // separately as we may not want it to be announced if it's part of a cursor
+  // change announcement.
+  if (this.cursorIsChanging_) {
+    this.cursorChangeQueue_.push(str);
+    return;
+  }
+
+  // Don't append newlines to the queue if the queue is empty. It won't have any
+  // impact.
+  if (str == '\n' && this.queue_.length > 0) {
+    this.queue_.push('');
+    // We don't need to trigger an announcement on newlines because they won't
+    // change the existing content that's output.
+    return;
+  }
+
+  if (this.queue_.length == 0) {
+    this.queue_.push(str);
+  } else {
+    // We put a space between strings that appear on the same line.
+    // TODO(raymes): We should check the location on the row and not add a space
+    // if the strings are joined together.
+    let padding = '';
+    if (this.queue_[this.queue_.length - 1].length != 0) {
+      padding = ' ';
+    }
+    this.queue_[this.queue_.length - 1] += padding + str;
+  }
+
+  // If we've already scheduled text being added to the live region, wait for it
+  // to happen.
+  if (this.nextReadTimer_) {
+    return;
+  }
+
+  // If there's only one item in the queue, we may get other text being added
+  // very soon after. In that case, wait a small delay so we can merge the
+  // related strings.
+  if (this.queue_.length == 1) {
+    this.nextReadTimer_ = setTimeout(this.addToLiveRegion_.bind(this),
+                                     hterm.AccessibilityReader.DELAY);
+  } else {
+    throw new Error(
+        'Expected only one item in queue_ or nextReadTimer_ to be running.');
+  }
+};
+
+/**
+ * Voice an announcement that will interrupt other announcements.
+ *
+ * @param {string} str The string to announce using a live region.
+ */
+hterm.AccessibilityReader.prototype.assertiveAnnounce = function(str) {
+  if (this.hasUserGesture && str == ' ') {
+    str = hterm.msg('SPACE_CHARACTER', [], 'Space');
+  }
+
+  // If the same string is announced twice, an attribute change won't be
+  // registered and the screen reader won't know that the string has changed.
+  // So we slightly change the string to ensure that the attribute change gets
+  // registered.
+  str = str.trim();
+  if (str == this.assertiveLiveElement_.getAttribute('aria-label')) {
+    str = '\n' + str;
+  }
+
+  this.clear();
+  this.assertiveLiveElement_.setAttribute('aria-label', str);
+};
+
+/**
+ * Add a newline to the text that will be announced to the live region.
+ */
+hterm.AccessibilityReader.prototype.newLine = function() {
+  this.announce('\n');
+};
+
+/**
+ * Clear the live region and any in-flight announcements.
+ */
+hterm.AccessibilityReader.prototype.clear = function() {
+  this.liveElement_.setAttribute('aria-label', '');
+  this.assertiveLiveElement_.setAttribute('aria-label', '');
+  clearTimeout(this.nextReadTimer_);
+  this.nextReadTimer_ = null;
+  this.queue_ = [];
+
+  this.cursorIsChanging_ = false;
+  this.cursorChangeQueue_ = [];
+  this.lastCursorRowString_ = null;
+  this.lastCursorRow_ = null;
+  this.lastCursorColumn_ = null;
+  this.hasUserGesture = false;
+};
+
+/**
+ * This will announce an action that is related to a cursor change, for example
+ * when the user deletes a character we want the character deleted to be
+ * announced. Similarly, when the user moves the cursor along the line, we want
+ * the characters selected to be announced.
+ *
+ * Note that this function is a heuristic. Because of the nature of terminal
+ * emulators, we can't distinguish input and output, which means we don't really
+ * know what output is the result of a keypress and what isn't. Also in some
+ * terminal applications certain announcements may make sense whereas others may
+ * not. This function should try to account for the most common cases.
+ *
+ * @param {string} cursorRowString The text in the row that the cursor is
+ *     currently on.
+ * @param {integer} cursorRow The index of the row that the cursor is currently
+ *     on, including rows in the scrollback buffer.
+ * @param {integer} cursorColumn The index of the column that the cursor is
+ *     currently on.
+ */
+hterm.AccessibilityReader.prototype.announceAction_ =
+    function(cursorRowString, cursorRow, cursorColumn) {
+  // If the cursor changes rows, we don't announce anything at present.
+  if (this.lastCursorRow_ != cursorRow) {
+    return false;
+  }
+
+  // The case when the row of text hasn't changed at all.
+  if (this.lastCursorRowString_ == cursorRowString) {
+    // Moving the cursor along the line. We check that no significant changes
+    // have been queued. If they have, it may not just be a cursor movement and
+    // it may be better to read those out.
+    if (this.lastCursorColumn_ != cursorColumn &&
+        this.cursorChangeQueue_.join('').trim() == '') {
+      // Announce the text between the old cursor position and the new one.
+      const start = Math.min(this.lastCursorColumn_, cursorColumn);
+      const len = Math.abs(cursorColumn - this.lastCursorColumn_);
+      this.assertiveAnnounce(
+          lib.wc.substr(this.lastCursorRowString_, start, len));
+      return true;
+    }
+    return false;
+  }
+
+  // The case when the row of text has changed.
+  if (this.lastCursorRowString_ != cursorRowString) {
+    // Spacebar. We manually announce this character since the screen reader may
+    // not announce the whitespace in a live region.
+    if (this.lastCursorColumn_ + 1 == cursorColumn) {
+      if (lib.wc.substr(cursorRowString, cursorColumn - 1, 1) == ' ' &&
+          this.cursorChangeQueue_.length > 0 &&
+          this.cursorChangeQueue_[0] == ' ') {
+        this.assertiveAnnounce(' ');
+        return true;
+      }
+    }
+
+    // Backspace and deletion.
+    // The position of the characters deleted is right after the current
+    // position of the cursor in the case of backspace and delete.
+    const cursorDeleted = cursorColumn;
+    // Check that the current row string is shorter than the previous. Also
+    // check that the start of the strings (up to the cursor) match.
+    if (lib.wc.strWidth(cursorRowString) <=
+        lib.wc.strWidth(this.lastCursorRowString_) &&
+        lib.wc.substr(this.lastCursorRowString_, 0, cursorDeleted) ==
+        lib.wc.substr(cursorRowString, 0, cursorDeleted)) {
+      // Find the length of the current row string ignoring space characters.
+      // These may be inserted at the end of the string when deleting characters
+      // so they should be ignored.
+      let lengthOfCurrentRow = lib.wc.strWidth(cursorRowString);
+      for (; lengthOfCurrentRow > 0; --lengthOfCurrentRow) {
+        if (lengthOfCurrentRow == cursorDeleted ||
+            lib.wc.substr(cursorRowString, lengthOfCurrentRow - 1, 1) != ' ') {
+          break;
+        }
+      }
+
+      const numCharsDeleted =
+          lib.wc.strWidth(this.lastCursorRowString_) - lengthOfCurrentRow;
+
+      // Check that the end of the strings match.
+      const lengthOfEndOfString = lengthOfCurrentRow - cursorDeleted;
+      const endOfLastRowString = lib.wc.substr(
+          this.lastCursorRowString_, cursorDeleted + numCharsDeleted,
+          lengthOfEndOfString);
+      const endOfCurrentRowString =
+          lib.wc.substr(cursorRowString, cursorDeleted, lengthOfEndOfString);
+      if (endOfLastRowString == endOfCurrentRowString) {
+        const deleted = lib.wc.substr(
+            this.lastCursorRowString_, cursorDeleted, numCharsDeleted);
+        if (deleted != '') {
+          this.assertiveAnnounce(deleted);
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  return false;
+};
+
+/**
+ * Add text from queue_ to the live region.
+ *
+ */
+hterm.AccessibilityReader.prototype.addToLiveRegion_ = function() {
+  this.nextReadTimer_ = null;
+
+  let str = this.queue_.join('\n').trim();
+
+  // If the same string is announced twice, an attribute change won't be
+  // registered and the screen reader won't know that the string has changed.
+  // So we slightly change the string to ensure that the attribute change gets
+  // registered.
+  if (str == this.liveElement_.getAttribute('aria-label')) {
+    str = '\n' + str;
+  }
+
+  this.liveElement_.setAttribute('aria-label', str);
+  this.queue_ = [];
+};
+// SOURCE FILE: hterm/js/hterm_contextmenu.js
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Context menu handling.
+ */
+
+/**
+ * Manage the context menu usually shown when right clicking.
+ */
+hterm.ContextMenu = function() {
+  // The document that contains this context menu.
+  this.document_ = null;
+  // The generated context menu (i.e. HTML elements).
+  this.element_ = null;
+  // The structured menu (i.e. JS objects).
+  this.menu_ = [];
+};
+
+/**
+ * Constant to add a separator to the context menu.
+ */
+hterm.ContextMenu.SEPARATOR = {};
+
+/**
+ * Bind context menu to a specific document element.
+ *
+ * @param {HTMLDocument} document The document to use when creating elements.
+ */
+hterm.ContextMenu.prototype.setDocument = function(document) {
+  if (this.element_) {
+    this.element_.remove();
+    this.element_ = null;
+  }
+  this.document_ = document;
+  this.regenerate_();
+  this.document_.body.appendChild(this.element_);
+};
+
+/**
+ * Regenerate the HTML elements based on internal menu state.
+ */
+hterm.ContextMenu.prototype.regenerate_ = function() {
+  if (!this.element_) {
+    this.element_ = this.document_.createElement('menu');
+    this.element_.id = 'hterm:context-menu';
+    this.element_.style.cssText = `
+        display: none;
+        border: solid 1px;
+        position: absolute;
+    `;
+  } else {
+    this.hide();
+  }
+
+  // Clear out existing menu entries.
+  while (this.element_.firstChild) {
+    this.element_.removeChild(this.element_.firstChild);
+  }
+
+  this.menu_.forEach(([name, action]) => {
+    const menuitem = this.document_.createElement('menuitem');
+    if (name === hterm.ContextMenu.SEPARATOR) {
+      menuitem.innerHTML = '<hr>';
+      menuitem.className = 'separator';
+    } else {
+      menuitem.innerText = name;
+      menuitem.addEventListener('mousedown', function(e) {
+        e.preventDefault();
+        action(e);
+      });
+    }
+    this.element_.appendChild(menuitem);
+  });
+};
+
+/**
+ * Set all the entries in the context menu.
+ *
+ * This is an array of arrays.  The first element in the array is the string to
+ * display while the second element is the function to call.
+ *
+ * The first element may also be the SEPARATOR constant to add a separator.
+ *
+ * This resets all existing menu entries.
+ *
+ * @param {Array<Array<string, function(Event)>>} items The menu entries.
+ */
+hterm.ContextMenu.prototype.setItems = function(items) {
+  this.menu_ = items;
+  this.regenerate_();
+};
+
+/**
+ * Show the context menu.
+ *
+ * The event is used to determine where to show the menu.
+ *
+ * If no menu entries are defined, then nothing will be shown.
+ *
+ * @param {Event} e The event triggering this display.
+ * @param {hterm.Terminal=} terminal The terminal object to get style info from.
+ */
+hterm.ContextMenu.prototype.show = function(e, terminal) {
+  // If there are no menu entries, then don't try to show anything.
+  if (this.menu_.length == 0) {
+    return;
+  }
+
+  // If we have the terminal, sync the style preferences over.
+  if (terminal) {
+    this.element_.style.backgroundColor = terminal.getBackgroundColor();
+    this.element_.style.color = terminal.getForegroundColor();
+    this.element_.style.fontSize = terminal.getFontSize();
+    this.element_.style.fontFamily = terminal.getFontFamily();
+  }
+
+  this.element_.style.top = `${e.clientY}px`;
+  this.element_.style.left = `${e.clientX}px`;
+  const docSize = hterm.getClientSize(this.document_.body);
+
+  this.element_.style.display = 'block';
+
+  // We can't calculate sizes until after it's displayed.
+  const eleSize = hterm.getClientSize(this.element_);
+  // Make sure the menu isn't clipped outside of the current element.
+  const minY = Math.max(0, docSize.height - eleSize.height);
+  const minX = Math.max(0, docSize.width - eleSize.width);
+  if (minY < e.clientY) {
+    this.element_.style.top = `${minY}px`;
+  }
+  if (minX < e.clientX) {
+    this.element_.style.left = `${minX}px`;
+  }
+};
+
+/**
+ * Hide the context menu.
+ */
+hterm.ContextMenu.prototype.hide = function() {
+  if (!this.element_) {
+    return;
+  }
+
+  this.element_.style.display = 'none';
+};
+// SOURCE FILE: hterm/js/hterm_frame.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * First draft of the interface between the terminal and a third party dialog.
+ *
+ * This is rough.  It's just the terminal->dialog layer.  To complete things
+ * we'll also need a command->terminal layer.  That will have to facilitate
+ * command->terminal->dialog or direct command->dialog communication.
+ *
+ * I imagine this class will change significantly when that happens.
+ */
+
+/**
+ * Construct a new frame for the given terminal.
+ *
+ * @param terminal {hterm.Terminal} The parent terminal object.
+ * @param url {String} The url to load in the frame.
+ * @param opt_options {Object} Optional options for the frame.  Not implemented.
+ */
+hterm.Frame = function(terminal, url, opt_options) {
+  this.terminal_ = terminal;
+  this.div_ = terminal.div_;
+  this.url = url;
+  this.options = opt_options || {};
+  this.iframe_ = null;
+  this.container_ = null;
+  this.messageChannel_ = null;
+};
+
+/**
+ * Handle messages from the iframe.
+ */
+hterm.Frame.prototype.onMessage_ = function(e) {
+  switch (e.data.name) {
+    case 'ipc-init-ok':
+      // We get this response after we send them ipc-init and they finish.
+      this.sendTerminalInfo_();
+      return;
+    case 'terminal-info-ok':
+      // We get this response after we send them terminal-info and they finish.
+      // Show the finished frame, and then rebind our message handler to the
+      // callback below.
+      this.container_.style.display = 'flex';
+      this.postMessage('visible');
+      this.messageChannel_.port1.onmessage = this.onMessage.bind(this);
+      this.onLoad();
+      return;
+    default:
+      console.log('Unknown message from frame:', e.data);
+      return;
+  }
+};
+
+/**
+ * Clients could override this, I guess.
+ *
+ * It doesn't support multiple listeners, but I'm not sure that would make sense
+ * here.  It's probably better to speak directly to our parents.
+ */
+hterm.Frame.prototype.onMessage = function() {};
+
+/**
+ * Handle iframe onLoad event.
+ */
+hterm.Frame.prototype.onLoad_ = function() {
+  this.messageChannel_ = new MessageChannel();
+  this.messageChannel_.port1.onmessage = this.onMessage_.bind(this);
+  this.messageChannel_.port1.start();
+  this.iframe_.contentWindow.postMessage(
+      {name: 'ipc-init', argv: [{messagePort: this.messageChannel_.port2}]},
+      this.url, [this.messageChannel_.port2]);
+};
+
+/**
+ * Clients may override this.
+ */
+hterm.Frame.prototype.onLoad = function() {};
+
+/**
+ * Sends the terminal-info message to the iframe.
+ */
+hterm.Frame.prototype.sendTerminalInfo_ = function() {
+  lib.i18n.getAcceptLanguages(function(languages) {
+      this.postMessage('terminal-info', [{
+         acceptLanguages: languages,
+         foregroundColor: this.terminal_.getForegroundColor(),
+         backgroundColor: this.terminal_.getBackgroundColor(),
+         cursorColor: this.terminal_.getCursorColor(),
+         fontSize: this.terminal_.getFontSize(),
+         fontFamily: this.terminal_.getFontFamily(),
+         baseURL: lib.f.getURL('/')
+          }]
+        );
+    }.bind(this));
+};
+
+/**
+ * User clicked the close button on the frame decoration.
+ */
+hterm.Frame.prototype.onCloseClicked_ = function() {
+  this.close();
+};
+
+/**
+ * Close this frame.
+ */
+hterm.Frame.prototype.close = function() {
+  if (!this.container_ || !this.container_.parentNode)
+      return;
+
+  this.container_.parentNode.removeChild(this.container_);
+  this.onClose();
+};
+
+
+/**
+ * Clients may override this.
+ */
+hterm.Frame.prototype.onClose = function() {};
+
+/**
+ * Send a message to the iframe.
+ */
+hterm.Frame.prototype.postMessage = function(name, argv) {
+  if (!this.messageChannel_)
+    throw new Error('Message channel is not set up.');
+
+  this.messageChannel_.port1.postMessage({name: name, argv: argv});
+};
+
+/**
+ * Show the UI for this frame.
+ *
+ * The iframe src is not loaded until this method is called.
+ */
+hterm.Frame.prototype.show = function() {
+  var self = this;
+
+  function opt(name, defaultValue) {
+    if (name in self.options)
+      return self.options[name];
+
+    return defaultValue;
+  }
+
+  var self = this;
+
+  if (this.container_ && this.container_.parentNode) {
+    console.error('Frame already visible');
+    return;
+  }
+
+  var headerHeight = '16px';
+
+  var divSize = hterm.getClientSize(this.div_);
+
+  var width = opt('width', 640);
+  var height = opt('height', 480);
+  var left = (divSize.width - width) / 2;
+  var top = (divSize.height - height) / 2;
+
+  var document = this.terminal_.document_;
+
+  var container = this.container_ = document.createElement('div');
+  container.style.cssText = (
+      'position: absolute;' +
+      'display: none;' +
+      'flex-direction: column;' +
+      'top: 10%;' +
+      'left: 4%;' +
+      'width: 90%;' +
+      'height: 80%;' +
+      'min-height: 20%;' +
+      'max-height: 80%;' +
+      'box-shadow: 0 0 2px ' + this.terminal_.getForegroundColor() + ';' +
+      'border: 2px ' + this.terminal_.getForegroundColor() + ' solid;');
+
+  if (false) {
+    // No use for the close button, so no use for the window header either.
+    var header = document.createElement('div');
+    header.style.cssText = (
+        'display: flex;' +
+        'justify-content: flex-end;' +
+        'height: ' + headerHeight + ';' +
+        'background-color: ' + this.terminal_.getForegroundColor() + ';' +
+        'color: ' + this.terminal_.getBackgroundColor() + ';' +
+        'font-size: 16px;' +
+        'font-family: ' + this.terminal_.getFontFamily());
+    container.appendChild(header);
+
+    var button = document.createElement('div');
+    button.setAttribute('role', 'button');
+    button.style.cssText = (
+        'margin-top: -3px;' +
+        'margin-right: 3px;' +
+        'cursor: pointer;');
+    button.textContent = '\u2a2f';
+    button.addEventListener('click', this.onCloseClicked_.bind(this));
+    header.appendChild(button);
+  }
+
+  var iframe = this.iframe_ = document.createElement('iframe');
+  iframe.onload = this.onLoad_.bind(this);
+  iframe.style.cssText = (
+      'display: flex;' +
+      'flex: 1;' +
+      'width: 100%');
+  iframe.setAttribute('src', this.url);
+  iframe.setAttribute('seamless', true);
+  container.appendChild(iframe);
+
+  this.div_.appendChild(container);
+};
+// SOURCE FILE: hterm/js/hterm_keyboard.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Keyboard handler.
+ *
+ * Consumes onKey* events and invokes onVTKeystroke on the associated
+ * hterm.Terminal object.
+ *
+ * See also: [XTERM] as referenced in vt.js.
+ *
+ * @param {hterm.Terminal} The Terminal object associated with this keyboard.
+ */
+hterm.Keyboard = function(terminal) {
+  // The parent vt interpreter.
+  this.terminal = terminal;
+
+  // The element we're currently capturing keyboard events for.
+  this.keyboardElement_ = null;
+
+  // The event handlers we are interested in, and their bound callbacks, saved
+  // so they can be uninstalled with removeEventListener, when required.
+  this.handlers_ = [
+      ['focusout', this.onFocusOut_.bind(this)],
+      ['keydown', this.onKeyDown_.bind(this)],
+      ['keypress', this.onKeyPress_.bind(this)],
+      ['keyup', this.onKeyUp_.bind(this)],
+      ['textInput', this.onTextInput_.bind(this)]
+  ];
+
+  /**
+   * The current key map.
+   */
+  this.keyMap = new hterm.Keyboard.KeyMap(this);
+
+  this.bindings = new hterm.Keyboard.Bindings(this);
+
+  /**
+   * none: Disable any AltGr related munging.
+   * ctrl-alt: Assume Ctrl+Alt means AltGr.
+   * left-alt: Assume left Alt means AltGr.
+   * right-alt: Assume right Alt means AltGr.
+   */
+  this.altGrMode = 'none';
+
+  /**
+   * If true, Shift-Insert will fall through to the browser as a paste.
+   * If false, the keystroke will be sent to the host.
+   */
+  this.shiftInsertPaste = true;
+
+  /**
+   * If true, home/end will control the terminal scrollbar and shift home/end
+   * will send the VT keycodes.  If false then home/end sends VT codes and
+   * shift home/end scrolls.
+   */
+  this.homeKeysScroll = false;
+
+  /**
+   * Same as above, except for page up/page down.
+   */
+  this.pageKeysScroll = false;
+
+  /**
+   * If true, Ctrl-Plus/Minus/Zero controls zoom.
+   * If false, Ctrl-Shift-Plus/Minus/Zero controls zoom, Ctrl-Minus sends ^_,
+   * Ctrl-Plus/Zero do nothing.
+   */
+  this.ctrlPlusMinusZeroZoom = true;
+
+  /**
+   * Ctrl+C copies if true, sends ^C to host if false.
+   * Ctrl+Shift+C sends ^C to host if true, copies if false.
+   */
+  this.ctrlCCopy = false;
+
+  /**
+   * Ctrl+V pastes if true, sends ^V to host if false.
+   * Ctrl+Shift+V sends ^V to host if true, pastes if false.
+   */
+  this.ctrlVPaste = false;
+
+  /**
+   * Enable/disable application keypad.
+   *
+   * This changes the way numeric keys are sent from the keyboard.
+   */
+  this.applicationKeypad = false;
+
+  /**
+   * Enable/disable the application cursor mode.
+   *
+   * This changes the way cursor keys are sent from the keyboard.
+   */
+  this.applicationCursor = false;
+
+  /**
+   * If true, the backspace should send BS ('\x08', aka ^H).  Otherwise
+   * the backspace key should send '\x7f'.
+   */
+  this.backspaceSendsBackspace = false;
+
+  /**
+   * Set whether the meta key sends a leading escape or not.
+   */
+  this.metaSendsEscape = true;
+
+  /**
+   * Set whether meta-V gets passed to host.
+   */
+  this.passMetaV = true;
+
+  /**
+   * Controls how the alt key is handled.
+   *
+   *  escape....... Send an ESC prefix.
+   *  8-bit........ Add 128 to the unshifted character as in xterm.
+   *  browser-key.. Wait for the keypress event and see what the browser says.
+   *                (This won't work well on platforms where the browser
+   *                 performs a default action for some alt sequences.)
+   *
+   * This setting only matters when alt is distinct from meta (altIsMeta is
+   * false.)
+   */
+  this.altSendsWhat = 'escape';
+
+  /**
+   * Set whether the alt key acts as a meta key, instead of producing 8-bit
+   * characters.
+   *
+   * True to enable, false to disable, null to autodetect based on platform.
+   */
+  this.altIsMeta = false;
+
+  /**
+   * If true, tries to detect DEL key events that are from alt-backspace on
+   * Chrome OS vs from a true DEL key press.
+   *
+   * Background: At the time of writing, on Chrome OS, alt-backspace is mapped
+   * to DEL. Some users may be happy with this, but others may be frustrated
+   * that it's impossible to do meta-backspace. If the user enables this pref,
+   * we use a trick to tell a true DEL keypress from alt-backspace: on
+   * alt-backspace, we will see the alt key go down, then get a DEL keystroke
+   * that indicates that alt is not pressed. See https://crbug.com/174410 .
+   */
+  this.altBackspaceIsMetaBackspace = false;
+
+  /**
+   * Used to keep track of the current alt-key state, which is necessary for
+   * the altBackspaceIsMetaBackspace preference above and for the altGrMode
+   * preference.  This is a bitmap with where bit positions correspond to the
+   * "location" property of the key event.
+   */
+  this.altKeyPressed = 0;
+
+  /**
+   * If true, Chrome OS media keys will be mapped to their F-key equivalent.
+   * E.g. "Back" will be mapped to F1. If false, Chrome will handle the keys.
+   */
+  this.mediaKeysAreFKeys = false;
+
+  /**
+   * Holds the previous setting of altSendsWhat when DECSET 1039 is used. When
+   * DECRST 1039 is used, altSendsWhat is changed back to this and this is
+   * nulled out.
+   */
+  this.previousAltSendsWhat_ = null;
+};
+
+/**
+ * Special handling for keyCodes in a keyboard layout.
+ */
+hterm.Keyboard.KeyActions = {
+  /**
+   * Call preventDefault and stopPropagation for this key event and nothing
+   * else.
+   */
+  CANCEL: Symbol('CANCEL'),
+
+  /**
+   * This performs the default terminal action for the key.  If used in the
+   * 'normal' action and the the keystroke represents a printable key, the
+   * character will be sent to the host.  If used in one of the modifier
+   * actions, the terminal will perform the normal action after (possibly)
+   * altering it.
+   *
+   *  - If the normal sequence starts with CSI, the sequence will be adjusted
+   *    to include the modifier parameter as described in [XTERM] in the final
+   *    table of the "PC-Style Function Keys" section.
+   *
+   *  - If the control key is down and the key represents a printable character,
+   *    and the uppercase version of the unshifted keycap is between
+   *    64 (ASCII '@') and 95 (ASCII '_'), then the uppercase version of the
+   *    unshifted keycap minus 64 is sent.  This makes '^@' send '\x00' and
+   *    '^_' send '\x1f'.  (Note that one higher that 0x1f is 0x20, which is
+   *    the first printable ASCII value.)
+   *
+   *  - If the alt key is down and the key represents a printable character then
+   *    the value of the character is shifted up by 128.
+   *
+   *  - If meta is down and configured to send an escape, '\x1b' will be sent
+   *    before the normal action is performed.
+   */
+  DEFAULT: Symbol('DEFAULT'),
+
+  /**
+   * Causes the terminal to opt out of handling the key event, instead letting
+   * the browser deal with it.
+   */
+  PASS: Symbol('PASS'),
+
+  /**
+   * Insert the first or second character of the keyCap, based on e.shiftKey.
+   * The key will be handled in onKeyDown, and e.preventDefault() will be
+   * called.
+   *
+   * It is useful for a modified key action, where it essentially strips the
+   * modifier while preventing the browser from reacting to the key.
+   */
+  STRIP: Symbol('STRIP')
+};
+
+/**
+ * Capture keyboard events sent to the associated element.
+ *
+ * This enables the keyboard.  Captured events are consumed by this class
+ * and will not perform their default action or bubble to other elements.
+ *
+ * Passing a null element will uninstall the keyboard handlers.
+ *
+ * @param {HTMLElement} element The element whose events should be captured, or
+ *     null to disable the keyboard.
+ */
+hterm.Keyboard.prototype.installKeyboard = function(element) {
+  if (element == this.keyboardElement_)
+    return;
+
+  if (element && this.keyboardElement_)
+    this.installKeyboard(null);
+
+  for (var i = 0; i < this.handlers_.length; i++) {
+    var handler = this.handlers_[i];
+    if (element) {
+      element.addEventListener(handler[0], handler[1]);
+    } else {
+      this.keyboardElement_.removeEventListener(handler[0], handler[1]);
+    }
+  }
+
+  this.keyboardElement_ = element;
+};
+
+/**
+ * Disable keyboard event capture.
+ *
+ * This will allow the browser to process key events normally.
+ */
+hterm.Keyboard.prototype.uninstallKeyboard = function() {
+  this.installKeyboard(null);
+};
+
+/**
+ * Handle onTextInput events.
+ *
+ * These are generated when using IMEs, Virtual Keyboards (VKs), compose keys,
+ * Unicode input, etc...
+ */
+hterm.Keyboard.prototype.onTextInput_ = function(e) {
+  if (!e.data)
+    return;
+
+  // Just pass the generated buffer straight down.  No need for us to split it
+  // up or otherwise parse it ahead of times.
+  this.terminal.onVTKeystroke(e.data);
+};
+
+/**
+ * Handle onKeyPress events.
+ *
+ * TODO(vapier): Drop this event entirely and only use keydown.
+ */
+hterm.Keyboard.prototype.onKeyPress_ = function(e) {
+  // FF doesn't set keyCode reliably in keypress events.  Stick to the which
+  // field here until we can move to keydown entirely.
+  const key = String.fromCharCode(e.which).toLowerCase();
+  if ((e.ctrlKey || e.metaKey) && (key == 'c' || key == 'v')) {
+    // On FF the key press (not key down) event gets fired for copy/paste.
+    // Let it fall through for the default browser behavior.
+    return;
+  }
+
+  if (e.keyCode == 9 /* Tab */) {
+    // On FF, a key press event will be fired in addition of key down for the
+    // Tab key if key down isn't handled. This would only happen if a custom
+    // PASS binding has been created and therefore this should be handled by the
+    // browser.
+    return;
+  }
+
+  if (e.altKey && this.altSendsWhat == 'browser-key' && e.charCode == 0) {
+    // If we got here because we were expecting the browser to handle an
+    // alt sequence but it didn't do it, then we might be on an OS without
+    // an enabled IME system.  In that case we fall back to xterm-like
+    // behavior.
+    //
+    // This happens here only as a fallback.  Typically these platforms should
+    // set altSendsWhat to either 'escape' or '8-bit'.
+    var ch = String.fromCharCode(e.keyCode);
+    if (!e.shiftKey)
+      ch = ch.toLowerCase();
+
+  } else if (e.charCode >= 32) {
+    ch = e.charCode;
+  }
+
+  if (ch)
+    this.terminal.onVTKeystroke(String.fromCharCode(ch));
+
+  e.preventDefault();
+  e.stopPropagation();
+};
+
+/**
+ * Prevent default handling for non-ctrl-shifted event.
+ *
+ * When combined with Chrome permission 'app.window.fullscreen.overrideEsc',
+ * and called for both key down and key up events,
+ * the ESC key remains usable within fullscreen Chrome app windows.
+ */
+hterm.Keyboard.prototype.preventChromeAppNonCtrlShiftDefault_ = function(e) {
+  if (!window.chrome || !window.chrome.app || !window.chrome.app.window)
+    return;
+  if (!e.ctrlKey || !e.shiftKey)
+    e.preventDefault();
+};
+
+hterm.Keyboard.prototype.onFocusOut_ = function(e) {
+  this.altKeyPressed = 0;
+};
+
+hterm.Keyboard.prototype.onKeyUp_ = function(e) {
+  if (e.keyCode == 18)
+    this.altKeyPressed = this.altKeyPressed & ~(1 << (e.location - 1));
+
+  if (e.keyCode == 27)
+    this.preventChromeAppNonCtrlShiftDefault_(e);
+};
+
+/**
+ * Handle onKeyDown events.
+ */
+hterm.Keyboard.prototype.onKeyDown_ = function(e) {
+  if (e.keyCode == 18)
+    this.altKeyPressed = this.altKeyPressed | (1 << (e.location - 1));
+
+  if (e.keyCode == 27)
+    this.preventChromeAppNonCtrlShiftDefault_(e);
+
+  var keyDef = this.keyMap.keyDefs[e.keyCode];
+  if (!keyDef) {
+    // If this key hasn't been explicitly registered, fall back to the unknown
+    // key mapping (keyCode == 0), and then automatically register it to avoid
+    // any further warnings here.
+    console.warn(`No definition for key ${e.key} (keyCode ${e.keyCode})`);
+    keyDef = this.keyMap.keyDefs[0];
+    this.keyMap.addKeyDef(e.keyCode, keyDef);
+  }
+
+  // The type of action we're going to use.
+  var resolvedActionType = null;
+
+  var self = this;
+  function getAction(name) {
+    // Get the key action for the given action name.  If the action is a
+    // function, dispatch it.  If the action defers to the normal action,
+    // resolve that instead.
+
+    resolvedActionType = name;
+
+    var action = keyDef[name];
+    if (typeof action == 'function')
+      action = action.apply(self.keyMap, [e, keyDef]);
+
+    if (action === DEFAULT && name != 'normal')
+      action = getAction('normal');
+
+    return action;
+  }
+
+  // Note that we use the triple-equals ('===') operator to test equality for
+  // these constants, in order to distinguish usage of the constant from usage
+  // of a literal string that happens to contain the same bytes.
+  var CANCEL = hterm.Keyboard.KeyActions.CANCEL;
+  var DEFAULT = hterm.Keyboard.KeyActions.DEFAULT;
+  var PASS = hterm.Keyboard.KeyActions.PASS;
+  var STRIP = hterm.Keyboard.KeyActions.STRIP;
+
+  var control = e.ctrlKey;
+  var alt = this.altIsMeta ? false : e.altKey;
+  var meta = this.altIsMeta ? (e.altKey || e.metaKey) : e.metaKey;
+
+  // In the key-map, we surround the keyCap for non-printables in "[...]"
+  var isPrintable = !(/^\[\w+\]$/.test(keyDef.keyCap));
+
+  switch (this.altGrMode) {
+    case 'ctrl-alt':
+    if (isPrintable && control && alt) {
+      // ctrl-alt-printable means altGr.  We clear out the control and
+      // alt modifiers and wait to see the charCode in the keydown event.
+      control = false;
+      alt = false;
+    }
+    break;
+
+    case 'right-alt':
+    if (isPrintable && (this.terminal.keyboard.altKeyPressed & 2)) {
+      control = false;
+      alt = false;
+    }
+    break;
+
+    case 'left-alt':
+    if (isPrintable && (this.terminal.keyboard.altKeyPressed & 1)) {
+      control = false;
+      alt = false;
+    }
+    break;
+  }
+
+  var action;
+
+  if (control) {
+    action = getAction('control');
+  } else if (alt) {
+    action = getAction('alt');
+  } else if (meta) {
+    action = getAction('meta');
+  } else {
+    action = getAction('normal');
+  }
+
+  // If e.maskShiftKey was set (during getAction) it means the shift key is
+  // already accounted for in the action, and we should not act on it any
+  // further. This is currently only used for Ctrl-Shift-Tab, which should send
+  // "CSI Z", not "CSI 1 ; 2 Z".
+  var shift = !e.maskShiftKey && e.shiftKey;
+
+  var keyDown = {
+    keyCode: e.keyCode,
+    shift: e.shiftKey, // not `var shift` from above.
+    ctrl: control,
+    alt: alt,
+    meta: meta
+  };
+
+  var binding = this.bindings.getBinding(keyDown);
+
+  if (binding) {
+    // Clear out the modifier bits so we don't try to munge the sequence
+    // further.
+    shift = control = alt = meta = false;
+    resolvedActionType = 'normal';
+    action = binding.action;
+
+    if (typeof action == 'function')
+      action = action.call(this, this.terminal, keyDown);
+  }
+
+  if (alt && this.altSendsWhat == 'browser-key' && action == DEFAULT) {
+    // When altSendsWhat is 'browser-key', we wait for the keypress event.
+    // In keypress, the browser should have set the event.charCode to the
+    // appropriate character.
+    // TODO(rginda): Character compositions will need some black magic.
+    action = PASS;
+  }
+
+  if (action === PASS || (action === DEFAULT && !(control || alt || meta))) {
+    // If this key is supposed to be handled by the browser, or it is an
+    // unmodified key with the default action, then exit this event handler.
+    // If it's an unmodified key, it'll be handled in onKeyPress where we
+    // can tell for sure which ASCII code to insert.
+    //
+    // This block needs to come before the STRIP test, otherwise we'll strip
+    // the modifier and think it's ok to let the browser handle the keypress.
+    // The browser won't know we're trying to ignore the modifiers and might
+    // perform some default action.
+    return;
+  }
+
+  if (action === STRIP) {
+    alt = control = false;
+    action = keyDef.normal;
+    if (typeof action == 'function')
+      action = action.apply(this.keyMap, [e, keyDef]);
+
+    if (action == DEFAULT && keyDef.keyCap.length == 2)
+      action = keyDef.keyCap.substr((shift ? 1 : 0), 1);
+  }
+
+  e.preventDefault();
+  e.stopPropagation();
+
+  if (action === CANCEL)
+    return;
+
+  if (action !== DEFAULT && typeof action != 'string') {
+    console.warn('Invalid action: ' + JSON.stringify(action));
+    return;
+  }
+
+  // Strip the modifier that is associated with the action, since we assume that
+  // modifier has already been accounted for in the action.
+  if (resolvedActionType == 'control') {
+    control = false;
+  } else if (resolvedActionType == 'alt') {
+    alt = false;
+  } else if (resolvedActionType == 'meta') {
+    meta = false;
+  }
+
+  if (typeof action == 'string' && action.substr(0, 2) == '\x1b[' &&
+      (alt || control || shift || meta)) {
+    // The action is an escape sequence that and it was triggered in the
+    // presence of a keyboard modifier, we may need to alter the action to
+    // include the modifier before sending it.
+
+    // The math is funky but aligns w/xterm.
+    let imod = 1;
+    if (shift)
+      imod += 1;
+    if (alt)
+      imod += 2;
+    if (control)
+      imod += 4;
+    if (meta)
+      imod += 8;
+    let mod = ';' + imod;
+
+    if (action.length == 3) {
+      // Some of the CSI sequences have zero parameters unless modified.
+      action = '\x1b[1' + mod + action.substr(2, 1);
+    } else {
+      // Others always have at least one parameter.
+      action = action.substr(0, action.length - 1) + mod +
+          action.substr(action.length - 1);
+    }
+
+  } else {
+    if (action === DEFAULT) {
+      action = keyDef.keyCap.substr((shift ? 1 : 0), 1);
+
+      if (control) {
+        var unshifted = keyDef.keyCap.substr(0, 1);
+        var code = unshifted.charCodeAt(0);
+        if (code >= 64 && code <= 95) {
+          action = String.fromCharCode(code - 64);
+        }
+      }
+    }
+
+    if (alt && this.altSendsWhat == '8-bit' && action.length == 1) {
+      var code = action.charCodeAt(0) + 128;
+      action = String.fromCharCode(code);
+    }
+
+    // We respect alt/metaSendsEscape even if the keymap action was a literal
+    // string.  Otherwise, every overridden alt/meta action would have to
+    // check alt/metaSendsEscape.
+    if ((alt && this.altSendsWhat == 'escape') ||
+        (meta && this.metaSendsEscape)) {
+      action = '\x1b' + action;
+    }
+  }
+
+  this.terminal.onVTKeystroke(action);
+};
+// SOURCE FILE: hterm/js/hterm_keyboard_bindings.js
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * A mapping from hterm.Keyboard.KeyPattern to an action.
+ *
+ * TODO(rginda): For now this bindings code is only used for user overrides.
+ * hterm.Keyboard.KeyMap still handles all of the built-in key mappings.
+ * It'd be nice if we migrated that over to be hterm.Keyboard.Bindings based.
+ */
+hterm.Keyboard.Bindings = function() {
+  this.bindings_ = {};
+};
+
+/**
+ * Remove all bindings.
+ */
+hterm.Keyboard.Bindings.prototype.clear = function () {
+  this.bindings_ = {};
+};
+
+/**
+ * Add a new binding.
+ *
+ * Internal API that assumes parsed objects as inputs.
+ * See the public addBinding for more details.
+ *
+ * @param {hterm.Keyboard.KeyPattern} keyPattern
+ * @param {string|function|hterm.Keyboard.KeyAction} action
+ */
+hterm.Keyboard.Bindings.prototype.addBinding_ = function(keyPattern, action) {
+  var binding = null;
+  var list = this.bindings_[keyPattern.keyCode];
+  if (list) {
+    for (var i = 0; i < list.length; i++) {
+      if (list[i].keyPattern.matchKeyPattern(keyPattern)) {
+        binding = list[i];
+        break;
+      }
+    }
+  }
+
+  if (binding) {
+    binding.action = action;
+  } else {
+    binding = {keyPattern: keyPattern, action: action};
+
+    if (!list) {
+      this.bindings_[keyPattern.keyCode] = [binding];
+    } else {
+      this.bindings_[keyPattern.keyCode].push(binding);
+
+      list.sort(function(a, b) {
+        return hterm.Keyboard.KeyPattern.sortCompare(
+            a.keyPattern, b.keyPattern);
+      });
+    }
+  }
+};
+
+/**
+ * Add a new binding.
+ *
+ * If a binding for the keyPattern already exists it will be overridden.
+ *
+ * More specific keyPatterns take precedence over those with wildcards.  Given
+ * bindings for "Ctrl-A" and "Ctrl-*-A", and a "Ctrl-A" keydown, the "Ctrl-A"
+ * binding will match even if "Ctrl-*-A" was created last.
+ *
+ * If action is a string, it will be passed through hterm.Parser.parseKeyAction.
+ *
+ * For example:
+ *   // Will replace Ctrl-P keystrokes with the string "hiya!".
+ *   addBinding('Ctrl-P', "'hiya!'");
+ *   // Will cancel the keystroke entirely (make it do nothing).
+ *   addBinding('Alt-D', hterm.Keyboard.KeyActions.CANCEL);
+ *   // Will execute the code and return the action.
+ *   addBinding('Ctrl-T', function() {
+ *     console.log('Got a T!');
+ *     return hterm.Keyboard.KeyActions.PASS;
+ *   });
+ *
+ * @param {string|hterm.Keyboard.KeyPattern} keyPattern
+ * @param {string|function|hterm.Keyboard.KeyAction} action
+ */
+hterm.Keyboard.Bindings.prototype.addBinding = function(key, action) {
+  // If we're given a hterm.Keyboard.KeyPattern object, pass it down.
+  if (typeof key != 'string') {
+    this.addBinding_(key, action);
+    return;
+  }
+
+  // Here we treat key as a string.
+  var p = new hterm.Parser();
+
+  p.reset(key);
+  var sequence;
+
+  try {
+    sequence = p.parseKeySequence();
+  } catch (ex) {
+    console.error(ex);
+    return;
+  }
+
+  if (!p.isComplete()) {
+    console.error(p.error('Expected end of sequence: ' + sequence));
+    return;
+  }
+
+  // If action is a string, parse it.  Otherwise assume it's callable.
+  if (typeof action == 'string') {
+    p.reset(action);
+    try {
+      action = p.parseKeyAction();
+    } catch (ex) {
+      console.error(ex);
+      return;
+    }
+  }
+
+  if (!p.isComplete()) {
+    console.error(p.error('Expected end of sequence: ' + sequence));
+    return;
+  }
+
+  this.addBinding_(new hterm.Keyboard.KeyPattern(sequence), action);
+};
+
+/**
+ * Add multiple bindings at a time using a map of {string: string, ...}
+ *
+ * This uses hterm.Parser to parse the maps key into KeyPatterns, and the
+ * map values into {string|function|KeyAction}.
+ *
+ * For example:
+ *  {
+ *    // Will replace Ctrl-P keystrokes with the string "hiya!".
+ *    'Ctrl-P': "'hiya!'",
+ *    // Will cancel the keystroke entirely (make it do nothing).
+ *    'Alt-D': hterm.Keyboard.KeyActions.CANCEL,
+ *  }
+ *
+ * @param {Object} map
+ */
+hterm.Keyboard.Bindings.prototype.addBindings = function(map) {
+  for (var key in map) {
+    this.addBinding(key, map[key]);
+  }
+};
+
+/**
+ * Return the binding that is the best match for the given keyDown record,
+ * or null if there is no match.
+ *
+ * @param {Object} keyDown An object with a keyCode property and zero or
+ *   more boolean properties representing key modifiers.  These property names
+ *   must match those defined in hterm.Keyboard.KeyPattern.modifiers.
+ */
+hterm.Keyboard.Bindings.prototype.getBinding = function(keyDown) {
+  var list = this.bindings_[keyDown.keyCode];
+  if (!list)
+    return null;
+
+  for (var i = 0; i < list.length; i++) {
+    var binding = list[i];
+    if (binding.keyPattern.matchKeyDown(keyDown))
+      return binding;
+  }
+
+  return null;
+};
+// SOURCE FILE: hterm/js/hterm_keyboard_keymap.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * The default key map for hterm.
+ *
+ * Contains a mapping of keyCodes to keyDefs (aka key definitions).  The key
+ * definition tells the hterm.Keyboard class how to handle keycodes.
+ *
+ * This should work for most cases, as the printable characters get handled
+ * in the keypress event.  In that case, even if the keycap is wrong in the
+ * key map, the correct character should be sent.
+ *
+ * Different layouts, such as Dvorak should work with this keymap, as those
+ * layouts typically move keycodes around on the keyboard without disturbing
+ * the actual keycaps.
+ *
+ * There may be issues with control keys on non-US keyboards or with keyboards
+ * that very significantly from the expectations here, in which case we may
+ * have to invent new key maps.
+ *
+ * The sequences defined in this key map come from [XTERM] as referenced in
+ * vt.js, starting with the section titled "Alt and Meta Keys".
+ */
+hterm.Keyboard.KeyMap = function(keyboard) {
+  this.keyboard = keyboard;
+  this.keyDefs = {};
+  this.reset();
+};
+
+/**
+ * Add a single key definition.
+ *
+ * The definition is an object containing the following fields: 'keyCap',
+ * 'normal', 'control', 'alt', and 'meta'.
+ *
+ *  - keyCap is a string identifying the key on the keyboard.  For printable
+ *    keys, the key cap should be exactly two characters, starting with the
+ *    unshifted version.  For example, 'aA', 'bB', '1!' and '=+'.  For
+ *    non-printable the key cap should be surrounded in square braces, as in
+ *    '[INS]', '[LEFT]'.  By convention, non-printable keycaps are in uppercase
+ *    but this is not a strict requirement.
+ *
+ *  - Normal is the action that should be performed when the key is pressed
+ *    in the absence of any modifier.  See below for the supported actions.
+ *
+ *  - Control is the action that should be performed when the key is pressed
+ *    along with the control modifier.  See below for the supported actions.
+ *
+ *  - Alt is the action that should be performed when the key is pressed
+ *    along with the alt modifier.  See below for the supported actions.
+ *
+ *  - Meta is the action that should be performed when the key is pressed
+ *    along with the meta modifier.  See below for the supported actions.
+ *
+ * Actions can be one of the hterm.Keyboard.KeyActions as documented below,
+ * a literal string, or an array.  If the action is a literal string then
+ * the string is sent directly to the host.  If the action is an array it
+ * is taken to be an escape sequence that may be altered by modifier keys.
+ * The second-to-last element of the array will be overwritten with the
+ * state of the modifier keys, as specified in the final table of "PC-Style
+ * Function Keys" from [XTERM].
+ */
+hterm.Keyboard.KeyMap.prototype.addKeyDef = function(keyCode, def) {
+  if (keyCode in this.keyDefs)
+    console.warn('Duplicate keyCode: ' + keyCode);
+
+  this.keyDefs[keyCode] = def;
+};
+
+/**
+ * Add multiple key definitions in a single call.
+ *
+ * This function takes the key definitions as variable argument list.  Each
+ * argument is the key definition specified as an array.
+ *
+ * (If the function took everything as one big hash we couldn't detect
+ * duplicates, and there would be a lot more typing involved.)
+ *
+ * Each key definition should have 6 elements: (keyCode, keyCap, normal action,
+ * control action, alt action and meta action).  See KeyMap.addKeyDef for the
+ * meaning of these elements.
+ */
+hterm.Keyboard.KeyMap.prototype.addKeyDefs = function(var_args) {
+  for (var i = 0; i < arguments.length; i++) {
+    this.addKeyDef(arguments[i][0],
+                   { keyCap: arguments[i][1],
+                     normal: arguments[i][2],
+                     control: arguments[i][3],
+                     alt: arguments[i][4],
+                     meta: arguments[i][5]
+                   });
+  }
+};
+
+/**
+ * Set up the default state for this keymap.
+ */
+hterm.Keyboard.KeyMap.prototype.reset = function() {
+  this.keyDefs = {};
+
+  var self = this;
+
+  // This function is used by the "macro" functions below.  It makes it
+  // possible to use the call() macro as an argument to any other macro.
+  function resolve(action, e, k) {
+    if (typeof action == 'function')
+      return action.apply(self, [e, k]);
+
+    return action;
+  }
+
+  // If not application keypad a, else b.  The keys that care about
+  // application keypad ignore it when the key is modified.
+  function ak(a, b) {
+    return function(e, k) {
+      var action = (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey ||
+                    !self.keyboard.applicationKeypad) ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  // If mod or not application cursor a, else b.  The keys that care about
+  // application cursor ignore it when the key is modified.
+  function ac(a, b) {
+    return function(e, k) {
+      var action = (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey ||
+                    !self.keyboard.applicationCursor) ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  // If not backspace-sends-backspace keypad a, else b.
+  function bs(a, b) {
+    return function(e, k) {
+      var action = !self.keyboard.backspaceSendsBackspace ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  // If not e.shiftKey a, else b.
+  function sh(a, b) {
+    return function(e, k) {
+      var action = !e.shiftKey ? a : b;
+      e.maskShiftKey = true;
+      return resolve(action, e, k);
+    };
+  }
+
+  // If not e.altKey a, else b.
+  function alt(a, b) {
+    return function(e, k) {
+      var action = !e.altKey ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  // If no modifiers a, else b.
+  function mod(a, b) {
+    return function(e, k) {
+      var action = !(e.shiftKey || e.ctrlKey || e.altKey || e.metaKey) ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  // Compute a control character for a given character.
+  function ctl(ch) { return String.fromCharCode(ch.charCodeAt(0) - 64); }
+
+  // Call a method on the keymap instance.
+  function c(m) { return function(e, k) { return this[m](e, k); }; }
+
+  // Ignore if not trapping media keys.
+  function med(fn) {
+    return function(e, k) {
+      if (!self.keyboard.mediaKeysAreFKeys) {
+        // Block Back, Forward, and Reload keys to avoid navigating away from
+        // the current page.
+        return (e.keyCode == 166 || e.keyCode == 167 || e.keyCode == 168) ?
+            hterm.Keyboard.KeyActions.CANCEL :
+            hterm.Keyboard.KeyActions.PASS;
+      }
+      return resolve(fn, e, k);
+    };
+  }
+
+  // Browser-specific differences.
+  if (window.navigator && navigator.userAgent) {
+    if (navigator.userAgent.includes('Firefox')) {
+      // Firefox defines some keys uniquely.  No other browser defines these is
+      // this way.  Some even conflict.  The keyCode field isn't well documented
+      // as it isn't standardized.  At some point we should switch to "key".
+      // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
+      // http://unixpapa.com/js/key.html
+      var keycapMute = 181;   // Mute
+      var keycapVolDn = 182;  // Volume Down
+      var keycapVolUp = 183;  // Volume Up
+      var keycapSC = 59;      // ;:
+      var keycapEP = 61;      // =+
+      var keycapMU = 173;     // -_
+
+      this.addKeyDefs(
+        // Firefox Italian +*.
+        [171, '+*', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')]
+      );
+    } else {
+      // All other browsers use these mappings.
+      var keycapMute = 173;   // Mute
+      var keycapVolDn = 174;  // Volume Down
+      var keycapVolUp = 175;  // Volume Up
+      var keycapSC = 186;     // ;:
+      var keycapEP = 187;     // =+
+      var keycapMU = 189;     // -_
+    }
+  }
+
+  var ESC = '\x1b';
+  var CSI = '\x1b[';
+  var SS3 = '\x1bO';
+
+  var CANCEL = hterm.Keyboard.KeyActions.CANCEL;
+  var DEFAULT = hterm.Keyboard.KeyActions.DEFAULT;
+  var PASS = hterm.Keyboard.KeyActions.PASS;
+  var STRIP = hterm.Keyboard.KeyActions.STRIP;
+
+  this.addKeyDefs(
+    // These fields are: [keycode, keycap, normal, control, alt, meta]
+
+    // The browser sends the keycode 0 for some keys.  We'll just assume it's
+    // going to do the right thing by default for those keys.
+    [0,   '[UNKNOWN]', PASS, PASS, PASS, PASS],
+
+    // First row.
+    // These bindings match xterm for lack of a better standard.  The emitted
+    // values might look like they're skipping values, but it's what xterm does.
+    // https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-PC-Style-Function-Keys
+    [27,  '[ESC]', ESC,                       DEFAULT, DEFAULT,     DEFAULT],
+    [112, '[F1]',  mod(SS3 + 'P', CSI + 'P'), DEFAULT, CSI + "23~", DEFAULT],
+    [113, '[F2]',  mod(SS3 + 'Q', CSI + 'Q'), DEFAULT, CSI + "24~", DEFAULT],
+    [114, '[F3]',  mod(SS3 + 'R', CSI + 'R'), DEFAULT, CSI + "25~", DEFAULT],
+    [115, '[F4]',  mod(SS3 + 'S', CSI + 'S'), DEFAULT, CSI + "26~", DEFAULT],
+    [116, '[F5]',  CSI + '15~',               DEFAULT, CSI + "28~", DEFAULT],
+    [117, '[F6]',  CSI + '17~',               DEFAULT, CSI + "29~", DEFAULT],
+    [118, '[F7]',  CSI + '18~',               DEFAULT, CSI + "31~", DEFAULT],
+    [119, '[F8]',  CSI + '19~',               DEFAULT, CSI + "32~", DEFAULT],
+    [120, '[F9]',  CSI + '20~',               DEFAULT, CSI + "33~", DEFAULT],
+    [121, '[F10]', CSI + '21~',               DEFAULT, CSI + "34~", DEFAULT],
+    [122, '[F11]', c('onF11_'),               DEFAULT, CSI + "42~", DEFAULT],
+    [123, '[F12]', CSI + '24~',               DEFAULT, CSI + "43~", DEFAULT],
+
+    // Second row.
+    [192, '`~', DEFAULT, sh(ctl('@'), ctl('^')),     DEFAULT,           PASS],
+    [49,  '1!', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [50,  '2@', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [51,  '3#', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [52,  '4$', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [53,  '5%', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [54,  '6^', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [55,  '7&', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [56,  '8*', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [57,  '9(', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_')],
+    [48,  '0)', DEFAULT, c('onPlusMinusZero_'),c('onAltNum_'),c('onPlusMinusZero_')],
+    [keycapMU, '-_', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')],
+    [keycapEP, '=+', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')],
+
+    [8,   '[BKSP]', bs('\x7f', '\b'), bs('\b', '\x7f'), DEFAULT,     DEFAULT],
+
+    // Third row.
+    [9,   '[TAB]', sh('\t', CSI + 'Z'), STRIP,     PASS,    DEFAULT],
+    [81,  'qQ',    DEFAULT,             ctl('Q'),  DEFAULT, DEFAULT],
+    [87,  'wW',    DEFAULT,             ctl('W'),  DEFAULT, DEFAULT],
+    [69,  'eE',    DEFAULT,             ctl('E'),  DEFAULT, DEFAULT],
+    [82,  'rR',    DEFAULT,             ctl('R'),  DEFAULT, DEFAULT],
+    [84,  'tT',    DEFAULT,             ctl('T'),  DEFAULT, DEFAULT],
+    [89,  'yY',    DEFAULT,             ctl('Y'),  DEFAULT, DEFAULT],
+    [85,  'uU',    DEFAULT,             ctl('U'),  DEFAULT, DEFAULT],
+    [73,  'iI',    DEFAULT,             ctl('I'),  DEFAULT, DEFAULT],
+    [79,  'oO',    DEFAULT,             ctl('O'),  DEFAULT, DEFAULT],
+    [80,  'pP',    DEFAULT,             ctl('P'),  DEFAULT, DEFAULT],
+    [219, '[{',    DEFAULT,             ctl('['),  DEFAULT, DEFAULT],
+    [221, ']}',    DEFAULT,             ctl(']'),  DEFAULT, DEFAULT],
+    [220, '\\|',   DEFAULT,             ctl('\\'), DEFAULT, DEFAULT],
+
+    // Fourth row. We let Ctrl-Shift-J pass for Chrome DevTools.
+    // To be compliant with xterm's behavior for modifiers on Enter
+    // would mean maximizing the window with Alt-Enter... so we don't
+    // want to do that. Our behavior on Enter is what most other
+    // modern emulators do.
+    [20,  '[CAPS]',  PASS,    PASS,                           PASS,    DEFAULT],
+    [65,  'aA',      DEFAULT, ctl('A'),                       DEFAULT, DEFAULT],
+    [83,  'sS',      DEFAULT, ctl('S'),                       DEFAULT, DEFAULT],
+    [68,  'dD',      DEFAULT, ctl('D'),                       DEFAULT, DEFAULT],
+    [70,  'fF',      DEFAULT, ctl('F'),                       DEFAULT, DEFAULT],
+    [71,  'gG',      DEFAULT, ctl('G'),                       DEFAULT, DEFAULT],
+    [72,  'hH',      DEFAULT, ctl('H'),                       DEFAULT, DEFAULT],
+    [74,  'jJ',      DEFAULT, sh(ctl('J'), PASS),             DEFAULT, DEFAULT],
+    [75,  'kK',      DEFAULT, sh(ctl('K'), c('onClear_')),    DEFAULT, DEFAULT],
+    [76,  'lL',      DEFAULT, sh(ctl('L'), PASS),             DEFAULT, DEFAULT],
+    [keycapSC, ';:', DEFAULT, STRIP,                          DEFAULT, DEFAULT],
+    [222, '\'"',     DEFAULT, STRIP,                          DEFAULT, DEFAULT],
+    [13,  '[ENTER]', '\r',    DEFAULT,                        DEFAULT, DEFAULT],
+
+    // Fifth row.  This includes the copy/paste shortcuts.  On some
+    // platforms it's Ctrl-C/V, on others it's Meta-C/V.  We assume either
+    // Ctrl-C/Meta-C should pass to the browser when there is a selection,
+    // and Ctrl-Shift-V/Meta-*-V should always pass to the browser (since
+    // these seem to be recognized as paste too).
+    [16,  '[SHIFT]', PASS, PASS,                   PASS,    DEFAULT],
+    [90,  'zZ',   DEFAULT, ctl('Z'),               DEFAULT, DEFAULT],
+    [88,  'xX',   DEFAULT, ctl('X'),               DEFAULT, DEFAULT],
+    [67,  'cC',   DEFAULT, c('onCtrlC_'),          DEFAULT, c('onMetaC_')],
+    [86,  'vV',   DEFAULT, c('onCtrlV_'),          DEFAULT, c('onMetaV_')],
+    [66,  'bB',   DEFAULT, sh(ctl('B'), PASS),     DEFAULT, sh(DEFAULT, PASS)],
+    [78,  'nN',   DEFAULT, c('onCtrlN_'),          DEFAULT, c('onMetaN_')],
+    [77,  'mM',   DEFAULT, ctl('M'),               DEFAULT, DEFAULT],
+    [188, ',<',   DEFAULT, alt(STRIP, PASS),       DEFAULT, DEFAULT],
+    [190, '.>',   DEFAULT, alt(STRIP, PASS),       DEFAULT, DEFAULT],
+    [191, '/?',   DEFAULT, sh(ctl('_'), ctl('?')), DEFAULT, DEFAULT],
+
+    // Sixth and final row.
+    [17,  '[CTRL]',  PASS,    PASS,     PASS,    PASS],
+    [18,  '[ALT]',   PASS,    PASS,     PASS,    PASS],
+    [91,  '[LAPL]',  PASS,    PASS,     PASS,    PASS],
+    [32,  ' ',       DEFAULT, ctl('@'), DEFAULT, DEFAULT],
+    [92,  '[RAPL]',  PASS,    PASS,     PASS,    PASS],
+    [93,  '[RMENU]', PASS,    PASS,     PASS,    PASS],
+
+    // These things.
+    [42,  '[PRTSCR]', PASS, PASS, PASS, PASS],
+    [145, '[SCRLK]',  PASS, PASS, PASS, PASS],
+    [19,  '[BREAK]',  PASS, PASS, PASS, PASS],
+
+    // The block of six keys above the arrows.
+    [45,  '[INSERT]', c('onKeyInsert_'),   DEFAULT, DEFAULT, DEFAULT],
+    [36,  '[HOME]',   c('onKeyHome_'),     DEFAULT, DEFAULT, DEFAULT],
+    [33,  '[PGUP]',   c('onKeyPageUp_'),   DEFAULT, DEFAULT, DEFAULT],
+    [46,  '[DEL]',    c('onKeyDel_'),      DEFAULT, DEFAULT, DEFAULT],
+    [35,  '[END]',    c('onKeyEnd_'),      DEFAULT, DEFAULT, DEFAULT],
+    [34,  '[PGDOWN]', c('onKeyPageDown_'), DEFAULT, DEFAULT, DEFAULT],
+
+    // Arrow keys.  When unmodified they respect the application cursor state,
+    // otherwise they always send the CSI codes.
+    [38, '[UP]',    c('onKeyArrowUp_'), DEFAULT, DEFAULT, DEFAULT],
+    [40, '[DOWN]',  c('onKeyArrowDown_'), DEFAULT, DEFAULT, DEFAULT],
+    [39, '[RIGHT]', ac(CSI + 'C', SS3 + 'C'), DEFAULT, DEFAULT, DEFAULT],
+    [37, '[LEFT]',  ac(CSI + 'D', SS3 + 'D'), DEFAULT, DEFAULT, DEFAULT],
+
+    [144, '[NUMLOCK]', PASS, PASS, PASS, PASS],
+
+    // On Apple keyboards, the NumLock key is a Clear key.  It also tends to be
+    // what KP5 sends when numlock is off.  Not clear if we could do anything
+    // useful with it, so just pass it along.
+    [12, '[CLEAR]', PASS, PASS, PASS, PASS],
+
+    // With numlock off, the keypad generates the same key codes as the arrows
+    // and 'block of six' for some keys, and null key codes for the rest.
+
+    // Keypad with numlock on generates unique key codes...
+    [96,  '[KP0]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [97,  '[KP1]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [98,  '[KP2]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [99,  '[KP3]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [100, '[KP4]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [101, '[KP5]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [102, '[KP6]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [103, '[KP7]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [104, '[KP8]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [105, '[KP9]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [107, '[KP+]', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')],
+    [109, '[KP-]', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')],
+    [106, '[KP*]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [111, '[KP/]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+    [110, '[KP.]', DEFAULT, DEFAULT, DEFAULT, DEFAULT]
+  );
+
+  // OS-specific differences.
+  if (hterm.os == 'cros') {
+    this.addKeyDefs(
+      // Chrome OS keyboard top row.  The media-keys-are-fkeys preference allows
+      // users to make these always behave as function keys (see those bindings
+      // above for more details).
+      [166, '[BACK]',   med(mod(SS3+'P', CSI+'P')), DEFAULT, CSI+'23~', DEFAULT],  // F1
+      [167, '[FWD]',    med(mod(SS3+'Q', CSI+'Q')), DEFAULT, CSI+'24~', DEFAULT],  // F2
+      [168, '[RELOAD]', med(mod(SS3+'R', CSI+'R')), DEFAULT, CSI+'25~', DEFAULT],  // F3
+      [183, '[FSCR]',   med(mod(SS3+'S', CSI+'S')), DEFAULT, CSI+'26~', DEFAULT],  // F4
+      [182, '[WINS]',   med(CSI + '15~'),           DEFAULT, CSI+'28~', DEFAULT],  // F5
+      [216, '[BRIT-]',  med(CSI + '17~'),           DEFAULT, CSI+'29~', DEFAULT],  // F6
+      [217, '[BRIT+]',  med(CSI + '18~'),           DEFAULT, CSI+'31~', DEFAULT],  // F7
+      [173, '[MUTE]',   med(CSI + '19~'),           DEFAULT, CSI+'32~', DEFAULT],  // F8
+      [174, '[VOL-]',   med(CSI + '20~'),           DEFAULT, CSI+'33~', DEFAULT],  // F9
+      [175, '[VOL+]',   med(CSI + '21~'),           DEFAULT, CSI+'34~', DEFAULT],  // F10
+
+      // We could make this into F11, but it'd be a bit weird.  Chrome allows us
+      // to see this and react, but it doesn't actually allow us to block or
+      // cancel it, so it makes the screen flash/lock still.
+      [152, '[POWER]',  DEFAULT, DEFAULT, DEFAULT, DEFAULT],
+
+      // The Pixelbook has a slightly different layout.  This means half the keys
+      // above are off by one.  https://crbug.com/807513
+      [179, '[PLAY]',   med(CSI + '18~'),           DEFAULT, CSI + '31~', DEFAULT], // F7
+      // The settings / hamburgers / three hot dogs / menu / whatever-it's-called.
+      [154, '[DOGS]',   med(CSI + '23~'),           DEFAULT, CSI + '42~', DEFAULT], // F11
+
+      // We don't use this for anything, but keep it from popping up by default.
+      [153, '[ASSIST]', DEFAULT, DEFAULT, DEFAULT, DEFAULT]
+    );
+  }
+};
+
+/**
+ * Either allow the paste or send a key sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyInsert_ = function(e) {
+  if (this.keyboard.shiftInsertPaste && e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  return '\x1b[2~';
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyHome_ = function(e) {
+  if (!this.keyboard.homeKeysScroll ^ e.shiftKey) {
+    if ((e.altey || e.ctrlKey || e.shiftKey) ||
+        !this.keyboard.applicationCursor) {
+      return '\x1b[H';
+    }
+
+    return '\x1bOH';
+  }
+
+  this.keyboard.terminal.scrollHome();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyEnd_ = function(e) {
+  if (!this.keyboard.homeKeysScroll ^ e.shiftKey) {
+    if ((e.altKey || e.ctrlKey || e.shiftKey) ||
+        !this.keyboard.applicationCursor) {
+      return '\x1b[F';
+    }
+
+    return '\x1bOF';
+  }
+
+  this.keyboard.terminal.scrollEnd();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyPageUp_ = function(e) {
+  if (!this.keyboard.pageKeysScroll ^ e.shiftKey)
+    return '\x1b[5~';
+
+  this.keyboard.terminal.scrollPageUp();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Either send a true DEL, or sub in meta-backspace.
+ *
+ * On Chrome OS, if we know the alt key is down, but we get a DEL event that
+ * claims that the alt key is not pressed, we know the DEL was a synthetic
+ * one from a user that hit alt-backspace. Based on a user pref, we can sub
+ * in meta-backspace in this case.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyDel_ = function(e) {
+  if (this.keyboard.altBackspaceIsMetaBackspace &&
+      this.keyboard.altKeyPressed && !e.altKey)
+    return '\x1b\x7f';
+  return '\x1b[3~';
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyPageDown_ = function(e) {
+  if (!this.keyboard.pageKeysScroll ^ e.shiftKey)
+    return '\x1b[6~';
+
+  this.keyboard.terminal.scrollPageDown();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyArrowUp_ = function(e) {
+  if (!this.keyboard.applicationCursor && e.shiftKey) {
+    this.keyboard.terminal.scrollLineUp();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  return (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey ||
+          !this.keyboard.applicationCursor) ? '\x1b[A' : '\x1bOA';
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyArrowDown_ = function(e) {
+  if (!this.keyboard.applicationCursor && e.shiftKey) {
+    this.keyboard.terminal.scrollLineDown();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  return (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey ||
+          !this.keyboard.applicationCursor) ? '\x1b[B' : '\x1bOB';
+};
+
+/**
+ * Clear the primary/alternate screens and the scrollback buffer.
+ */
+hterm.Keyboard.KeyMap.prototype.onClear_ = function(e, keyDef) {
+  this.keyboard.terminal.wipeContents();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Handle F11 behavior (fullscreen) when not in a window.
+ *
+ * It would be nice to use the Fullscreen API, but the UX is slightly different
+ * a bad way: the Escape key is automatically registered for exiting.  If we let
+ * the browser handle F11 directly though, we still get to capture Escape.
+ */
+hterm.Keyboard.KeyMap.prototype.onF11_ = function(e, keyDef) {
+  if (hterm.windowType != 'popup')
+    return hterm.Keyboard.KeyActions.PASS;
+  else
+    return '\x1b[23~';
+};
+
+/**
+ * Either pass Ctrl-1..9 to the browser or send them to the host.
+ *
+ * Note that Ctrl-1 and Ctrl-9 don't actually have special sequences mapped
+ * to them in xterm or gnome-terminal.  The range is really Ctrl-2..8, but
+ * we handle 1..9 since Chrome treats the whole range special.
+ */
+hterm.Keyboard.KeyMap.prototype.onCtrlNum_ = function(e, keyDef) {
+  // Compute a control character for a given character.
+  function ctl(ch) { return String.fromCharCode(ch.charCodeAt(0) - 64); }
+
+  if (this.keyboard.terminal.passCtrlNumber && !e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  switch (keyDef.keyCap.substr(0, 1)) {
+    case '1': return '1';
+    case '2': return ctl('@');
+    case '3': return ctl('[');
+    case '4': return ctl('\\');
+    case '5': return ctl(']');
+    case '6': return ctl('^');
+    case '7': return ctl('_');
+    case '8': return '\x7f';
+    case '9': return '9';
+  }
+};
+
+/**
+ * Either pass Alt-1..9 to the browser or send them to the host.
+ */
+hterm.Keyboard.KeyMap.prototype.onAltNum_ = function(e, keyDef) {
+  if (this.keyboard.terminal.passAltNumber && !e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  return hterm.Keyboard.KeyActions.DEFAULT;
+};
+
+/**
+ * Either pass Meta-1..9 to the browser or send them to the host.
+ */
+hterm.Keyboard.KeyMap.prototype.onMetaNum_ = function(e, keyDef) {
+  if (this.keyboard.terminal.passMetaNumber && !e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  return hterm.Keyboard.KeyActions.DEFAULT;
+};
+
+/**
+ * Either send a ^C or interpret the keystroke as a copy command.
+ */
+hterm.Keyboard.KeyMap.prototype.onCtrlC_ = function(e, keyDef) {
+  var selection = this.keyboard.terminal.getDocument().getSelection();
+
+  if (!selection.isCollapsed) {
+    if (this.keyboard.ctrlCCopy && !e.shiftKey) {
+      // Ctrl-C should copy if there is a selection, send ^C otherwise.
+      // Perform the copy by letting the browser handle Ctrl-C.  On most
+      // browsers, this is the *only* way to place text on the clipboard from
+      // the 'drive-by' web.
+      if (this.keyboard.terminal.clearSelectionAfterCopy) {
+        setTimeout(selection.collapseToEnd.bind(selection), 50);
+      }
+      return hterm.Keyboard.KeyActions.PASS;
+    }
+
+    if (!this.keyboard.ctrlCCopy && e.shiftKey) {
+      // Ctrl-Shift-C should copy if there is a selection, send ^C otherwise.
+      // Perform the copy manually.  This only works in situations where
+      // document.execCommand('copy') is allowed.
+      if (this.keyboard.terminal.clearSelectionAfterCopy) {
+        setTimeout(selection.collapseToEnd.bind(selection), 50);
+      }
+      this.keyboard.terminal.copySelectionToClipboard();
+      return hterm.Keyboard.KeyActions.CANCEL;
+    }
+  }
+
+  return '\x03';
+};
+
+/**
+ * Either send a ^N or open a new window to the same location.
+ */
+hterm.Keyboard.KeyMap.prototype.onCtrlN_ = function(e, keyDef) {
+  if (e.shiftKey) {
+    lib.f.openWindow(document.location.href, '',
+                     'chrome=no,close=yes,resize=yes,scrollbars=yes,' +
+                     'minimizable=yes,width=' + window.innerWidth +
+                     ',height=' + window.innerHeight);
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  return '\x0e';
+};
+
+/**
+ * Either send a ^V or issue a paste command.
+ *
+ * The default behavior is to paste if the user presses Ctrl-Shift-V, and send
+ * a ^V if the user presses Ctrl-V. This can be flipped with the
+ * 'ctrl-v-paste' preference.
+ *
+ */
+hterm.Keyboard.KeyMap.prototype.onCtrlV_ = function(e, keyDef) {
+  if ((!e.shiftKey && this.keyboard.ctrlVPaste) ||
+      (e.shiftKey && !this.keyboard.ctrlVPaste)) {
+    // We try to do the pasting ourselves as not all browsers/OSs bind Ctrl-V to
+    // pasting.  Notably, on macOS, Ctrl-V/Ctrl-Shift-V do nothing.
+    // However, this might run into web restrictions, so if it fails, we still
+    // fallback to the letting the native behavior (hopefully) save us.
+    if (this.keyboard.terminal.paste())
+      return hterm.Keyboard.KeyActions.CANCEL;
+    else
+      return hterm.Keyboard.KeyActions.PASS;
+  }
+
+  return '\x16';
+};
+
+/**
+ * Either the default action or open a new window to the same location.
+ */
+hterm.Keyboard.KeyMap.prototype.onMetaN_ = function(e, keyDef) {
+  if (e.shiftKey) {
+    lib.f.openWindow(document.location.href, '',
+                     'chrome=no,close=yes,resize=yes,scrollbars=yes,' +
+                     'minimizable=yes,width=' + window.outerWidth +
+                     ',height=' + window.outerHeight);
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  return hterm.Keyboard.KeyActions.DEFAULT;
+};
+
+/**
+ * Either send a Meta-C or allow the browser to interpret the keystroke as a
+ * copy command.
+ *
+ * If there is no selection, or if the user presses Meta-Shift-C, then we'll
+ * transmit an '\x1b' (if metaSendsEscape is on) followed by 'c' or 'C'.
+ *
+ * If there is a selection, we defer to the browser.  In this case we clear out
+ * the selection so the user knows we heard them, and also to give them a
+ * chance to send a Meta-C by just hitting the key again.
+ */
+hterm.Keyboard.KeyMap.prototype.onMetaC_ = function(e, keyDef) {
+  var document = this.keyboard.terminal.getDocument();
+  if (e.shiftKey || document.getSelection().isCollapsed) {
+    // If the shift key is being held, or there is no document selection, send
+    // a Meta-C.  The keyboard code will add the ESC if metaSendsEscape is true,
+    // we just have to decide between 'c' and 'C'.
+    return keyDef.keyCap.substr(e.shiftKey ? 1 : 0, 1);
+  }
+
+  // Otherwise let the browser handle it as a copy command.
+  if (this.keyboard.terminal.clearSelectionAfterCopy) {
+    setTimeout(function() { document.getSelection().collapseToEnd(); }, 50);
+  }
+  return hterm.Keyboard.KeyActions.PASS;
+};
+
+/**
+ * Either PASS or DEFAULT Meta-V, depending on preference.
+ *
+ * Always PASS Meta-Shift-V to allow browser to interpret the keystroke as
+ * a paste command.
+ */
+hterm.Keyboard.KeyMap.prototype.onMetaV_ = function(e, keyDef) {
+  if (e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  return this.keyboard.passMetaV ?
+      hterm.Keyboard.KeyActions.PASS :
+      hterm.Keyboard.KeyActions.DEFAULT;
+};
+
+/**
+ * Handle font zooming.
+ *
+ * The browser's built-in zoom has a bit of an issue at certain zoom levels.
+ * At some magnifications, the measured height of a row of text differs from
+ * the height that was explicitly set.
+ *
+ * We override the browser zoom keys to change the ScrollPort's font size to
+ * avoid the issue.
+ */
+hterm.Keyboard.KeyMap.prototype.onPlusMinusZero_ = function(e, keyDef) {
+  if (!(this.keyboard.ctrlPlusMinusZeroZoom ^ e.shiftKey)) {
+    // If ctrl-PMZ controls zoom and the shift key is pressed, or
+    // ctrl-shift-PMZ controls zoom and this shift key is not pressed,
+    // then we want to send the control code instead of affecting zoom.
+    if (keyDef.keyCap == '-_')
+      return '\x1f';  // ^_
+
+    // Only ^_ is valid, the other sequences have no meaning.
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  if (this.keyboard.terminal.getZoomFactor() != 1) {
+    // If we're not at 1:1 zoom factor, let the Ctrl +/-/0 keys control the
+    // browser zoom, so it's easier to for the user to get back to 100%.
+    return hterm.Keyboard.KeyActions.PASS;
+  }
+
+  var cap = keyDef.keyCap.substr(0, 1);
+  if (cap == '0') {
+      this.keyboard.terminal.setFontSize(0);
+  } else {
+    var size = this.keyboard.terminal.getFontSize();
+
+    if (cap == '-' || keyDef.keyCap == '[KP-]') {
+      size -= 1;
+    } else {
+      size += 1;
+    }
+
+    this.keyboard.terminal.setFontSize(size);
+  }
+
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+// SOURCE FILE: hterm/js/hterm_keyboard_keypattern.js
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * A record of modifier bits and keycode used to define a key binding.
+ *
+ * The modifier names are enumerated in the static KeyPattern.modifiers
+ * property below.  Each modifier can be true, false, or "*".  True means
+ * the modifier key must be present, false means it must not, and "*" means
+ * it doesn't matter.
+ */
+hterm.Keyboard.KeyPattern = function(spec) {
+  this.wildcardCount = 0;
+  this.keyCode = spec.keyCode;
+
+  hterm.Keyboard.KeyPattern.modifiers.forEach(function(mod) {
+    this[mod] = spec[mod] || false;
+    if (this[mod] == '*')
+      this.wildcardCount++;
+  }.bind(this));
+};
+
+/**
+ * Valid modifier names.
+ */
+hterm.Keyboard.KeyPattern.modifiers = [
+  'shift', 'ctrl', 'alt', 'meta'
+];
+
+/**
+ * A compare callback for Array.prototype.sort().
+ *
+ * The bindings code wants to be sure to search through the strictest key
+ * patterns first, so that loosely defined patterns have a lower priority than
+ * exact patterns.
+ *
+ * @param {hterm.Keyboard.KeyPattern} a
+ * @param {hterm.Keyboard.KeyPattern} b
+ */
+hterm.Keyboard.KeyPattern.sortCompare = function(a, b) {
+  if (a.wildcardCount < b.wildcardCount)
+    return -1;
+
+  if (a.wildcardCount > b.wildcardCount)
+    return 1;
+
+  return 0;
+};
+
+/**
+ * Private method used to match this key pattern against other key patterns
+ * or key down events.
+ *
+ * @param {Object} The object to match.
+ * @param {boolean} True if we should ignore wildcards.  Useful when you want
+ *   to perform and exact match against another key pattern.
+ */
+hterm.Keyboard.KeyPattern.prototype.match_ = function(obj, exactMatch) {
+  if (this.keyCode != obj.keyCode)
+    return false;
+
+  var rv = true;
+
+  hterm.Keyboard.KeyPattern.modifiers.forEach(function(mod) {
+    var modValue = (mod in obj) ? obj[mod] : false;
+    if (!rv || (!exactMatch && this[mod] == '*') || this[mod] == modValue)
+      return;
+
+    rv = false;
+  }.bind(this));
+
+  return rv;
+};
+
+/**
+ * Return true if the given keyDown object is a match for this key pattern.
+ *
+ * @param {Object} keyDown An object with a keyCode property and zero or
+ *   more boolean properties representing key modifiers.  These property names
+ *   must match those defined in hterm.Keyboard.KeyPattern.modifiers.
+ */
+hterm.Keyboard.KeyPattern.prototype.matchKeyDown = function(keyDown) {
+  return this.match_(keyDown, false);
+};
+
+/**
+ * Return true if the given hterm.Keyboard.KeyPattern is exactly the same as
+ * this one.
+ *
+ * @param {hterm.Keyboard.KeyPattern}
+ */
+hterm.Keyboard.KeyPattern.prototype.matchKeyPattern = function(keyPattern) {
+  return this.match_(keyPattern, true);
+};
+// SOURCE FILE: hterm/js/hterm_options.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview This file implements the hterm.Options class,
+ * which stores current operating conditions for the terminal.  This object is
+ * used instead of a series of parameters to allow saving/restoring of cursor
+ * conditions easily, and to provide an easy place for common configuration
+ * options.
+ *
+ * Original code by Cory Maccarrone.
+ */
+
+/**
+ * Constructor for the hterm.Options class, optionally acting as a copy
+ * constructor.
+ *
+ * The defaults are as defined in http://www.vt100.net/docs/vt510-rm/DECSTR
+ * except that we enable autowrap (wraparound) by default since that seems to
+ * be what xterm does.
+ *
+ * @param {hterm.Options=} opt_copy Optional instance to copy.
+ * @constructor
+ */
+hterm.Options = function(opt_copy) {
+  // All attributes in this class are public to allow easy access by the
+  // terminal.
+
+  this.wraparound = opt_copy ? opt_copy.wraparound : true;
+  this.reverseWraparound = opt_copy ? opt_copy.reverseWraparound : false;
+  this.originMode = opt_copy ? opt_copy.originMode : false;
+  this.autoCarriageReturn = opt_copy ? opt_copy.autoCarriageReturn : false;
+  this.cursorVisible = opt_copy ? opt_copy.cursorVisible : false;
+  this.cursorBlink = opt_copy ? opt_copy.cursorBlink : false;
+  this.insertMode = opt_copy ? opt_copy.insertMode : false;
+  this.reverseVideo = opt_copy ? opt_copy.reverseVideo : false;
+  this.bracketedPaste = opt_copy ? opt_copy.bracketedPaste : false;
+};
+// SOURCE FILE: hterm/js/hterm_parser.js
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * Parses the key definition syntax used for user keyboard customizations.
+ */
+hterm.Parser = function() {
+  /**
+   * @type {string} The source string.
+   */
+  this.source = '';
+
+  /**
+   * @type {number} The current position.
+   */
+  this.pos = 0;
+
+  /**
+   * @type {string?} The character at the current position.
+   */
+  this.ch = null;
+};
+
+hterm.Parser.prototype.error = function(message) {
+  return new Error('Parse error at ' + this.pos + ': ' + message);
+};
+
+hterm.Parser.prototype.isComplete = function() {
+  return this.pos == this.source.length;
+};
+
+hterm.Parser.prototype.reset = function(source, opt_pos) {
+  this.source = source;
+  this.pos = opt_pos || 0;
+  this.ch = source.substr(0, 1);
+};
+
+/**
+ * Parse a key sequence.
+ *
+ * A key sequence is zero or more of the key modifiers defined in
+ * hterm.Parser.identifiers.modifierKeys followed by a key code.  Key
+ * codes can be an integer or an identifier from
+ * hterm.Parser.identifiers.keyCodes.  Modifiers and keyCodes should be joined
+ * by the dash character.
+ *
+ * An asterisk "*" can be used to indicate that the unspecified modifiers
+ * are optional.
+ *
+ * For example:
+ *   A: Matches only an unmodified "A" character.
+ *   65: Same as above.
+ *   0x41: Same as above.
+ *   Ctrl-A: Matches only Ctrl-A.
+ *   Ctrl-65: Same as above.
+ *   Ctrl-0x41: Same as above.
+ *   Ctrl-Shift-A: Matches only Ctrl-Shift-A.
+ *   Ctrl-*-A: Matches Ctrl-A, as well as any other key sequence that includes
+ *     at least the Ctrl and A keys.
+ *
+ * @return {Object} An object with shift, ctrl, alt, meta, keyCode
+ *   properties.
+ */
+hterm.Parser.prototype.parseKeySequence = function() {
+  var rv = {
+    keyCode: null
+  };
+
+  for (var k in hterm.Parser.identifiers.modifierKeys) {
+    rv[hterm.Parser.identifiers.modifierKeys[k]] = false;
+  }
+
+  while (this.pos < this.source.length) {
+    this.skipSpace();
+
+    var token = this.parseToken();
+    if (token.type == 'integer') {
+      rv.keyCode = token.value;
+
+    } else if (token.type == 'identifier') {
+      var ucValue = token.value.toUpperCase();
+      if (ucValue in hterm.Parser.identifiers.modifierKeys &&
+          hterm.Parser.identifiers.modifierKeys.hasOwnProperty(ucValue)) {
+        var mod = hterm.Parser.identifiers.modifierKeys[ucValue];
+        if (rv[mod] && rv[mod] != '*')
+          throw this.error('Duplicate modifier: ' + token.value);
+        rv[mod] = true;
+
+      } else if (ucValue in hterm.Parser.identifiers.keyCodes &&
+                 hterm.Parser.identifiers.keyCodes.hasOwnProperty(ucValue)) {
+        rv.keyCode = hterm.Parser.identifiers.keyCodes[ucValue];
+
+      } else {
+        throw this.error('Unknown key: ' + token.value);
+      }
+
+    } else if (token.type == 'symbol') {
+      if (token.value == '*') {
+        for (var id in hterm.Parser.identifiers.modifierKeys) {
+          var p = hterm.Parser.identifiers.modifierKeys[id];
+          if (!rv[p])
+            rv[p] =  '*';
+        }
+      } else {
+        throw this.error('Unexpected symbol: ' + token.value);
+      }
+    } else {
+      throw this.error('Expected integer or identifier');
+    }
+
+    this.skipSpace();
+
+    if (this.ch != '-')
+      break;
+
+    if (rv.keyCode != null)
+      throw this.error('Extra definition after target key');
+
+    this.advance(1);
+  }
+
+  if (rv.keyCode == null)
+    throw this.error('Missing target key');
+
+  return rv;
+};
+
+hterm.Parser.prototype.parseKeyAction = function() {
+  this.skipSpace();
+
+  var token = this.parseToken();
+
+  if (token.type == 'string')
+    return token.value;
+
+  if (token.type == 'identifier') {
+    if (token.value in hterm.Parser.identifiers.actions &&
+        hterm.Parser.identifiers.actions.hasOwnProperty(token.value))
+      return hterm.Parser.identifiers.actions[token.value];
+
+    throw this.error('Unknown key action: ' + token.value);
+  }
+
+  throw this.error('Expected string or identifier');
+
+};
+
+hterm.Parser.prototype.peekString = function() {
+  return this.ch == '\'' || this.ch == '"';
+};
+
+hterm.Parser.prototype.peekIdentifier = function() {
+  return this.ch.match(/[a-z_]/i);
+};
+
+hterm.Parser.prototype.peekInteger = function() {
+  return this.ch.match(/[0-9]/);
+};
+
+hterm.Parser.prototype.parseToken = function() {
+  if (this.ch == '*') {
+    var rv = {type: 'symbol', value: this.ch};
+    this.advance(1);
+    return rv;
+  }
+
+  if (this.peekIdentifier())
+    return {type: 'identifier', value: this.parseIdentifier()};
+
+  if (this.peekString())
+    return {type: 'string', value: this.parseString()};
+
+  if (this.peekInteger())
+    return {type: 'integer', value: this.parseInteger()};
+
+
+  throw this.error('Unexpected token');
+};
+
+hterm.Parser.prototype.parseIdentifier = function() {
+  if (!this.peekIdentifier())
+    throw this.error('Expected identifier');
+
+  return this.parsePattern(/[a-z0-9_]+/ig);
+};
+
+hterm.Parser.prototype.parseInteger = function() {
+  var base = 10;
+
+  if (this.ch == '0' && this.pos < this.source.length - 1 &&
+      this.source.substr(this.pos + 1, 1) == 'x') {
+    return parseInt(this.parsePattern(/0x[0-9a-f]+/gi));
+  }
+
+  return parseInt(this.parsePattern(/\d+/g));
+};
+
+/**
+ * Parse a single or double quoted string.
+ *
+ * The current position should point at the initial quote character.  Single
+ * quoted strings will be treated literally, double quoted will process escapes.
+ *
+ * TODO(rginda): Variable interpolation.
+ *
+ * @param {ParseState} parseState
+ * @param {string} quote A single or double-quote character.
+ * @return {string}
+ */
+hterm.Parser.prototype.parseString = function() {
+  var result = '';
+
+  var quote = this.ch;
+  if (quote != '"' && quote != '\'')
+    throw this.error('String expected');
+
+  this.advance(1);
+
+  var re = new RegExp('[\\\\' + quote + ']', 'g');
+
+  while (this.pos < this.source.length) {
+    re.lastIndex = this.pos;
+    if (!re.exec(this.source))
+      throw this.error('Unterminated string literal');
+
+    result += this.source.substring(this.pos, re.lastIndex - 1);
+
+    this.advance(re.lastIndex - this.pos - 1);
+
+    if (quote == '"' && this.ch == '\\') {
+      this.advance(1);
+      result += this.parseEscape();
+      continue;
+    }
+
+    if (quote == '\'' && this.ch == '\\') {
+      result += this.ch;
+      this.advance(1);
+      continue;
+    }
+
+    if (this.ch == quote) {
+      this.advance(1);
+      return result;
+    }
+  }
+
+  throw this.error('Unterminated string literal');
+};
+
+
+/**
+ * Parse an escape code from the current position (which should point to
+ * the first character AFTER the leading backslash.)
+ *
+ * @return {string}
+ */
+hterm.Parser.prototype.parseEscape = function() {
+  var map = {
+    '"': '"',
+    '\'': '\'',
+    '\\': '\\',
+    'a': '\x07',
+    'b': '\x08',
+    'e': '\x1b',
+    'f': '\x0c',
+    'n': '\x0a',
+    'r': '\x0d',
+    't': '\x09',
+    'v': '\x0b',
+    'x': function() {
+      var value = this.parsePattern(/[a-z0-9]{2}/ig);
+      return String.fromCharCode(parseInt(value, 16));
+    },
+    'u': function() {
+      var value = this.parsePattern(/[a-z0-9]{4}/ig);
+      return String.fromCharCode(parseInt(value, 16));
+    }
+  };
+
+  if (!(this.ch in map && map.hasOwnProperty(this.ch)))
+    throw this.error('Unknown escape: ' + this.ch);
+
+  var value = map[this.ch];
+  this.advance(1);
+
+  if (typeof value == 'function')
+    value = value.call(this);
+
+  return value;
+};
+
+/**
+ * Parse the given pattern starting from the current position.
+ *
+ * @param {RegExp} pattern A pattern representing the characters to span.  MUST
+ *   include the "global" RegExp flag.
+ * @return {string}
+ */
+hterm.Parser.prototype.parsePattern = function(pattern) {
+  if (!pattern.global)
+    throw this.error('Internal error: Span patterns must be global');
+
+  pattern.lastIndex = this.pos;
+  var ary = pattern.exec(this.source);
+
+  if (!ary || pattern.lastIndex - ary[0].length != this.pos)
+    throw this.error('Expected match for: ' + pattern);
+
+  this.pos = pattern.lastIndex - 1;
+  this.advance(1);
+
+  return ary[0];
+};
+
+
+/**
+ * Advance the current position.
+ *
+ * @param {number} count
+ */
+hterm.Parser.prototype.advance = function(count) {
+  this.pos += count;
+  this.ch = this.source.substr(this.pos, 1);
+};
+
+/**
+ * @param {string=} opt_expect A list of valid non-whitespace characters to
+ *   terminate on.
+ * @return {void}
+ */
+hterm.Parser.prototype.skipSpace = function(opt_expect) {
+  if (!/\s/.test(this.ch))
+    return;
+
+  var re = /\s+/gm;
+  re.lastIndex = this.pos;
+
+  var source = this.source;
+  if (re.exec(source))
+    this.pos = re.lastIndex;
+
+  this.ch = this.source.substr(this.pos, 1);
+
+  if (opt_expect) {
+    if (this.ch.indexOf(opt_expect) == -1) {
+      throw this.error('Expected one of ' + opt_expect + ', found: ' +
+          this.ch);
+    }
+  }
+};
+// SOURCE FILE: hterm/js/hterm_parser_identifiers.js
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Collections of identifier for hterm.Parser.
+ */
+hterm.Parser.identifiers = {};
+
+/**
+ * Modifier key names used when defining key sequences.
+ *
+ * These are upper case so we can normalize the user input and be forgiving.
+ * "CTRL-A" and "Ctrl-A" and "ctrl-a" are all accepted.
+ *
+ * Note: Names here cannot overlap with hterm.Parser.identifiers.keyCodes.
+ */
+hterm.Parser.identifiers.modifierKeys = {
+  SHIFT: 'shift',
+  CTRL: 'ctrl',
+  // Common alias.
+  CONTROL: 'ctrl',
+  ALT: 'alt',
+  META: 'meta'
+};
+
+/**
+ * Key codes useful when defining key sequences.
+ *
+ * Punctuation is mostly left out of this list because they can move around
+ * based on keyboard locale and browser.
+ *
+ * In a key sequence like "Ctrl-ESC", the ESC comes from this list of
+ * identifiers.  It is equivalent to "Ctrl-27" and "Ctrl-0x1b".
+ *
+ * These are upper case so we can normalize the user input and be forgiving.
+ * "Ctrl-ESC" and "Ctrl-Esc" an "Ctrl-esc" are all accepted.
+ *
+ * We also include common aliases for the same key.  "Esc" and "Escape" are the
+ * same key.
+ *
+ * Note: Names here cannot overlap with hterm.Parser.identifiers.modifierKeys.
+ */
+hterm.Parser.identifiers.keyCodes = {
+  // Top row.
+  ESCAPE: 27,
+  ESC: 27,
+  F1: 112,
+  F2: 113,
+  F3: 114,
+  F4: 115,
+  F5: 116,
+  F6: 117,
+  F7: 118,
+  F8: 119,
+  F9: 120,
+  F10: 121,
+  F11: 122,
+  F12: 123,
+
+  // Row two.
+  ONE: 49,
+  TWO: 50,
+  THREE: 51,
+  FOUR: 52,
+  FIVE: 53,
+  SIX: 54,
+  SEVEN: 55,
+  EIGHT: 56,
+  NINE: 57,
+  ZERO: 48,
+  BACKSPACE: 8,
+  BKSP: 8,
+  BS: 8,
+
+  // Row three.
+  TAB: 9,
+  Q: 81,
+  W: 87,
+  E: 69,
+  R: 82,
+  T: 84,
+  Y: 89,
+  U: 85,
+  I: 73,
+  O: 79,
+  P: 80,
+
+  // Row four.
+  CAPS_LOCK: 20,
+  CAPSLOCK: 20,
+  CAPS: 20,
+  A: 65,
+  S: 83,
+  D: 68,
+  F: 70,
+  G: 71,
+  H: 72,
+  J: 74,
+  K: 75,
+  L: 76,
+  // We map enter and return together even though enter should really be 10
+  // because most people don't know or care about the history here.  Plus,
+  // most keyboards/programs map them together already.  If they really want
+  // to bind them differently, they can also use the numeric value.
+  ENTER: 13,
+  ENT: 13,
+  RETURN: 13,
+  RET: 13,
+
+  // Row five.
+  Z: 90,
+  X: 88,
+  C: 67,
+  V: 86,
+  B: 66,
+  N: 78,
+  M: 77,
+
+  // Etc.
+  SPACE: 32,
+  SP: 32,
+  PRINT_SCREEN: 42,
+  PRTSC: 42,
+  SCROLL_LOCK: 145,
+  SCRLK: 145,
+  BREAK: 19,
+  BRK: 19,
+  INSERT: 45,
+  INS: 45,
+  HOME: 36,
+  PAGE_UP: 33,
+  PGUP: 33,
+  DELETE: 46,
+  DEL: 46,
+  END: 35,
+  PAGE_DOWN: 34,
+  PGDOWN: 34,
+  PGDN: 34,
+  UP: 38,
+  DOWN: 40,
+  RIGHT: 39,
+  LEFT: 37,
+  NUMLOCK: 144,
+
+  // Keypad
+  KP0: 96,
+  KP1: 97,
+  KP2: 98,
+  KP3: 99,
+  KP4: 100,
+  KP5: 101,
+  KP6: 102,
+  KP7: 103,
+  KP8: 104,
+  KP9: 105,
+  KP_PLUS: 107,
+  KP_ADD: 107,
+  KP_MINUS: 109,
+  KP_SUBTRACT: 109,
+  KP_STAR: 106,
+  KP_MULTIPLY: 106,
+  KP_DIVIDE: 111,
+  KP_DECIMAL: 110,
+  KP_PERIOD: 110,
+
+  // Chrome OS media keys
+  NAVIGATE_BACK: 166,
+  NAVIGATE_FORWARD: 167,
+  RELOAD: 168,
+  FULL_SCREEN: 183,
+  WINDOW_OVERVIEW: 182,
+  BRIGHTNESS_UP: 216,
+  BRIGHTNESS_DOWN: 217
+};
+
+/**
+ * Identifiers for use in key actions.
+ */
+hterm.Parser.identifiers.actions = {
+  /**
+   * Prevent the browser and operating system from handling the event.
+   */
+  CANCEL: hterm.Keyboard.KeyActions.CANCEL,
+
+  /**
+   * Wait for a "keypress" event, send the keypress charCode to the host.
+   */
+  DEFAULT: hterm.Keyboard.KeyActions.DEFAULT,
+
+  /**
+   * Let the browser or operating system handle the key.
+   */
+  PASS: hterm.Keyboard.KeyActions.PASS,
+
+  /**
+   * Scroll the terminal one line up.
+   */
+  scrollLineUp: function(terminal) {
+    terminal.scrollLineUp();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal one line down.
+   */
+  scrollLineDown: function(terminal) {
+    terminal.scrollLineDown();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal one page up.
+   */
+  scrollPageUp: function(terminal) {
+    terminal.scrollPageUp();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal one page down.
+   */
+  scrollPageDown: function(terminal) {
+    terminal.scrollPageDown();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal to the top.
+   */
+  scrollToTop: function(terminal) {
+    terminal.scrollHome();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal to the bottom.
+   */
+  scrollToBottom: function(terminal) {
+    terminal.scrollEnd();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Clear the active screen and move the cursor to (0,0).
+   */
+  clearScreen: function(terminal) {
+    terminal.clearHome();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Clear the scrollback buffer.
+   */
+  clearScrollback: function(terminal) {
+    terminal.clearScrollback();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Clear the terminal and scrollback buffer and move the cursor to (0,0).
+   */
+  clearTerminal: function(terminal) {
+    terminal.wipeContents();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Perform a full terminal reset.
+   */
+  fullReset: function(terminal) {
+    terminal.reset();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Perform a soft terminal reset.
+   */
+  softReset: function(terminal) {
+    terminal.softReset();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+};
+// SOURCE FILE: hterm/js/hterm_preference_manager.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * PreferenceManager subclass managing global NaSSH preferences.
+ *
+ * This is currently just an ordered list of known connection profiles.
+ */
+hterm.PreferenceManager = function(profileId) {
+  lib.PreferenceManager.call(this, hterm.defaultStorage,
+                             hterm.PreferenceManager.prefix_ + profileId);
+  Object.entries(hterm.PreferenceManager.defaultPreferences).forEach(
+      ([key, entry]) => {
+        this.definePreference(key, entry['default']);
+      });
+};
+
+/**
+ * The storage key prefix to namespace the preferences.
+ */
+hterm.PreferenceManager.prefix_ = '/hterm/profiles/';
+
+/**
+ * List all the defined profiles.
+ *
+ * @param {function(Array<string>)} callback Called with the list of profiles.
+ */
+hterm.PreferenceManager.listProfiles = function(callback) {
+  hterm.defaultStorage.getItems(null, (items) => {
+    const profiles = {};
+    for (let key of Object.keys(items)) {
+      if (key.startsWith(hterm.PreferenceManager.prefix_)) {
+        // Turn "/hterm/profiles/foo/bar/cow" to "foo/bar/cow".
+        const subKey = key.slice(hterm.PreferenceManager.prefix_.length);
+        // Turn "foo/bar/cow" into "foo".
+        profiles[subKey.split('/', 1)[0]] = true;
+      }
+    }
+    callback(Object.keys(profiles));
+  });
+};
+
+hterm.PreferenceManager.categories = {};
+hterm.PreferenceManager.categories.Keyboard = 'Keyboard';
+hterm.PreferenceManager.categories.Appearance = 'Appearance';
+hterm.PreferenceManager.categories.CopyPaste = 'CopyPaste';
+hterm.PreferenceManager.categories.Sounds = 'Sounds';
+hterm.PreferenceManager.categories.Scrolling = 'Scrolling';
+hterm.PreferenceManager.categories.Encoding = 'Encoding';
+hterm.PreferenceManager.categories.Extensions = 'Extensions';
+hterm.PreferenceManager.categories.Miscellaneous = 'Miscellaneous';
+
+/**
+ * List of categories, ordered by display order (top to bottom)
+ */
+hterm.PreferenceManager.categoryDefinitions = [
+  { id: hterm.PreferenceManager.categories.Appearance,
+    text: 'Appearance (fonts, colors, images)'},
+  { id: hterm.PreferenceManager.categories.CopyPaste,
+    text: 'Copy & Paste'},
+  { id: hterm.PreferenceManager.categories.Encoding,
+    text: 'Encoding'},
+  { id: hterm.PreferenceManager.categories.Keyboard,
+    text: 'Keyboard'},
+  { id: hterm.PreferenceManager.categories.Scrolling,
+    text: 'Scrolling'},
+  { id: hterm.PreferenceManager.categories.Sounds,
+    text: 'Sounds'},
+  { id: hterm.PreferenceManager.categories.Extensions,
+    text: 'Extensions'},
+  { id: hterm.PreferenceManager.categories.Miscellaneous,
+    text: 'Miscellaneous'}
+];
+
+/**
+ * Internal helper to create a default preference object.
+ *
+ * @param {hterm.PreferenceManager.categories} category The pref category.
+ * @param {string} name The user readable name/title.
+ * @param {Object} defaultValue The default pref value.
+ * @param {Object} type The type for this pref (or an array for enums).
+ * @param {string} help The user readable help text.
+ * @return {Object} The default pref object.
+ */
+hterm.PreferenceManager.definePref_ = function(
+    name, category, defaultValue, type, help) {
+  return {
+    'name': name,
+    'category': category,
+    'default': defaultValue,
+    'type': type,
+    'help': help,
+  };
+};
+
+hterm.PreferenceManager.defaultPreferences = {
+  'alt-gr-mode': hterm.PreferenceManager.definePref_(
+      'AltGr key mode',
+      hterm.PreferenceManager.categories.Keyboard,
+      null, [null, 'none', 'ctrl-alt', 'left-alt', 'right-alt'],
+      `Select an AltGr detection heuristic.\n` +
+      `\n` +
+      `'null': Autodetect based on navigator.language:\n` +
+      `      'en-us' => 'none', else => 'right-alt'\n` +
+      `'none': Disable any AltGr related munging.\n` +
+      `'ctrl-alt': Assume Ctrl+Alt means AltGr.\n` +
+      `'left-alt': Assume left Alt means AltGr.\n` +
+      `'right-alt': Assume right Alt means AltGr.`
+  ),
+
+  'alt-backspace-is-meta-backspace': hterm.PreferenceManager.definePref_(
+      'Alt-Backspace is Meta-Backspace',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `If set, undoes the Chrome OS Alt-Backspace->DEL remap, so that ` +
+      `Alt-Backspace indeed is Alt-Backspace.`
+  ),
+
+  'alt-is-meta': hterm.PreferenceManager.definePref_(
+      'Treat Alt key as Meta key',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `Whether the Alt key acts as a Meta key or as a distinct Alt key.`
+  ),
+
+  'alt-sends-what': hterm.PreferenceManager.definePref_(
+      'Alt key modifier handling',
+      hterm.PreferenceManager.categories.Keyboard,
+      'escape', ['escape', '8-bit', 'browser-key'],
+      `Controls how the Alt key is handled.\n` +
+      `\n` +
+      `  escape: Send an ESC prefix.\n` +
+      `  8-bit: Add 128 to the typed character as in xterm.\n` +
+      `  browser-key: Wait for the keypress event and see what the browser\n` +
+      `    says. (This won't work well on platforms where the browser\n` +
+      `    performs a default action for some Alt sequences.)`
+  ),
+
+  'audible-bell-sound': hterm.PreferenceManager.definePref_(
+      'Alert bell sound (URI)',
+      hterm.PreferenceManager.categories.Sounds,
+      'lib-resource:hterm/audio/bell', 'url',
+      `URL of the terminal bell sound. Empty string for no audible bell.`
+  ),
+
+  'desktop-notification-bell': hterm.PreferenceManager.definePref_(
+      'Create desktop notifications for alert bells',
+      hterm.PreferenceManager.categories.Sounds,
+      false, 'bool',
+      `If true, terminal bells in the background will create a Web ` +
+      `Notification. https://www.w3.org/TR/notifications/\n` +
+      `\n` +
+      `Displaying notifications requires permission from the user. When this ` +
+      `option is set to true, hterm will attempt to ask the user for ` +
+      `permission if necessary. Browsers may not show this permission ` +
+      `request if it was not triggered by a user action.\n` +
+      `\n` +
+      `Chrome extensions with the "notifications" permission have permission ` +
+      `to display notifications.`
+  ),
+
+  'background-color': hterm.PreferenceManager.definePref_(
+      'Background color',
+      hterm.PreferenceManager.categories.Appearance,
+      'rgb(16, 16, 16)', 'color',
+      `The background color for text with no other color attributes.`
+  ),
+
+  'background-image': hterm.PreferenceManager.definePref_(
+      'Background image',
+      hterm.PreferenceManager.categories.Appearance,
+      '', 'string',
+      `CSS value of the background image. Empty string for no image.\n` +
+      `\n` +
+      `For example:\n` +
+      `  url(https://goo.gl/anedTK)\n` +
+      `  linear-gradient(top bottom, blue, red)`
+  ),
+
+  'background-size': hterm.PreferenceManager.definePref_(
+      'Background image size',
+      hterm.PreferenceManager.categories.Appearance,
+      '', 'string',
+      `CSS value of the background image size.`
+  ),
+
+  'background-position': hterm.PreferenceManager.definePref_(
+      'Background image position',
+      hterm.PreferenceManager.categories.Appearance,
+      '', 'string',
+      `CSS value of the background image position.\n` +
+      `\n` +
+      `For example:\n` +
+      `  10% 10%\n` +
+      `  center`
+  ),
+
+  'backspace-sends-backspace': hterm.PreferenceManager.definePref_(
+      'Backspace key behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `If true, the backspace should send BS ('\\x08', aka ^H). Otherwise ` +
+      `the backspace key should send '\\x7f'.`
+  ),
+
+  'character-map-overrides': hterm.PreferenceManager.definePref_(
+      'Character map overrides',
+      hterm.PreferenceManager.categories.Appearance,
+      null, 'value',
+      `This is specified as an object. It is a sparse array, where each ` +
+      `property is the character set code and the value is an object that is ` +
+      `a sparse array itself. In that sparse array, each property is the ` +
+      `received character and the value is the displayed character.\n` +
+      `\n` +
+      `For example:\n` +
+      `  {"0":{"+":"\\u2192",",":"\\u2190","-":"\\u2191",".":"\\u2193", ` +
+      `"0":"\\u2588"}}`
+  ),
+
+  'close-on-exit': hterm.PreferenceManager.definePref_(
+      'Close window on exit',
+      hterm.PreferenceManager.categories.Miscellaneous,
+      true, 'bool',
+      `Whether to close the window when the command finishes executing.`
+  ),
+
+  'cursor-blink': hterm.PreferenceManager.definePref_(
+      'Cursor blink',
+      hterm.PreferenceManager.categories.Appearance,
+      false, 'bool',
+      `Whether the text cursor blinks by default. This can be toggled at ` +
+      `runtime via terminal escape sequences.`
+  ),
+
+  'cursor-blink-cycle': hterm.PreferenceManager.definePref_(
+      'Cursor blink rate',
+      hterm.PreferenceManager.categories.Appearance,
+      [1000, 500], 'value',
+      `The text cursor blink rate in milliseconds.\n` +
+      `\n` +
+      `A two element array, the first of which is how long the text cursor ` +
+      `should be on, second is how long it should be off.`
+  ),
+
+  'cursor-shape': hterm.PreferenceManager.definePref_(
+      'Text cursor shape',
+      hterm.PreferenceManager.categories.Appearance,
+      'BLOCK', ['BLOCK', 'BEAM', 'UNDERLINE'],
+      `The shape of the visible text cursor. This can be toggled at ` +
+      `runtime via terminal escape sequences.`
+  ),
+
+  'cursor-color': hterm.PreferenceManager.definePref_(
+      'Text cursor color',
+      hterm.PreferenceManager.categories.Appearance,
+      'rgba(255, 0, 0, 0.5)', 'color',
+      `The color of the visible text cursor.`
+  ),
+
+  'color-palette-overrides': hterm.PreferenceManager.definePref_(
+      'Initial color palette',
+      hterm.PreferenceManager.categories.Appearance,
+      null, 'value',
+      `Override colors in the default palette.\n` +
+      `\n` +
+      `This can be specified as an array or an object. If specified as an ` +
+      `object it is assumed to be a sparse array, where each property ` +
+      `is a numeric index into the color palette.\n` +
+      `\n` +
+      `Values can be specified as almost any CSS color value. This ` +
+      `includes #RGB, #RRGGBB, rgb(...), rgba(...), and any color names ` +
+      `that are also part of the standard X11 rgb.txt file.\n` +
+      `\n` +
+      `You can use 'null' to specify that the default value should be not ` +
+      `be changed. This is useful for skipping a small number of indices ` +
+      `when the value is specified as an array.\n` +
+      `\n` +
+      `For example, these both set color index 1 to blue:\n` +
+      `  {1: "#0000ff"}\n` +
+      `  [null, "#0000ff"]`
+  ),
+
+  'copy-on-select': hterm.PreferenceManager.definePref_(
+      'Automatically copy selected content',
+      hterm.PreferenceManager.categories.CopyPaste,
+      true, 'bool',
+      `Automatically copy mouse selection to the clipboard.`
+  ),
+
+  'use-default-window-copy': hterm.PreferenceManager.definePref_(
+      'Let the browser handle text copying',
+      hterm.PreferenceManager.categories.CopyPaste,
+      false, 'bool',
+      `Whether to use the default browser/OS's copy behavior.\n` +
+      `\n` +
+      `Allow the browser/OS to handle the copy event directly which might ` +
+      `improve compatibility with some systems (where copying doesn't work ` +
+      `at all), but makes the text selection less robust.\n` +
+      `\n` +
+      `For example, long lines that were automatically line wrapped will ` +
+      `be copied with the newlines still in them.`
+  ),
+
+  'clear-selection-after-copy': hterm.PreferenceManager.definePref_(
+      'Automatically clear text selection',
+      hterm.PreferenceManager.categories.CopyPaste,
+      true, 'bool',
+      `Whether to clear the selection after copying.`
+  ),
+
+  'ctrl-plus-minus-zero-zoom': hterm.PreferenceManager.definePref_(
+      'Ctrl-+/-/0 zoom behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      true, 'bool',
+      `If true, Ctrl-Plus/Minus/Zero controls zoom.\n` +
+      `If false, Ctrl-Shift-Plus/Minus/Zero controls zoom, Ctrl-Minus sends ` +
+      `^_, Ctrl-Plus/Zero do nothing.`
+  ),
+
+  'ctrl-c-copy': hterm.PreferenceManager.definePref_(
+      'Ctrl-C copy behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `Ctrl-C copies if true, send ^C to host if false.\n` +
+      `Ctrl-Shift-C sends ^C to host if true, copies if false.`
+  ),
+
+  'ctrl-v-paste': hterm.PreferenceManager.definePref_(
+      'Ctrl-V paste behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `Ctrl-V pastes if true, send ^V to host if false.\n` +
+      `Ctrl-Shift-V sends ^V to host if true, pastes if false.`
+  ),
+
+  'east-asian-ambiguous-as-two-column': hterm.PreferenceManager.definePref_(
+      'East Asian Ambiguous use two columns',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `Whether East Asian Ambiguous characters have two column width.`
+  ),
+
+  'enable-8-bit-control': hterm.PreferenceManager.definePref_(
+      'Support non-UTF-8 C1 control characters',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `True to enable 8-bit control characters, false to ignore them.\n` +
+      `\n` +
+      `We'll respect the two-byte versions of these control characters ` +
+      `regardless of this setting.`
+  ),
+
+  'enable-bold': hterm.PreferenceManager.definePref_(
+      'Bold text behavior',
+      hterm.PreferenceManager.categories.Appearance,
+      null, 'tristate',
+      `If true, use bold weight font for text with the bold/bright ` +
+      `attribute. False to use the normal weight font. Null to autodetect.`
+  ),
+
+  'enable-bold-as-bright': hterm.PreferenceManager.definePref_(
+      'Use bright colors with bold text',
+      hterm.PreferenceManager.categories.Appearance,
+      true, 'bool',
+      `If true, use bright colors (8-15 on a 16 color palette) for any text ` +
+      `with the bold attribute. False otherwise.`
+  ),
+
+  'enable-blink': hterm.PreferenceManager.definePref_(
+      'Enable blinking text',
+      hterm.PreferenceManager.categories.Appearance,
+      true, 'bool',
+      `If true, respect the blink attribute. False to ignore it.`
+  ),
+
+  'enable-clipboard-notice': hterm.PreferenceManager.definePref_(
+      'Show notification when copying content',
+      hterm.PreferenceManager.categories.CopyPaste,
+      true, 'bool',
+      `Whether to show a message in the terminal when the host writes to the ` +
+      `clipboard.`
+  ),
+
+  'enable-clipboard-write': hterm.PreferenceManager.definePref_(
+      'Allow remote clipboard writes',
+      hterm.PreferenceManager.categories.CopyPaste,
+      true, 'bool',
+      `Allow the remote host to write directly to the local system ` +
+      `clipboard.\n` +
+      `Read access is never granted regardless of this setting.\n` +
+      `\n` +
+      `This is used to control access to features like OSC-52.`
+  ),
+
+  'enable-dec12': hterm.PreferenceManager.definePref_(
+      'Allow changing of text cursor blinking',
+      hterm.PreferenceManager.categories.Miscellaneous,
+      false, 'bool',
+      `Respect the host's attempt to change the text cursor blink status ` +
+      `using DEC Private Mode 12.`
+  ),
+
+  'enable-csi-j-3': hterm.PreferenceManager.definePref_(
+      'Allow clearing of scrollback buffer (CSI-J-3)',
+      hterm.PreferenceManager.categories.Miscellaneous,
+      true, 'bool',
+      `Whether CSI-J (Erase Display) mode 3 may clear the terminal ` +
+      `scrollback buffer.\n` +
+      `\n` +
+      `Enabling this by default is safe.`
+  ),
+
+  'environment': hterm.PreferenceManager.definePref_(
+      'Environment variables',
+      hterm.PreferenceManager.categories.Miscellaneous,
+      {
+        // Signal ncurses based apps to use UTF-8 output instead of legacy
+        // drawing modes (which only work in ISO-2022 mode).  Since hterm is
+        // always UTF-8, this shouldn't cause problems.
+        'NCURSES_NO_UTF8_ACS': '1',
+        'TERM': 'xterm-256color',
+        // Set this env var that a bunch of mainstream terminal emulators set
+        // to indicate we support true colors.
+        // https://gist.github.com/XVilka/8346728
+        'COLORTERM': 'truecolor',
+      },
+      'value',
+      `The initial set of environment variables, as an object.`
+  ),
+
+  'font-family': hterm.PreferenceManager.definePref_(
+      'Text font family',
+      hterm.PreferenceManager.categories.Appearance,
+      '"DejaVu Sans Mono", "Noto Sans Mono", "Everson Mono", FreeMono, ' +
+      'Menlo, Terminal, monospace',
+      'string',
+      `Default font family for the terminal text.`
+  ),
+
+  'font-size': hterm.PreferenceManager.definePref_(
+      'Text font size',
+      hterm.PreferenceManager.categories.Appearance,
+      15, 'int',
+      `The default font size in pixels.`
+  ),
+
+  'font-smoothing': hterm.PreferenceManager.definePref_(
+      'Text font smoothing',
+      hterm.PreferenceManager.categories.Appearance,
+      'antialiased', 'string',
+      `CSS font-smoothing property.`
+  ),
+
+  'foreground-color': hterm.PreferenceManager.definePref_(
+      'Text color',
+      hterm.PreferenceManager.categories.Appearance,
+      'rgb(240, 240, 240)', 'color',
+      `The foreground color for text with no other color attributes.`
+  ),
+
+  'hide-mouse-while-typing': hterm.PreferenceManager.definePref_(
+      'Hide mouse cursor while typing',
+      hterm.PreferenceManager.categories.Keyboard,
+      null, 'tristate',
+      `Whether to automatically hide the mouse cursor when typing. ` +
+      `By default, autodetect whether the platform/OS handles this.\n` +
+      `\n` +
+      `Note: Some operating systems may override this setting and thus you ` +
+      `might not be able to always disable it.`
+  ),
+
+  'home-keys-scroll': hterm.PreferenceManager.definePref_(
+      'Home/End key scroll behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `If true, Home/End controls the terminal scrollbar and Shift-Home/` +
+      `Shift-End are sent to the remote host. If false, then Home/End are ` +
+      `sent to the remote host and Shift-Home/Shift-End scrolls.`
+  ),
+
+  'keybindings': hterm.PreferenceManager.definePref_(
+      'Keyboard bindings/shortcuts',
+      hterm.PreferenceManager.categories.Keyboard,
+      null, 'value',
+      `A map of key sequence to key actions. Key sequences include zero or ` +
+      `more modifier keys followed by a key code. Key codes can be decimal ` +
+      `or hexadecimal numbers, or a key identifier. Key actions can be ` +
+      `specified as a string to send to the host, or an action identifier. ` +
+      `For a full explanation of the format, see https://goo.gl/LWRndr.\n` +
+      `\n` +
+      `Sample keybindings:\n` +
+      `{\n` +
+      `  "Ctrl-Alt-K": "clearTerminal",\n` +
+      `  "Ctrl-Shift-L": "PASS",\n` +
+      `  "Ctrl-H": "'Hello World'"\n` +
+      `}`
+  ),
+
+  'media-keys-are-fkeys': hterm.PreferenceManager.definePref_(
+      'Media keys are Fkeys',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `If true, convert media keys to their Fkey equivalent. If false, let ` +
+      `the browser handle the keys.`
+  ),
+
+  'meta-sends-escape': hterm.PreferenceManager.definePref_(
+      'Meta key modifier handling',
+      hterm.PreferenceManager.categories.Keyboard,
+      true, 'bool',
+      `Send an ESC prefix when pressing a key while holding the Meta key.\n` +
+      `\n` +
+      `For example, when enabled, pressing Meta-K will send ^[k as if you ` +
+      `typed Escape then k. When disabled, only k will be sent.`
+  ),
+
+  'mouse-right-click-paste': hterm.PreferenceManager.definePref_(
+      'Mouse right clicks paste content',
+      hterm.PreferenceManager.categories.CopyPaste,
+      true, 'bool',
+      `Paste on right mouse button clicks.\n` +
+      `\n` +
+      `This option is independent of the "mouse-paste-button" setting.\n` +
+      `\n` +
+      `Note: This will handle left & right handed mice correctly.`
+  ),
+
+  'mouse-paste-button': hterm.PreferenceManager.definePref_(
+      'Mouse button paste',
+      hterm.PreferenceManager.categories.CopyPaste,
+      null, [null, 0, 1, 2, 3, 4, 5, 6],
+      `Mouse paste button, or null to autodetect.\n` +
+      `\n` +
+      `For autodetect, we'll use the middle mouse button for non-X11 ` +
+      `platforms (including Chrome OS). On X11, we'll use the right mouse ` +
+      `button (since the native window manager should paste via the middle ` +
+      `mouse button).\n` +
+      `\n` +
+      `0 == left (primary) button.\n` +
+      `1 == middle (auxiliary) button.\n` +
+      `2 == right (secondary) button.\n` +
+      `\n` +
+      `This option is independent of the setting for right-click paste.\n` +
+      `\n` +
+      `Note: This will handle left & right handed mice correctly.`
+  ),
+
+  'word-break-match-left': hterm.PreferenceManager.definePref_(
+      'Automatic selection halting (to the left)',
+      hterm.PreferenceManager.categories.CopyPaste,
+      '[^\\s\\[\\](){}<>"\'\\^!@#$%&*,;:`]', 'string',
+      `Regular expression to halt matching to the left (start) of a ` +
+      `selection.\n` +
+      `\n` +
+      `Normally this is a character class to reject specific characters.\n` +
+      `We allow "~" and "." by default as paths frequently start with those.`
+  ),
+
+  'word-break-match-right': hterm.PreferenceManager.definePref_(
+      'Automatic selection halting (to the right)',
+      hterm.PreferenceManager.categories.CopyPaste,
+      '[^\\s\\[\\](){}<>"\'\\^!@#$%&*,;:~.`]', 'string',
+      `Regular expression to halt matching to the right (end) of a ` +
+      `selection.\n` +
+      `\n` +
+      `Normally this is a character class to reject specific characters.`
+  ),
+
+  'word-break-match-middle': hterm.PreferenceManager.definePref_(
+      'Word break characters',
+      hterm.PreferenceManager.categories.CopyPaste,
+      '[^\\s\\[\\](){}<>"\'\\^]*', 'string',
+      `Regular expression to match all the characters in the middle.\n` +
+      `\n` +
+      `Normally this is a character class to reject specific characters.\n` +
+      `\n` +
+      `Used to expand the selection surrounding the starting point.`
+  ),
+
+  'page-keys-scroll': hterm.PreferenceManager.definePref_(
+      'Page Up/Down key scroll behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      false, 'bool',
+      `If true, Page Up/Page Down controls the terminal scrollbar and ` +
+      `Shift-Page Up/Shift-Page Down are sent to the remote host. If false, ` +
+      `then Page Up/Page Down are sent to the remote host and Shift-Page Up/` +
+      `Shift-Page Down scrolls.`
+  ),
+
+  'pass-alt-number': hterm.PreferenceManager.definePref_(
+      'Pass Alt-1..9 key behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      null, 'tristate',
+      `Whether Alt-1..9 is passed to the browser.\n` +
+      `\n` +
+      `This is handy when running hterm in a browser tab, so that you don't ` +
+      `lose Chrome's "switch to tab" keyboard accelerators. When not running ` +
+      `in a tab it's better to send these keys to the host so they can be ` +
+      `used in vim or emacs.\n` +
+      `\n` +
+      `If true, Alt-1..9 will be handled by the browser. If false, Alt-1..9 ` +
+      `will be sent to the host. If null, autodetect based on browser ` +
+      `platform and window type.`
+  ),
+
+  'pass-ctrl-number': hterm.PreferenceManager.definePref_(
+      'Pass Ctrl-1..9 key behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      null, 'tristate',
+      `Whether Ctrl-1..9 is passed to the browser.\n` +
+      `\n` +
+      `This is handy when running hterm in a browser tab, so that you don't ` +
+      `lose Chrome's "switch to tab" keyboard accelerators. When not running ` +
+      `in a tab it's better to send these keys to the host so they can be ` +
+      `used in vim or emacs.\n` +
+      `\n` +
+      `If true, Ctrl-1..9 will be handled by the browser. If false, ` +
+      `Ctrl-1..9 will be sent to the host. If null, autodetect based on ` +
+      `browser platform and window type.`
+  ),
+
+  'pass-meta-number': hterm.PreferenceManager.definePref_(
+      'Pass Meta-1..9 key behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      null, 'tristate',
+      `Whether Meta-1..9 is passed to the browser.\n` +
+      `\n` +
+      `This is handy when running hterm in a browser tab, so that you don't ` +
+      `lose Chrome's "switch to tab" keyboard accelerators. When not running ` +
+      `in a tab it's better to send these keys to the host so they can be ` +
+      `used in vim or emacs.\n` +
+      `\n` +
+      `If true, Meta-1..9 will be handled by the browser. If false, ` +
+      `Meta-1..9 will be sent to the host. If null, autodetect based on ` +
+      `browser platform and window type.`
+  ),
+
+  'pass-meta-v': hterm.PreferenceManager.definePref_(
+      'Pass Meta-V key behavior',
+      hterm.PreferenceManager.categories.Keyboard,
+      true, 'bool',
+      `Whether Meta-V gets passed to host.`
+  ),
+
+  'paste-on-drop': hterm.PreferenceManager.definePref_(
+      'Allow drag & drop to paste',
+      hterm.PreferenceManager.categories.CopyPaste,
+      true, 'bool',
+      `If true, Drag and dropped text will paste into terminal.\n` +
+      `If false, dropped text will be ignored.`
+  ),
+
+  'receive-encoding': hterm.PreferenceManager.definePref_(
+      'Receive encoding',
+      hterm.PreferenceManager.categories.Encoding,
+      'utf-8', ['utf-8', 'raw'],
+      `Set the expected encoding for data received from the host.\n` +
+      `If the encodings do not match, visual bugs are likely to be ` +
+      `observed.\n` +
+      `\n` +
+      `Valid values are 'utf-8' and 'raw'.`
+  ),
+
+  'scroll-on-keystroke': hterm.PreferenceManager.definePref_(
+      'Scroll to bottom after keystroke',
+      hterm.PreferenceManager.categories.Scrolling,
+      true, 'bool',
+      `Whether to scroll to the bottom on any keystroke.`
+  ),
+
+  'scroll-on-output': hterm.PreferenceManager.definePref_(
+      'Scroll to bottom after new output',
+      hterm.PreferenceManager.categories.Scrolling,
+      false, 'bool',
+      `Whether to scroll to the bottom on terminal output.`
+  ),
+
+  'scrollbar-visible': hterm.PreferenceManager.definePref_(
+      'Scrollbar visibility',
+      hterm.PreferenceManager.categories.Scrolling,
+      true, 'bool',
+      `The vertical scrollbar mode.`
+  ),
+
+  'scroll-wheel-may-send-arrow-keys': hterm.PreferenceManager.definePref_(
+      'Emulate arrow keys with scroll wheel',
+      hterm.PreferenceManager.categories.Scrolling,
+      false, 'bool',
+      `When using the alternative screen buffer, and DECCKM (Application ` +
+      `Cursor Keys) is active, mouse wheel scroll events will emulate arrow ` +
+      `keys.\n` +
+      `\n` +
+      `It can be temporarily disabled by holding the Shift key.\n` +
+      `\n` +
+      `This frequently comes up when using pagers (less) or reading man ` +
+      `pages or text editors (vi/nano) or using screen/tmux.`
+  ),
+
+  'scroll-wheel-move-multiplier': hterm.PreferenceManager.definePref_(
+      'Mouse scroll wheel multiplier',
+      hterm.PreferenceManager.categories.Scrolling,
+      1, 'int',
+      `The multiplier for scroll wheel events when measured in pixels.\n` +
+      `\n` +
+      `Alters how fast the page scrolls.`
+  ),
+
+  'terminal-encoding': hterm.PreferenceManager.definePref_(
+      'Terminal encoding',
+      hterm.PreferenceManager.categories.Encoding,
+      'utf-8', ['iso-2022', 'utf-8', 'utf-8-locked'],
+      `The default terminal encoding (DOCS).\n` +
+      `\n` +
+      `ISO-2022 enables character map translations (like graphics maps).\n` +
+      `UTF-8 disables support for those.\n` +
+      `\n` +
+      `The locked variant means the encoding cannot be changed at runtime ` +
+      `via terminal escape sequences.\n` +
+      `\n` +
+      `You should stick with UTF-8 unless you notice broken rendering with ` +
+      `legacy applications.`
+  ),
+
+  'shift-insert-paste': hterm.PreferenceManager.definePref_(
+      'Shift-Insert paste',
+      hterm.PreferenceManager.categories.Keyboard,
+      true, 'bool',
+      `Whether Shift-Insert is used for pasting or is sent to the remote host.`
+  ),
+
+  'user-css': hterm.PreferenceManager.definePref_(
+      'Custom CSS (URI)',
+      hterm.PreferenceManager.categories.Appearance,
+      '', 'url',
+      `URL of user stylesheet to include in the terminal document.`
+  ),
+
+  'user-css-text': hterm.PreferenceManager.definePref_(
+      'Custom CSS (inline text)',
+      hterm.PreferenceManager.categories.Appearance,
+      '', 'multiline-string',
+      `Custom CSS text for styling the terminal.`
+  ),
+
+  'allow-images-inline': hterm.PreferenceManager.definePref_(
+      'Allow inline image display',
+      hterm.PreferenceManager.categories.Extensions,
+      null, 'tristate',
+      `Whether to allow the remote host to display images in the terminal.\n` +
+      `\n` +
+      `By default, we prompt until a choice is made.`
+  ),
+};
+
+hterm.PreferenceManager.prototype =
+    Object.create(lib.PreferenceManager.prototype);
+hterm.PreferenceManager.constructor = hterm.PreferenceManager;
+// SOURCE FILE: hterm/js/hterm_pubsub.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Utility class used to add publish/subscribe/unsubscribe functionality to
+ * an existing object.
+ */
+hterm.PubSub = function() {
+  this.observers_ = {};
+};
+
+/**
+ * Add publish, subscribe, and unsubscribe methods to an existing object.
+ *
+ * No other properties of the object are touched, so there is no need to
+ * worry about clashing private properties.
+ *
+ * @param {Object} obj The object to add this behavior to.
+ */
+hterm.PubSub.addBehavior = function(obj) {
+  var pubsub = new hterm.PubSub();
+  for (var m in hterm.PubSub.prototype) {
+    obj[m] = hterm.PubSub.prototype[m].bind(pubsub);
+  }
+};
+
+/**
+ * Subscribe to be notified of messages about a subject.
+ *
+ * @param {string} subject The subject to subscribe to.
+ * @param {function(Object)} callback The function to invoke for notifications.
+ */
+hterm.PubSub.prototype.subscribe = function(subject, callback) {
+  if (!(subject in this.observers_))
+    this.observers_[subject] = [];
+
+  this.observers_[subject].push(callback);
+};
+
+/**
+ * Unsubscribe from a subject.
+ *
+ * @param {string} subject The subject to unsubscribe from.
+ * @param {function(Object)} callback A callback previously registered via
+ *     subscribe().
+ */
+hterm.PubSub.prototype.unsubscribe = function(subject, callback) {
+  var list = this.observers_[subject];
+  if (!list)
+    throw 'Invalid subject: ' + subject;
+
+  var i = list.indexOf(callback);
+  if (i < 0)
+    throw 'Not subscribed: ' + subject;
+
+  list.splice(i, 1);
+};
+
+/**
+ * Publish a message about a subject.
+ *
+ * Subscribers (and the optional final callback) are invoked asynchronously.
+ * This method will return before anyone is actually notified.
+ *
+ * @param {string} subject The subject to publish about.
+ * @param {Object} e An arbitrary object associated with this notification.
+ * @param {function(Object)} opt_lastCallback An optional function to call after
+ *     all subscribers have been notified.
+ */
+hterm.PubSub.prototype.publish = function(subject, e, opt_lastCallback) {
+  function notifyList(i) {
+    // Set this timeout before invoking the callback, so we don't have to
+    // concern ourselves with exceptions.
+    if (i < list.length - 1)
+      setTimeout(notifyList, 0, i + 1);
+
+    list[i](e);
+  }
+
+  var list = this.observers_[subject];
+  if (list) {
+    // Copy the list, in case it changes while we're notifying.
+    list = [].concat(list);
+  }
+
+  if (opt_lastCallback) {
+    if (list) {
+      list.push(opt_lastCallback);
+    } else {
+      list = [opt_lastCallback];
+    }
+  }
+
+  if (list)
+    setTimeout(notifyList, 0, 0);
+};
+// SOURCE FILE: hterm/js/hterm_screen.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview This class represents a single terminal screen full of text.
+ *
+ * It maintains the current cursor position and has basic methods for text
+ * insert and overwrite, and adding or removing rows from the screen.
+ *
+ * This class has no knowledge of the scrollback buffer.
+ *
+ * The number of rows on the screen is determined only by the number of rows
+ * that the caller inserts into the screen.  If a caller wants to ensure a
+ * constant number of rows on the screen, it's their responsibility to remove a
+ * row for each row inserted.
+ *
+ * The screen width, in contrast, is enforced locally.
+ *
+ *
+ * In practice...
+ * - The hterm.Terminal class holds two hterm.Screen instances.  One for the
+ * primary screen and one for the alternate screen.
+ *
+ * - The html.Screen class only cares that rows are HTMLElements.  In the
+ * larger context of hterm, however, the rows happen to be displayed by an
+ * hterm.ScrollPort and have to follow a few rules as a result.  Each
+ * row must be rooted by the custom HTML tag 'x-row', and each must have a
+ * rowIndex property that corresponds to the index of the row in the context
+ * of the scrollback buffer.  These invariants are enforced by hterm.Terminal
+ * because that is the class using the hterm.Screen in the context of an
+ * hterm.ScrollPort.
+ */
+
+/**
+ * Create a new screen instance.
+ *
+ * The screen initially has no rows and a maximum column count of 0.
+ *
+ * @param {integer=} columnCount The maximum number of columns for this
+ *    screen.  See insertString() and overwriteString() for information about
+ *    what happens when too many characters are added too a row.  Defaults to
+ *    0 if not provided.
+ */
+hterm.Screen = function(columnCount=0) {
+  /**
+   * Public, read-only access to the rows in this screen.
+   */
+  this.rowsArray = [];
+
+  // The max column width for this screen.
+  this.columnCount_ = columnCount;
+
+  // The current color, bold, underline and blink attributes.
+  this.textAttributes = new hterm.TextAttributes(window.document);
+
+  // Current zero-based cursor coordinates.
+  this.cursorPosition = new hterm.RowCol(0, 0);
+
+  // Saved state used by DECSC and related settings.  This is only for saving
+  // and restoring specific state, not for the current/active state.
+  this.cursorState_ = new hterm.Screen.CursorState(this);
+
+  // The node containing the row that the cursor is positioned on.
+  this.cursorRowNode_ = null;
+
+  // The node containing the span of text that the cursor is positioned on.
+  this.cursorNode_ = null;
+
+  // The offset in column width into cursorNode_ where the cursor is positioned.
+  this.cursorOffset_ = null;
+
+  // Regexes for expanding word selections.
+  this.wordBreakMatchLeft = null;
+  this.wordBreakMatchRight = null;
+  this.wordBreakMatchMiddle = null;
+};
+
+/**
+ * Return the screen size as an hterm.Size object.
+ *
+ * @return {hterm.Size} hterm.Size object representing the current number
+ *     of rows and columns in this screen.
+ */
+hterm.Screen.prototype.getSize = function() {
+  return new hterm.Size(this.columnCount_, this.rowsArray.length);
+};
+
+/**
+ * Return the current number of rows in this screen.
+ *
+ * @return {integer} The number of rows in this screen.
+ */
+hterm.Screen.prototype.getHeight = function() {
+  return this.rowsArray.length;
+};
+
+/**
+ * Return the current number of columns in this screen.
+ *
+ * @return {integer} The number of columns in this screen.
+ */
+hterm.Screen.prototype.getWidth = function() {
+  return this.columnCount_;
+};
+
+/**
+ * Set the maximum number of columns per row.
+ *
+ * @param {integer} count The maximum number of columns per row.
+ */
+hterm.Screen.prototype.setColumnCount = function(count) {
+  this.columnCount_ = count;
+
+  if (this.cursorPosition.column >= count)
+    this.setCursorPosition(this.cursorPosition.row, count - 1);
+};
+
+/**
+ * Remove the first row from the screen and return it.
+ *
+ * @return {HTMLElement} The first row in this screen.
+ */
+hterm.Screen.prototype.shiftRow = function() {
+  return this.shiftRows(1)[0];
+};
+
+/**
+ * Remove rows from the top of the screen and return them as an array.
+ *
+ * @param {integer} count The number of rows to remove.
+ * @return {Array.<HTMLElement>} The selected rows.
+ */
+hterm.Screen.prototype.shiftRows = function(count) {
+  return this.rowsArray.splice(0, count);
+};
+
+/**
+ * Insert a row at the top of the screen.
+ *
+ * @param {HTMLElement} row The row to insert.
+ */
+hterm.Screen.prototype.unshiftRow = function(row) {
+  this.rowsArray.splice(0, 0, row);
+};
+
+/**
+ * Insert rows at the top of the screen.
+ *
+ * @param {Array.<HTMLElement>} rows The rows to insert.
+ */
+hterm.Screen.prototype.unshiftRows = function(rows) {
+  this.rowsArray.unshift.apply(this.rowsArray, rows);
+};
+
+/**
+ * Remove the last row from the screen and return it.
+ *
+ * @return {HTMLElement} The last row in this screen.
+ */
+hterm.Screen.prototype.popRow = function() {
+  return this.popRows(1)[0];
+};
+
+/**
+ * Remove rows from the bottom of the screen and return them as an array.
+ *
+ * @param {integer} count The number of rows to remove.
+ * @return {Array.<HTMLElement>} The selected rows.
+ */
+hterm.Screen.prototype.popRows = function(count) {
+  return this.rowsArray.splice(this.rowsArray.length - count, count);
+};
+
+/**
+ * Insert a row at the bottom of the screen.
+ *
+ * @param {HTMLElement} row The row to insert.
+ */
+hterm.Screen.prototype.pushRow = function(row) {
+  this.rowsArray.push(row);
+};
+
+/**
+ * Insert rows at the bottom of the screen.
+ *
+ * @param {Array.<HTMLElement>} rows The rows to insert.
+ */
+hterm.Screen.prototype.pushRows = function(rows) {
+  rows.push.apply(this.rowsArray, rows);
+};
+
+/**
+ * Insert a row at the specified row of the screen.
+ *
+ * @param {integer} index The index to insert the row.
+ * @param {HTMLElement} row The row to insert.
+ */
+hterm.Screen.prototype.insertRow = function(index, row) {
+  this.rowsArray.splice(index, 0, row);
+};
+
+/**
+ * Insert rows at the specified row of the screen.
+ *
+ * @param {integer} index The index to insert the rows.
+ * @param {Array.<HTMLElement>} rows The rows to insert.
+ */
+hterm.Screen.prototype.insertRows = function(index, rows) {
+  for (var i = 0; i < rows.length; i++) {
+    this.rowsArray.splice(index + i, 0, rows[i]);
+  }
+};
+
+/**
+ * Remove a row from the screen and return it.
+ *
+ * @param {integer} index The index of the row to remove.
+ * @return {HTMLElement} The selected row.
+ */
+hterm.Screen.prototype.removeRow = function(index) {
+  return this.rowsArray.splice(index, 1)[0];
+};
+
+/**
+ * Remove rows from the bottom of the screen and return them as an array.
+ *
+ * @param {integer} index The index to start removing rows.
+ * @param {integer} count The number of rows to remove.
+ * @return {Array.<HTMLElement>} The selected rows.
+ */
+hterm.Screen.prototype.removeRows = function(index, count) {
+  return this.rowsArray.splice(index, count);
+};
+
+/**
+ * Invalidate the current cursor position.
+ *
+ * This sets this.cursorPosition to (0, 0) and clears out some internal
+ * data.
+ *
+ * Attempting to insert or overwrite text while the cursor position is invalid
+ * will raise an obscure exception.
+ */
+hterm.Screen.prototype.invalidateCursorPosition = function() {
+  this.cursorPosition.move(0, 0);
+  this.cursorRowNode_ = null;
+  this.cursorNode_ = null;
+  this.cursorOffset_ = null;
+};
+
+/**
+ * Clear the contents of the cursor row.
+ */
+hterm.Screen.prototype.clearCursorRow = function() {
+  this.cursorRowNode_.innerHTML = '';
+  this.cursorRowNode_.removeAttribute('line-overflow');
+  this.cursorOffset_ = 0;
+  this.cursorPosition.column = 0;
+  this.cursorPosition.overflow = false;
+
+  var text;
+  if (this.textAttributes.isDefault()) {
+    text = '';
+  } else {
+    text = ' '.repeat(this.columnCount_);
+  }
+
+  // We shouldn't honor inverse colors when clearing an area, to match
+  // xterm's back color erase behavior.
+  var inverse = this.textAttributes.inverse;
+  this.textAttributes.inverse = false;
+  this.textAttributes.syncColors();
+
+  var node = this.textAttributes.createContainer(text);
+  this.cursorRowNode_.appendChild(node);
+  this.cursorNode_ = node;
+
+  this.textAttributes.inverse = inverse;
+  this.textAttributes.syncColors();
+};
+
+/**
+ * Mark the current row as having overflowed to the next line.
+ *
+ * The line overflow state is used when converting a range of rows into text.
+ * It makes it possible to recombine two or more overflow terminal rows into
+ * a single line.
+ *
+ * This is distinct from the cursor being in the overflow state.  Cursor
+ * overflow indicates that printing at the cursor position will commit a
+ * line overflow, unless it is preceded by a repositioning of the cursor
+ * to a non-overflow state.
+ */
+hterm.Screen.prototype.commitLineOverflow = function() {
+  this.cursorRowNode_.setAttribute('line-overflow', true);
+};
+
+/**
+ * Relocate the cursor to a give row and column.
+ *
+ * @param {integer} row The zero based row.
+ * @param {integer} column The zero based column.
+ */
+hterm.Screen.prototype.setCursorPosition = function(row, column) {
+  if (!this.rowsArray.length) {
+    console.warn('Attempt to set cursor position on empty screen.');
+    return;
+  }
+
+  if (row >= this.rowsArray.length) {
+    console.error('Row out of bounds: ' + row);
+    row = this.rowsArray.length - 1;
+  } else if (row < 0) {
+    console.error('Row out of bounds: ' + row);
+    row = 0;
+  }
+
+  if (column >= this.columnCount_) {
+    console.error('Column out of bounds: ' + column);
+    column = this.columnCount_ - 1;
+  } else if (column < 0) {
+    console.error('Column out of bounds: ' + column);
+    column = 0;
+  }
+
+  this.cursorPosition.overflow = false;
+
+  var rowNode = this.rowsArray[row];
+  var node = rowNode.firstChild;
+
+  if (!node) {
+    node = rowNode.ownerDocument.createTextNode('');
+    rowNode.appendChild(node);
+  }
+
+  var currentColumn = 0;
+
+  if (rowNode == this.cursorRowNode_) {
+    if (column >= this.cursorPosition.column - this.cursorOffset_) {
+      node = this.cursorNode_;
+      currentColumn = this.cursorPosition.column - this.cursorOffset_;
+    }
+  } else {
+    this.cursorRowNode_ = rowNode;
+  }
+
+  this.cursorPosition.move(row, column);
+
+  while (node) {
+    var offset = column - currentColumn;
+    var width = hterm.TextAttributes.nodeWidth(node);
+    if (!node.nextSibling || width > offset) {
+      this.cursorNode_ = node;
+      this.cursorOffset_ = offset;
+      return;
+    }
+
+    currentColumn += width;
+    node = node.nextSibling;
+  }
+};
+
+/**
+ * Set the provided selection object to be a caret selection at the current
+ * cursor position.
+ */
+hterm.Screen.prototype.syncSelectionCaret = function(selection) {
+  try {
+    selection.collapse(this.cursorNode_, this.cursorOffset_);
+  } catch (firefoxIgnoredException) {
+    // FF can throw an exception if the range is off, rather than just not
+    // performing the collapse.
+  }
+};
+
+/**
+ * Split a single node into two nodes at the given offset.
+ *
+ * For example:
+ * Given the DOM fragment '<div><span>Hello World</span></div>', call splitNode_
+ * passing the span and an offset of 6.  This would modify the fragment to
+ * become: '<div><span>Hello </span><span>World</span></div>'.  If the span
+ * had any attributes they would have been copied to the new span as well.
+ *
+ * The to-be-split node must have a container, so that the new node can be
+ * placed next to it.
+ *
+ * @param {HTMLNode} node The node to split.
+ * @param {integer} offset The offset into the node where the split should
+ *     occur.
+ */
+hterm.Screen.prototype.splitNode_ = function(node, offset) {
+  var afterNode = node.cloneNode(false);
+
+  var textContent = node.textContent;
+  node.textContent = hterm.TextAttributes.nodeSubstr(node, 0, offset);
+  afterNode.textContent = lib.wc.substr(textContent, offset);
+
+  if (afterNode.textContent)
+    node.parentNode.insertBefore(afterNode, node.nextSibling);
+  if (!node.textContent)
+    node.parentNode.removeChild(node);
+};
+
+/**
+ * Ensure that text is clipped and the cursor is clamped to the column count.
+ */
+hterm.Screen.prototype.maybeClipCurrentRow = function() {
+  var width = hterm.TextAttributes.nodeWidth(this.cursorRowNode_);
+
+  if (width <= this.columnCount_) {
+    // Current row does not need clipping, but may need clamping.
+    if (this.cursorPosition.column >= this.columnCount_) {
+      this.setCursorPosition(this.cursorPosition.row, this.columnCount_ - 1);
+      this.cursorPosition.overflow = true;
+    }
+
+    return;
+  }
+
+  // Save off the current column so we can maybe restore it later.
+  var currentColumn = this.cursorPosition.column;
+
+  // Move the cursor to the final column.
+  this.setCursorPosition(this.cursorPosition.row, this.columnCount_ - 1);
+
+  // Remove any text that partially overflows.
+  width = hterm.TextAttributes.nodeWidth(this.cursorNode_);
+
+  if (this.cursorOffset_ < width - 1) {
+    this.cursorNode_.textContent = hterm.TextAttributes.nodeSubstr(
+        this.cursorNode_, 0, this.cursorOffset_ + 1);
+  }
+
+  // Remove all nodes after the cursor.
+  var rowNode = this.cursorRowNode_;
+  var node = this.cursorNode_.nextSibling;
+
+  while (node) {
+    rowNode.removeChild(node);
+    node = this.cursorNode_.nextSibling;
+  }
+
+  if (currentColumn < this.columnCount_) {
+    // If the cursor was within the screen before we started then restore its
+    // position.
+    this.setCursorPosition(this.cursorPosition.row, currentColumn);
+  } else {
+    // Otherwise leave it at the the last column in the overflow state.
+    this.cursorPosition.overflow = true;
+  }
+};
+
+/**
+ * Insert a string at the current character position using the current
+ * text attributes.
+ *
+ * You must call maybeClipCurrentRow() after in order to clip overflowed
+ * text and clamp the cursor.
+ *
+ * It is also up to the caller to properly maintain the line overflow state
+ * using hterm.Screen..commitLineOverflow().
+ */
+hterm.Screen.prototype.insertString = function(str, wcwidth=undefined) {
+  var cursorNode = this.cursorNode_;
+  var cursorNodeText = cursorNode.textContent;
+
+  this.cursorRowNode_.removeAttribute('line-overflow');
+
+  // We may alter the width of the string by prepending some missing
+  // whitespaces, so we need to record the string width ahead of time.
+  if (wcwidth === undefined)
+    wcwidth = lib.wc.strWidth(str);
+
+  // No matter what, before this function exits the cursor column will have
+  // moved this much.
+  this.cursorPosition.column += wcwidth;
+
+  // Local cache of the cursor offset.
+  var offset = this.cursorOffset_;
+
+  // Reverse offset is the offset measured from the end of the string.
+  // Zero implies that the cursor is at the end of the cursor node.
+  var reverseOffset = hterm.TextAttributes.nodeWidth(cursorNode) - offset;
+
+  if (reverseOffset < 0) {
+    // A negative reverse offset means the cursor is positioned past the end
+    // of the characters on this line.  We'll need to insert the missing
+    // whitespace.
+    const ws = ' '.repeat(-reverseOffset);
+
+    // This whitespace should be completely unstyled.  Underline, background
+    // color, and strikethrough would be visible on whitespace, so we can't use
+    // one of those spans to hold the text.
+    if (!(this.textAttributes.underline ||
+          this.textAttributes.strikethrough ||
+          this.textAttributes.background ||
+          this.textAttributes.wcNode ||
+          !this.textAttributes.asciiNode ||
+          this.textAttributes.tileData != null)) {
+      // Best case scenario, we can just pretend the spaces were part of the
+      // original string.
+      str = ws + str;
+    } else if (cursorNode.nodeType == Node.TEXT_NODE ||
+               !(cursorNode.wcNode ||
+                 !cursorNode.asciiNode ||
+                 cursorNode.tileNode ||
+                 cursorNode.style.textDecoration ||
+                 cursorNode.style.textDecorationStyle ||
+                 cursorNode.style.textDecorationLine ||
+                 cursorNode.style.backgroundColor)) {
+      // Second best case, the current node is able to hold the whitespace.
+      cursorNode.textContent = (cursorNodeText += ws);
+    } else {
+      // Worst case, we have to create a new node to hold the whitespace.
+      var wsNode = cursorNode.ownerDocument.createTextNode(ws);
+      this.cursorRowNode_.insertBefore(wsNode, cursorNode.nextSibling);
+      this.cursorNode_ = cursorNode = wsNode;
+      this.cursorOffset_ = offset = -reverseOffset;
+      cursorNodeText = ws;
+    }
+
+    // We now know for sure that we're at the last character of the cursor node.
+    reverseOffset = 0;
+  }
+
+  if (this.textAttributes.matchesContainer(cursorNode)) {
+    // The new text can be placed directly in the cursor node.
+    if (reverseOffset == 0) {
+      cursorNode.textContent = cursorNodeText + str;
+    } else if (offset == 0) {
+      cursorNode.textContent = str + cursorNodeText;
+    } else {
+      cursorNode.textContent =
+          hterm.TextAttributes.nodeSubstr(cursorNode, 0, offset) +
+          str + hterm.TextAttributes.nodeSubstr(cursorNode, offset);
+    }
+
+    this.cursorOffset_ += wcwidth;
+    return;
+  }
+
+  // The cursor node is the wrong style for the new text.  If we're at the
+  // beginning or end of the cursor node, then the adjacent node is also a
+  // potential candidate.
+
+  if (offset == 0) {
+    // At the beginning of the cursor node, the check the previous sibling.
+    var previousSibling = cursorNode.previousSibling;
+    if (previousSibling &&
+        this.textAttributes.matchesContainer(previousSibling)) {
+      previousSibling.textContent += str;
+      this.cursorNode_ = previousSibling;
+      this.cursorOffset_ = lib.wc.strWidth(previousSibling.textContent);
+      return;
+    }
+
+    var newNode = this.textAttributes.createContainer(str);
+    this.cursorRowNode_.insertBefore(newNode, cursorNode);
+    this.cursorNode_ = newNode;
+    this.cursorOffset_ = wcwidth;
+    return;
+  }
+
+  if (reverseOffset == 0) {
+    // At the end of the cursor node, the check the next sibling.
+    var nextSibling = cursorNode.nextSibling;
+    if (nextSibling &&
+        this.textAttributes.matchesContainer(nextSibling)) {
+      nextSibling.textContent = str + nextSibling.textContent;
+      this.cursorNode_ = nextSibling;
+      this.cursorOffset_ = lib.wc.strWidth(str);
+      return;
+    }
+
+    var newNode = this.textAttributes.createContainer(str);
+    this.cursorRowNode_.insertBefore(newNode, nextSibling);
+    this.cursorNode_ = newNode;
+    // We specifically need to include any missing whitespace here, since it's
+    // going in a new node.
+    this.cursorOffset_ = hterm.TextAttributes.nodeWidth(newNode);
+    return;
+  }
+
+  // Worst case, we're somewhere in the middle of the cursor node.  We'll
+  // have to split it into two nodes and insert our new container in between.
+  this.splitNode_(cursorNode, offset);
+  var newNode = this.textAttributes.createContainer(str);
+  this.cursorRowNode_.insertBefore(newNode, cursorNode.nextSibling);
+  this.cursorNode_ = newNode;
+  this.cursorOffset_ = wcwidth;
+};
+
+/**
+ * Overwrite the text at the current cursor position.
+ *
+ * You must call maybeClipCurrentRow() after in order to clip overflowed
+ * text and clamp the cursor.
+ *
+ * It is also up to the caller to properly maintain the line overflow state
+ * using hterm.Screen..commitLineOverflow().
+ */
+hterm.Screen.prototype.overwriteString = function(str, wcwidth=undefined) {
+  var maxLength = this.columnCount_ - this.cursorPosition.column;
+  if (!maxLength)
+    return;
+
+  if (wcwidth === undefined)
+    wcwidth = lib.wc.strWidth(str);
+
+  if (this.textAttributes.matchesContainer(this.cursorNode_) &&
+      this.cursorNode_.textContent.substr(this.cursorOffset_) == str) {
+    // This overwrite would be a no-op, just move the cursor and return.
+    this.cursorOffset_ += wcwidth;
+    this.cursorPosition.column += wcwidth;
+    return;
+  }
+
+  this.deleteChars(Math.min(wcwidth, maxLength));
+  this.insertString(str, wcwidth);
+};
+
+/**
+ * Forward-delete one or more characters at the current cursor position.
+ *
+ * Text to the right of the deleted characters is shifted left.  Only affects
+ * characters on the same row as the cursor.
+ *
+ * @param {integer} count The column width of characters to delete.  This is
+ *     clamped to the column width minus the cursor column.
+ * @return {integer} The column width of the characters actually deleted.
+ */
+hterm.Screen.prototype.deleteChars = function(count) {
+  var node = this.cursorNode_;
+  var offset = this.cursorOffset_;
+
+  var currentCursorColumn = this.cursorPosition.column;
+  count = Math.min(count, this.columnCount_ - currentCursorColumn);
+  if (!count)
+    return 0;
+
+  var rv = count;
+  var startLength, endLength;
+
+  while (node && count) {
+    // Sanity check so we don't loop forever, but we don't also go quietly.
+    if (count < 0) {
+      console.error(`Deleting ${rv} chars went negative: ${count}`);
+      break;
+    }
+
+    startLength = hterm.TextAttributes.nodeWidth(node);
+    node.textContent = hterm.TextAttributes.nodeSubstr(node, 0, offset) +
+        hterm.TextAttributes.nodeSubstr(node, offset + count);
+    endLength = hterm.TextAttributes.nodeWidth(node);
+
+    // Deal with splitting wide characters.  There are two ways: we could delete
+    // the first column or the second column.  In both cases, we delete the wide
+    // character and replace one of the columns with a space (since the other
+    // was deleted).  If there are more chars to delete, the next loop will pick
+    // up the slack.
+    if (node.wcNode && offset < startLength &&
+        ((endLength && startLength == endLength) || (!endLength && offset == 1))) {
+      // No characters were deleted when there should be.  We're probably trying
+      // to delete one column width from a wide character node.  We remove the
+      // wide character node here and replace it with a single space.
+      var spaceNode = this.textAttributes.createContainer(' ');
+      node.parentNode.insertBefore(spaceNode, offset ? node : node.nextSibling);
+      node.textContent = '';
+      endLength = 0;
+      count -= 1;
+    } else
+      count -= startLength - endLength;
+
+    var nextNode = node.nextSibling;
+    if (endLength == 0 && node != this.cursorNode_) {
+      node.parentNode.removeChild(node);
+    }
+    node = nextNode;
+    offset = 0;
+  }
+
+  // Remove this.cursorNode_ if it is an empty non-text node.
+  if (this.cursorNode_.nodeType != Node.TEXT_NODE &&
+      !this.cursorNode_.textContent) {
+    var cursorNode = this.cursorNode_;
+    if (cursorNode.previousSibling) {
+      this.cursorNode_ = cursorNode.previousSibling;
+      this.cursorOffset_ = hterm.TextAttributes.nodeWidth(
+          cursorNode.previousSibling);
+    } else if (cursorNode.nextSibling) {
+      this.cursorNode_ = cursorNode.nextSibling;
+      this.cursorOffset_ = 0;
+    } else {
+      var emptyNode = this.cursorRowNode_.ownerDocument.createTextNode('');
+      this.cursorRowNode_.appendChild(emptyNode);
+      this.cursorNode_ = emptyNode;
+      this.cursorOffset_ = 0;
+    }
+    this.cursorRowNode_.removeChild(cursorNode);
+  }
+
+  return rv;
+};
+
+/**
+ * Finds first X-ROW of a line containing specified X-ROW.
+ * Used to support line overflow.
+ *
+ * @param {Node} row X-ROW to begin search for first row of line.
+ * @return {Node} The X-ROW that is at the beginning of the line.
+ **/
+hterm.Screen.prototype.getLineStartRow_ = function(row) {
+  while (row.previousSibling &&
+         row.previousSibling.hasAttribute('line-overflow')) {
+    row = row.previousSibling;
+  }
+  return row;
+};
+
+/**
+ * Gets text of a line beginning with row.
+ * Supports line overflow.
+ *
+ * @param {Node} row First X-ROW of line.
+ * @return {string} Text content of line.
+ **/
+hterm.Screen.prototype.getLineText_ = function(row) {
+  var rowText = "";
+  while (row) {
+    rowText += row.textContent;
+    if (row.hasAttribute('line-overflow')) {
+      row = row.nextSibling;
+    } else {
+      break;
+    }
+  }
+  return rowText;
+};
+
+/**
+ * Returns X-ROW that is ancestor of the node.
+ *
+ * @param {Node} node Node to get X-ROW ancestor for.
+ * @return {Node} X-ROW ancestor of node, or null if not found.
+ **/
+hterm.Screen.prototype.getXRowAncestor_ = function(node) {
+  while (node) {
+    if (node.nodeName === 'X-ROW')
+      break;
+    node = node.parentNode;
+  }
+  return node;
+};
+
+/**
+ * Returns position within line of character at offset within node.
+ * Supports line overflow.
+ *
+ * @param {Node} row X-ROW at beginning of line.
+ * @param {Node} node Node to get position of.
+ * @param {integer} offset Offset into node.
+ *
+ * @return {integer} Position within line of character at offset within node.
+ **/
+hterm.Screen.prototype.getPositionWithOverflow_ = function(row, node, offset) {
+  if (!node)
+    return -1;
+  var ancestorRow = this.getXRowAncestor_(node);
+  if (!ancestorRow)
+    return -1;
+  var position = 0;
+  while (ancestorRow != row) {
+    position += hterm.TextAttributes.nodeWidth(row);
+    if (row.hasAttribute('line-overflow') && row.nextSibling) {
+      row = row.nextSibling;
+    } else {
+      return -1;
+    }
+  }
+  return position + this.getPositionWithinRow_(row, node, offset);
+};
+
+/**
+ * Returns position within row of character at offset within node.
+ * Does not support line overflow.
+ *
+ * @param {Node} row X-ROW to get position within.
+ * @param {Node} node Node to get position for.
+ * @param {integer} offset Offset within node to get position for.
+ * @return {integer} Position within row of character at offset within node.
+ **/
+hterm.Screen.prototype.getPositionWithinRow_ = function(row, node, offset) {
+  if (node.parentNode != row) {
+    // If we traversed to the top node, then there's nothing to find here.
+    if (node.parentNode == null)
+      return -1;
+
+    return this.getPositionWithinRow_(node.parentNode, node, offset) +
+           this.getPositionWithinRow_(row, node.parentNode, 0);
+  }
+  var position = 0;
+  for (var i = 0; i < row.childNodes.length; i++) {
+    var currentNode = row.childNodes[i];
+    if (currentNode == node)
+      return position + offset;
+    position += hterm.TextAttributes.nodeWidth(currentNode);
+  }
+  return -1;
+};
+
+/**
+ * Returns the node and offset corresponding to position within line.
+ * Supports line overflow.
+ *
+ * @param {Node} row X-ROW at beginning of line.
+ * @param {integer} position Position within line to retrieve node and offset.
+ * @return {Array} Two element array containing node and offset respectively.
+ **/
+hterm.Screen.prototype.getNodeAndOffsetWithOverflow_ = function(row, position) {
+  while (row && position > hterm.TextAttributes.nodeWidth(row)) {
+    if (row.hasAttribute('line-overflow') && row.nextSibling) {
+      position -= hterm.TextAttributes.nodeWidth(row);
+      row = row.nextSibling;
+    } else {
+      return -1;
+    }
+  }
+  return this.getNodeAndOffsetWithinRow_(row, position);
+};
+
+/**
+ * Returns the node and offset corresponding to position within row.
+ * Does not support line overflow.
+ *
+ * @param {Node} row X-ROW to get position within.
+ * @param {integer} position Position within row to retrieve node and offset.
+ * @return {Array} Two element array containing node and offset respectively.
+ **/
+hterm.Screen.prototype.getNodeAndOffsetWithinRow_ = function(row, position) {
+  for (var i = 0; i < row.childNodes.length; i++) {
+    var node = row.childNodes[i];
+    var nodeTextWidth = hterm.TextAttributes.nodeWidth(node);
+    if (position <= nodeTextWidth) {
+      if (node.nodeName === 'SPAN') {
+        /** Drill down to node contained by SPAN. **/
+        return this.getNodeAndOffsetWithinRow_(node, position);
+      } else {
+        return [node, position];
+      }
+    }
+    position -= nodeTextWidth;
+  }
+  return null;
+};
+
+/**
+ * Returns the node and offset corresponding to position within line.
+ * Supports line overflow.
+ *
+ * @param {Node} row X-ROW at beginning of line.
+ * @param {integer} start Start position of range within line.
+ * @param {integer} end End position of range within line.
+ * @param {Range} range Range to modify.
+ **/
+hterm.Screen.prototype.setRange_ = function(row, start, end, range) {
+  var startNodeAndOffset = this.getNodeAndOffsetWithOverflow_(row, start);
+  if (startNodeAndOffset == null)
+    return;
+  var endNodeAndOffset = this.getNodeAndOffsetWithOverflow_(row, end);
+  if (endNodeAndOffset == null)
+    return;
+  range.setStart(startNodeAndOffset[0], startNodeAndOffset[1]);
+  range.setEnd(endNodeAndOffset[0], endNodeAndOffset[1]);
+};
+
+/**
+ * Expands selection to surrounding string with word break matches.
+ *
+ * @param {Selection} selection Selection to expand.
+ * @param {string} leftMatch left word break match.
+ * @param {string} rightMatch right word break match.
+ * @param {string} insideMatch inside word break match.
+ */
+hterm.Screen.prototype.expandSelectionWithWordBreakMatches_ =
+    function(selection, leftMatch, rightMatch, insideMatch) {
+  if (!selection)
+    return;
+
+  var range = selection.getRangeAt(0);
+  if (!range || range.toString().match(/\s/))
+    return;
+
+  const rowElement = this.getXRowAncestor_(range.startContainer);
+  if (!rowElement)
+    return;
+  const row = this.getLineStartRow_(rowElement);
+  if (!row)
+    return;
+
+  var startPosition = this.getPositionWithOverflow_(row,
+                                                    range.startContainer,
+                                                    range.startOffset);
+  if (startPosition == -1)
+    return;
+  var endPosition = this.getPositionWithOverflow_(row,
+                                                  range.endContainer,
+                                                  range.endOffset);
+  if (endPosition == -1)
+    return;
+
+  //Move start to the left.
+  var rowText = this.getLineText_(row);
+  var lineUpToRange = lib.wc.substring(rowText, 0, endPosition);
+  var leftRegularExpression = new RegExp(leftMatch + insideMatch + "$");
+  var expandedStart = lineUpToRange.search(leftRegularExpression);
+  if (expandedStart == -1 || expandedStart > startPosition)
+    return;
+
+  //Move end to the right.
+  var lineFromRange = lib.wc.substring(rowText, startPosition,
+                                       lib.wc.strWidth(rowText));
+  var rightRegularExpression = new RegExp("^" + insideMatch + rightMatch);
+  var found = lineFromRange.match(rightRegularExpression);
+  if (!found)
+    return;
+  var expandedEnd = startPosition + lib.wc.strWidth(found[0]);
+  if (expandedEnd == -1 || expandedEnd < endPosition)
+    return;
+
+  this.setRange_(row, expandedStart, expandedEnd, range);
+  selection.addRange(range);
+};
+
+/**
+ * Expands selection to surrounding string using the user's settings.
+ *
+ * @param {Selection} selection Selection to expand.
+ */
+hterm.Screen.prototype.expandSelection = function(selection) {
+  this.expandSelectionWithWordBreakMatches_(
+      selection,
+      this.wordBreakMatchLeft,
+      this.wordBreakMatchRight,
+      this.wordBreakMatchMiddle);
+};
+
+/**
+ * Expands selection to surrounding URL using a set of fixed match settings.
+ *
+ * @param {Selection} selection Selection to expand.
+ */
+hterm.Screen.prototype.expandSelectionForUrl = function(selection) {
+  this.expandSelectionWithWordBreakMatches_(
+      selection,
+      "[^\\s\\[\\](){}<>\"'\\^!@#$%&*,;:`]",
+      "[^\\s\\[\\](){}<>\"'\\^!@#$%&*,;:~.`]",
+      "[^\\s\\[\\](){}<>\"'\\^]*");
+};
+
+/**
+ * Save the current cursor state to the corresponding screens.
+ *
+ * @param {hterm.VT} vt The VT object to read graphic codeset details from.
+ */
+hterm.Screen.prototype.saveCursorAndState = function(vt) {
+  this.cursorState_.save(vt);
+};
+
+/**
+ * Restore the saved cursor state in the corresponding screens.
+ *
+ * @param {hterm.VT} vt The VT object to write graphic codeset details to.
+ */
+hterm.Screen.prototype.restoreCursorAndState = function(vt) {
+  this.cursorState_.restore(vt);
+};
+
+/**
+ * Track all the things related to the current "cursor".
+ *
+ * The set of things saved & restored here is defined by DEC:
+ * https://vt100.net/docs/vt510-rm/DECSC.html
+ * - Cursor position
+ * - Character attributes set by the SGR command
+ * - Character sets (G0, G1, G2, or G3) currently in GL and GR
+ * - Wrap flag (autowrap or no autowrap)
+ * - State of origin mode (DECOM)
+ * - Selective erase attribute
+ * - Any single shift 2 (SS2) or single shift 3 (SS3) functions sent
+ *
+ * These are done on a per-screen basis.
+ */
+hterm.Screen.CursorState = function(screen) {
+  this.screen_ = screen;
+  this.cursor = null;
+  this.textAttributes = null;
+  this.GL = this.GR = this.G0 = this.G1 = this.G2 = this.G3 = null;
+};
+
+/**
+ * Save all the cursor state.
+ *
+ * @param {hterm.VT} vt The VT object to read graphic codeset details from.
+ */
+hterm.Screen.CursorState.prototype.save = function(vt) {
+  this.cursor = vt.terminal.saveCursor();
+
+  this.textAttributes = this.screen_.textAttributes.clone();
+
+  this.GL = vt.GL;
+  this.GR = vt.GR;
+
+  this.G0 = vt.G0;
+  this.G1 = vt.G1;
+  this.G2 = vt.G2;
+  this.G3 = vt.G3;
+};
+
+/**
+ * Restore the previously saved cursor state.
+ *
+ * @param {hterm.VT} vt The VT object to write graphic codeset details to.
+ */
+hterm.Screen.CursorState.prototype.restore = function(vt) {
+  vt.terminal.restoreCursor(this.cursor);
+
+  // Cursor restore includes char attributes (bold/etc...), but does not change
+  // the color palette (which are a terminal setting).
+  const tattrs = this.textAttributes.clone();
+  tattrs.colorPalette = this.screen_.textAttributes.colorPalette;
+  tattrs.syncColors();
+
+  this.screen_.textAttributes = tattrs;
+
+  vt.GL = this.GL;
+  vt.GR = this.GR;
+
+  vt.G0 = this.G0;
+  vt.G1 = this.G1;
+  vt.G2 = this.G2;
+  vt.G3 = this.G3;
+};
+// SOURCE FILE: hterm/js/hterm_scrollport.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * A 'viewport' view of fixed-height rows with support for selection and
+ * copy-to-clipboard.
+ *
+ * 'Viewport' in this case means that only the visible rows are in the DOM.
+ * If the rowProvider has 100,000 rows, but the ScrollPort is only 25 rows
+ * tall, then only 25 dom nodes are created.  The ScrollPort will ask the
+ * RowProvider to create new visible rows on demand as they are scrolled in
+ * to the visible area.
+ *
+ * This viewport is designed so that select and copy-to-clipboard still works,
+ * even when all or part of the selection is scrolled off screen.
+ *
+ * Note that the X11 mouse clipboard does not work properly when all or part
+ * of the selection is off screen.  It would be difficult to fix this without
+ * adding significant overhead to pathologically large selection cases.
+ *
+ * The RowProvider should return rows rooted by the custom tag name 'x-row'.
+ * This ensures that we can quickly assign the correct display height
+ * to the rows with css.
+ *
+ * @param {RowProvider} rowProvider An object capable of providing rows as
+ *     raw text or row nodes.
+ */
+hterm.ScrollPort = function(rowProvider) {
+  hterm.PubSub.addBehavior(this);
+
+  this.rowProvider_ = rowProvider;
+
+  // SWAG the character size until we can measure it.
+  this.characterSize = new hterm.Size(10, 10);
+
+  // DOM node used for character measurement.
+  this.ruler_ = null;
+
+  this.selection = new hterm.ScrollPort.Selection(this);
+
+  // A map of rowIndex => rowNode for each row that is drawn as part of a
+  // pending redraw_() call.  Null if there is no pending redraw_ call.
+  this.currentRowNodeCache_ = null;
+
+  // A map of rowIndex => rowNode for each row that was drawn as part of the
+  // previous redraw_() call.
+  this.previousRowNodeCache_ = {};
+
+  // Used during scroll events to detect when the underlying cause is a resize.
+  this.lastScreenWidth_ = null;
+  this.lastScreenHeight_ = null;
+
+  // True if the user should be allowed to select text in the terminal.
+  // This is disabled when the host requests mouse drag events so that we don't
+  // end up with two notions of selection.
+  this.selectionEnabled_ = true;
+
+  // The last row count returned by the row provider, re-populated during
+  // syncScrollHeight().
+  this.lastRowCount_ = 0;
+
+  // The scroll wheel pixel delta multiplier to increase/decrease
+  // the scroll speed of mouse wheel events. See: https://goo.gl/sXelnq
+  this.scrollWheelMultiplier_ = 1;
+
+  // The last touch events we saw to support touch based scrolling.  Indexed
+  // by touch identifier since we can have more than one touch active.
+  this.lastTouch_ = {};
+
+  /**
+   * True if the last scroll caused the scrollport to show the final row.
+   */
+  this.isScrolledEnd = true;
+
+  /**
+   * A guess at the current scrollbar width, fixed in resize().
+   */
+  this.currentScrollbarWidthPx = 16;
+
+  /**
+   * Whether the ctrl-v key on the screen should paste.
+   */
+  this.ctrlVPaste = false;
+
+  /**
+   * Whether to paste on dropped text.
+   */
+  this.pasteOnDrop = true;
+
+  this.div_ = null;
+  this.document_ = null;
+
+  // Collection of active timeout handles.
+  this.timeouts_ = {};
+
+  this.observers_ = {};
+
+  // Offscreen selection rows that are set with 'aria-hidden'.
+  // They must be unset when selection changes or the rows are visible.
+  this.ariaHiddenSelectionRows_ = [];
+
+  this.DEBUG_ = false;
+};
+
+/**
+ * Proxy for the native selection object which understands how to walk up the
+ * DOM to find the containing row node and sort out which comes first.
+ *
+ * @param {hterm.ScrollPort} scrollPort The parent hterm.ScrollPort instance.
+ */
+hterm.ScrollPort.Selection = function(scrollPort) {
+  this.scrollPort_ = scrollPort;
+
+  /**
+   * The row containing the start of the selection.
+   *
+   * This may be partially or fully selected.  It may be the selection anchor
+   * or the focus, but its rowIndex is guaranteed to be less-than-or-equal-to
+   * that of the endRow.
+   *
+   * If only one row is selected then startRow == endRow.  If there is no
+   * selection or the selection is collapsed then startRow == null.
+   */
+  this.startRow = null;
+
+  /**
+   * The row containing the end of the selection.
+   *
+   * This may be partially or fully selected.  It may be the selection anchor
+   * or the focus, but its rowIndex is guaranteed to be greater-than-or-equal-to
+   * that of the startRow.
+   *
+   * If only one row is selected then startRow == endRow.  If there is no
+   * selection or the selection is collapsed then startRow == null.
+   */
+  this.endRow = null;
+
+  /**
+   * True if startRow != endRow.
+   */
+  this.isMultiline = null;
+
+  /**
+   * True if the selection is just a point rather than a range.
+   */
+  this.isCollapsed = null;
+};
+
+/**
+ * Given a list of DOM nodes and a container, return the DOM node that
+ * is first according to a depth-first search.
+ *
+ * Returns null if none of the children are found.
+ */
+hterm.ScrollPort.Selection.prototype.findFirstChild = function(
+    parent, childAry) {
+  var node = parent.firstChild;
+
+  while (node) {
+    if (childAry.indexOf(node) != -1)
+      return node;
+
+    if (node.childNodes.length) {
+      var rv = this.findFirstChild(node, childAry);
+      if (rv)
+        return rv;
+    }
+
+    node = node.nextSibling;
+  }
+
+  return null;
+};
+
+/**
+ * Synchronize this object with the current DOM selection.
+ *
+ * This is a one-way synchronization, the DOM selection is copied to this
+ * object, not the other way around.
+ */
+hterm.ScrollPort.Selection.prototype.sync = function() {
+  var self = this;
+
+  // The dom selection object has no way to tell which nodes come first in
+  // the document, so we have to figure that out.
+  //
+  // This function is used when we detect that the "anchor" node is first.
+  function anchorFirst() {
+    self.startRow = anchorRow;
+    self.startNode = selection.anchorNode;
+    self.startOffset = selection.anchorOffset;
+    self.endRow = focusRow;
+    self.endNode = selection.focusNode;
+    self.endOffset = selection.focusOffset;
+  }
+
+  // This function is used when we detect that the "focus" node is first.
+  function focusFirst() {
+    self.startRow = focusRow;
+    self.startNode = selection.focusNode;
+    self.startOffset = selection.focusOffset;
+    self.endRow = anchorRow;
+    self.endNode = selection.anchorNode;
+    self.endOffset = selection.anchorOffset;
+  }
+
+  var selection = this.scrollPort_.getDocument().getSelection();
+
+  this.startRow = null;
+  this.endRow = null;
+  this.isMultiline = null;
+  this.isCollapsed = !selection || selection.isCollapsed;
+
+  if (!selection) {
+    return;
+  }
+
+  // Usually collapsed selections wouldn't be interesting, however screen
+  // readers will set a collapsed selection as they navigate through the DOM.
+  // It is important to preserve these nodes in the DOM as scrolling happens
+  // so that screen reader navigation isn't cleared.
+  const accessibilityEnabled = this.scrollPort_.accessibilityReader_ &&
+      this.scrollPort_.accessibilityReader_.accessibilityEnabled;
+  if (this.isCollapsed && !accessibilityEnabled) {
+    return;
+  }
+
+  var anchorRow = selection.anchorNode;
+  while (anchorRow && anchorRow.nodeName != 'X-ROW') {
+    anchorRow = anchorRow.parentNode;
+  }
+
+  if (!anchorRow) {
+    // Don't set a selection if it's not a row node that's selected.
+    return;
+  }
+
+  var focusRow = selection.focusNode;
+  while (focusRow && focusRow.nodeName != 'X-ROW') {
+    focusRow = focusRow.parentNode;
+  }
+
+  if (!focusRow) {
+    // Don't set a selection if it's not a row node that's selected.
+    return;
+  }
+
+  if (anchorRow.rowIndex < focusRow.rowIndex) {
+    anchorFirst();
+
+  } else if (anchorRow.rowIndex > focusRow.rowIndex) {
+    focusFirst();
+
+  } else if (selection.focusNode == selection.anchorNode) {
+    if (selection.anchorOffset < selection.focusOffset) {
+      anchorFirst();
+    } else {
+      focusFirst();
+    }
+
+  } else {
+    // The selection starts and ends in the same row, but isn't contained all
+    // in a single node.
+    var firstNode = this.findFirstChild(
+        anchorRow, [selection.anchorNode, selection.focusNode]);
+
+    if (!firstNode)
+      throw new Error('Unexpected error syncing selection.');
+
+    if (firstNode == selection.anchorNode) {
+      anchorFirst();
+    } else {
+      focusFirst();
+    }
+  }
+
+  this.isMultiline = anchorRow.rowIndex != focusRow.rowIndex;
+};
+
+
+/**
+ * Turn a div into this hterm.ScrollPort.
+ */
+hterm.ScrollPort.prototype.decorate = function(div, callback) {
+  this.div_ = div;
+
+  this.iframe_ = div.ownerDocument.createElement('iframe');
+  this.iframe_.style.cssText = (
+      'border: 0;' +
+      'height: 100%;' +
+      'position: absolute;' +
+      'width: 100%');
+
+  div.appendChild(this.iframe_);
+
+  const onLoad = () => {
+    this.paintIframeContents_();
+    if (callback) {
+      callback();
+    }
+  };
+
+  // Insert Iframe content asynchronously in FF.  Otherwise when the frame's
+  // load event fires in FF it clears out the content of the iframe.
+  if ('mozInnerScreenX' in window) { // detect a FF only property
+    this.iframe_.addEventListener('load', () => onLoad());
+  } else {
+    onLoad();
+  }
+};
+
+
+/**
+ * Initialises the content of this.iframe_. This needs to be done asynchronously
+ * in FF after the Iframe's load event has fired.
+ * @private
+ */
+hterm.ScrollPort.prototype.paintIframeContents_ = function() {
+  this.iframe_.contentWindow.addEventListener('resize',
+                                              this.onResize_.bind(this));
+
+  var doc = this.document_ = this.iframe_.contentDocument;
+  doc.body.style.cssText = (
+      'margin: 0px;' +
+      'padding: 0px;' +
+      'height: 100%;' +
+      'width: 100%;' +
+      'overflow: hidden;' +
+      'cursor: var(--hterm-mouse-cursor-style);' +
+      '-webkit-user-select: none;' +
+      '-moz-user-select: none;');
+
+  const metaCharset = doc.createElement('meta');
+  metaCharset.setAttribute('charset', 'utf-8');
+  doc.head.appendChild(metaCharset);
+
+  if (this.DEBUG_) {
+    // When we're debugging we add padding to the body so that the offscreen
+    // elements are visible.
+    this.document_.body.style.paddingTop =
+        this.document_.body.style.paddingBottom =
+        'calc(var(--hterm-charsize-height) * 3)';
+  }
+
+  var style = doc.createElement('style');
+  style.textContent = (
+      'x-row {' +
+      '  display: block;' +
+      '  height: var(--hterm-charsize-height);' +
+      '  line-height: var(--hterm-charsize-height);' +
+      '}');
+  doc.head.appendChild(style);
+
+  this.userCssLink_ = doc.createElement('link');
+  this.userCssLink_.setAttribute('rel', 'stylesheet');
+
+  this.userCssText_ = doc.createElement('style');
+  doc.head.appendChild(this.userCssText_);
+
+  // TODO(rginda): Sorry, this 'screen_' isn't the same thing as hterm.Screen
+  // from screen.js.  I need to pick a better name for one of them to avoid
+  // the collision.
+  // We make this field editable even though we don't actually allow anything
+  // to be edited here so that Chrome will do the right thing with virtual
+  // keyboards and IMEs.  But make sure we turn off all the input helper logic
+  // that doesn't make sense here, and might inadvertently mung or save input.
+  // Some of these attributes are standard while others are browser specific,
+  // but should be safely ignored by other browsers.
+  this.screen_ = doc.createElement('x-screen');
+  this.screen_.setAttribute('contenteditable', 'true');
+  this.screen_.setAttribute('spellcheck', 'false');
+  this.screen_.setAttribute('autocomplete', 'off');
+  this.screen_.setAttribute('autocorrect', 'off');
+  this.screen_.setAttribute('autocapitalize', 'none');
+
+  // In some ways the terminal behaves like a text box but not in all ways. It
+  // is not editable in the same ways a text box is editable and the content we
+  // want to be read out by a screen reader does not always align with the edits
+  // (selection changes) that happen in the terminal window. Use the log role so
+  // that the screen reader doesn't treat it like a text box and announce all
+  // selection changes. The announcements that we want spoken are generated
+  // by a separate live region, which gives more control over what will be
+  // spoken.
+  this.screen_.setAttribute('role', 'log');
+  this.screen_.setAttribute('aria-live', 'off');
+  this.screen_.setAttribute('aria-roledescription', 'Terminal');
+
+  // Set aria-readonly to indicate to the screen reader that the text on the
+  // screen is not modifiable by the html cursor. It may be modifiable by
+  // sending input to the application running in the terminal, but this is
+  // orthogonal to the DOM's notion of modifiable.
+  this.screen_.setAttribute('aria-readonly', 'true');
+  this.screen_.setAttribute('tabindex', '-1');
+  this.screen_.style.cssText = (
+      'caret-color: transparent;' +
+      'display: block;' +
+      'font-family: monospace;' +
+      'font-size: 15px;' +
+      'font-variant-ligatures: none;' +
+      'height: 100%;' +
+      'overflow-y: scroll; overflow-x: hidden;' +
+      'white-space: pre;' +
+      'width: 100%;' +
+      'outline: none !important');
+
+  doc.body.appendChild(this.screen_);
+
+  this.screen_.addEventListener('scroll', this.onScroll_.bind(this));
+  this.screen_.addEventListener('wheel', this.onScrollWheel_.bind(this));
+  this.screen_.addEventListener('touchstart', this.onTouch_.bind(this));
+  this.screen_.addEventListener('touchmove', this.onTouch_.bind(this));
+  this.screen_.addEventListener('touchend', this.onTouch_.bind(this));
+  this.screen_.addEventListener('touchcancel', this.onTouch_.bind(this));
+  this.screen_.addEventListener('copy', this.onCopy_.bind(this));
+  this.screen_.addEventListener('paste', this.onPaste_.bind(this));
+  this.screen_.addEventListener('drop', this.onDragAndDrop_.bind(this));
+
+  doc.body.addEventListener('keydown', this.onBodyKeyDown_.bind(this));
+
+  // Add buttons to make accessible scrolling through terminal history work
+  // well. These are positioned off-screen until they are selected, at which
+  // point they are moved on-screen.
+  const scrollButtonHeight = 30;
+  const scrollButtonBorder = 1;
+  const scrollButtonTotalHeight = scrollButtonHeight + 2 * scrollButtonBorder;
+  const scrollButtonStyle = `right: 0px;
+                             position:fixed;
+                             z-index: 1;
+                             text-align: center;
+                             cursor: pointer;
+                             height: ${scrollButtonHeight}px;
+                             width: 110px;
+                             line-height: ${scrollButtonHeight}px;
+                             border-width: ${scrollButtonBorder}px;
+                             border-style: solid;
+                             font-weight: bold;`;
+  // Note: we use a <div> rather than a <button> because we don't want it to be
+  // focusable. If it's focusable this interferes with the contenteditable
+  // focus.
+  this.scrollUpButton_ = this.document_.createElement('div');
+  this.scrollUpButton_.id = 'hterm:a11y:page-up';
+  this.scrollUpButton_.innerText = hterm.msg('BUTTON_PAGE_UP', [], 'Page up');
+  this.scrollUpButton_.setAttribute('role', 'button');
+  this.scrollUpButton_.style.cssText = scrollButtonStyle;
+  this.scrollUpButton_.style.top = -scrollButtonTotalHeight + 'px';
+  this.scrollUpButton_.addEventListener('click', this.scrollPageUp.bind(this));
+
+  this.scrollDownButton_ = this.document_.createElement('div');
+  this.scrollDownButton_.id = 'hterm:a11y:page-down';
+  this.scrollDownButton_.innerText =
+      hterm.msg('BUTTON_PAGE_DOWN', [], 'Page down');
+  this.scrollDownButton_.setAttribute('role', 'button');
+  this.scrollDownButton_.style.cssText = scrollButtonStyle;
+  this.scrollDownButton_.style.bottom = -scrollButtonTotalHeight + 'px';
+  this.scrollDownButton_.addEventListener(
+      'click', this.scrollPageDown.bind(this));
+
+  // We only allow the scroll buttons to display after a delay, otherwise the
+  // page up button can flash onto the screen during the intial change in focus.
+  // This seems to be because it is the first element inside the <x-screen>
+  // element, which will get focussed on page load.
+  this.allowScrollButtonsToDisplay_ = false;
+  setTimeout(() => { this.allowScrollButtonsToDisplay_ = true; }, 500);
+  this.document_.addEventListener('selectionchange', () => {
+    this.selection.sync();
+
+    if (!this.allowScrollButtonsToDisplay_)
+      return;
+
+    const accessibilityEnabled = this.accessibilityReader_ &&
+        this.accessibilityReader_.accessibilityEnabled;
+
+    const selectedElement = this.document_.getSelection().anchorNode;
+    if (accessibilityEnabled && selectedElement == this.scrollUpButton_) {
+      this.scrollUpButton_.style.top = '0px';
+    } else {
+      this.scrollUpButton_.style.top = -scrollButtonTotalHeight + 'px';
+    }
+    if (accessibilityEnabled && selectedElement == this.scrollDownButton_) {
+      this.scrollDownButton_.style.bottom = '0px';
+    } else {
+      this.scrollDownButton_.style.bottom = -scrollButtonTotalHeight + 'px';
+    }
+  });
+
+  this.screen_.appendChild(this.scrollUpButton_);
+
+  // This is the main container for the fixed rows.
+  this.rowNodes_ = doc.createElement('div');
+  this.rowNodes_.id = 'hterm:row-nodes';
+  this.rowNodes_.style.cssText = (
+      'display: block;' +
+      'position: fixed;' +
+      'overflow: hidden;' +
+      '-webkit-user-select: text;' +
+      '-moz-user-select: text;');
+  this.screen_.appendChild(this.rowNodes_);
+
+  this.screen_.appendChild(this.scrollDownButton_);
+
+  // Two nodes to hold offscreen text during the copy event.
+  this.topSelectBag_ = doc.createElement('x-select-bag');
+  this.topSelectBag_.style.cssText = (
+      'display: block;' +
+      'overflow: hidden;' +
+      'height: var(--hterm-charsize-height);' +
+      'white-space: pre;');
+
+  this.bottomSelectBag_ = this.topSelectBag_.cloneNode();
+
+  // Nodes above the top fold and below the bottom fold are hidden.  They are
+  // only used to hold rows that are part of the selection but are currently
+  // scrolled off the top or bottom of the visible range.
+  this.topFold_ = doc.createElement('x-fold');
+  this.topFold_.id = 'hterm:top-fold-for-row-selection';
+  this.topFold_.style.cssText = 'display: block;';
+  this.rowNodes_.appendChild(this.topFold_);
+
+  this.bottomFold_ = this.topFold_.cloneNode();
+  this.bottomFold_.id = 'hterm:bottom-fold-for-row-selection';
+  this.rowNodes_.appendChild(this.bottomFold_);
+
+  // This hidden div accounts for the vertical space that would be consumed by
+  // all the rows in the buffer if they were visible.  It's what causes the
+  // scrollbar to appear on the 'x-screen', and it moves within the screen when
+  // the scrollbar is moved.
+  //
+  // It is set 'visibility: hidden' to keep the browser from trying to include
+  // it in the selection when a user 'drag selects' upwards (drag the mouse to
+  // select and scroll at the same time).  Without this, the selection gets
+  // out of whack.
+  this.scrollArea_ = doc.createElement('div');
+  this.scrollArea_.id = 'hterm:scrollarea';
+  this.scrollArea_.style.cssText = 'visibility: hidden';
+  this.screen_.appendChild(this.scrollArea_);
+
+  // This svg element is used to detect when the browser is zoomed.  It must be
+  // placed in the outermost document for currentScale to be correct.
+  // TODO(rginda): This means that hterm nested in an iframe will not correctly
+  // detect browser zoom level.  We should come up with a better solution.
+  // Note: This must be http:// else Chrome cannot create the element correctly.
+  var xmlns = 'http://www.w3.org/2000/svg';
+  this.svg_ = this.div_.ownerDocument.createElementNS(xmlns, 'svg');
+  this.svg_.id = 'hterm:zoom-detector';
+  this.svg_.setAttribute('xmlns', xmlns);
+  this.svg_.setAttribute('version', '1.1');
+  this.svg_.style.cssText = (
+      'position: absolute;' +
+      'top: 0;' +
+      'left: 0;' +
+      'visibility: hidden');
+
+
+  // We send focus to this element just before a paste happens, so we can
+  // capture the pasted text and forward it on to someone who cares.
+  this.pasteTarget_ = doc.createElement('textarea');
+  this.pasteTarget_.id = 'hterm:ctrl-v-paste-target';
+  this.pasteTarget_.setAttribute('tabindex', '-1');
+  this.pasteTarget_.setAttribute('aria-hidden', 'true');
+  this.pasteTarget_.style.cssText = (
+    'position: absolute;' +
+    'height: 1px;' +
+    'width: 1px;' +
+    'left: 0px; ' +
+    'bottom: 0px;' +
+    'opacity: 0');
+  this.pasteTarget_.contentEditable = true;
+
+  this.screen_.appendChild(this.pasteTarget_);
+  this.pasteTarget_.addEventListener(
+      'textInput', this.handlePasteTargetTextInput_.bind(this));
+
+  this.resize();
+};
+
+/**
+ * Set the AccessibilityReader object to use to announce page scroll updates.
+ *
+ * @param {hterm.AccessibilityReader} accessibilityReader for announcing page
+ *     scroll updates.
+ */
+hterm.ScrollPort.prototype.setAccessibilityReader =
+    function(accessibilityReader) {
+  this.accessibilityReader_ = accessibilityReader;
+};
+
+/**
+ * Scroll the terminal one page up (minus one line) relative to the current
+ * position.
+ */
+hterm.ScrollPort.prototype.scrollPageUp = function() {
+  if (this.getTopRowIndex() == 0) {
+    return;
+  }
+
+  const i = this.getTopRowIndex();
+  this.scrollRowToTop(i - this.visibleRowCount + 1);
+
+  this.assertiveAnnounce_();
+};
+
+/**
+ * Scroll the terminal one page down (minus one line) relative to the current
+ * position.
+ */
+hterm.ScrollPort.prototype.scrollPageDown = function() {
+  if (this.isScrolledEnd) {
+    return;
+  }
+
+  const i = this.getTopRowIndex();
+  this.scrollRowToTop(i + this.visibleRowCount - 1);
+
+  this.assertiveAnnounce_();
+};
+
+/**
+ * Select the font-family and font-smoothing for this scrollport.
+ *
+ * @param {string} fontFamily Value of the CSS 'font-family' to use for this
+ *     scrollport.  Should be a monospace font.
+ * @param {string} opt_smoothing Optional value for '-webkit-font-smoothing'.
+ *     Defaults to an empty string if not specified.
+ */
+hterm.ScrollPort.prototype.setFontFamily = function(fontFamily, opt_smoothing) {
+  this.screen_.style.fontFamily = fontFamily;
+  if (opt_smoothing) {
+    this.screen_.style.webkitFontSmoothing = opt_smoothing;
+  } else {
+    this.screen_.style.webkitFontSmoothing = '';
+  }
+
+  this.syncCharacterSize();
+};
+
+hterm.ScrollPort.prototype.getFontFamily = function() {
+  return this.screen_.style.fontFamily;
+};
+
+/**
+ * Set a custom stylesheet to include in the scrollport.
+ *
+ * Defaults to null, meaning no custom css is loaded.  Set it back to null or
+ * the empty string to remove a previously applied custom css.
+ */
+hterm.ScrollPort.prototype.setUserCssUrl = function(url) {
+  if (url) {
+    this.userCssLink_.setAttribute('href', url);
+
+    if (!this.userCssLink_.parentNode)
+      this.document_.head.appendChild(this.userCssLink_);
+  } else if (this.userCssLink_.parentNode) {
+    this.document_.head.removeChild(this.userCssLink_);
+  }
+};
+
+hterm.ScrollPort.prototype.setUserCssText = function(text) {
+  this.userCssText_.textContent = text;
+};
+
+hterm.ScrollPort.prototype.focus = function() {
+  this.iframe_.focus();
+  this.screen_.focus();
+  this.publish('focus');
+};
+
+hterm.ScrollPort.prototype.getForegroundColor = function() {
+  return this.screen_.style.color;
+};
+
+hterm.ScrollPort.prototype.setForegroundColor = function(color) {
+  this.screen_.style.color = color;
+  this.scrollUpButton_.style.backgroundColor = color;
+  this.scrollDownButton_.style.backgroundColor = color;
+};
+
+hterm.ScrollPort.prototype.getBackgroundColor = function() {
+  return this.screen_.style.backgroundColor;
+};
+
+hterm.ScrollPort.prototype.setBackgroundColor = function(color) {
+  this.screen_.style.backgroundColor = color;
+  this.scrollUpButton_.style.color = color;
+  this.scrollDownButton_.style.color = color;
+};
+
+hterm.ScrollPort.prototype.setBackgroundImage = function(image) {
+  this.screen_.style.backgroundImage = image;
+};
+
+hterm.ScrollPort.prototype.setBackgroundSize = function(size) {
+  this.screen_.style.backgroundSize = size;
+};
+
+hterm.ScrollPort.prototype.setBackgroundPosition = function(position) {
+  this.screen_.style.backgroundPosition = position;
+};
+
+hterm.ScrollPort.prototype.setCtrlVPaste = function(ctrlVPaste) {
+  this.ctrlVPaste = ctrlVPaste;
+};
+
+hterm.ScrollPort.prototype.setPasteOnDrop = function(pasteOnDrop) {
+  this.pasteOnDrop = pasteOnDrop;
+};
+
+/**
+ * Get the usable size of the scrollport screen.
+ *
+ * The width will not include the scrollbar width.
+ */
+hterm.ScrollPort.prototype.getScreenSize = function() {
+  var size = hterm.getClientSize(this.screen_);
+  return {
+    height: size.height,
+    width: size.width - this.currentScrollbarWidthPx
+  };
+};
+
+/**
+ * Get the usable width of the scrollport screen.
+ *
+ * This the widget width minus scrollbar width.
+ */
+hterm.ScrollPort.prototype.getScreenWidth = function() {
+  return this.getScreenSize().width ;
+};
+
+/**
+ * Get the usable height of the scrollport screen.
+ */
+hterm.ScrollPort.prototype.getScreenHeight = function() {
+  return this.getScreenSize().height;
+};
+
+/**
+ * Return the document that holds the visible rows of this hterm.ScrollPort.
+ */
+hterm.ScrollPort.prototype.getDocument = function() {
+  return this.document_;
+};
+
+/**
+ * Returns the x-screen element that holds the rows of this hterm.ScrollPort.
+ */
+hterm.ScrollPort.prototype.getScreenNode = function() {
+  return this.screen_;
+};
+
+/**
+ * Clear out any cached rowNodes.
+ */
+hterm.ScrollPort.prototype.resetCache = function() {
+  this.currentRowNodeCache_ = null;
+  this.previousRowNodeCache_ = {};
+};
+
+/**
+ * Change the current rowProvider.
+ *
+ * This will clear the row cache and cause a redraw.
+ *
+ * @param {Object} rowProvider An object capable of providing the rows
+ *     in this hterm.ScrollPort.
+ */
+hterm.ScrollPort.prototype.setRowProvider = function(rowProvider) {
+  this.resetCache();
+  this.rowProvider_ = rowProvider;
+  this.scheduleRedraw();
+};
+
+/**
+ * Inform the ScrollPort that the root DOM nodes for some or all of the visible
+ * rows are no longer valid.
+ *
+ * Specifically, this should be called if this.rowProvider_.getRowNode() now
+ * returns an entirely different node than it did before.  It does not
+ * need to be called if the content of a row node is the only thing that
+ * changed.
+ *
+ * This skips some of the overhead of a full redraw, but should not be used
+ * in cases where the scrollport has been scrolled, or when the row count has
+ * changed.
+ */
+hterm.ScrollPort.prototype.invalidate = function() {
+  var node = this.topFold_.nextSibling;
+  while (node != this.bottomFold_) {
+    var nextSibling = node.nextSibling;
+    node.parentElement.removeChild(node);
+    node = nextSibling;
+  }
+
+  this.previousRowNodeCache_ = null;
+  var topRowIndex = this.getTopRowIndex();
+  var bottomRowIndex = this.getBottomRowIndex(topRowIndex);
+
+  this.drawVisibleRows_(topRowIndex, bottomRowIndex);
+};
+
+hterm.ScrollPort.prototype.scheduleInvalidate = function() {
+  if (this.timeouts_.invalidate)
+    return;
+
+  var self = this;
+  this.timeouts_.invalidate = setTimeout(function () {
+      delete self.timeouts_.invalidate;
+      self.invalidate();
+    }, 0);
+};
+
+/**
+ * Set the font size of the ScrollPort.
+ */
+hterm.ScrollPort.prototype.setFontSize = function(px) {
+  this.screen_.style.fontSize = px + 'px';
+  this.syncCharacterSize();
+};
+
+/**
+ * Return the current font size of the ScrollPort.
+ */
+hterm.ScrollPort.prototype.getFontSize = function() {
+  return parseInt(this.screen_.style.fontSize);
+};
+
+/**
+ * Measure the size of a single character in pixels.
+ *
+ * @param {string} opt_weight The font weight to measure, or 'normal' if
+ *     omitted.
+ * @return {hterm.Size} A new hterm.Size object.
+ */
+hterm.ScrollPort.prototype.measureCharacterSize = function(opt_weight) {
+  // Number of lines used to average the height of a single character.
+  var numberOfLines = 100;
+  // Number of chars per line used to average the width of a single character.
+  var lineLength = 100;
+
+  if (!this.ruler_) {
+    this.ruler_ = this.document_.createElement('div');
+    this.ruler_.id = 'hterm:ruler-character-size';
+    this.ruler_.style.cssText = (
+        'position: absolute;' +
+        'top: 0;' +
+        'left: 0;' +
+        'visibility: hidden;' +
+        'height: auto !important;' +
+        'width: auto !important;');
+
+    // We need to put the text in a span to make the size calculation
+    // work properly in Firefox
+    this.rulerSpan_ = this.document_.createElement('span');
+    this.rulerSpan_.id = 'hterm:ruler-span-workaround';
+    this.rulerSpan_.innerHTML =
+        ('X'.repeat(lineLength) + '\r').repeat(numberOfLines);
+    this.ruler_.appendChild(this.rulerSpan_);
+
+    this.rulerBaseline_ = this.document_.createElement('span');
+    this.rulerSpan_.id = 'hterm:ruler-baseline';
+    // We want to collapse it on the baseline
+    this.rulerBaseline_.style.fontSize = '0px';
+    this.rulerBaseline_.textContent = 'X';
+  }
+
+  this.rulerSpan_.style.fontWeight = opt_weight || '';
+
+  this.rowNodes_.appendChild(this.ruler_);
+  var rulerSize = hterm.getClientSize(this.rulerSpan_);
+
+  var size = new hterm.Size(rulerSize.width / lineLength,
+                            rulerSize.height / numberOfLines);
+
+  this.ruler_.appendChild(this.rulerBaseline_);
+  this.ruler_.removeChild(this.rulerBaseline_);
+
+  this.rowNodes_.removeChild(this.ruler_);
+
+  this.div_.ownerDocument.body.appendChild(this.svg_);
+  size.zoomFactor = this.svg_.currentScale;
+  this.div_.ownerDocument.body.removeChild(this.svg_);
+
+  return size;
+};
+
+/**
+ * Synchronize the character size.
+ *
+ * This will re-measure the current character size and adjust the height
+ * of an x-row to match.
+ */
+hterm.ScrollPort.prototype.syncCharacterSize = function() {
+  this.characterSize = this.measureCharacterSize();
+
+  this.resize();
+};
+
+/**
+ * Reset dimensions and visible row count to account for a change in the
+ * dimensions of the 'x-screen'.
+ */
+hterm.ScrollPort.prototype.resize = function() {
+  this.currentScrollbarWidthPx = hterm.getClientWidth(this.screen_) -
+    this.screen_.clientWidth;
+
+  this.syncScrollHeight();
+  this.syncRowNodesDimensions_();
+
+  var self = this;
+  this.publish(
+      'resize', { scrollPort: this },
+      function() {
+        self.scrollRowToBottom(self.rowProvider_.getRowCount());
+        self.scheduleRedraw();
+      });
+};
+
+/**
+ * Announce text content on the current screen for the screen reader.
+ */
+hterm.ScrollPort.prototype.assertiveAnnounce_ = function() {
+  if (!this.accessibilityReader_) {
+    return;
+  }
+
+  const topRow = this.getTopRowIndex();
+  const bottomRow = this.getBottomRowIndex(topRow);
+
+  let percentScrolled = 100 * topRow /
+      Math.max(1, this.rowProvider_.getRowCount() - this.visibleRowCount);
+  percentScrolled = Math.min(100, Math.round(percentScrolled));
+  let currentScreenContent = hterm.msg('ANNOUNCE_CURRENT_SCREEN_HEADER',
+                                       [percentScrolled],
+                                       '$1% scrolled,');
+  currentScreenContent += '\n';
+
+  for (let i = topRow; i <= bottomRow; ++i) {
+    const node = this.fetchRowNode_(i);
+    currentScreenContent += node.textContent + '\n';
+  }
+
+  this.accessibilityReader_.assertiveAnnounce(currentScreenContent);
+};
+
+/**
+ * Set the position and size of the row nodes element.
+ */
+hterm.ScrollPort.prototype.syncRowNodesDimensions_ = function() {
+  var screenSize = this.getScreenSize();
+
+  this.lastScreenWidth_ = screenSize.width;
+  this.lastScreenHeight_ = screenSize.height;
+
+  // We don't want to show a partial row because it would be distracting
+  // in a terminal, so we floor any fractional row count.
+  this.visibleRowCount = lib.f.smartFloorDivide(
+      screenSize.height, this.characterSize.height);
+
+  // Then compute the height of our integral number of rows.
+  var visibleRowsHeight = this.visibleRowCount * this.characterSize.height;
+
+  // Then the difference between the screen height and total row height needs to
+  // be made up for as top margin.  We need to record this value so it
+  // can be used later to determine the topRowIndex.
+  this.visibleRowTopMargin = 0;
+  this.visibleRowBottomMargin = screenSize.height - visibleRowsHeight;
+
+  this.topFold_.style.marginBottom = this.visibleRowTopMargin + 'px';
+
+
+  var topFoldOffset = 0;
+  var node = this.topFold_.previousSibling;
+  while (node) {
+    topFoldOffset += hterm.getClientHeight(node);
+    node = node.previousSibling;
+  }
+
+  // Set the dimensions of the visible rows container.
+  this.rowNodes_.style.width = screenSize.width + 'px';
+  this.rowNodes_.style.height = visibleRowsHeight + topFoldOffset + 'px';
+  this.rowNodes_.style.left = this.screen_.offsetLeft + 'px';
+  this.rowNodes_.style.top = this.screen_.offsetTop - topFoldOffset + 'px';
+};
+
+hterm.ScrollPort.prototype.syncScrollHeight = function() {
+  // Resize the scroll area to appear as though it contains every row.
+  this.lastRowCount_ = this.rowProvider_.getRowCount();
+  this.scrollArea_.style.height = (this.characterSize.height *
+                                   this.lastRowCount_ +
+                                   this.visibleRowTopMargin +
+                                   this.visibleRowBottomMargin +
+                                   'px');
+};
+
+/**
+ * Schedule a redraw to happen asynchronously.
+ *
+ * If this method is called multiple times before the redraw has a chance to
+ * run only one redraw occurs.
+ */
+hterm.ScrollPort.prototype.scheduleRedraw = function() {
+  if (this.timeouts_.redraw)
+    return;
+
+  var self = this;
+  this.timeouts_.redraw = setTimeout(function () {
+      delete self.timeouts_.redraw;
+      self.redraw_();
+    }, 0);
+};
+
+/**
+ * Update the state of scroll up/down buttons.
+ *
+ * If the viewport is at the top or bottom row of output, these buttons will
+ * be made transparent and clicking them shouldn't scroll any further.
+ */
+hterm.ScrollPort.prototype.updateScrollButtonState_ = function() {
+  const setButton = (button, disabled) => {
+    button.setAttribute('aria-disabled', disabled ? 'true' : 'false');
+    button.style.opacity = disabled ? 0.5 : 1;
+  };
+  setButton(this.scrollUpButton_, this.getTopRowIndex() == 0);
+  setButton(this.scrollDownButton_, this.isScrolledEnd);
+};
+
+/**
+ * Redraw the current hterm.ScrollPort based on the current scrollbar position.
+ *
+ * When redrawing, we are careful to make sure that the rows that start or end
+ * the current selection are not touched in any way.  Doing so would disturb
+ * the selection, and cleaning up after that would cause flashes at best and
+ * incorrect selection at worst.  Instead, we modify the DOM around these nodes.
+ * We even stash the selection start/end outside of the visible area if
+ * they are not supposed to be visible in the hterm.ScrollPort.
+ */
+hterm.ScrollPort.prototype.redraw_ = function() {
+  this.resetSelectBags_();
+  this.selection.sync();
+
+  this.syncScrollHeight();
+
+  this.currentRowNodeCache_ = {};
+
+  var topRowIndex = this.getTopRowIndex();
+  var bottomRowIndex = this.getBottomRowIndex(topRowIndex);
+
+  this.drawTopFold_(topRowIndex);
+  this.drawBottomFold_(bottomRowIndex);
+  this.drawVisibleRows_(topRowIndex, bottomRowIndex);
+  this.ariaHideOffscreenSelectionRows_(topRowIndex, bottomRowIndex);
+
+  this.syncRowNodesDimensions_();
+
+  this.previousRowNodeCache_ = this.currentRowNodeCache_;
+  this.currentRowNodeCache_ = null;
+
+  this.isScrolledEnd = (
+    this.getTopRowIndex() + this.visibleRowCount >= this.lastRowCount_);
+
+  this.updateScrollButtonState_();
+};
+
+/**
+ * Ensure that the nodes above the top fold are as they should be.
+ *
+ * If the selection start and/or end nodes are above the visible range
+ * of this hterm.ScrollPort then the dom will be adjusted so that they appear
+ * before the top fold (the first x-fold element, aka this.topFold).
+ *
+ * If not, the top fold will be the first element.
+ *
+ * It is critical that this method does not move the selection nodes.  Doing
+ * so would clear the current selection.  Instead, the rest of the DOM is
+ * adjusted around them.
+ */
+hterm.ScrollPort.prototype.drawTopFold_ = function(topRowIndex) {
+  if (!this.selection.startRow ||
+      this.selection.startRow.rowIndex >= topRowIndex) {
+    // Selection is entirely below the top fold, just make sure the fold is
+    // the first child.
+    if (this.rowNodes_.firstChild != this.topFold_)
+      this.rowNodes_.insertBefore(this.topFold_, this.rowNodes_.firstChild);
+
+    return;
+  }
+
+  if (!this.selection.isMultiline ||
+      this.selection.endRow.rowIndex >= topRowIndex) {
+    // Only the startRow is above the fold.
+    if (this.selection.startRow.nextSibling != this.topFold_)
+      this.rowNodes_.insertBefore(this.topFold_,
+                                  this.selection.startRow.nextSibling);
+  } else {
+    // Both rows are above the fold.
+    if (this.selection.endRow.nextSibling != this.topFold_) {
+      this.rowNodes_.insertBefore(this.topFold_,
+                                  this.selection.endRow.nextSibling);
+    }
+
+    // Trim any intermediate lines.
+    while (this.selection.startRow.nextSibling !=
+           this.selection.endRow) {
+      this.rowNodes_.removeChild(this.selection.startRow.nextSibling);
+    }
+  }
+
+  while(this.rowNodes_.firstChild != this.selection.startRow) {
+    this.rowNodes_.removeChild(this.rowNodes_.firstChild);
+  }
+};
+
+/**
+ * Ensure that the nodes below the bottom fold are as they should be.
+ *
+ * If the selection start and/or end nodes are below the visible range
+ * of this hterm.ScrollPort then the dom will be adjusted so that they appear
+ * after the bottom fold (the second x-fold element, aka this.bottomFold).
+ *
+ * If not, the bottom fold will be the last element.
+ *
+ * It is critical that this method does not move the selection nodes.  Doing
+ * so would clear the current selection.  Instead, the rest of the DOM is
+ * adjusted around them.
+ */
+hterm.ScrollPort.prototype.drawBottomFold_ = function(bottomRowIndex) {
+  if (!this.selection.endRow ||
+      this.selection.endRow.rowIndex <= bottomRowIndex) {
+    // Selection is entirely above the bottom fold, just make sure the fold is
+    // the last child.
+    if (this.rowNodes_.lastChild != this.bottomFold_)
+      this.rowNodes_.appendChild(this.bottomFold_);
+
+    return;
+  }
+
+  if (!this.selection.isMultiline ||
+      this.selection.startRow.rowIndex <= bottomRowIndex) {
+    // Only the endRow is below the fold.
+    if (this.bottomFold_.nextSibling != this.selection.endRow)
+      this.rowNodes_.insertBefore(this.bottomFold_,
+                                  this.selection.endRow);
+  } else {
+    // Both rows are below the fold.
+    if (this.bottomFold_.nextSibling != this.selection.startRow) {
+      this.rowNodes_.insertBefore(this.bottomFold_,
+                                  this.selection.startRow);
+    }
+
+    // Trim any intermediate lines.
+    while (this.selection.startRow.nextSibling !=
+           this.selection.endRow) {
+      this.rowNodes_.removeChild(this.selection.startRow.nextSibling);
+    }
+  }
+
+  while(this.rowNodes_.lastChild != this.selection.endRow) {
+    this.rowNodes_.removeChild(this.rowNodes_.lastChild);
+  }
+};
+
+/**
+ * Ensure that the rows between the top and bottom folds are as they should be.
+ *
+ * This method assumes that drawTopFold_() and drawBottomFold_() have already
+ * run, and that they have left any visible selection row (selection start
+ * or selection end) between the folds.
+ *
+ * It recycles DOM nodes from the previous redraw where possible, but will ask
+ * the rowSource to make new nodes if necessary.
+ *
+ * It is critical that this method does not move the selection nodes.  Doing
+ * so would clear the current selection.  Instead, the rest of the DOM is
+ * adjusted around them.
+ */
+hterm.ScrollPort.prototype.drawVisibleRows_ = function(
+    topRowIndex, bottomRowIndex) {
+  var self = this;
+
+  // Keep removing nodes, starting with currentNode, until we encounter
+  // targetNode.  Throws on failure.
+  function removeUntilNode(currentNode, targetNode) {
+    while (currentNode != targetNode) {
+      if (!currentNode)
+        throw 'Did not encounter target node';
+
+      if (currentNode == self.bottomFold_)
+        throw 'Encountered bottom fold before target node';
+
+      var deadNode = currentNode;
+      currentNode = currentNode.nextSibling;
+      deadNode.parentNode.removeChild(deadNode);
+    }
+  }
+
+  // Shorthand for things we're going to use a lot.
+  var selectionStartRow = this.selection.startRow;
+  var selectionEndRow = this.selection.endRow;
+  var bottomFold = this.bottomFold_;
+
+  // The node we're examining during the current iteration.
+  var node = this.topFold_.nextSibling;
+
+  var targetDrawCount = Math.min(this.visibleRowCount,
+                                 this.rowProvider_.getRowCount());
+
+  for (var drawCount = 0; drawCount < targetDrawCount; drawCount++) {
+    var rowIndex = topRowIndex + drawCount;
+
+    if (node == bottomFold) {
+      // We've hit the bottom fold, we need to insert a new row.
+      var newNode = this.fetchRowNode_(rowIndex);
+      if (!newNode) {
+        console.log("Couldn't fetch row index: " + rowIndex);
+        break;
+      }
+
+      this.rowNodes_.insertBefore(newNode, node);
+      continue;
+    }
+
+    if (node.rowIndex == rowIndex) {
+      // This node is in the right place, move along.
+      node = node.nextSibling;
+      continue;
+    }
+
+    if (selectionStartRow && selectionStartRow.rowIndex == rowIndex) {
+      // The selection start row is supposed to be here, remove nodes until
+      // we find it.
+      removeUntilNode(node, selectionStartRow);
+      node = selectionStartRow.nextSibling;
+      continue;
+    }
+
+    if (selectionEndRow && selectionEndRow.rowIndex == rowIndex) {
+      // The selection end row is supposed to be here, remove nodes until
+      // we find it.
+      removeUntilNode(node, selectionEndRow);
+      node = selectionEndRow.nextSibling;
+      continue;
+    }
+
+    if (node == selectionStartRow || node == selectionEndRow) {
+      // We encountered the start/end of the selection, but we don't want it
+      // yet.  Insert a new row instead.
+      var newNode = this.fetchRowNode_(rowIndex);
+      if (!newNode) {
+        console.log("Couldn't fetch row index: " + rowIndex);
+        break;
+      }
+
+      this.rowNodes_.insertBefore(newNode, node);
+      continue;
+    }
+
+    // There is nothing special about this node, but it's in our way.  Replace
+    // it with the node that should be here.
+    var newNode = this.fetchRowNode_(rowIndex);
+    if (!newNode) {
+      console.log("Couldn't fetch row index: " + rowIndex);
+      break;
+    }
+
+    if (node == newNode) {
+      node = node.nextSibling;
+      continue;
+    }
+
+    this.rowNodes_.insertBefore(newNode, node);
+    if (!newNode.nextSibling)
+      debugger;
+    this.rowNodes_.removeChild(node);
+    node = newNode.nextSibling;
+  }
+
+  if (node != this.bottomFold_)
+    removeUntilNode(node, bottomFold);
+};
+
+/**
+ * Ensure aria-hidden is set on any selection rows that are offscreen.
+ *
+ * The attribute aria-hidden is set to 'true' so that hidden rows are ignored
+ * by screen readers.  We keep a list of currently hidden rows so they can be
+ * reset each time this function is called as the selection and/or scrolling
+ * may have changed.
+ *
+ * @param {number} topRowIndex Index of top row on screen.
+ * @param {number} bottomRowIndex Index of bottom row on screen.
+ */
+hterm.ScrollPort.prototype.ariaHideOffscreenSelectionRows_ = function(
+    topRowIndex, bottomRowIndex) {
+  // Reset previously hidden selection rows.
+  const hiddenRows = this.ariaHiddenSelectionRows_;
+  let row;
+  while (row = hiddenRows.pop()) {
+    row.removeAttribute('aria-hidden');
+  }
+
+  function checkRow(row) {
+    if (row && (row.rowIndex < topRowIndex || row.rowIndex > bottomRowIndex)) {
+      row.setAttribute('aria-hidden', 'true');
+      hiddenRows.push(row);
+    }
+  }
+  checkRow(this.selection.startRow);
+  checkRow(this.selection.endRow);
+};
+
+/**
+ * Empty out both select bags and remove them from the document.
+ *
+ * These nodes hold the text between the start and end of the selection
+ * when that text is otherwise off screen.  They are filled out in the
+ * onCopy_ event.
+ */
+hterm.ScrollPort.prototype.resetSelectBags_ = function() {
+  if (this.topSelectBag_.parentNode) {
+    this.topSelectBag_.textContent = '';
+    this.topSelectBag_.parentNode.removeChild(this.topSelectBag_);
+  }
+
+  if (this.bottomSelectBag_.parentNode) {
+    this.bottomSelectBag_.textContent = '';
+    this.bottomSelectBag_.parentNode.removeChild(this.bottomSelectBag_);
+  }
+};
+
+/**
+ * Place a row node in the cache of visible nodes.
+ *
+ * This method may only be used during a redraw_.
+ */
+hterm.ScrollPort.prototype.cacheRowNode_ = function(rowNode) {
+  this.currentRowNodeCache_[rowNode.rowIndex] = rowNode;
+};
+
+/**
+ * Fetch the row node for the given index.
+ *
+ * This will return a node from the cache if possible, or will request one
+ * from the RowProvider if not.
+ *
+ * If a redraw_ is in progress the row will be added to the current cache.
+ */
+hterm.ScrollPort.prototype.fetchRowNode_ = function(rowIndex) {
+  var node;
+
+  if (this.previousRowNodeCache_ && rowIndex in this.previousRowNodeCache_) {
+    node = this.previousRowNodeCache_[rowIndex];
+  } else {
+    node = this.rowProvider_.getRowNode(rowIndex);
+  }
+
+  if (this.currentRowNodeCache_)
+    this.cacheRowNode_(node);
+
+  return node;
+};
+
+/**
+ * Select all rows in the viewport.
+ */
+hterm.ScrollPort.prototype.selectAll = function() {
+  var firstRow;
+
+  if (this.topFold_.nextSibling.rowIndex != 0) {
+    while (this.topFold_.previousSibling) {
+      this.rowNodes_.removeChild(this.topFold_.previousSibling);
+    }
+
+    firstRow = this.fetchRowNode_(0);
+    this.rowNodes_.insertBefore(firstRow, this.topFold_);
+    this.syncRowNodesDimensions_();
+  } else {
+    firstRow = this.topFold_.nextSibling;
+  }
+
+  var lastRowIndex = this.rowProvider_.getRowCount() - 1;
+  var lastRow;
+
+  if (this.bottomFold_.previousSibling.rowIndex != lastRowIndex) {
+    while (this.bottomFold_.nextSibling) {
+      this.rowNodes_.removeChild(this.bottomFold_.nextSibling);
+    }
+
+    lastRow = this.fetchRowNode_(lastRowIndex);
+    this.rowNodes_.appendChild(lastRow);
+  } else {
+    lastRow = this.bottomFold_.previousSibling.rowIndex;
+  }
+
+  var selection = this.document_.getSelection();
+  selection.collapse(firstRow, 0);
+  selection.extend(lastRow, lastRow.childNodes.length);
+
+  this.selection.sync();
+};
+
+/**
+ * Return the maximum scroll position in pixels.
+ */
+hterm.ScrollPort.prototype.getScrollMax_ = function(e) {
+  return (hterm.getClientHeight(this.scrollArea_) +
+          this.visibleRowTopMargin + this.visibleRowBottomMargin -
+          hterm.getClientHeight(this.screen_));
+};
+
+/**
+ * Scroll the given rowIndex to the top of the hterm.ScrollPort.
+ *
+ * @param {integer} rowIndex Index of the target row.
+ */
+hterm.ScrollPort.prototype.scrollRowToTop = function(rowIndex) {
+  this.syncScrollHeight();
+
+  this.isScrolledEnd = (
+    rowIndex + this.visibleRowCount >= this.lastRowCount_);
+
+  var scrollTop = rowIndex * this.characterSize.height +
+      this.visibleRowTopMargin;
+
+  var scrollMax = this.getScrollMax_();
+  if (scrollTop > scrollMax)
+    scrollTop = scrollMax;
+
+  if (this.screen_.scrollTop == scrollTop)
+    return;
+
+  this.screen_.scrollTop = scrollTop;
+  this.scheduleRedraw();
+};
+
+/**
+ * Scroll the given rowIndex to the bottom of the hterm.ScrollPort.
+ *
+ * @param {integer} rowIndex Index of the target row.
+ */
+hterm.ScrollPort.prototype.scrollRowToBottom = function(rowIndex) {
+  this.syncScrollHeight();
+
+  this.isScrolledEnd = (
+    rowIndex + this.visibleRowCount >= this.lastRowCount_);
+
+  var scrollTop = rowIndex * this.characterSize.height +
+      this.visibleRowTopMargin + this.visibleRowBottomMargin;
+  scrollTop -= this.visibleRowCount * this.characterSize.height;
+
+  if (scrollTop < 0)
+    scrollTop = 0;
+
+  if (this.screen_.scrollTop == scrollTop)
+    return;
+
+  this.screen_.scrollTop = scrollTop;
+};
+
+/**
+ * Return the row index of the first visible row.
+ *
+ * This is based on the scroll position.  If a redraw_ is in progress this
+ * returns the row that *should* be at the top.
+ */
+hterm.ScrollPort.prototype.getTopRowIndex = function() {
+  return Math.round(this.screen_.scrollTop / this.characterSize.height);
+};
+
+/**
+ * Return the row index of the last visible row.
+ *
+ * This is based on the scroll position.  If a redraw_ is in progress this
+ * returns the row that *should* be at the bottom.
+ */
+hterm.ScrollPort.prototype.getBottomRowIndex = function(topRowIndex) {
+  return topRowIndex + this.visibleRowCount - 1;
+};
+
+/**
+ * Handler for scroll events.
+ *
+ * The onScroll event fires when scrollArea's scrollTop property changes.  This
+ * may be due to the user manually move the scrollbar, or a programmatic change.
+ */
+hterm.ScrollPort.prototype.onScroll_ = function(e) {
+  var screenSize = this.getScreenSize();
+  if (screenSize.width != this.lastScreenWidth_ ||
+      screenSize.height != this.lastScreenHeight_) {
+    // This event may also fire during a resize (but before the resize event!).
+    // This happens when the browser moves the scrollbar as part of the resize.
+    // In these cases, we want to ignore the scroll event and let onResize
+    // handle things.  If we don't, then we end up scrolling to the wrong
+    // position after a resize.
+    this.resize();
+    return;
+  }
+
+  this.redraw_();
+  this.publish('scroll', { scrollPort: this });
+};
+
+/**
+ * Clients can override this if they want to hear scrollwheel events.
+ *
+ * Clients may call event.preventDefault() if they want to keep the scrollport
+ * from also handling the events.
+ */
+hterm.ScrollPort.prototype.onScrollWheel = function(e) {};
+
+/**
+ * Handler for scroll-wheel events.
+ *
+ * The onScrollWheel event fires when the user moves their scrollwheel over this
+ * hterm.ScrollPort.  Because the frontmost element in the hterm.ScrollPort is
+ * a fixed position DIV, the scroll wheel does nothing by default.  Instead, we
+ * have to handle it manually.
+ */
+hterm.ScrollPort.prototype.onScrollWheel_ = function(e) {
+  this.onScrollWheel(e);
+
+  // Ignore the event if it was already handled (preventDefault was called),
+  // or if it is non-cancelable since preventDefault is ignored for these.
+  // See https://crbug.com/894223 where blink sends non-cancelable touchpad
+  // scrollWheel events.
+  if (e.defaultPrevented || !e.cancelable)
+    return;
+
+  // Figure out how far this event wants us to scroll.
+  const delta = this.scrollWheelDelta(e);
+
+  let top = this.screen_.scrollTop - delta.y;
+  if (top < 0)
+    top = 0;
+
+  var scrollMax = this.getScrollMax_();
+  if (top > scrollMax)
+    top = scrollMax;
+
+  if (top != this.screen_.scrollTop) {
+    // Moving scrollTop causes a scroll event, which triggers the redraw.
+    this.screen_.scrollTop = top;
+
+    // Only preventDefault when we've actually scrolled.  If there's nothing
+    // to scroll we want to pass the event through so Chrome can detect the
+    // overscroll.
+    e.preventDefault();
+  }
+};
+
+/**
+ * Calculate how far a wheel event should scroll.
+ *
+ * This normalizes the browser's concept of a scroll (pixels, lines, etc...)
+ * into a standard pixel distance.
+ *
+ * @param {WheelEvent} e The mouse wheel event to process.
+ * @return {Object} The x & y of how far (in pixels) to scroll.
+ */
+hterm.ScrollPort.prototype.scrollWheelDelta = function(e) {
+  const delta = {x: 0, y: 0};
+
+  switch (e.deltaMode) {
+    case WheelEvent.DOM_DELTA_PIXEL:
+      delta.x = e.deltaX * this.scrollWheelMultiplier_;
+      delta.y = e.deltaY * this.scrollWheelMultiplier_;
+      break;
+    case WheelEvent.DOM_DELTA_LINE:
+      delta.x = e.deltaX * this.characterSize.width;
+      delta.y = e.deltaY * this.characterSize.height;
+      break;
+    case WheelEvent.DOM_DELTA_PAGE:
+      delta.x = e.deltaX * this.characterSize.width * this.screen_.getWidth();
+      delta.y = e.deltaY * this.characterSize.height * this.screen_.getHeight();
+      break;
+  }
+
+  // The Y sign is inverted from what we would expect: up/down are
+  // negative/positive respectively.  The X sign is sane though: left/right
+  // are negative/positive respectively.
+  delta.y *= -1;
+
+  return delta;
+};
+
+
+/**
+ * Clients can override this if they want to hear touch events.
+ *
+ * Clients may call event.preventDefault() if they want to keep the scrollport
+ * from also handling the events.
+ */
+hterm.ScrollPort.prototype.onTouch = function(e) {};
+
+/**
+ * Handler for touch events.
+ */
+hterm.ScrollPort.prototype.onTouch_ = function(e) {
+  this.onTouch(e);
+
+  if (e.defaultPrevented)
+    return;
+
+  // Extract the fields from the Touch event that we need.  If we saved the
+  // event directly, it has references to other objects (like x-row) that
+  // might stick around for a long time.  This way we only have small objects
+  // in our lastTouch_ state.
+  var scrubTouch = function(t) {
+    return {
+      id: t.identifier,
+      y: t.clientY,
+      x: t.clientX,
+    };
+  };
+
+  var i, touch;
+  switch (e.type) {
+    case 'touchstart':
+      // Workaround focus bug on CrOS if possible.
+      // TODO(vapier): Drop this once https://crbug.com/919222 is fixed.
+      if (hterm.os == 'cros' && window.chrome && chrome.windows) {
+        chrome.windows.getCurrent((win) => {
+          if (!win.focused) {
+            chrome.windows.update(win.id, {focused: true});
+          }
+        });
+      }
+
+      // Save the current set of touches.
+      for (i = 0; i < e.changedTouches.length; ++i) {
+        touch = scrubTouch(e.changedTouches[i]);
+        this.lastTouch_[touch.id] = touch;
+      }
+      break;
+
+    case 'touchcancel':
+    case 'touchend':
+      // Throw away existing touches that we're finished with.
+      for (i = 0; i < e.changedTouches.length; ++i)
+        delete this.lastTouch_[e.changedTouches[i].identifier];
+      break;
+
+    case 'touchmove':
+      // Walk all of the touches in this one event and merge all of their
+      // changes into one delta.  This lets multiple fingers scroll faster.
+      var delta = 0;
+      for (i = 0; i < e.changedTouches.length; ++i) {
+        touch = scrubTouch(e.changedTouches[i]);
+        delta += (this.lastTouch_[touch.id].y - touch.y);
+        this.lastTouch_[touch.id] = touch;
+      }
+
+      // Invert to match the touchscreen scrolling direction of browser windows.
+      delta *= -1;
+
+      var top = this.screen_.scrollTop - delta;
+      if (top < 0)
+        top = 0;
+
+      var scrollMax = this.getScrollMax_();
+      if (top > scrollMax)
+        top = scrollMax;
+
+      if (top != this.screen_.scrollTop) {
+        // Moving scrollTop causes a scroll event, which triggers the redraw.
+        this.screen_.scrollTop = top;
+      }
+      break;
+  }
+
+  // To disable gestures or anything else interfering with our scrolling.
+  e.preventDefault();
+};
+
+/**
+ * Handler for resize events.
+ *
+ * The browser will resize us such that the top row stays at the top, but we
+ * prefer to the bottom row to stay at the bottom.
+ */
+hterm.ScrollPort.prototype.onResize_ = function(e) {
+  // Re-measure, since onResize also happens for browser zoom changes.
+  this.syncCharacterSize();
+};
+
+/**
+ * Clients can override this if they want to hear copy events.
+ *
+ * Clients may call event.preventDefault() if they want to keep the scrollport
+ * from also handling the events.
+ */
+hterm.ScrollPort.prototype.onCopy = function(e) { };
+
+/**
+ * Handler for copy-to-clipboard events.
+ *
+ * If some or all of the selected rows are off screen we may need to fill in
+ * the rows between selection start and selection end.  This handler determines
+ * if we're missing some of the selected text, and if so populates one or both
+ * of the "select bags" with the missing text.
+ */
+hterm.ScrollPort.prototype.onCopy_ = function(e) {
+  this.onCopy(e);
+
+  if (e.defaultPrevented)
+    return;
+
+  this.resetSelectBags_();
+  this.selection.sync();
+
+  if (this.selection.isCollapsed ||
+      this.selection.endRow.rowIndex - this.selection.startRow.rowIndex < 2) {
+    return;
+  }
+
+  var topRowIndex = this.getTopRowIndex();
+  var bottomRowIndex = this.getBottomRowIndex(topRowIndex);
+
+  if (this.selection.startRow.rowIndex < topRowIndex) {
+    // Start of selection is above the top fold.
+    var endBackfillIndex;
+
+    if (this.selection.endRow.rowIndex < topRowIndex) {
+      // Entire selection is above the top fold.
+      endBackfillIndex = this.selection.endRow.rowIndex;
+    } else {
+      // Selection extends below the top fold.
+      endBackfillIndex = this.topFold_.nextSibling.rowIndex;
+    }
+
+    this.topSelectBag_.textContent = this.rowProvider_.getRowsText(
+        this.selection.startRow.rowIndex + 1, endBackfillIndex);
+    this.rowNodes_.insertBefore(this.topSelectBag_,
+                                this.selection.startRow.nextSibling);
+    this.syncRowNodesDimensions_();
+  }
+
+  if (this.selection.endRow.rowIndex > bottomRowIndex) {
+    // Selection ends below the bottom fold.
+    var startBackfillIndex;
+
+    if (this.selection.startRow.rowIndex > bottomRowIndex) {
+      // Entire selection is below the bottom fold.
+      startBackfillIndex = this.selection.startRow.rowIndex + 1;
+    } else {
+      // Selection starts above the bottom fold.
+      startBackfillIndex = this.bottomFold_.previousSibling.rowIndex + 1;
+    }
+
+    this.bottomSelectBag_.textContent = this.rowProvider_.getRowsText(
+        startBackfillIndex, this.selection.endRow.rowIndex);
+    this.rowNodes_.insertBefore(this.bottomSelectBag_, this.selection.endRow);
+  }
+};
+
+/**
+ * Focuses on the paste target on a ctrl-v keydown event, as in
+ * FF a content editable element must be focused before the paste event.
+ */
+hterm.ScrollPort.prototype.onBodyKeyDown_ = function(e) {
+  if (!this.ctrlVPaste)
+    return;
+
+  if ((e.ctrlKey || e.metaKey) && e.keyCode == 86 /* 'V' */)
+    this.pasteTarget_.focus();
+};
+
+/**
+ * Handle a paste event on the the ScrollPort's screen element.
+ *
+ * TODO: Handle ClipboardData.files transfers.  https://crbug.com/433581.
+ */
+hterm.ScrollPort.prototype.onPaste_ = function(e) {
+  this.pasteTarget_.focus();
+
+  var self = this;
+  setTimeout(function() {
+      self.publish('paste', { text: self.pasteTarget_.value });
+      self.pasteTarget_.value = '';
+      self.focus();
+    }, 0);
+};
+
+/**
+ * Handles a textInput event on the paste target. Stops this from
+ * propagating as we want this to be handled in the onPaste_ method.
+ */
+hterm.ScrollPort.prototype.handlePasteTargetTextInput_ = function(e) {
+  e.stopPropagation();
+};
+
+/**
+ * Handle a drop event on the the ScrollPort's screen element.
+ *
+ * By default we try to copy in the structured format (HTML/whatever).
+ * The shift key can select plain text though.
+ *
+ * TODO: Handle DataTransfer.files transfers.  https://crbug.com/433581.
+ *
+ * @param {DragEvent} e The drag event that fired us.
+ */
+hterm.ScrollPort.prototype.onDragAndDrop_ = function(e) {
+  if (!this.pasteOnDrop)
+    return;
+
+  e.preventDefault();
+
+  let data;
+  let format;
+
+  // If the shift key active, try to find a "rich" text source (but not plain
+  // text).  e.g. text/html is OK.
+  if (e.shiftKey) {
+    e.dataTransfer.types.forEach((t) => {
+      if (!format && t != 'text/plain' && t.startsWith('text/'))
+        format = t;
+    });
+
+    // If we found a non-plain text source, try it out first.
+    if (format)
+      data = e.dataTransfer.getData(format);
+  }
+
+  // If we haven't loaded anything useful, fall back to plain text.
+  if (!data)
+    data = e.dataTransfer.getData('text/plain');
+
+  if (data)
+    this.publish('paste', {text: data});
+};
+
+/**
+ * Set the vertical scrollbar mode of the ScrollPort.
+ */
+hterm.ScrollPort.prototype.setScrollbarVisible = function(state) {
+  this.screen_.style.overflowY = state ? 'scroll' : 'hidden';
+};
+
+/**
+ * Set scroll wheel multiplier. This alters how much the screen scrolls on
+ * mouse wheel events.
+ */
+hterm.ScrollPort.prototype.setScrollWheelMoveMultipler = function(multiplier) {
+  this.scrollWheelMultiplier_ = multiplier;
+};
+// SOURCE FILE: hterm/js/hterm_terminal.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Constructor for the Terminal class.
+ *
+ * A Terminal pulls together the hterm.ScrollPort, hterm.Screen and hterm.VT100
+ * classes to provide the complete terminal functionality.
+ *
+ * There are a number of lower-level Terminal methods that can be called
+ * directly to manipulate the cursor, text, scroll region, and other terminal
+ * attributes.  However, the primary method is interpret(), which parses VT
+ * escape sequences and invokes the appropriate Terminal methods.
+ *
+ * This class was heavily influenced by Cory Maccarrone's Framebuffer class.
+ *
+ * TODO(rginda): Eventually we're going to need to support characters which are
+ * displayed twice as wide as standard latin characters.  This is to support
+ * CJK (and possibly other character sets).
+ *
+ * @param {string} opt_profileId Optional preference profile name.  If not
+ *     provided, defaults to 'default'.
+ */
+hterm.Terminal = function(opt_profileId) {
+  this.profileId_ = null;
+
+  // Two screen instances.
+  this.primaryScreen_ = new hterm.Screen();
+  this.alternateScreen_ = new hterm.Screen();
+
+  // The "current" screen.
+  this.screen_ = this.primaryScreen_;
+
+  // The local notion of the screen size.  ScreenBuffers also have a size which
+  // indicates their present size.  During size changes, the two may disagree.
+  // Also, the inactive screen's size is not altered until it is made the active
+  // screen.
+  this.screenSize = new hterm.Size(0, 0);
+
+  // The scroll port we'll be using to display the visible rows.
+  this.scrollPort_ = new hterm.ScrollPort(this);
+  this.scrollPort_.subscribe('resize', this.onResize_.bind(this));
+  this.scrollPort_.subscribe('scroll', this.onScroll_.bind(this));
+  this.scrollPort_.subscribe('paste', this.onPaste_.bind(this));
+  this.scrollPort_.subscribe('focus', this.onScrollportFocus_.bind(this));
+  this.scrollPort_.onCopy = this.onCopy_.bind(this);
+
+  // The div that contains this terminal.
+  this.div_ = null;
+
+  // The document that contains the scrollPort.  Defaulted to the global
+  // document here so that the terminal is functional even if it hasn't been
+  // inserted into a document yet, but re-set in decorate().
+  this.document_ = window.document;
+
+  // The rows that have scrolled off screen and are no longer addressable.
+  this.scrollbackRows_ = [];
+
+  // Saved tab stops.
+  this.tabStops_ = [];
+
+  // Keep track of whether default tab stops have been erased; after a TBC
+  // clears all tab stops, defaults aren't restored on resize until a reset.
+  this.defaultTabStops = true;
+
+  // The VT's notion of the top and bottom rows.  Used during some VT
+  // cursor positioning and scrolling commands.
+  this.vtScrollTop_ = null;
+  this.vtScrollBottom_ = null;
+
+  // The DIV element for the visible cursor.
+  this.cursorNode_ = null;
+
+  // The current cursor shape of the terminal.
+  this.cursorShape_ = hterm.Terminal.cursorShape.BLOCK;
+
+  // Cursor blink on/off cycle in ms, overwritten by prefs once they're loaded.
+  this.cursorBlinkCycle_ = [100, 100];
+
+  // Pre-bound onCursorBlink_ handler, so we don't have to do this for each
+  // cursor on/off servicing.
+  this.myOnCursorBlink_ = this.onCursorBlink_.bind(this);
+
+  // These prefs are cached so we don't have to read from local storage with
+  // each output and keystroke.  They are initialized by the preference manager.
+  this.backgroundColor_ = null;
+  this.foregroundColor_ = null;
+  this.scrollOnOutput_ = null;
+  this.scrollOnKeystroke_ = null;
+  this.scrollWheelArrowKeys_ = null;
+
+  // True if we should override mouse event reporting to allow local selection.
+  this.defeatMouseReports_ = false;
+
+  // Whether to auto hide the mouse cursor when typing.
+  this.setAutomaticMouseHiding();
+  // Timer to keep mouse visible while it's being used.
+  this.mouseHideDelay_ = null;
+
+  // Terminal bell sound.
+  this.bellAudio_ = this.document_.createElement('audio');
+  this.bellAudio_.id = 'hterm:bell-audio';
+  this.bellAudio_.setAttribute('preload', 'auto');
+
+  // The AccessibilityReader object for announcing command output.
+  this.accessibilityReader_ = null;
+
+  // The context menu object.
+  this.contextMenu = new hterm.ContextMenu();
+
+  // All terminal bell notifications that have been generated (not necessarily
+  // shown).
+  this.bellNotificationList_ = [];
+
+  // Whether we have permission to display notifications.
+  this.desktopNotificationBell_ = false;
+
+  // Cursor position and attributes saved with DECSC.
+  this.savedOptions_ = {};
+
+  // The current mode bits for the terminal.
+  this.options_ = new hterm.Options();
+
+  // Timeouts we might need to clear.
+  this.timeouts_ = {};
+
+  // The VT escape sequence interpreter.
+  this.vt = new hterm.VT(this);
+
+  this.saveCursorAndState(true);
+
+  // The keyboard handler.
+  this.keyboard = new hterm.Keyboard(this);
+
+  // General IO interface that can be given to third parties without exposing
+  // the entire terminal object.
+  this.io = new hterm.Terminal.IO(this);
+
+  // True if mouse-click-drag should scroll the terminal.
+  this.enableMouseDragScroll = true;
+
+  this.copyOnSelect = null;
+  this.mouseRightClickPaste = null;
+  this.mousePasteButton = null;
+
+  // Whether to use the default window copy behavior.
+  this.useDefaultWindowCopy = false;
+
+  this.clearSelectionAfterCopy = true;
+
+  this.realizeSize_(80, 24);
+  this.setDefaultTabStops();
+
+  // Whether we allow images to be shown.
+  this.allowImagesInline = null;
+
+  this.reportFocus = false;
+
+  this.setProfile(opt_profileId || 'default',
+                  function() { this.onTerminalReady(); }.bind(this));
+};
+
+/**
+ * Possible cursor shapes.
+ */
+hterm.Terminal.cursorShape = {
+  BLOCK: 'BLOCK',
+  BEAM: 'BEAM',
+  UNDERLINE: 'UNDERLINE'
+};
+
+/**
+ * Clients should override this to be notified when the terminal is ready
+ * for use.
+ *
+ * The terminal initialization is asynchronous, and shouldn't be used before
+ * this method is called.
+ */
+hterm.Terminal.prototype.onTerminalReady = function() { };
+
+/**
+ * Default tab with of 8 to match xterm.
+ */
+hterm.Terminal.prototype.tabWidth = 8;
+
+/**
+ * Select a preference profile.
+ *
+ * This will load the terminal preferences for the given profile name and
+ * associate subsequent preference changes with the new preference profile.
+ *
+ * @param {string} profileId The name of the preference profile.  Forward slash
+ *     characters will be removed from the name.
+ * @param {function} opt_callback Optional callback to invoke when the profile
+ *     transition is complete.
+ */
+hterm.Terminal.prototype.setProfile = function(profileId, opt_callback) {
+  this.profileId_ = profileId.replace(/\//g, '');
+
+  var terminal = this;
+
+  if (this.prefs_)
+    this.prefs_.deactivate();
+
+  this.prefs_ = new hterm.PreferenceManager(this.profileId_);
+  this.prefs_.addObservers(null, {
+    'alt-gr-mode': function(v) {
+      if (v == null) {
+        if (navigator.language.toLowerCase() == 'en-us') {
+          v = 'none';
+        } else {
+          v = 'right-alt';
+        }
+      } else if (typeof v == 'string') {
+        v = v.toLowerCase();
+      } else {
+        v = 'none';
+      }
+
+      if (!/^(none|ctrl-alt|left-alt|right-alt)$/.test(v))
+        v = 'none';
+
+      terminal.keyboard.altGrMode = v;
+    },
+
+    'alt-backspace-is-meta-backspace': function(v) {
+      terminal.keyboard.altBackspaceIsMetaBackspace = v;
+    },
+
+    'alt-is-meta': function(v) {
+      terminal.keyboard.altIsMeta = v;
+    },
+
+    'alt-sends-what': function(v) {
+      if (!/^(escape|8-bit|browser-key)$/.test(v))
+        v = 'escape';
+
+      terminal.keyboard.altSendsWhat = v;
+    },
+
+    'audible-bell-sound': function(v) {
+      var ary = v.match(/^lib-resource:(\S+)/);
+      if (ary) {
+        terminal.bellAudio_.setAttribute('src',
+                                         lib.resource.getDataUrl(ary[1]));
+      } else {
+        terminal.bellAudio_.setAttribute('src', v);
+      }
+    },
+
+    'desktop-notification-bell': function(v) {
+      if (v && Notification) {
+        terminal.desktopNotificationBell_ =
+            Notification.permission === 'granted';
+        if (!terminal.desktopNotificationBell_) {
+          // Note: We don't call Notification.requestPermission here because
+          // Chrome requires the call be the result of a user action (such as an
+          // onclick handler), and pref listeners are run asynchronously.
+          //
+          // A way of working around this would be to display a dialog in the
+          // terminal with a "click-to-request-permission" button.
+          console.warn('desktop-notification-bell is true but we do not have ' +
+                       'permission to display notifications.');
+        }
+      } else {
+        terminal.desktopNotificationBell_ = false;
+      }
+    },
+
+    'background-color': function(v) {
+      terminal.setBackgroundColor(v);
+    },
+
+    'background-image': function(v) {
+      terminal.scrollPort_.setBackgroundImage(v);
+    },
+
+    'background-size': function(v) {
+      terminal.scrollPort_.setBackgroundSize(v);
+    },
+
+    'background-position': function(v) {
+      terminal.scrollPort_.setBackgroundPosition(v);
+    },
+
+    'backspace-sends-backspace': function(v) {
+      terminal.keyboard.backspaceSendsBackspace = v;
+    },
+
+    'character-map-overrides': function(v) {
+      if (!(v == null || v instanceof Object)) {
+        console.warn('Preference character-map-modifications is not an ' +
+                     'object: ' + v);
+        return;
+      }
+
+      terminal.vt.characterMaps.reset();
+      terminal.vt.characterMaps.setOverrides(v);
+    },
+
+    'cursor-blink': function(v) {
+      terminal.setCursorBlink(!!v);
+    },
+
+    'cursor-shape': function(v) {
+      terminal.setCursorShape(v);
+    },
+
+    'cursor-blink-cycle': function(v) {
+        if (v instanceof Array &&
+            typeof v[0] == 'number' &&
+            typeof v[1] == 'number') {
+          terminal.cursorBlinkCycle_ = v;
+        } else if (typeof v == 'number') {
+          terminal.cursorBlinkCycle_ = [v, v];
+        } else {
+          // Fast blink indicates an error.
+          terminal.cursorBlinkCycle_ = [100, 100];
+        }
+    },
+
+    'cursor-color': function(v) {
+      terminal.setCursorColor(v);
+    },
+
+    'color-palette-overrides': function(v) {
+      if (!(v == null || v instanceof Object || v instanceof Array)) {
+        console.warn('Preference color-palette-overrides is not an array or ' +
+                     'object: ' + v);
+        return;
+      }
+
+      lib.colors.colorPalette = lib.colors.stockColorPalette.concat();
+
+      if (v) {
+        for (var key in v) {
+          var i = parseInt(key);
+          if (isNaN(i) || i < 0 || i > 255) {
+            console.log('Invalid value in palette: ' + key + ': ' + v[key]);
+            continue;
+          }
+
+          if (v[i]) {
+            var rgb = lib.colors.normalizeCSS(v[i]);
+            if (rgb)
+              lib.colors.colorPalette[i] = rgb;
+          }
+        }
+      }
+
+      terminal.primaryScreen_.textAttributes.resetColorPalette();
+      terminal.alternateScreen_.textAttributes.resetColorPalette();
+    },
+
+    'copy-on-select': function(v) {
+      terminal.copyOnSelect = !!v;
+    },
+
+    'use-default-window-copy': function(v) {
+      terminal.useDefaultWindowCopy = !!v;
+    },
+
+    'clear-selection-after-copy': function(v) {
+      terminal.clearSelectionAfterCopy = !!v;
+    },
+
+    'ctrl-plus-minus-zero-zoom': function(v) {
+      terminal.keyboard.ctrlPlusMinusZeroZoom = v;
+    },
+
+    'ctrl-c-copy': function(v) {
+      terminal.keyboard.ctrlCCopy = v;
+    },
+
+    'ctrl-v-paste': function(v) {
+      terminal.keyboard.ctrlVPaste = v;
+      terminal.scrollPort_.setCtrlVPaste(v);
+    },
+
+    'paste-on-drop': function(v) {
+      terminal.scrollPort_.setPasteOnDrop(v);
+    },
+
+    'east-asian-ambiguous-as-two-column': function(v) {
+      lib.wc.regardCjkAmbiguous = v;
+    },
+
+    'enable-8-bit-control': function(v) {
+      terminal.vt.enable8BitControl = !!v;
+    },
+
+    'enable-bold': function(v) {
+      terminal.syncBoldSafeState();
+    },
+
+    'enable-bold-as-bright': function(v) {
+      terminal.primaryScreen_.textAttributes.enableBoldAsBright = !!v;
+      terminal.alternateScreen_.textAttributes.enableBoldAsBright = !!v;
+    },
+
+    'enable-blink': function(v) {
+      terminal.setTextBlink(!!v);
+    },
+
+    'enable-clipboard-write': function(v) {
+      terminal.vt.enableClipboardWrite = !!v;
+    },
+
+    'enable-dec12': function(v) {
+      terminal.vt.enableDec12 = !!v;
+    },
+
+    'enable-csi-j-3': function(v) {
+      terminal.vt.enableCsiJ3 = !!v;
+    },
+
+    'font-family': function(v) {
+      terminal.syncFontFamily();
+    },
+
+    'font-size': function(v) {
+      v = parseInt(v);
+      if (v <= 0) {
+        console.error(`Invalid font size: ${v}`);
+        return;
+      }
+
+      terminal.setFontSize(v);
+    },
+
+    'font-smoothing': function(v) {
+      terminal.syncFontFamily();
+    },
+
+    'foreground-color': function(v) {
+      terminal.setForegroundColor(v);
+    },
+
+    'hide-mouse-while-typing': function(v) {
+      terminal.setAutomaticMouseHiding(v);
+    },
+
+    'home-keys-scroll': function(v) {
+      terminal.keyboard.homeKeysScroll = v;
+    },
+
+    'keybindings': function(v) {
+      terminal.keyboard.bindings.clear();
+
+      if (!v)
+        return;
+
+      if (!(v instanceof Object)) {
+        console.error('Error in keybindings preference: Expected object');
+        return;
+      }
+
+      try {
+        terminal.keyboard.bindings.addBindings(v);
+      } catch (ex) {
+        console.error('Error in keybindings preference: ' + ex);
+      }
+    },
+
+    'media-keys-are-fkeys': function(v) {
+      terminal.keyboard.mediaKeysAreFKeys = v;
+    },
+
+    'meta-sends-escape': function(v) {
+      terminal.keyboard.metaSendsEscape = v;
+    },
+
+    'mouse-right-click-paste': function(v) {
+      terminal.mouseRightClickPaste = v;
+    },
+
+    'mouse-paste-button': function(v) {
+      terminal.syncMousePasteButton();
+    },
+
+    'page-keys-scroll': function(v) {
+      terminal.keyboard.pageKeysScroll = v;
+    },
+
+    'pass-alt-number': function(v) {
+      if (v == null) {
+        // Let Alt-1..9 pass to the browser (to control tab switching) on
+        // non-OS X systems, or if hterm is not opened in an app window.
+        v = (hterm.os != 'mac' && hterm.windowType != 'popup');
+      }
+
+      terminal.passAltNumber = v;
+    },
+
+    'pass-ctrl-number': function(v) {
+      if (v == null) {
+        // Let Ctrl-1..9 pass to the browser (to control tab switching) on
+        // non-OS X systems, or if hterm is not opened in an app window.
+        v = (hterm.os != 'mac' && hterm.windowType != 'popup');
+      }
+
+      terminal.passCtrlNumber = v;
+    },
+
+    'pass-meta-number': function(v) {
+      if (v == null) {
+        // Let Meta-1..9 pass to the browser (to control tab switching) on
+        // OS X systems, or if hterm is not opened in an app window.
+        v = (hterm.os == 'mac' && hterm.windowType != 'popup');
+      }
+
+      terminal.passMetaNumber = v;
+    },
+
+    'pass-meta-v': function(v) {
+      terminal.keyboard.passMetaV = v;
+    },
+
+    'receive-encoding': function(v) {
+       if (!(/^(utf-8|raw)$/).test(v)) {
+         console.warn('Invalid value for "receive-encoding": ' + v);
+         v = 'utf-8';
+       }
+
+       terminal.vt.characterEncoding = v;
+    },
+
+    'scroll-on-keystroke': function(v) {
+      terminal.scrollOnKeystroke_ = v;
+    },
+
+    'scroll-on-output': function(v) {
+      terminal.scrollOnOutput_ = v;
+    },
+
+    'scrollbar-visible': function(v) {
+      terminal.setScrollbarVisible(v);
+    },
+
+    'scroll-wheel-may-send-arrow-keys': function(v) {
+      terminal.scrollWheelArrowKeys_ = v;
+    },
+
+    'scroll-wheel-move-multiplier': function(v) {
+      terminal.setScrollWheelMoveMultipler(v);
+    },
+
+    'shift-insert-paste': function(v) {
+      terminal.keyboard.shiftInsertPaste = v;
+    },
+
+    'terminal-encoding': function(v) {
+      terminal.vt.setEncoding(v);
+    },
+
+    'user-css': function(v) {
+      terminal.scrollPort_.setUserCssUrl(v);
+    },
+
+    'user-css-text': function(v) {
+      terminal.scrollPort_.setUserCssText(v);
+    },
+
+    'word-break-match-left': function(v) {
+      terminal.primaryScreen_.wordBreakMatchLeft = v;
+      terminal.alternateScreen_.wordBreakMatchLeft = v;
+    },
+
+    'word-break-match-right': function(v) {
+      terminal.primaryScreen_.wordBreakMatchRight = v;
+      terminal.alternateScreen_.wordBreakMatchRight = v;
+    },
+
+    'word-break-match-middle': function(v) {
+      terminal.primaryScreen_.wordBreakMatchMiddle = v;
+      terminal.alternateScreen_.wordBreakMatchMiddle = v;
+    },
+
+    'allow-images-inline': function(v) {
+      terminal.allowImagesInline = v;
+    },
+  });
+
+  this.prefs_.readStorage(function() {
+    this.prefs_.notifyAll();
+
+    if (opt_callback)
+      opt_callback();
+  }.bind(this));
+};
+
+
+/**
+ * Returns the preferences manager used for configuring this terminal.
+ *
+ * @return {hterm.PreferenceManager}
+ */
+hterm.Terminal.prototype.getPrefs = function() {
+  return this.prefs_;
+};
+
+/**
+ * Enable or disable bracketed paste mode.
+ *
+ * @param {boolean} state The value to set.
+ */
+hterm.Terminal.prototype.setBracketedPaste = function(state) {
+  this.options_.bracketedPaste = state;
+};
+
+/**
+ * Set the color for the cursor.
+ *
+ * If you want this setting to persist, set it through prefs_, rather than
+ * with this method.
+ *
+ * @param {string=} color The color to set.  If not defined, we reset to the
+ *     saved user preference.
+ */
+hterm.Terminal.prototype.setCursorColor = function(color) {
+  if (color === undefined)
+    color = this.prefs_.get('cursor-color');
+
+  this.setCssVar('cursor-color', color);
+};
+
+/**
+ * Return the current cursor color as a string.
+ * @return {string}
+ */
+hterm.Terminal.prototype.getCursorColor = function() {
+  return this.getCssVar('cursor-color');
+};
+
+/**
+ * Enable or disable mouse based text selection in the terminal.
+ *
+ * @param {boolean} state The value to set.
+ */
+hterm.Terminal.prototype.setSelectionEnabled = function(state) {
+  this.enableMouseDragScroll = state;
+};
+
+/**
+ * Set the background color.
+ *
+ * If you want this setting to persist, set it through prefs_, rather than
+ * with this method.
+ *
+ * @param {string=} color The color to set.  If not defined, we reset to the
+ *     saved user preference.
+ */
+hterm.Terminal.prototype.setBackgroundColor = function(color) {
+  if (color === undefined)
+    color = this.prefs_.get('background-color');
+
+  this.backgroundColor_ = lib.colors.normalizeCSS(color);
+  this.primaryScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_);
+  this.alternateScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_);
+  this.scrollPort_.setBackgroundColor(color);
+};
+
+/**
+ * Return the current terminal background color.
+ *
+ * Intended for use by other classes, so we don't have to expose the entire
+ * prefs_ object.
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getBackgroundColor = function() {
+  return this.backgroundColor_;
+};
+
+/**
+ * Set the foreground color.
+ *
+ * If you want this setting to persist, set it through prefs_, rather than
+ * with this method.
+ *
+ * @param {string=} color The color to set.  If not defined, we reset to the
+ *     saved user preference.
+ */
+hterm.Terminal.prototype.setForegroundColor = function(color) {
+  if (color === undefined)
+    color = this.prefs_.get('foreground-color');
+
+  this.foregroundColor_ = lib.colors.normalizeCSS(color);
+  this.primaryScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_);
+  this.alternateScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_);
+  this.scrollPort_.setForegroundColor(color);
+};
+
+/**
+ * Return the current terminal foreground color.
+ *
+ * Intended for use by other classes, so we don't have to expose the entire
+ * prefs_ object.
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getForegroundColor = function() {
+  return this.foregroundColor_;
+};
+
+/**
+ * Create a new instance of a terminal command and run it with a given
+ * argument string.
+ *
+ * @param {function} commandClass The constructor for a terminal command.
+ * @param {string} argString The argument string to pass to the command.
+ */
+hterm.Terminal.prototype.runCommandClass = function(commandClass, argString) {
+  var environment = this.prefs_.get('environment');
+  if (typeof environment != 'object' || environment == null)
+    environment = {};
+
+  var self = this;
+  this.command = new commandClass(
+      { argString: argString || '',
+        io: this.io.push(),
+        environment: environment,
+        onExit: function(code) {
+          self.io.pop();
+          self.uninstallKeyboard();
+          if (self.prefs_.get('close-on-exit'))
+              window.close();
+        }
+      });
+
+  this.installKeyboard();
+  this.command.run();
+};
+
+/**
+ * Returns true if the current screen is the primary screen, false otherwise.
+ *
+ * @return {boolean}
+ */
+hterm.Terminal.prototype.isPrimaryScreen = function() {
+  return this.screen_ == this.primaryScreen_;
+};
+
+/**
+ * Install the keyboard handler for this terminal.
+ *
+ * This will prevent the browser from seeing any keystrokes sent to the
+ * terminal.
+ */
+hterm.Terminal.prototype.installKeyboard = function() {
+  this.keyboard.installKeyboard(this.scrollPort_.getDocument().body);
+};
+
+/**
+ * Uninstall the keyboard handler for this terminal.
+ */
+hterm.Terminal.prototype.uninstallKeyboard = function() {
+  this.keyboard.installKeyboard(null);
+};
+
+/**
+ * Set a CSS variable.
+ *
+ * Normally this is used to set variables in the hterm namespace.
+ *
+ * @param {string} name The variable to set.
+ * @param {string} value The value to assign to the variable.
+ * @param {string?} opt_prefix The variable namespace/prefix to use.
+ */
+hterm.Terminal.prototype.setCssVar = function(name, value,
+                                              opt_prefix='--hterm-') {
+  this.document_.documentElement.style.setProperty(
+      `${opt_prefix}${name}`, value);
+};
+
+/**
+ * Get a CSS variable.
+ *
+ * Normally this is used to get variables in the hterm namespace.
+ *
+ * @param {string} name The variable to read.
+ * @param {string?} opt_prefix The variable namespace/prefix to use.
+ * @return {string} The current setting for this variable.
+ */
+hterm.Terminal.prototype.getCssVar = function(name, opt_prefix='--hterm-') {
+  return this.document_.documentElement.style.getPropertyValue(
+      `${opt_prefix}${name}`);
+};
+
+/**
+ * Set the font size for this terminal.
+ *
+ * Call setFontSize(0) to reset to the default font size.
+ *
+ * This function does not modify the font-size preference.
+ *
+ * @param {number} px The desired font size, in pixels.
+ */
+hterm.Terminal.prototype.setFontSize = function(px) {
+  if (px <= 0)
+    px = this.prefs_.get('font-size');
+
+  this.scrollPort_.setFontSize(px);
+  this.setCssVar('charsize-width', this.scrollPort_.characterSize.width + 'px');
+  this.setCssVar('charsize-height',
+                 this.scrollPort_.characterSize.height + 'px');
+};
+
+/**
+ * Get the current font size.
+ *
+ * @return {number}
+ */
+hterm.Terminal.prototype.getFontSize = function() {
+  return this.scrollPort_.getFontSize();
+};
+
+/**
+ * Get the current font family.
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getFontFamily = function() {
+  return this.scrollPort_.getFontFamily();
+};
+
+/**
+ * Set the CSS "font-family" for this terminal.
+ */
+hterm.Terminal.prototype.syncFontFamily = function() {
+  this.scrollPort_.setFontFamily(this.prefs_.get('font-family'),
+                                 this.prefs_.get('font-smoothing'));
+  this.syncBoldSafeState();
+};
+
+/**
+ * Set this.mousePasteButton based on the mouse-paste-button pref,
+ * autodetecting if necessary.
+ */
+hterm.Terminal.prototype.syncMousePasteButton = function() {
+  var button = this.prefs_.get('mouse-paste-button');
+  if (typeof button == 'number') {
+    this.mousePasteButton = button;
+    return;
+  }
+
+  if (hterm.os != 'linux') {
+    this.mousePasteButton = 1;  // Middle mouse button.
+  } else {
+    this.mousePasteButton = 2;  // Right mouse button.
+  }
+};
+
+/**
+ * Enable or disable bold based on the enable-bold pref, autodetecting if
+ * necessary.
+ */
+hterm.Terminal.prototype.syncBoldSafeState = function() {
+  var enableBold = this.prefs_.get('enable-bold');
+  if (enableBold !== null) {
+    this.primaryScreen_.textAttributes.enableBold = enableBold;
+    this.alternateScreen_.textAttributes.enableBold = enableBold;
+    return;
+  }
+
+  var normalSize = this.scrollPort_.measureCharacterSize();
+  var boldSize = this.scrollPort_.measureCharacterSize('bold');
+
+  var isBoldSafe = normalSize.equals(boldSize);
+  if (!isBoldSafe) {
+    console.warn('Bold characters disabled: Size of bold weight differs ' +
+                 'from normal.  Font family is: ' +
+                 this.scrollPort_.getFontFamily());
+  }
+
+  this.primaryScreen_.textAttributes.enableBold = isBoldSafe;
+  this.alternateScreen_.textAttributes.enableBold = isBoldSafe;
+};
+
+/**
+ * Control text blinking behavior.
+ *
+ * @param {boolean=} state Whether to enable support for blinking text.
+ */
+hterm.Terminal.prototype.setTextBlink = function(state) {
+  if (state === undefined)
+    state = this.prefs_.get('enable-blink');
+  this.setCssVar('blink-node-duration', state ? '0.7s' : '0');
+};
+
+/**
+ * Set the mouse cursor style based on the current terminal mode.
+ */
+hterm.Terminal.prototype.syncMouseStyle = function() {
+  this.setCssVar('mouse-cursor-style',
+                 this.vt.mouseReport == this.vt.MOUSE_REPORT_DISABLED ?
+                     'var(--hterm-mouse-cursor-text)' :
+                     'var(--hterm-mouse-cursor-default)');
+};
+
+/**
+ * Return a copy of the current cursor position.
+ *
+ * @return {hterm.RowCol} The RowCol object representing the current position.
+ */
+hterm.Terminal.prototype.saveCursor = function() {
+  return this.screen_.cursorPosition.clone();
+};
+
+/**
+ * Return the current text attributes.
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getTextAttributes = function() {
+  return this.screen_.textAttributes;
+};
+
+/**
+ * Set the text attributes.
+ *
+ * @param {string} textAttributes The attributes to set.
+ */
+hterm.Terminal.prototype.setTextAttributes = function(textAttributes) {
+  this.screen_.textAttributes = textAttributes;
+};
+
+/**
+ * Return the current browser zoom factor applied to the terminal.
+ *
+ * @return {number} The current browser zoom factor.
+ */
+hterm.Terminal.prototype.getZoomFactor = function() {
+  return this.scrollPort_.characterSize.zoomFactor;
+};
+
+/**
+ * Change the title of this terminal's window.
+ *
+ * @param {string} title The title to set.
+ */
+hterm.Terminal.prototype.setWindowTitle = function(title) {
+  window.document.title = title;
+};
+
+/**
+ * Restore a previously saved cursor position.
+ *
+ * @param {hterm.RowCol} cursor The position to restore.
+ */
+hterm.Terminal.prototype.restoreCursor = function(cursor) {
+  var row = lib.f.clamp(cursor.row, 0, this.screenSize.height - 1);
+  var column = lib.f.clamp(cursor.column, 0, this.screenSize.width - 1);
+  this.screen_.setCursorPosition(row, column);
+  if (cursor.column > column ||
+      cursor.column == column && cursor.overflow) {
+    this.screen_.cursorPosition.overflow = true;
+  }
+};
+
+/**
+ * Clear the cursor's overflow flag.
+ */
+hterm.Terminal.prototype.clearCursorOverflow = function() {
+  this.screen_.cursorPosition.overflow = false;
+};
+
+/**
+ * Save the current cursor state to the corresponding screens.
+ *
+ * See the hterm.Screen.CursorState class for more details.
+ *
+ * @param {boolean=} both If true, update both screens, else only update the
+ *     current screen.
+ */
+hterm.Terminal.prototype.saveCursorAndState = function(both) {
+  if (both) {
+    this.primaryScreen_.saveCursorAndState(this.vt);
+    this.alternateScreen_.saveCursorAndState(this.vt);
+  } else
+    this.screen_.saveCursorAndState(this.vt);
+};
+
+/**
+ * Restore the saved cursor state in the corresponding screens.
+ *
+ * See the hterm.Screen.CursorState class for more details.
+ *
+ * @param {boolean=} both If true, update both screens, else only update the
+ *     current screen.
+ */
+hterm.Terminal.prototype.restoreCursorAndState = function(both) {
+  if (both) {
+    this.primaryScreen_.restoreCursorAndState(this.vt);
+    this.alternateScreen_.restoreCursorAndState(this.vt);
+  } else
+    this.screen_.restoreCursorAndState(this.vt);
+};
+
+/**
+ * Sets the cursor shape
+ *
+ * @param {string} shape The shape to set.
+ */
+hterm.Terminal.prototype.setCursorShape = function(shape) {
+  this.cursorShape_ = shape;
+  this.restyleCursor_();
+};
+
+/**
+ * Get the cursor shape
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getCursorShape = function() {
+  return this.cursorShape_;
+};
+
+/**
+ * Set the width of the terminal, resizing the UI to match.
+ *
+ * @param {number} columnCount
+ */
+hterm.Terminal.prototype.setWidth = function(columnCount) {
+  if (columnCount == null) {
+    this.div_.style.width = '100%';
+    return;
+  }
+
+  this.div_.style.width = Math.ceil(
+      this.scrollPort_.characterSize.width *
+      columnCount + this.scrollPort_.currentScrollbarWidthPx) + 'px';
+  this.realizeSize_(columnCount, this.screenSize.height);
+  this.scheduleSyncCursorPosition_();
+};
+
+/**
+ * Set the height of the terminal, resizing the UI to match.
+ *
+ * @param {number} rowCount The height in rows.
+ */
+hterm.Terminal.prototype.setHeight = function(rowCount) {
+  if (rowCount == null) {
+    this.div_.style.height = '100%';
+    return;
+  }
+
+  this.div_.style.height =
+      this.scrollPort_.characterSize.height * rowCount + 'px';
+  this.realizeSize_(this.screenSize.width, rowCount);
+  this.scheduleSyncCursorPosition_();
+};
+
+/**
+ * Deal with terminal size changes.
+ *
+ * @param {number} columnCount The number of columns.
+ * @param {number} rowCount The number of rows.
+ */
+hterm.Terminal.prototype.realizeSize_ = function(columnCount, rowCount) {
+  let notify = false;
+
+  if (columnCount != this.screenSize.width) {
+    notify = true;
+    this.realizeWidth_(columnCount);
+  }
+
+  if (rowCount != this.screenSize.height) {
+    notify = true;
+    this.realizeHeight_(rowCount);
+  }
+
+  // Send new terminal size to plugin.
+  if (notify) {
+    this.io.onTerminalResize_(columnCount, rowCount);
+  }
+};
+
+/**
+ * Deal with terminal width changes.
+ *
+ * This function does what needs to be done when the terminal width changes
+ * out from under us.  It happens here rather than in onResize_() because this
+ * code may need to run synchronously to handle programmatic changes of
+ * terminal width.
+ *
+ * Relying on the browser to send us an async resize event means we may not be
+ * in the correct state yet when the next escape sequence hits.
+ *
+ * @param {number} columnCount The number of columns.
+ */
+hterm.Terminal.prototype.realizeWidth_ = function(columnCount) {
+  if (columnCount <= 0)
+    throw new Error('Attempt to realize bad width: ' + columnCount);
+
+  var deltaColumns = columnCount - this.screen_.getWidth();
+  if (deltaColumns == 0) {
+    // No change, so don't bother recalculating things.
+    return;
+  }
+
+  this.screenSize.width = columnCount;
+  this.screen_.setColumnCount(columnCount);
+
+  if (deltaColumns > 0) {
+    if (this.defaultTabStops)
+      this.setDefaultTabStops(this.screenSize.width - deltaColumns);
+  } else {
+    for (var i = this.tabStops_.length - 1; i >= 0; i--) {
+      if (this.tabStops_[i] < columnCount)
+        break;
+
+      this.tabStops_.pop();
+    }
+  }
+
+  this.screen_.setColumnCount(this.screenSize.width);
+};
+
+/**
+ * Deal with terminal height changes.
+ *
+ * This function does what needs to be done when the terminal height changes
+ * out from under us.  It happens here rather than in onResize_() because this
+ * code may need to run synchronously to handle programmatic changes of
+ * terminal height.
+ *
+ * Relying on the browser to send us an async resize event means we may not be
+ * in the correct state yet when the next escape sequence hits.
+ *
+ * @param {number} rowCount The number of rows.
+ */
+hterm.Terminal.prototype.realizeHeight_ = function(rowCount) {
+  if (rowCount <= 0)
+    throw new Error('Attempt to realize bad height: ' + rowCount);
+
+  var deltaRows = rowCount - this.screen_.getHeight();
+  if (deltaRows == 0) {
+    // No change, so don't bother recalculating things.
+    return;
+  }
+
+  this.screenSize.height = rowCount;
+
+  var cursor = this.saveCursor();
+
+  if (deltaRows < 0) {
+    // Screen got smaller.
+    deltaRows *= -1;
+    while (deltaRows) {
+      var lastRow = this.getRowCount() - 1;
+      if (lastRow - this.scrollbackRows_.length == cursor.row)
+        break;
+
+      if (this.getRowText(lastRow))
+        break;
+
+      this.screen_.popRow();
+      deltaRows--;
+    }
+
+    var ary = this.screen_.shiftRows(deltaRows);
+    this.scrollbackRows_.push.apply(this.scrollbackRows_, ary);
+
+    // We just removed rows from the top of the screen, we need to update
+    // the cursor to match.
+    cursor.row = Math.max(cursor.row - deltaRows, 0);
+  } else if (deltaRows > 0) {
+    // Screen got larger.
+
+    if (deltaRows <= this.scrollbackRows_.length) {
+      var scrollbackCount = Math.min(deltaRows, this.scrollbackRows_.length);
+      var rows = this.scrollbackRows_.splice(
+          this.scrollbackRows_.length - scrollbackCount, scrollbackCount);
+      this.screen_.unshiftRows(rows);
+      deltaRows -= scrollbackCount;
+      cursor.row += scrollbackCount;
+    }
+
+    if (deltaRows)
+      this.appendRows_(deltaRows);
+  }
+
+  this.setVTScrollRegion(null, null);
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Scroll the terminal to the top of the scrollback buffer.
+ */
+hterm.Terminal.prototype.scrollHome = function() {
+  this.scrollPort_.scrollRowToTop(0);
+};
+
+/**
+ * Scroll the terminal to the end.
+ */
+hterm.Terminal.prototype.scrollEnd = function() {
+  this.scrollPort_.scrollRowToBottom(this.getRowCount());
+};
+
+/**
+ * Scroll the terminal one page up (minus one line) relative to the current
+ * position.
+ */
+hterm.Terminal.prototype.scrollPageUp = function() {
+  this.scrollPort_.scrollPageUp();
+};
+
+/**
+ * Scroll the terminal one page down (minus one line) relative to the current
+ * position.
+ */
+hterm.Terminal.prototype.scrollPageDown = function() {
+  this.scrollPort_.scrollPageDown();
+};
+
+/**
+ * Scroll the terminal one line up relative to the current position.
+ */
+hterm.Terminal.prototype.scrollLineUp = function() {
+  var i = this.scrollPort_.getTopRowIndex();
+  this.scrollPort_.scrollRowToTop(i - 1);
+};
+
+/**
+ * Scroll the terminal one line down relative to the current position.
+ */
+hterm.Terminal.prototype.scrollLineDown = function() {
+  var i = this.scrollPort_.getTopRowIndex();
+  this.scrollPort_.scrollRowToTop(i + 1);
+};
+
+/**
+ * Clear primary screen, secondary screen, and the scrollback buffer.
+ */
+hterm.Terminal.prototype.wipeContents = function() {
+  this.clearHome(this.primaryScreen_);
+  this.clearHome(this.alternateScreen_);
+
+  this.clearScrollback();
+};
+
+/**
+ * Clear scrollback buffer.
+ */
+hterm.Terminal.prototype.clearScrollback = function() {
+  // Move to the end of the buffer in case the screen was scrolled back.
+  // We're going to throw it away which would leave the display invalid.
+  this.scrollEnd();
+
+  this.scrollbackRows_.length = 0;
+  this.scrollPort_.resetCache();
+
+  [this.primaryScreen_, this.alternateScreen_].forEach((screen) => {
+    const bottom = screen.getHeight();
+    this.renumberRows_(0, bottom, screen);
+  });
+
+  this.syncCursorPosition_();
+  this.scrollPort_.invalidate();
+};
+
+/**
+ * Full terminal reset.
+ *
+ * Perform a full reset to the default values listed in
+ * https://vt100.net/docs/vt510-rm/RIS.html
+ */
+hterm.Terminal.prototype.reset = function() {
+  this.vt.reset();
+
+  this.clearAllTabStops();
+  this.setDefaultTabStops();
+
+  const resetScreen = (screen) => {
+    // We want to make sure to reset the attributes before we clear the screen.
+    // The attributes might be used to initialize default/empty rows.
+    screen.textAttributes.reset();
+    screen.textAttributes.resetColorPalette();
+    this.clearHome(screen);
+    screen.saveCursorAndState(this.vt);
+  };
+  resetScreen(this.primaryScreen_);
+  resetScreen(this.alternateScreen_);
+
+  // Reset terminal options to their default values.
+  this.options_ = new hterm.Options();
+  this.setCursorBlink(!!this.prefs_.get('cursor-blink'));
+
+  this.setVTScrollRegion(null, null);
+
+  this.setCursorVisible(true);
+};
+
+/**
+ * Soft terminal reset.
+ *
+ * Perform a soft reset to the default values listed in
+ * http://www.vt100.net/docs/vt510-rm/DECSTR#T5-9
+ */
+hterm.Terminal.prototype.softReset = function() {
+  this.vt.reset();
+
+  // Reset terminal options to their default values.
+  this.options_ = new hterm.Options();
+
+  // We show the cursor on soft reset but do not alter the blink state.
+  this.options_.cursorBlink = !!this.timeouts_.cursorBlink;
+
+  const resetScreen = (screen) => {
+    // Xterm also resets the color palette on soft reset, even though it doesn't
+    // seem to be documented anywhere.
+    screen.textAttributes.reset();
+    screen.textAttributes.resetColorPalette();
+    screen.saveCursorAndState(this.vt);
+  };
+  resetScreen(this.primaryScreen_);
+  resetScreen(this.alternateScreen_);
+
+  // The xterm man page explicitly says this will happen on soft reset.
+  this.setVTScrollRegion(null, null);
+
+  // Xterm also shows the cursor on soft reset, but does not alter the blink
+  // state.
+  this.setCursorVisible(true);
+};
+
+/**
+ * Move the cursor forward to the next tab stop, or to the last column
+ * if no more tab stops are set.
+ */
+hterm.Terminal.prototype.forwardTabStop = function() {
+  var column = this.screen_.cursorPosition.column;
+
+  for (var i = 0; i < this.tabStops_.length; i++) {
+    if (this.tabStops_[i] > column) {
+      this.setCursorColumn(this.tabStops_[i]);
+      return;
+    }
+  }
+
+  // xterm does not clear the overflow flag on HT or CHT.
+  var overflow = this.screen_.cursorPosition.overflow;
+  this.setCursorColumn(this.screenSize.width - 1);
+  this.screen_.cursorPosition.overflow = overflow;
+};
+
+/**
+ * Move the cursor backward to the previous tab stop, or to the first column
+ * if no previous tab stops are set.
+ */
+hterm.Terminal.prototype.backwardTabStop = function() {
+  var column = this.screen_.cursorPosition.column;
+
+  for (var i = this.tabStops_.length - 1; i >= 0; i--) {
+    if (this.tabStops_[i] < column) {
+      this.setCursorColumn(this.tabStops_[i]);
+      return;
+    }
+  }
+
+  this.setCursorColumn(1);
+};
+
+/**
+ * Set a tab stop at the given column.
+ *
+ * @param {integer} column Zero based column.
+ */
+hterm.Terminal.prototype.setTabStop = function(column) {
+  for (var i = this.tabStops_.length - 1; i >= 0; i--) {
+    if (this.tabStops_[i] == column)
+      return;
+
+    if (this.tabStops_[i] < column) {
+      this.tabStops_.splice(i + 1, 0, column);
+      return;
+    }
+  }
+
+  this.tabStops_.splice(0, 0, column);
+};
+
+/**
+ * Clear the tab stop at the current cursor position.
+ *
+ * No effect if there is no tab stop at the current cursor position.
+ */
+hterm.Terminal.prototype.clearTabStopAtCursor = function() {
+  var column = this.screen_.cursorPosition.column;
+
+  var i = this.tabStops_.indexOf(column);
+  if (i == -1)
+    return;
+
+  this.tabStops_.splice(i, 1);
+};
+
+/**
+ * Clear all tab stops.
+ */
+hterm.Terminal.prototype.clearAllTabStops = function() {
+  this.tabStops_.length = 0;
+  this.defaultTabStops = false;
+};
+
+/**
+ * Set up the default tab stops, starting from a given column.
+ *
+ * This sets a tabstop every (column % this.tabWidth) column, starting
+ * from the specified column, or 0 if no column is provided.  It also flags
+ * future resizes to set them up.
+ *
+ * This does not clear the existing tab stops first, use clearAllTabStops
+ * for that.
+ *
+ * @param {integer} opt_start Optional starting zero based starting column, useful
+ *     for filling out missing tab stops when the terminal is resized.
+ */
+hterm.Terminal.prototype.setDefaultTabStops = function(opt_start) {
+  var start = opt_start || 0;
+  var w = this.tabWidth;
+  // Round start up to a default tab stop.
+  start = start - 1 - ((start - 1) % w) + w;
+  for (var i = start; i < this.screenSize.width; i += w) {
+    this.setTabStop(i);
+  }
+
+  this.defaultTabStops = true;
+};
+
+/**
+ * Interpret a sequence of characters.
+ *
+ * Incomplete escape sequences are buffered until the next call.
+ *
+ * @param {string} str Sequence of characters to interpret or pass through.
+ */
+hterm.Terminal.prototype.interpret = function(str) {
+  this.scheduleSyncCursorPosition_();
+  this.vt.interpret(str);
+};
+
+/**
+ * Take over the given DIV for use as the terminal display.
+ *
+ * @param {HTMLDivElement} div The div to use as the terminal display.
+ */
+hterm.Terminal.prototype.decorate = function(div) {
+  const charset = div.ownerDocument.characterSet.toLowerCase();
+  if (charset != 'utf-8') {
+    console.warn(`Document encoding should be set to utf-8, not "${charset}";` +
+                 ` Add <meta charset='utf-8'/> to your HTML <head> to fix.`);
+  }
+
+  this.div_ = div;
+
+  this.accessibilityReader_ = new hterm.AccessibilityReader(div);
+
+  this.scrollPort_.decorate(div, () => this.setupScrollPort_());
+};
+
+/**
+ * Initialisation of ScrollPort properties which need to be set after its DOM
+ * has been initialised.
+ * @private
+ */
+hterm.Terminal.prototype.setupScrollPort_ = function() {
+  this.scrollPort_.setBackgroundImage(this.prefs_.get('background-image'));
+  this.scrollPort_.setBackgroundSize(this.prefs_.get('background-size'));
+  this.scrollPort_.setBackgroundPosition(
+      this.prefs_.get('background-position'));
+  this.scrollPort_.setUserCssUrl(this.prefs_.get('user-css'));
+  this.scrollPort_.setUserCssText(this.prefs_.get('user-css-text'));
+  this.scrollPort_.setAccessibilityReader(this.accessibilityReader_);
+
+  this.div_.focus = this.focus.bind(this);
+
+  this.setFontSize(this.prefs_.get('font-size'));
+  this.syncFontFamily();
+
+  this.setScrollbarVisible(this.prefs_.get('scrollbar-visible'));
+  this.setScrollWheelMoveMultipler(
+      this.prefs_.get('scroll-wheel-move-multiplier'));
+
+  this.document_ = this.scrollPort_.getDocument();
+  this.accessibilityReader_.decorate(this.document_);
+
+  this.document_.body.oncontextmenu = function() { return false; };
+  this.contextMenu.setDocument(this.document_);
+
+  var onMouse = this.onMouse_.bind(this);
+  var screenNode = this.scrollPort_.getScreenNode();
+  screenNode.addEventListener('mousedown', onMouse);
+  screenNode.addEventListener('mouseup', onMouse);
+  screenNode.addEventListener('mousemove', onMouse);
+  this.scrollPort_.onScrollWheel = onMouse;
+
+  screenNode.addEventListener('keydown', this.onKeyboardActivity_.bind(this));
+
+  screenNode.addEventListener(
+      'focus', this.onFocusChange_.bind(this, true));
+  // Listen for mousedown events on the screenNode as in FF the focus
+  // events don't bubble.
+  screenNode.addEventListener('mousedown', function() {
+    setTimeout(this.onFocusChange_.bind(this, true));
+  }.bind(this));
+
+  screenNode.addEventListener(
+      'blur', this.onFocusChange_.bind(this, false));
+
+  var style = this.document_.createElement('style');
+  style.textContent =
+      ('.cursor-node[focus="false"] {' +
+       '  box-sizing: border-box;' +
+       '  background-color: transparent !important;' +
+       '  border-width: 2px;' +
+       '  border-style: solid;' +
+       '}' +
+       'menu {' +
+       '  margin: 0;' +
+       '  padding: 0;' +
+       '  cursor: var(--hterm-mouse-cursor-pointer);' +
+       '}' +
+       'menuitem {' +
+       '  white-space: nowrap;' +
+       '  border-bottom: 1px dashed;' +
+       '  display: block;' +
+       '  padding: 0.3em 0.3em 0 0.3em;' +
+       '}' +
+       'menuitem.separator {' +
+       '  border-bottom: none;' +
+       '  height: 0.5em;' +
+       '  padding: 0;' +
+       '}' +
+       'menuitem:hover {' +
+       '  color: var(--hterm-cursor-color);' +
+       '}' +
+       '.wc-node {' +
+       '  display: inline-block;' +
+       '  text-align: center;' +
+       '  width: calc(var(--hterm-charsize-width) * 2);' +
+       '  line-height: var(--hterm-charsize-height);' +
+       '}' +
+       ':root {' +
+       '  --hterm-charsize-width: ' + this.scrollPort_.characterSize.width + 'px;' +
+       '  --hterm-charsize-height: ' + this.scrollPort_.characterSize.height + 'px;' +
+       // Default position hides the cursor for when the window is initializing.
+       '  --hterm-cursor-offset-col: -1;' +
+       '  --hterm-cursor-offset-row: -1;' +
+       '  --hterm-blink-node-duration: 0.7s;' +
+       '  --hterm-mouse-cursor-default: default;' +
+       '  --hterm-mouse-cursor-text: text;' +
+       '  --hterm-mouse-cursor-pointer: pointer;' +
+       '  --hterm-mouse-cursor-style: var(--hterm-mouse-cursor-text);' +
+       '}' +
+       '.uri-node:hover {' +
+       '  text-decoration: underline;' +
+       '  cursor: var(--hterm-mouse-cursor-pointer);' +
+       '}' +
+       '@keyframes blink {' +
+       '  from { opacity: 1.0; }' +
+       '  to { opacity: 0.0; }' +
+       '}' +
+       '.blink-node {' +
+       '  animation-name: blink;' +
+       '  animation-duration: var(--hterm-blink-node-duration);' +
+       '  animation-iteration-count: infinite;' +
+       '  animation-timing-function: ease-in-out;' +
+       '  animation-direction: alternate;' +
+       '}');
+  // Insert this stock style as the first node so that any user styles will
+  // override w/out having to use !important everywhere.  The rules above mix
+  // runtime variables with default ones designed to be overridden by the user,
+  // but we can wait for a concrete case from the users to determine the best
+  // way to split the sheet up to before & after the user-css settings.
+  this.document_.head.insertBefore(style, this.document_.head.firstChild);
+
+  this.cursorNode_ = this.document_.createElement('div');
+  this.cursorNode_.id = 'hterm:terminal-cursor';
+  this.cursorNode_.className = 'cursor-node';
+  this.cursorNode_.style.cssText =
+      ('position: absolute;' +
+       'left: calc(var(--hterm-charsize-width) * var(--hterm-cursor-offset-col));' +
+       'top: calc(var(--hterm-charsize-height) * var(--hterm-cursor-offset-row));' +
+       'display: ' + (this.options_.cursorVisible ? '' : 'none') + ';' +
+       'width: var(--hterm-charsize-width);' +
+       'height: var(--hterm-charsize-height);' +
+       'background-color: var(--hterm-cursor-color);' +
+       'border-color: var(--hterm-cursor-color);' +
+       '-webkit-transition: opacity, background-color 100ms linear;' +
+       '-moz-transition: opacity, background-color 100ms linear;');
+
+  this.setCursorColor();
+  this.setCursorBlink(!!this.prefs_.get('cursor-blink'));
+  this.restyleCursor_();
+
+  this.document_.body.appendChild(this.cursorNode_);
+
+  // When 'enableMouseDragScroll' is off we reposition this element directly
+  // under the mouse cursor after a click.  This makes Chrome associate
+  // subsequent mousemove events with the scroll-blocker.  Since the
+  // scroll-blocker is a peer (not a child) of the scrollport, the mousemove
+  // events do not cause the scrollport to scroll.
+  //
+  // It's a hack, but it's the cleanest way I could find.
+  this.scrollBlockerNode_ = this.document_.createElement('div');
+  this.scrollBlockerNode_.id = 'hterm:mouse-drag-scroll-blocker';
+  this.scrollBlockerNode_.setAttribute('aria-hidden', 'true');
+  this.scrollBlockerNode_.style.cssText =
+      ('position: absolute;' +
+       'top: -99px;' +
+       'display: block;' +
+       'width: 10px;' +
+       'height: 10px;');
+  this.document_.body.appendChild(this.scrollBlockerNode_);
+
+  this.scrollPort_.onScrollWheel = onMouse;
+  ['mousedown', 'mouseup', 'mousemove', 'click', 'dblclick',
+   ].forEach(function(event) {
+       this.scrollBlockerNode_.addEventListener(event, onMouse);
+       this.cursorNode_.addEventListener(event, onMouse);
+       this.document_.addEventListener(event, onMouse);
+     }.bind(this));
+
+  this.cursorNode_.addEventListener('mousedown', function() {
+      setTimeout(this.focus.bind(this));
+    }.bind(this));
+
+  this.setReverseVideo(false);
+
+  this.scrollPort_.focus();
+  this.scrollPort_.scheduleRedraw();
+};
+
+/**
+ * Return the HTML document that contains the terminal DOM nodes.
+ *
+ * @return {HTMLDocument}
+ */
+hterm.Terminal.prototype.getDocument = function() {
+  return this.document_;
+};
+
+/**
+ * Focus the terminal.
+ */
+hterm.Terminal.prototype.focus = function() {
+  this.scrollPort_.focus();
+};
+
+/**
+ * Return the HTML Element for a given row index.
+ *
+ * This is a method from the RowProvider interface.  The ScrollPort uses
+ * it to fetch rows on demand as they are scrolled into view.
+ *
+ * TODO(rginda): Consider saving scrollback rows as (HTML source, text content)
+ * pairs to conserve memory.
+ *
+ * @param {integer} index The zero-based row index, measured relative to the
+ *     start of the scrollback buffer.  On-screen rows will always have the
+ *     largest indices.
+ * @return {HTMLElement} The 'x-row' element containing for the requested row.
+ */
+hterm.Terminal.prototype.getRowNode = function(index) {
+  if (index < this.scrollbackRows_.length)
+    return this.scrollbackRows_[index];
+
+  var screenIndex = index - this.scrollbackRows_.length;
+  return this.screen_.rowsArray[screenIndex];
+};
+
+/**
+ * Return the text content for a given range of rows.
+ *
+ * This is a method from the RowProvider interface.  The ScrollPort uses
+ * it to fetch text content on demand when the user attempts to copy their
+ * selection to the clipboard.
+ *
+ * @param {integer} start The zero-based row index to start from, measured
+ *     relative to the start of the scrollback buffer.  On-screen rows will
+ *     always have the largest indices.
+ * @param {integer} end The zero-based row index to end on, measured
+ *     relative to the start of the scrollback buffer.
+ * @return {string} A single string containing the text value of the range of
+ *     rows.  Lines will be newline delimited, with no trailing newline.
+ */
+hterm.Terminal.prototype.getRowsText = function(start, end) {
+  var ary = [];
+  for (var i = start; i < end; i++) {
+    var node = this.getRowNode(i);
+    ary.push(node.textContent);
+    if (i < end - 1 && !node.getAttribute('line-overflow'))
+      ary.push('\n');
+  }
+
+  return ary.join('');
+};
+
+/**
+ * Return the text content for a given row.
+ *
+ * This is a method from the RowProvider interface.  The ScrollPort uses
+ * it to fetch text content on demand when the user attempts to copy their
+ * selection to the clipboard.
+ *
+ * @param {integer} index The zero-based row index to return, measured
+ *     relative to the start of the scrollback buffer.  On-screen rows will
+ *     always have the largest indices.
+ * @return {string} A string containing the text value of the selected row.
+ */
+hterm.Terminal.prototype.getRowText = function(index) {
+  var node = this.getRowNode(index);
+  return node.textContent;
+};
+
+/**
+ * Return the total number of rows in the addressable screen and in the
+ * scrollback buffer of this terminal.
+ *
+ * This is a method from the RowProvider interface.  The ScrollPort uses
+ * it to compute the size of the scrollbar.
+ *
+ * @return {integer} The number of rows in this terminal.
+ */
+hterm.Terminal.prototype.getRowCount = function() {
+  return this.scrollbackRows_.length + this.screen_.rowsArray.length;
+};
+
+/**
+ * Create DOM nodes for new rows and append them to the end of the terminal.
+ *
+ * This is the only correct way to add a new DOM node for a row.  Notice that
+ * the new row is appended to the bottom of the list of rows, and does not
+ * require renumbering (of the rowIndex property) of previous rows.
+ *
+ * If you think you want a new blank row somewhere in the middle of the
+ * terminal, look into moveRows_().
+ *
+ * This method does not pay attention to vtScrollTop/Bottom, since you should
+ * be using moveRows() in cases where they would matter.
+ *
+ * The cursor will be positioned at column 0 of the first inserted line.
+ *
+ * @param {number} count The number of rows to created.
+ */
+hterm.Terminal.prototype.appendRows_ = function(count) {
+  var cursorRow = this.screen_.rowsArray.length;
+  var offset = this.scrollbackRows_.length + cursorRow;
+  for (var i = 0; i < count; i++) {
+    var row = this.document_.createElement('x-row');
+    row.appendChild(this.document_.createTextNode(''));
+    row.rowIndex = offset + i;
+    this.screen_.pushRow(row);
+  }
+
+  var extraRows = this.screen_.rowsArray.length - this.screenSize.height;
+  if (extraRows > 0) {
+    var ary = this.screen_.shiftRows(extraRows);
+    Array.prototype.push.apply(this.scrollbackRows_, ary);
+    if (this.scrollPort_.isScrolledEnd)
+      this.scheduleScrollDown_();
+  }
+
+  if (cursorRow >= this.screen_.rowsArray.length)
+    cursorRow = this.screen_.rowsArray.length - 1;
+
+  this.setAbsoluteCursorPosition(cursorRow, 0);
+};
+
+/**
+ * Relocate rows from one part of the addressable screen to another.
+ *
+ * This is used to recycle rows during VT scrolls (those which are driven
+ * by VT commands, rather than by the user manipulating the scrollbar.)
+ *
+ * In this case, the blank lines scrolled into the scroll region are made of
+ * the nodes we scrolled off.  These have their rowIndex properties carefully
+ * renumbered so as not to confuse the ScrollPort.
+ *
+ * @param {number} fromIndex The start index.
+ * @param {number} count The number of rows to move.
+ * @param {number} toIndex The destination index.
+ */
+hterm.Terminal.prototype.moveRows_ = function(fromIndex, count, toIndex) {
+  var ary = this.screen_.removeRows(fromIndex, count);
+  this.screen_.insertRows(toIndex, ary);
+
+  var start, end;
+  if (fromIndex < toIndex) {
+    start = fromIndex;
+    end = toIndex + count;
+  } else {
+    start = toIndex;
+    end = fromIndex + count;
+  }
+
+  this.renumberRows_(start, end);
+  this.scrollPort_.scheduleInvalidate();
+};
+
+/**
+ * Renumber the rowIndex property of the given range of rows.
+ *
+ * The start and end indices are relative to the screen, not the scrollback.
+ * Rows in the scrollback buffer cannot be renumbered.  Since they are not
+ * addressable (you can't delete them, scroll them, etc), you should have
+ * no need to renumber scrollback rows.
+ *
+ * @param {number} start The start index.
+ * @param {number} end The end index.
+ * @param {hterm.Screen} opt_screen The screen to renumber.
+ */
+hterm.Terminal.prototype.renumberRows_ = function(start, end, opt_screen) {
+  var screen = opt_screen || this.screen_;
+
+  var offset = this.scrollbackRows_.length;
+  for (var i = start; i < end; i++) {
+    screen.rowsArray[i].rowIndex = offset + i;
+  }
+};
+
+/**
+ * Print a string to the terminal.
+ *
+ * This respects the current insert and wraparound modes.  It will add new lines
+ * to the end of the terminal, scrolling off the top into the scrollback buffer
+ * if necessary.
+ *
+ * The string is *not* parsed for escape codes.  Use the interpret() method if
+ * that's what you're after.
+ *
+ * @param{string} str The string to print.
+ */
+hterm.Terminal.prototype.print = function(str) {
+  this.scheduleSyncCursorPosition_();
+
+  // Basic accessibility output for the screen reader.
+  this.accessibilityReader_.announce(str);
+
+  var startOffset = 0;
+
+  var strWidth = lib.wc.strWidth(str);
+  // Fun edge case: If the string only contains zero width codepoints (like
+  // combining characters), we make sure to iterate at least once below.
+  if (strWidth == 0 && str)
+    strWidth = 1;
+
+  while (startOffset < strWidth) {
+    if (this.options_.wraparound && this.screen_.cursorPosition.overflow) {
+      this.screen_.commitLineOverflow();
+      this.newLine(true);
+    }
+
+    var count = strWidth - startOffset;
+    var didOverflow = false;
+    var substr;
+
+    if (this.screen_.cursorPosition.column + count >= this.screenSize.width) {
+      didOverflow = true;
+      count = this.screenSize.width - this.screen_.cursorPosition.column;
+    }
+
+    if (didOverflow && !this.options_.wraparound) {
+      // If the string overflowed the line but wraparound is off, then the
+      // last printed character should be the last of the string.
+      // TODO: This will add to our problems with multibyte UTF-16 characters.
+      substr = lib.wc.substr(str, startOffset, count - 1) +
+          lib.wc.substr(str, strWidth - 1);
+      count = strWidth;
+    } else {
+      substr = lib.wc.substr(str, startOffset, count);
+    }
+
+    var tokens = hterm.TextAttributes.splitWidecharString(substr);
+    for (var i = 0; i < tokens.length; i++) {
+      this.screen_.textAttributes.wcNode = tokens[i].wcNode;
+      this.screen_.textAttributes.asciiNode = tokens[i].asciiNode;
+
+      if (this.options_.insertMode) {
+        this.screen_.insertString(tokens[i].str, tokens[i].wcStrWidth);
+      } else {
+        this.screen_.overwriteString(tokens[i].str, tokens[i].wcStrWidth);
+      }
+      this.screen_.textAttributes.wcNode = false;
+      this.screen_.textAttributes.asciiNode = true;
+    }
+
+    this.screen_.maybeClipCurrentRow();
+    startOffset += count;
+  }
+
+  if (this.scrollOnOutput_)
+    this.scrollPort_.scrollRowToBottom(this.getRowCount());
+};
+
+/**
+ * Set the VT scroll region.
+ *
+ * This also resets the cursor position to the absolute (0, 0) position, since
+ * that's what xterm appears to do.
+ *
+ * Setting the scroll region to the full height of the terminal will clear
+ * the scroll region.  This is *NOT* what most terminals do.  We're explicitly
+ * going "off-spec" here because it makes `screen` and `tmux` overflow into the
+ * local scrollback buffer, which means the scrollbars and shift-pgup/pgdn
+ * continue to work as most users would expect.
+ *
+ * @param {integer} scrollTop The zero-based top of the scroll region.
+ * @param {integer} scrollBottom The zero-based bottom of the scroll region,
+ *     inclusive.
+ */
+hterm.Terminal.prototype.setVTScrollRegion = function(scrollTop, scrollBottom) {
+  if (scrollTop == 0 && scrollBottom == this.screenSize.height - 1) {
+    this.vtScrollTop_ = null;
+    this.vtScrollBottom_ = null;
+  } else {
+    this.vtScrollTop_ = scrollTop;
+    this.vtScrollBottom_ = scrollBottom;
+  }
+};
+
+/**
+ * Return the top row index according to the VT.
+ *
+ * This will return 0 unless the terminal has been told to restrict scrolling
+ * to some lower row.  It is used for some VT cursor positioning and scrolling
+ * commands.
+ *
+ * @return {integer} The topmost row in the terminal's scroll region.
+ */
+hterm.Terminal.prototype.getVTScrollTop = function() {
+  if (this.vtScrollTop_ != null)
+    return this.vtScrollTop_;
+
+  return 0;
+};
+
+/**
+ * Return the bottom row index according to the VT.
+ *
+ * This will return the height of the terminal unless the it has been told to
+ * restrict scrolling to some higher row.  It is used for some VT cursor
+ * positioning and scrolling commands.
+ *
+ * @return {integer} The bottom most row in the terminal's scroll region.
+ */
+hterm.Terminal.prototype.getVTScrollBottom = function() {
+  if (this.vtScrollBottom_ != null)
+    return this.vtScrollBottom_;
+
+  return this.screenSize.height - 1;
+};
+
+/**
+ * Process a '\n' character.
+ *
+ * If the cursor is on the final row of the terminal this will append a new
+ * blank row to the screen and scroll the topmost row into the scrollback
+ * buffer.
+ *
+ * Otherwise, this moves the cursor to column zero of the next row.
+ *
+ * @param {boolean=} dueToOverflow Whether the newline is due to wraparound of
+ *     the terminal.
+ */
+hterm.Terminal.prototype.newLine = function(dueToOverflow = false) {
+  if (!dueToOverflow)
+    this.accessibilityReader_.newLine();
+
+  var cursorAtEndOfScreen = (this.screen_.cursorPosition.row ==
+                             this.screen_.rowsArray.length - 1);
+
+  if (this.vtScrollBottom_ != null) {
+    // A VT Scroll region is active, we never append new rows.
+    if (this.screen_.cursorPosition.row == this.vtScrollBottom_) {
+      // We're at the end of the VT Scroll Region, perform a VT scroll.
+      this.vtScrollUp(1);
+      this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row, 0);
+    } else if (cursorAtEndOfScreen) {
+      // We're at the end of the screen, the only thing to do is put the
+      // cursor to column 0.
+      this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row, 0);
+    } else {
+      // Anywhere else, advance the cursor row, and reset the column.
+      this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row + 1, 0);
+    }
+  } else if (cursorAtEndOfScreen) {
+    // We're at the end of the screen.  Append a new row to the terminal,
+    // shifting the top row into the scrollback.
+    this.appendRows_(1);
+  } else {
+    // Anywhere else in the screen just moves the cursor.
+    this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row + 1, 0);
+  }
+};
+
+/**
+ * Like newLine(), except maintain the cursor column.
+ */
+hterm.Terminal.prototype.lineFeed = function() {
+  var column = this.screen_.cursorPosition.column;
+  this.newLine();
+  this.setCursorColumn(column);
+};
+
+/**
+ * If autoCarriageReturn is set then newLine(), else lineFeed().
+ */
+hterm.Terminal.prototype.formFeed = function() {
+  if (this.options_.autoCarriageReturn) {
+    this.newLine();
+  } else {
+    this.lineFeed();
+  }
+};
+
+/**
+ * Move the cursor up one row, possibly inserting a blank line.
+ *
+ * The cursor column is not changed.
+ */
+hterm.Terminal.prototype.reverseLineFeed = function() {
+  var scrollTop = this.getVTScrollTop();
+  var currentRow = this.screen_.cursorPosition.row;
+
+  if (currentRow == scrollTop) {
+    this.insertLines(1);
+  } else {
+    this.setAbsoluteCursorRow(currentRow - 1);
+  }
+};
+
+/**
+ * Replace all characters to the left of the current cursor with the space
+ * character.
+ *
+ * TODO(rginda): This should probably *remove* the characters (not just replace
+ * with a space) if there are no characters at or beyond the current cursor
+ * position.
+ */
+hterm.Terminal.prototype.eraseToLeft = function() {
+  var cursor = this.saveCursor();
+  this.setCursorColumn(0);
+  const count = cursor.column + 1;
+  this.screen_.overwriteString(' '.repeat(count), count);
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Erase a given number of characters to the right of the cursor.
+ *
+ * The cursor position is unchanged.
+ *
+ * If the current background color is not the default background color this
+ * will insert spaces rather than delete.  This is unfortunate because the
+ * trailing space will affect text selection, but it's difficult to come up
+ * with a way to style empty space that wouldn't trip up the hterm.Screen
+ * code.
+ *
+ * eraseToRight is ignored in the presence of a cursor overflow.  This deviates
+ * from xterm, but agrees with gnome-terminal and konsole, xfce4-terminal.  See
+ * crbug.com/232390 for details.
+ *
+ * @param {number} opt_count The number of characters to erase.
+ */
+hterm.Terminal.prototype.eraseToRight = function(opt_count) {
+  if (this.screen_.cursorPosition.overflow)
+    return;
+
+  var maxCount = this.screenSize.width - this.screen_.cursorPosition.column;
+  var count = opt_count ? Math.min(opt_count, maxCount) : maxCount;
+
+  if (this.screen_.textAttributes.background ===
+      this.screen_.textAttributes.DEFAULT_COLOR) {
+    var cursorRow = this.screen_.rowsArray[this.screen_.cursorPosition.row];
+    if (hterm.TextAttributes.nodeWidth(cursorRow) <=
+        this.screen_.cursorPosition.column + count) {
+      this.screen_.deleteChars(count);
+      this.clearCursorOverflow();
+      return;
+    }
+  }
+
+  var cursor = this.saveCursor();
+  this.screen_.overwriteString(' '.repeat(count), count);
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Erase the current line.
+ *
+ * The cursor position is unchanged.
+ */
+hterm.Terminal.prototype.eraseLine = function() {
+  var cursor = this.saveCursor();
+  this.screen_.clearCursorRow();
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Erase all characters from the start of the screen to the current cursor
+ * position, regardless of scroll region.
+ *
+ * The cursor position is unchanged.
+ */
+hterm.Terminal.prototype.eraseAbove = function() {
+  var cursor = this.saveCursor();
+
+  this.eraseToLeft();
+
+  for (var i = 0; i < cursor.row; i++) {
+    this.setAbsoluteCursorPosition(i, 0);
+    this.screen_.clearCursorRow();
+  }
+
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Erase all characters from the current cursor position to the end of the
+ * screen, regardless of scroll region.
+ *
+ * The cursor position is unchanged.
+ */
+hterm.Terminal.prototype.eraseBelow = function() {
+  var cursor = this.saveCursor();
+
+  this.eraseToRight();
+
+  var bottom = this.screenSize.height - 1;
+  for (var i = cursor.row + 1; i <= bottom; i++) {
+    this.setAbsoluteCursorPosition(i, 0);
+    this.screen_.clearCursorRow();
+  }
+
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Fill the terminal with a given character.
+ *
+ * This methods does not respect the VT scroll region.
+ *
+ * @param {string} ch The character to use for the fill.
+ */
+hterm.Terminal.prototype.fill = function(ch) {
+  var cursor = this.saveCursor();
+
+  this.setAbsoluteCursorPosition(0, 0);
+  for (var row = 0; row < this.screenSize.height; row++) {
+    for (var col = 0; col < this.screenSize.width; col++) {
+      this.setAbsoluteCursorPosition(row, col);
+      this.screen_.overwriteString(ch, 1);
+    }
+  }
+
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Erase the entire display and leave the cursor at (0, 0).
+ *
+ * This does not respect the scroll region.
+ *
+ * @param {hterm.Screen} opt_screen Optional screen to operate on.  Defaults
+ *     to the current screen.
+ */
+hterm.Terminal.prototype.clearHome = function(opt_screen) {
+  var screen = opt_screen || this.screen_;
+  var bottom = screen.getHeight();
+
+  this.accessibilityReader_.clear();
+
+  if (bottom == 0) {
+    // Empty screen, nothing to do.
+    return;
+  }
+
+  for (var i = 0; i < bottom; i++) {
+    screen.setCursorPosition(i, 0);
+    screen.clearCursorRow();
+  }
+
+  screen.setCursorPosition(0, 0);
+};
+
+/**
+ * Erase the entire display without changing the cursor position.
+ *
+ * The cursor position is unchanged.  This does not respect the scroll
+ * region.
+ *
+ * @param {hterm.Screen} opt_screen Optional screen to operate on.  Defaults
+ *     to the current screen.
+ */
+hterm.Terminal.prototype.clear = function(opt_screen) {
+  var screen = opt_screen || this.screen_;
+  var cursor = screen.cursorPosition.clone();
+  this.clearHome(screen);
+  screen.setCursorPosition(cursor.row, cursor.column);
+};
+
+/**
+ * VT command to insert lines at the current cursor row.
+ *
+ * This respects the current scroll region.  Rows pushed off the bottom are
+ * lost (they won't show up in the scrollback buffer).
+ *
+ * @param {integer} count The number of lines to insert.
+ */
+hterm.Terminal.prototype.insertLines = function(count) {
+  var cursorRow = this.screen_.cursorPosition.row;
+
+  var bottom = this.getVTScrollBottom();
+  count = Math.min(count, bottom - cursorRow);
+
+  // The moveCount is the number of rows we need to relocate to make room for
+  // the new row(s).  The count is the distance to move them.
+  var moveCount = bottom - cursorRow - count + 1;
+  if (moveCount)
+    this.moveRows_(cursorRow, moveCount, cursorRow + count);
+
+  for (var i = count - 1; i >= 0; i--) {
+    this.setAbsoluteCursorPosition(cursorRow + i, 0);
+    this.screen_.clearCursorRow();
+  }
+};
+
+/**
+ * VT command to delete lines at the current cursor row.
+ *
+ * New rows are added to the bottom of scroll region to take their place.  New
+ * rows are strictly there to take up space and have no content or style.
+ *
+ * @param {number} count The number of lines to delete.
+ */
+hterm.Terminal.prototype.deleteLines = function(count) {
+  var cursor = this.saveCursor();
+
+  var top = cursor.row;
+  var bottom = this.getVTScrollBottom();
+
+  var maxCount = bottom - top + 1;
+  count = Math.min(count, maxCount);
+
+  var moveStart = bottom - count + 1;
+  if (count != maxCount)
+    this.moveRows_(top, count, moveStart);
+
+  for (var i = 0; i < count; i++) {
+    this.setAbsoluteCursorPosition(moveStart + i, 0);
+    this.screen_.clearCursorRow();
+  }
+
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Inserts the given number of spaces at the current cursor position.
+ *
+ * The cursor position is not changed.
+ *
+ * @param {number} count The number of spaces to insert.
+ */
+hterm.Terminal.prototype.insertSpace = function(count) {
+  var cursor = this.saveCursor();
+
+  const ws = ' '.repeat(count || 1);
+  this.screen_.insertString(ws, ws.length);
+  this.screen_.maybeClipCurrentRow();
+
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Forward-delete the specified number of characters starting at the cursor
+ * position.
+ *
+ * @param {integer} count The number of characters to delete.
+ */
+hterm.Terminal.prototype.deleteChars = function(count) {
+  var deleted = this.screen_.deleteChars(count);
+  if (deleted && !this.screen_.textAttributes.isDefault()) {
+    var cursor = this.saveCursor();
+    this.setCursorColumn(this.screenSize.width - deleted);
+    this.screen_.insertString(' '.repeat(deleted));
+    this.restoreCursor(cursor);
+  }
+
+  this.clearCursorOverflow();
+};
+
+/**
+ * Shift rows in the scroll region upwards by a given number of lines.
+ *
+ * New rows are inserted at the bottom of the scroll region to fill the
+ * vacated rows.  The new rows not filled out with the current text attributes.
+ *
+ * This function does not affect the scrollback rows at all.  Rows shifted
+ * off the top are lost.
+ *
+ * The cursor position is not altered.
+ *
+ * @param {integer} count The number of rows to scroll.
+ */
+hterm.Terminal.prototype.vtScrollUp = function(count) {
+  var cursor = this.saveCursor();
+
+  this.setAbsoluteCursorRow(this.getVTScrollTop());
+  this.deleteLines(count);
+
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Shift rows below the cursor down by a given number of lines.
+ *
+ * This function respects the current scroll region.
+ *
+ * New rows are inserted at the top of the scroll region to fill the
+ * vacated rows.  The new rows not filled out with the current text attributes.
+ *
+ * This function does not affect the scrollback rows at all.  Rows shifted
+ * off the bottom are lost.
+ *
+ * @param {integer} count The number of rows to scroll.
+ */
+hterm.Terminal.prototype.vtScrollDown = function(opt_count) {
+  var cursor = this.saveCursor();
+
+  this.setAbsoluteCursorPosition(this.getVTScrollTop(), 0);
+  this.insertLines(opt_count);
+
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Enable accessibility-friendly features that have a performance impact.
+ *
+ * This will generate additional DOM nodes in an aria-live region that will
+ * cause Assitive Technology to announce the output of the terminal. It also
+ * enables other features that aid assistive technology. All the features gated
+ * behind this flag have a performance impact on the terminal which is why they
+ * are made optional.
+ *
+ * @param {boolean} enabled Whether to enable accessibility-friendly features.
+ */
+hterm.Terminal.prototype.setAccessibilityEnabled = function(enabled) {
+  this.accessibilityReader_.setAccessibilityEnabled(enabled);
+};
+
+/**
+ * Set the cursor position.
+ *
+ * The cursor row is relative to the scroll region if the terminal has
+ * 'origin mode' enabled, or relative to the addressable screen otherwise.
+ *
+ * @param {integer} row The new zero-based cursor row.
+ * @param {integer} row The new zero-based cursor column.
+ */
+hterm.Terminal.prototype.setCursorPosition = function(row, column) {
+  if (this.options_.originMode) {
+    this.setRelativeCursorPosition(row, column);
+  } else {
+    this.setAbsoluteCursorPosition(row, column);
+  }
+};
+
+/**
+ * Move the cursor relative to its current position.
+ *
+ * @param {number} row
+ * @param {number} column
+ */
+hterm.Terminal.prototype.setRelativeCursorPosition = function(row, column) {
+  var scrollTop = this.getVTScrollTop();
+  row = lib.f.clamp(row + scrollTop, scrollTop, this.getVTScrollBottom());
+  column = lib.f.clamp(column, 0, this.screenSize.width - 1);
+  this.screen_.setCursorPosition(row, column);
+};
+
+/**
+ * Move the cursor to the specified position.
+ *
+ * @param {number} row
+ * @param {number} column
+ */
+hterm.Terminal.prototype.setAbsoluteCursorPosition = function(row, column) {
+  row = lib.f.clamp(row, 0, this.screenSize.height - 1);
+  column = lib.f.clamp(column, 0, this.screenSize.width - 1);
+  this.screen_.setCursorPosition(row, column);
+};
+
+/**
+ * Set the cursor column.
+ *
+ * @param {integer} column The new zero-based cursor column.
+ */
+hterm.Terminal.prototype.setCursorColumn = function(column) {
+  this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row, column);
+};
+
+/**
+ * Return the cursor column.
+ *
+ * @return {integer} The zero-based cursor column.
+ */
+hterm.Terminal.prototype.getCursorColumn = function() {
+  return this.screen_.cursorPosition.column;
+};
+
+/**
+ * Set the cursor row.
+ *
+ * The cursor row is relative to the scroll region if the terminal has
+ * 'origin mode' enabled, or relative to the addressable screen otherwise.
+ *
+ * @param {integer} row The new cursor row.
+ */
+hterm.Terminal.prototype.setAbsoluteCursorRow = function(row) {
+  this.setAbsoluteCursorPosition(row, this.screen_.cursorPosition.column);
+};
+
+/**
+ * Return the cursor row.
+ *
+ * @return {integer} The zero-based cursor row.
+ */
+hterm.Terminal.prototype.getCursorRow = function() {
+  return this.screen_.cursorPosition.row;
+};
+
+/**
+ * Request that the ScrollPort redraw itself soon.
+ *
+ * The redraw will happen asynchronously, soon after the call stack winds down.
+ * Multiple calls will be coalesced into a single redraw.
+ */
+hterm.Terminal.prototype.scheduleRedraw_ = function() {
+  if (this.timeouts_.redraw)
+    return;
+
+  var self = this;
+  this.timeouts_.redraw = setTimeout(function() {
+      delete self.timeouts_.redraw;
+      self.scrollPort_.redraw_();
+    }, 0);
+};
+
+/**
+ * Request that the ScrollPort be scrolled to the bottom.
+ *
+ * The scroll will happen asynchronously, soon after the call stack winds down.
+ * Multiple calls will be coalesced into a single scroll.
+ *
+ * This affects the scrollbar position of the ScrollPort, and has nothing to
+ * do with the VT scroll commands.
+ */
+hterm.Terminal.prototype.scheduleScrollDown_ = function() {
+  if (this.timeouts_.scrollDown)
+    return;
+
+  var self = this;
+  this.timeouts_.scrollDown = setTimeout(function() {
+      delete self.timeouts_.scrollDown;
+      self.scrollPort_.scrollRowToBottom(self.getRowCount());
+    }, 10);
+};
+
+/**
+ * Move the cursor up a specified number of rows.
+ *
+ * @param {integer} count The number of rows to move the cursor.
+ */
+hterm.Terminal.prototype.cursorUp = function(count) {
+  return this.cursorDown(-(count || 1));
+};
+
+/**
+ * Move the cursor down a specified number of rows.
+ *
+ * @param {integer} count The number of rows to move the cursor.
+ */
+hterm.Terminal.prototype.cursorDown = function(count) {
+  count = count || 1;
+  var minHeight = (this.options_.originMode ? this.getVTScrollTop() : 0);
+  var maxHeight = (this.options_.originMode ? this.getVTScrollBottom() :
+                   this.screenSize.height - 1);
+
+  var row = lib.f.clamp(this.screen_.cursorPosition.row + count,
+                        minHeight, maxHeight);
+  this.setAbsoluteCursorRow(row);
+};
+
+/**
+ * Move the cursor left a specified number of columns.
+ *
+ * If reverse wraparound mode is enabled and the previous row wrapped into
+ * the current row then we back up through the wraparound as well.
+ *
+ * @param {integer} count The number of columns to move the cursor.
+ */
+hterm.Terminal.prototype.cursorLeft = function(count) {
+  count = count || 1;
+
+  if (count < 1)
+    return;
+
+  var currentColumn = this.screen_.cursorPosition.column;
+  if (this.options_.reverseWraparound) {
+    if (this.screen_.cursorPosition.overflow) {
+      // If this cursor is in the right margin, consume one count to get it
+      // back to the last column.  This only applies when we're in reverse
+      // wraparound mode.
+      count--;
+      this.clearCursorOverflow();
+
+      if (!count)
+        return;
+    }
+
+    var newRow = this.screen_.cursorPosition.row;
+    var newColumn = currentColumn - count;
+    if (newColumn < 0) {
+      newRow = newRow - Math.floor(count / this.screenSize.width) - 1;
+      if (newRow < 0) {
+        // xterm also wraps from row 0 to the last row.
+        newRow = this.screenSize.height + newRow % this.screenSize.height;
+      }
+      newColumn = this.screenSize.width + newColumn % this.screenSize.width;
+    }
+
+    this.setCursorPosition(Math.max(newRow, 0), newColumn);
+
+  } else {
+    var newColumn = Math.max(currentColumn - count, 0);
+    this.setCursorColumn(newColumn);
+  }
+};
+
+/**
+ * Move the cursor right a specified number of columns.
+ *
+ * @param {integer} count The number of columns to move the cursor.
+ */
+hterm.Terminal.prototype.cursorRight = function(count) {
+  count = count || 1;
+
+  if (count < 1)
+    return;
+
+  var column = lib.f.clamp(this.screen_.cursorPosition.column + count,
+                           0, this.screenSize.width - 1);
+  this.setCursorColumn(column);
+};
+
+/**
+ * Reverse the foreground and background colors of the terminal.
+ *
+ * This only affects text that was drawn with no attributes.
+ *
+ * TODO(rginda): Test xterm to see if reverse is respected for text that has
+ * been drawn with attributes that happen to coincide with the default
+ * 'no-attribute' colors.  My guess is probably not.
+ *
+ * @param {boolean} state The state to set.
+ */
+hterm.Terminal.prototype.setReverseVideo = function(state) {
+  this.options_.reverseVideo = state;
+  if (state) {
+    this.scrollPort_.setForegroundColor(this.backgroundColor_);
+    this.scrollPort_.setBackgroundColor(this.foregroundColor_);
+  } else {
+    this.scrollPort_.setForegroundColor(this.foregroundColor_);
+    this.scrollPort_.setBackgroundColor(this.backgroundColor_);
+  }
+};
+
+/**
+ * Ring the terminal bell.
+ *
+ * This will not play the bell audio more than once per second.
+ */
+hterm.Terminal.prototype.ringBell = function() {
+  this.cursorNode_.style.backgroundColor =
+      this.scrollPort_.getForegroundColor();
+
+  var self = this;
+  setTimeout(function() {
+      self.restyleCursor_();
+    }, 200);
+
+  // bellSquelchTimeout_ affects both audio and notification bells.
+  if (this.bellSquelchTimeout_)
+    return;
+
+  if (this.bellAudio_.getAttribute('src')) {
+    this.bellAudio_.play();
+    this.bellSequelchTimeout_ = setTimeout(function() {
+        delete this.bellSquelchTimeout_;
+      }.bind(this), 500);
+  } else {
+    delete this.bellSquelchTimeout_;
+  }
+
+  if (this.desktopNotificationBell_ && !this.document_.hasFocus()) {
+    var n = hterm.notify();
+    this.bellNotificationList_.push(n);
+    // TODO: Should we try to raise the window here?
+    n.onclick = function() { self.closeBellNotifications_(); };
+  }
+};
+
+/**
+ * Set the origin mode bit.
+ *
+ * If origin mode is on, certain VT cursor and scrolling commands measure their
+ * row parameter relative to the VT scroll region.  Otherwise, row 0 corresponds
+ * to the top of the addressable screen.
+ *
+ * Defaults to off.
+ *
+ * @param {boolean} state True to set origin mode, false to unset.
+ */
+hterm.Terminal.prototype.setOriginMode = function(state) {
+  this.options_.originMode = state;
+  this.setCursorPosition(0, 0);
+};
+
+/**
+ * Set the insert mode bit.
+ *
+ * If insert mode is on, existing text beyond the cursor position will be
+ * shifted right to make room for new text.  Otherwise, new text overwrites
+ * any existing text.
+ *
+ * Defaults to off.
+ *
+ * @param {boolean} state True to set insert mode, false to unset.
+ */
+hterm.Terminal.prototype.setInsertMode = function(state) {
+  this.options_.insertMode = state;
+};
+
+/**
+ * Set the auto carriage return bit.
+ *
+ * If auto carriage return is on then a formfeed character is interpreted
+ * as a newline, otherwise it's the same as a linefeed.  The difference boils
+ * down to whether or not the cursor column is reset.
+ *
+ * @param {boolean} state The state to set.
+ */
+hterm.Terminal.prototype.setAutoCarriageReturn = function(state) {
+  this.options_.autoCarriageReturn = state;
+};
+
+/**
+ * Set the wraparound mode bit.
+ *
+ * If wraparound mode is on, certain VT commands will allow the cursor to wrap
+ * to the start of the following row.  Otherwise, the cursor is clamped to the
+ * end of the screen and attempts to write past it are ignored.
+ *
+ * Defaults to on.
+ *
+ * @param {boolean} state True to set wraparound mode, false to unset.
+ */
+hterm.Terminal.prototype.setWraparound = function(state) {
+  this.options_.wraparound = state;
+};
+
+/**
+ * Set the reverse-wraparound mode bit.
+ *
+ * If wraparound mode is off, certain VT commands will allow the cursor to wrap
+ * to the end of the previous row.  Otherwise, the cursor is clamped to column
+ * 0.
+ *
+ * Defaults to off.
+ *
+ * @param {boolean} state True to set reverse-wraparound mode, false to unset.
+ */
+hterm.Terminal.prototype.setReverseWraparound = function(state) {
+  this.options_.reverseWraparound = state;
+};
+
+/**
+ * Selects between the primary and alternate screens.
+ *
+ * If alternate mode is on, the alternate screen is active.  Otherwise the
+ * primary screen is active.
+ *
+ * Swapping screens has no effect on the scrollback buffer.
+ *
+ * Each screen maintains its own cursor position.
+ *
+ * Defaults to off.
+ *
+ * @param {boolean} state True to set alternate mode, false to unset.
+ */
+hterm.Terminal.prototype.setAlternateMode = function(state) {
+  var cursor = this.saveCursor();
+  this.screen_ = state ? this.alternateScreen_ : this.primaryScreen_;
+
+  if (this.screen_.rowsArray.length &&
+      this.screen_.rowsArray[0].rowIndex != this.scrollbackRows_.length) {
+    // If the screen changed sizes while we were away, our rowIndexes may
+    // be incorrect.
+    var offset = this.scrollbackRows_.length;
+    var ary = this.screen_.rowsArray;
+    for (var i = 0; i < ary.length; i++) {
+      ary[i].rowIndex = offset + i;
+    }
+  }
+
+  this.realizeWidth_(this.screenSize.width);
+  this.realizeHeight_(this.screenSize.height);
+  this.scrollPort_.syncScrollHeight();
+  this.scrollPort_.invalidate();
+
+  this.restoreCursor(cursor);
+  this.scrollPort_.resize();
+};
+
+/**
+ * Set the cursor-blink mode bit.
+ *
+ * If cursor-blink is on, the cursor will blink when it is visible.  Otherwise
+ * a visible cursor does not blink.
+ *
+ * You should make sure to turn blinking off if you're going to dispose of a
+ * terminal, otherwise you'll leak a timeout.
+ *
+ * Defaults to on.
+ *
+ * @param {boolean} state True to set cursor-blink mode, false to unset.
+ */
+hterm.Terminal.prototype.setCursorBlink = function(state) {
+  this.options_.cursorBlink = state;
+
+  if (!state && this.timeouts_.cursorBlink) {
+    clearTimeout(this.timeouts_.cursorBlink);
+    delete this.timeouts_.cursorBlink;
+  }
+
+  if (this.options_.cursorVisible)
+    this.setCursorVisible(true);
+};
+
+/**
+ * Set the cursor-visible mode bit.
+ *
+ * If cursor-visible is on, the cursor will be visible.  Otherwise it will not.
+ *
+ * Defaults to on.
+ *
+ * @param {boolean} state True to set cursor-visible mode, false to unset.
+ */
+hterm.Terminal.prototype.setCursorVisible = function(state) {
+  this.options_.cursorVisible = state;
+
+  if (!state) {
+    if (this.timeouts_.cursorBlink) {
+      clearTimeout(this.timeouts_.cursorBlink);
+      delete this.timeouts_.cursorBlink;
+    }
+    this.cursorNode_.style.opacity = '0';
+    return;
+  }
+
+  this.syncCursorPosition_();
+
+  this.cursorNode_.style.opacity = '1';
+
+  if (this.options_.cursorBlink) {
+    if (this.timeouts_.cursorBlink)
+      return;
+
+    this.onCursorBlink_();
+  } else {
+    if (this.timeouts_.cursorBlink) {
+      clearTimeout(this.timeouts_.cursorBlink);
+      delete this.timeouts_.cursorBlink;
+    }
+  }
+};
+
+/**
+ * Synchronizes the visible cursor and document selection with the current
+ * cursor coordinates.
+ *
+ * @return {boolean} True if the cursor is onscreen and synced.
+ */
+hterm.Terminal.prototype.syncCursorPosition_ = function() {
+  var topRowIndex = this.scrollPort_.getTopRowIndex();
+  var bottomRowIndex = this.scrollPort_.getBottomRowIndex(topRowIndex);
+  var cursorRowIndex = this.scrollbackRows_.length +
+      this.screen_.cursorPosition.row;
+
+  let forceSyncSelection = false;
+  if (this.accessibilityReader_.accessibilityEnabled) {
+    // Report the new position of the cursor for accessibility purposes.
+    const cursorColumnIndex = this.screen_.cursorPosition.column;
+    const cursorLineText =
+        this.screen_.rowsArray[this.screen_.cursorPosition.row].innerText;
+    // This will force the selection to be sync'd to the cursor position if the
+    // user has pressed a key. Generally we would only sync the cursor position
+    // when selection is collapsed so that if the user has selected something
+    // we don't clear the selection by moving the selection. However when a
+    // screen reader is used, it's intuitive for entering a key to move the
+    // selection to the cursor.
+    forceSyncSelection = this.accessibilityReader_.hasUserGesture;
+    this.accessibilityReader_.afterCursorChange(
+        cursorLineText, cursorRowIndex, cursorColumnIndex);
+  }
+
+  if (cursorRowIndex > bottomRowIndex) {
+    // Cursor is scrolled off screen, move it outside of the visible area.
+    this.setCssVar('cursor-offset-row', '-1');
+    return false;
+  }
+
+  if (this.options_.cursorVisible &&
+      this.cursorNode_.style.display == 'none') {
+    // Re-display the terminal cursor if it was hidden by the mouse cursor.
+    this.cursorNode_.style.display = '';
+  }
+
+  // Position the cursor using CSS variable math.  If we do the math in JS,
+  // the float math will end up being more precise than the CSS which will
+  // cause the cursor tracking to be off.
+  this.setCssVar(
+      'cursor-offset-row',
+      `${cursorRowIndex - topRowIndex} + ` +
+      `${this.scrollPort_.visibleRowTopMargin}px`);
+  this.setCssVar('cursor-offset-col', this.screen_.cursorPosition.column);
+
+  this.cursorNode_.setAttribute('title',
+                                '(' + this.screen_.cursorPosition.column +
+                                ', ' + this.screen_.cursorPosition.row +
+                                ')');
+
+  // Update the caret for a11y purposes.
+  var selection = this.document_.getSelection();
+  if (selection && (selection.isCollapsed || forceSyncSelection)) {
+    this.screen_.syncSelectionCaret(selection);
+  }
+  return true;
+};
+
+/**
+ * Adjusts the style of this.cursorNode_ according to the current cursor shape
+ * and character cell dimensions.
+ */
+hterm.Terminal.prototype.restyleCursor_ = function() {
+  var shape = this.cursorShape_;
+
+  if (this.cursorNode_.getAttribute('focus') == 'false') {
+    // Always show a block cursor when unfocused.
+    shape = hterm.Terminal.cursorShape.BLOCK;
+  }
+
+  var style = this.cursorNode_.style;
+
+  switch (shape) {
+    case hterm.Terminal.cursorShape.BEAM:
+      style.backgroundColor = 'transparent';
+      style.borderBottomStyle = null;
+      style.borderLeftStyle = 'solid';
+      break;
+
+    case hterm.Terminal.cursorShape.UNDERLINE:
+      style.backgroundColor = 'transparent';
+      style.borderBottomStyle = 'solid';
+      style.borderLeftStyle = null;
+      break;
+
+    default:
+      style.backgroundColor = 'var(--hterm-cursor-color)';
+      style.borderBottomStyle = null;
+      style.borderLeftStyle = null;
+      break;
+  }
+};
+
+/**
+ * Synchronizes the visible cursor with the current cursor coordinates.
+ *
+ * The sync will happen asynchronously, soon after the call stack winds down.
+ * Multiple calls will be coalesced into a single sync. This should be called
+ * prior to the cursor actually changing position.
+ */
+hterm.Terminal.prototype.scheduleSyncCursorPosition_ = function() {
+  if (this.timeouts_.syncCursor)
+    return;
+
+  if (this.accessibilityReader_.accessibilityEnabled) {
+    // Report the previous position of the cursor for accessibility purposes.
+    const cursorRowIndex = this.scrollbackRows_.length +
+        this.screen_.cursorPosition.row;
+    const cursorColumnIndex = this.screen_.cursorPosition.column;
+    const cursorLineText =
+        this.screen_.rowsArray[this.screen_.cursorPosition.row].innerText;
+    this.accessibilityReader_.beforeCursorChange(
+        cursorLineText, cursorRowIndex, cursorColumnIndex);
+  }
+
+  var self = this;
+  this.timeouts_.syncCursor = setTimeout(function() {
+      self.syncCursorPosition_();
+      delete self.timeouts_.syncCursor;
+    }, 0);
+};
+
+/**
+ * Show or hide the zoom warning.
+ *
+ * The zoom warning is a message warning the user that their browser zoom must
+ * be set to 100% in order for hterm to function properly.
+ *
+ * @param {boolean} state True to show the message, false to hide it.
+ */
+hterm.Terminal.prototype.showZoomWarning_ = function(state) {
+  if (!this.zoomWarningNode_) {
+    if (!state)
+      return;
+
+    this.zoomWarningNode_ = this.document_.createElement('div');
+    this.zoomWarningNode_.id = 'hterm:zoom-warning';
+    this.zoomWarningNode_.style.cssText = (
+        'color: black;' +
+        'background-color: #ff2222;' +
+        'font-size: large;' +
+        'border-radius: 8px;' +
+        'opacity: 0.75;' +
+        'padding: 0.2em 0.5em 0.2em 0.5em;' +
+        'top: 0.5em;' +
+        'right: 1.2em;' +
+        'position: absolute;' +
+        '-webkit-text-size-adjust: none;' +
+        '-webkit-user-select: none;' +
+        '-moz-text-size-adjust: none;' +
+        '-moz-user-select: none;');
+
+    this.zoomWarningNode_.addEventListener('click', function(e) {
+      this.parentNode.removeChild(this);
+    });
+  }
+
+  this.zoomWarningNode_.textContent = lib.i18n.replaceReferences(
+      hterm.zoomWarningMessage,
+      [parseInt(this.scrollPort_.characterSize.zoomFactor * 100)]);
+
+  this.zoomWarningNode_.style.fontFamily = this.prefs_.get('font-family');
+
+  if (state) {
+    if (!this.zoomWarningNode_.parentNode)
+      this.div_.parentNode.appendChild(this.zoomWarningNode_);
+  } else if (this.zoomWarningNode_.parentNode) {
+    this.zoomWarningNode_.parentNode.removeChild(this.zoomWarningNode_);
+  }
+};
+
+/**
+ * Show the terminal overlay for a given amount of time.
+ *
+ * The terminal overlay appears in inverse video in a large font, centered
+ * over the terminal.  You should probably keep the overlay message brief,
+ * since it's in a large font and you probably aren't going to check the size
+ * of the terminal first.
+ *
+ * @param {string} msg The text (not HTML) message to display in the overlay.
+ * @param {number} opt_timeout The amount of time to wait before fading out
+ *     the overlay.  Defaults to 1.5 seconds.  Pass null to have the overlay
+ *     stay up forever (or until the next overlay).
+ */
+hterm.Terminal.prototype.showOverlay = function(msg, opt_timeout) {
+  if (!this.overlayNode_) {
+    if (!this.div_)
+      return;
+
+    this.overlayNode_ = this.document_.createElement('div');
+    this.overlayNode_.style.cssText = (
+        'border-radius: 15px;' +
+        'font-size: xx-large;' +
+        'opacity: 0.75;' +
+        'padding: 0.2em 0.5em 0.2em 0.5em;' +
+        'position: absolute;' +
+        '-webkit-user-select: none;' +
+        '-webkit-transition: opacity 180ms ease-in;' +
+        '-moz-user-select: none;' +
+        '-moz-transition: opacity 180ms ease-in;');
+
+    this.overlayNode_.addEventListener('mousedown', function(e) {
+      e.preventDefault();
+      e.stopPropagation();
+    }, true);
+  }
+
+  this.overlayNode_.style.color = this.prefs_.get('background-color');
+  this.overlayNode_.style.backgroundColor = this.prefs_.get('foreground-color');
+  this.overlayNode_.style.fontFamily = this.prefs_.get('font-family');
+
+  this.overlayNode_.textContent = msg;
+  this.overlayNode_.style.opacity = '0.75';
+
+  if (!this.overlayNode_.parentNode)
+    this.div_.appendChild(this.overlayNode_);
+
+  var divSize = hterm.getClientSize(this.div_);
+  var overlaySize = hterm.getClientSize(this.overlayNode_);
+
+  this.overlayNode_.style.top =
+      (divSize.height - overlaySize.height) / 2 + 'px';
+  this.overlayNode_.style.left = (divSize.width - overlaySize.width -
+      this.scrollPort_.currentScrollbarWidthPx) / 2 + 'px';
+
+  if (this.overlayTimeout_)
+    clearTimeout(this.overlayTimeout_);
+
+  this.accessibilityReader_.assertiveAnnounce(msg);
+
+  if (opt_timeout === null)
+    return;
+
+  this.overlayTimeout_ = setTimeout(() => {
+    this.overlayNode_.style.opacity = '0';
+    this.overlayTimeout_ = setTimeout(() => this.hideOverlay(), 200);
+  }, opt_timeout || 1500);
+};
+
+/**
+ * Hide the terminal overlay immediately.
+ *
+ * Useful when we show an overlay for an event with an unknown end time.
+ */
+hterm.Terminal.prototype.hideOverlay = function() {
+  if (this.overlayTimeout_)
+    clearTimeout(this.overlayTimeout_);
+  this.overlayTimeout_ = null;
+
+  if (this.overlayNode_.parentNode)
+    this.overlayNode_.parentNode.removeChild(this.overlayNode_);
+  this.overlayNode_.style.opacity = '0.75';
+};
+
+/**
+ * Paste from the system clipboard to the terminal.
+ */
+hterm.Terminal.prototype.paste = function() {
+  return hterm.pasteFromClipboard(this.document_);
+};
+
+/**
+ * Copy a string to the system clipboard.
+ *
+ * Note: If there is a selected range in the terminal, it'll be cleared.
+ *
+ * @param {string} str The string to copy.
+ */
+hterm.Terminal.prototype.copyStringToClipboard = function(str) {
+  if (this.prefs_.get('enable-clipboard-notice'))
+    setTimeout(this.showOverlay.bind(this, hterm.notifyCopyMessage, 500), 200);
+
+  hterm.copySelectionToClipboard(this.document_, str);
+};
+
+/**
+ * Display an image.
+ *
+ * Either URI or buffer or blob fields must be specified.
+ *
+ * @param {Object} options The image to display.
+ * @param {string=} options.name A human readable string for the image.
+ * @param {string|number=} options.size The size (in bytes).
+ * @param {boolean=} options.preserveAspectRatio Whether to preserve aspect.
+ * @param {boolean=} options.inline Whether to display the image inline.
+ * @param {string|number=} options.width The width of the image.
+ * @param {string|number=} options.height The height of the image.
+ * @param {string=} options.align Direction to align the image.
+ * @param {string=} options.uri The source URI for the image.
+ * @param {ArrayBuffer=} options.buffer The ArrayBuffer image data.
+ * @param {Blob=} options.blob The Blob image data.
+ * @param {string=} options.type The MIME type of the image data.
+ * @param {function=} onLoad Callback when loading finishes.
+ * @param {function(Event)=} onError Callback when loading fails.
+ */
+hterm.Terminal.prototype.displayImage = function(options, onLoad, onError) {
+  // Make sure we're actually given a resource to display.
+  if (options.uri === undefined && options.buffer === undefined &&
+      options.blob === undefined)
+    return;
+
+  // Set up the defaults to simplify code below.
+  if (!options.name)
+    options.name = '';
+
+  // See if the mime type is available.  If not, guess from the filename.
+  // We don't list all possible mime types because the browser can usually
+  // guess it correctly.  So list the ones that need a bit more help.
+  if (!options.type) {
+    const ary = options.name.split('.');
+    const ext = ary[ary.length - 1].trim();
+    switch (ext) {
+      case 'svg':
+      case 'svgz':
+        options.type = 'image/svg+xml';
+        break;
+    }
+  }
+
+  // Has the user approved image display yet?
+  if (this.allowImagesInline !== true) {
+    this.newLine();
+    const row = this.getRowNode(this.scrollbackRows_.length +
+                                this.getCursorRow() - 1);
+
+    if (this.allowImagesInline === false) {
+      row.textContent = hterm.msg('POPUP_INLINE_IMAGE_DISABLED', [],
+                                  'Inline Images Disabled');
+      return;
+    }
+
+    // Show a prompt.
+    let button;
+    const span = this.document_.createElement('span');
+    span.innerText = hterm.msg('POPUP_INLINE_IMAGE', [], 'Inline Images');
+    span.style.fontWeight = 'bold';
+    span.style.borderWidth = '1px';
+    span.style.borderStyle = 'dashed';
+    button = this.document_.createElement('span');
+    button.innerText = hterm.msg('BUTTON_BLOCK', [], 'block');
+    button.style.marginLeft = '1em';
+    button.style.borderWidth = '1px';
+    button.style.borderStyle = 'solid';
+    button.addEventListener('click', () => {
+      this.prefs_.set('allow-images-inline', false);
+    });
+    span.appendChild(button);
+    button = this.document_.createElement('span');
+    button.innerText = hterm.msg('BUTTON_ALLOW_SESSION', [],
+                                 'allow this session');
+    button.style.marginLeft = '1em';
+    button.style.borderWidth = '1px';
+    button.style.borderStyle = 'solid';
+    button.addEventListener('click', () => {
+      this.allowImagesInline = true;
+    });
+    span.appendChild(button);
+    button = this.document_.createElement('span');
+    button.innerText = hterm.msg('BUTTON_ALLOW_ALWAYS', [], 'always allow');
+    button.style.marginLeft = '1em';
+    button.style.borderWidth = '1px';
+    button.style.borderStyle = 'solid';
+    button.addEventListener('click', () => {
+      this.prefs_.set('allow-images-inline', true);
+    });
+    span.appendChild(button);
+
+    row.appendChild(span);
+    return;
+  }
+
+  // See if we should show this object directly, or download it.
+  if (options.inline) {
+    const io = this.io.push();
+    io.showOverlay(hterm.msg('LOADING_RESOURCE_START', [options.name],
+                             'Loading $1 ...'), null);
+
+    // While we're loading the image, eat all the user's input.
+    io.onVTKeystroke = io.sendString = () => {};
+
+    // Initialize this new image.
+    const img =
+        /** @type {!HTMLImageElement} */ (this.document_.createElement('img'));
+    if (options.uri !== undefined) {
+      img.src = options.uri;
+    } else if (options.buffer !== undefined) {
+      const blob = new Blob([options.buffer], {type: options.type});
+      img.src = URL.createObjectURL(blob);
+    } else {
+      const blob = new Blob([options.blob], {type: options.type});
+      img.src = URL.createObjectURL(options.blob);
+    }
+    img.title = img.alt = options.name;
+
+    // Attach the image to the page to let it load/render.  It won't stay here.
+    // This is needed so it's visible and the DOM can calculate the height.  If
+    // the image is hidden or not in the DOM, the height is always 0.
+    this.document_.body.appendChild(img);
+
+    // Wait for the image to finish loading before we try moving it to the
+    // right place in the terminal.
+    img.onload = () => {
+      // Now that we have the image dimensions, figure out how to show it.
+      img.style.objectFit = options.preserveAspectRatio ? 'scale-down' : 'fill';
+      img.style.maxWidth = `${this.document_.body.clientWidth}px`;
+      img.style.maxHeight = `${this.document_.body.clientHeight}px`;
+
+      // Parse a width/height specification.
+      const parseDim = (dim, maxDim, cssVar) => {
+        if (!dim || dim == 'auto')
+          return '';
+
+        const ary = dim.match(/^([0-9]+)(px|%)?$/);
+        if (ary) {
+          if (ary[2] == '%')
+            return maxDim * parseInt(ary[1]) / 100 + 'px';
+          else if (ary[2] == 'px')
+            return dim;
+          else
+            return `calc(${dim} * var(${cssVar}))`;
+        }
+
+        return '';
+      };
+      img.style.width =
+          parseDim(options.width, this.document_.body.clientWidth,
+                   '--hterm-charsize-width');
+      img.style.height =
+          parseDim(options.height,  this.document_.body.clientHeight,
+                   '--hterm-charsize-height');
+
+      // Figure out how many rows the image occupies, then add that many.
+      // XXX: This count will be inaccurate if the font size changes on us.
+      const padRows = Math.ceil(img.clientHeight /
+                                this.scrollPort_.characterSize.height);
+      for (let i = 0; i < padRows; ++i)
+        this.newLine();
+
+      // Update the max height in case the user shrinks the character size.
+      img.style.maxHeight = `calc(${padRows} * var(--hterm-charsize-height))`;
+
+      // Move the image to the last row.  This way when we scroll up, it doesn't
+      // disappear when the first row gets clipped.  It will disappear when we
+      // scroll down and the last row is clipped ...
+      this.document_.body.removeChild(img);
+      // Create a wrapper node so we can do an absolute in a relative position.
+      // This helps with rounding errors between JS & CSS counts.
+      const div = this.document_.createElement('div');
+      div.style.position = 'relative';
+      div.style.textAlign = options.align;
+      img.style.position = 'absolute';
+      img.style.bottom = 'calc(0px - var(--hterm-charsize-height))';
+      div.appendChild(img);
+      const row = this.getRowNode(this.scrollbackRows_.length +
+                                  this.getCursorRow() - 1);
+      row.appendChild(div);
+
+      // Now that the image has been read, we can revoke the source.
+      if (options.uri === undefined) {
+        URL.revokeObjectURL(img.src);
+      }
+
+      io.hideOverlay();
+      io.pop();
+
+      if (onLoad)
+        onLoad();
+    };
+
+    // If we got a malformed image, give up.
+    img.onerror = (e) => {
+      this.document_.body.removeChild(img);
+      io.showOverlay(hterm.msg('LOADING_RESOURCE_FAILED', [options.name],
+                               'Loading $1 failed'));
+      io.pop();
+
+      if (onError)
+        onError(e);
+    };
+  } else {
+    // We can't use chrome.downloads.download as that requires "downloads"
+    // permissions, and that works only in extensions, not apps.
+    const a = this.document_.createElement('a');
+    if (options.uri !== undefined) {
+      a.href = options.uri;
+    } else if (options.buffer !== undefined) {
+      const blob = new Blob([options.buffer]);
+      a.href = URL.createObjectURL(blob);
+    } else {
+      a.href = URL.createObjectURL(options.blob);
+    }
+    a.download = options.name;
+    this.document_.body.appendChild(a);
+    a.click();
+    a.remove();
+    if (options.uri === undefined) {
+      URL.revokeObjectURL(a.href);
+    }
+  }
+};
+
+/**
+ * Returns the selected text, or null if no text is selected.
+ *
+ * @return {string|null}
+ */
+hterm.Terminal.prototype.getSelectionText = function() {
+  var selection = this.scrollPort_.selection;
+  selection.sync();
+
+  if (selection.isCollapsed)
+    return null;
+
+  // Start offset measures from the beginning of the line.
+  var startOffset = selection.startOffset;
+  var node = selection.startNode;
+
+  // If an x-row isn't selected, |node| will be null.
+  if (!node)
+    return null;
+
+  if (node.nodeName != 'X-ROW') {
+    // If the selection doesn't start on an x-row node, then it must be
+    // somewhere inside the x-row.  Add any characters from previous siblings
+    // into the start offset.
+
+    if (node.nodeName == '#text' && node.parentNode.nodeName == 'SPAN') {
+      // If node is the text node in a styled span, move up to the span node.
+      node = node.parentNode;
+    }
+
+    while (node.previousSibling) {
+      node = node.previousSibling;
+      startOffset += hterm.TextAttributes.nodeWidth(node);
+    }
+  }
+
+  // End offset measures from the end of the line.
+  var endOffset = (hterm.TextAttributes.nodeWidth(selection.endNode) -
+                   selection.endOffset);
+  node = selection.endNode;
+
+  if (node.nodeName != 'X-ROW') {
+    // If the selection doesn't end on an x-row node, then it must be
+    // somewhere inside the x-row.  Add any characters from following siblings
+    // into the end offset.
+
+    if (node.nodeName == '#text' && node.parentNode.nodeName == 'SPAN') {
+      // If node is the text node in a styled span, move up to the span node.
+      node = node.parentNode;
+    }
+
+    while (node.nextSibling) {
+      node = node.nextSibling;
+      endOffset += hterm.TextAttributes.nodeWidth(node);
+    }
+  }
+
+  var rv = this.getRowsText(selection.startRow.rowIndex,
+                            selection.endRow.rowIndex + 1);
+  return lib.wc.substring(rv, startOffset, lib.wc.strWidth(rv) - endOffset);
+};
+
+/**
+ * Copy the current selection to the system clipboard, then clear it after a
+ * short delay.
+ */
+hterm.Terminal.prototype.copySelectionToClipboard = function() {
+  var text = this.getSelectionText();
+  if (text != null)
+    this.copyStringToClipboard(text);
+};
+
+hterm.Terminal.prototype.overlaySize = function() {
+  this.showOverlay(this.screenSize.width + 'x' + this.screenSize.height);
+};
+
+/**
+ * Invoked by hterm.Terminal.Keyboard when a VT keystroke is detected.
+ *
+ * @param {string} string The VT string representing the keystroke, in UTF-16.
+ */
+hterm.Terminal.prototype.onVTKeystroke = function(string) {
+  if (this.scrollOnKeystroke_)
+    this.scrollPort_.scrollRowToBottom(this.getRowCount());
+
+  this.io.onVTKeystroke(string);
+};
+
+/**
+ * Open the selected url.
+ */
+hterm.Terminal.prototype.openSelectedUrl_ = function() {
+  var str = this.getSelectionText();
+
+  // If there is no selection, try and expand wherever they clicked.
+  if (str == null) {
+    this.screen_.expandSelectionForUrl(this.document_.getSelection());
+    str = this.getSelectionText();
+
+    // If clicking in empty space, return.
+    if (str == null)
+      return;
+  }
+
+  // Make sure URL is valid before opening.
+  if (str.length > 2048 || str.search(/[\s\[\](){}<>"'\\^`]/) >= 0)
+    return;
+
+  // If the URI isn't anchored, it'll open relative to the extension.
+  // We have no way of knowing the correct schema, so assume http.
+  if (str.search('^[a-zA-Z][a-zA-Z0-9+.-]*://') < 0) {
+    // We have to whitelist a few protocols that lack authorities and thus
+    // never use the //.  Like mailto.
+    switch (str.split(':', 1)[0]) {
+      case 'mailto':
+        break;
+      default:
+        str = 'http://' + str;
+        break;
+    }
+  }
+
+  hterm.openUrl(str);
+};
+
+/**
+ * Manage the automatic mouse hiding behavior while typing.
+ *
+ * @param {boolean=} v Whether to enable automatic hiding.
+ */
+hterm.Terminal.prototype.setAutomaticMouseHiding = function(v=null) {
+  // Since Chrome OS & macOS do this by default everywhere, we don't need to.
+  // Linux & Windows seem to leave this to specific applications to manage.
+  if (v === null)
+    v = (hterm.os != 'cros' && hterm.os != 'mac');
+
+  this.mouseHideWhileTyping_ = !!v;
+};
+
+/**
+ * Handler for monitoring user keyboard activity.
+ *
+ * This isn't for processing the keystrokes directly, but for updating any
+ * state that might toggle based on the user using the keyboard at all.
+ *
+ * @param {KeyboardEvent} e The keyboard event that triggered us.
+ */
+hterm.Terminal.prototype.onKeyboardActivity_ = function(e) {
+  // When the user starts typing, hide the mouse cursor.
+  if (this.mouseHideWhileTyping_ && !this.mouseHideDelay_)
+    this.setCssVar('mouse-cursor-style', 'none');
+};
+
+/**
+ * Add the terminalRow and terminalColumn properties to mouse events and
+ * then forward on to onMouse().
+ *
+ * The terminalRow and terminalColumn properties contain the (row, column)
+ * coordinates for the mouse event.
+ *
+ * @param {Event} e The mouse event to handle.
+ */
+hterm.Terminal.prototype.onMouse_ = function(e) {
+  if (e.processedByTerminalHandler_) {
+    // We register our event handlers on the document, as well as the cursor
+    // and the scroll blocker.  Mouse events that occur on the cursor or
+    // scroll blocker will also appear on the document, but we don't want to
+    // process them twice.
+    //
+    // We can't just prevent bubbling because that has other side effects, so
+    // we decorate the event object with this property instead.
+    return;
+  }
+
+  // Consume navigation events.  Button 3 is usually "browser back" and
+  // button 4 is "browser forward" which we don't want to happen.
+  if (e.button > 2) {
+    e.preventDefault();
+    // We don't return so click events can be passed to the remote below.
+  }
+
+  var reportMouseEvents = (!this.defeatMouseReports_ &&
+      this.vt.mouseReport != this.vt.MOUSE_REPORT_DISABLED);
+
+  e.processedByTerminalHandler_ = true;
+
+  // Handle auto hiding of mouse cursor while typing.
+  if (this.mouseHideWhileTyping_ && !this.mouseHideDelay_) {
+    // Make sure the mouse cursor is visible.
+    this.syncMouseStyle();
+    // This debounce isn't perfect, but should work well enough for such a
+    // simple implementation.  If the user moved the mouse, we enabled this
+    // debounce, and then moved the mouse just before the timeout, we wouldn't
+    // debounce that later movement.
+    this.mouseHideDelay_ = setTimeout(() => this.mouseHideDelay_ = null, 1000);
+  }
+
+  // One based row/column stored on the mouse event.
+  e.terminalRow = parseInt((e.clientY - this.scrollPort_.visibleRowTopMargin) /
+                           this.scrollPort_.characterSize.height) + 1;
+  e.terminalColumn = parseInt(e.clientX /
+                              this.scrollPort_.characterSize.width) + 1;
+
+  if (e.type == 'mousedown' && e.terminalColumn > this.screenSize.width) {
+    // Mousedown in the scrollbar area.
+    return;
+  }
+
+  if (this.options_.cursorVisible && !reportMouseEvents) {
+    // If the cursor is visible and we're not sending mouse events to the
+    // host app, then we want to hide the terminal cursor when the mouse
+    // cursor is over top.  This keeps the terminal cursor from interfering
+    // with local text selection.
+    if (e.terminalRow - 1 == this.screen_.cursorPosition.row &&
+        e.terminalColumn - 1 == this.screen_.cursorPosition.column) {
+      this.cursorNode_.style.display = 'none';
+    } else if (this.cursorNode_.style.display == 'none') {
+      this.cursorNode_.style.display = '';
+    }
+  }
+
+  if (e.type == 'mousedown') {
+    this.contextMenu.hide(e);
+
+    if (e.altKey || !reportMouseEvents) {
+      // If VT mouse reporting is disabled, or has been defeated with
+      // alt-mousedown, then the mouse will act on the local selection.
+      this.defeatMouseReports_ = true;
+      this.setSelectionEnabled(true);
+    } else {
+      // Otherwise we defer ownership of the mouse to the VT.
+      this.defeatMouseReports_ = false;
+      this.document_.getSelection().collapseToEnd();
+      this.setSelectionEnabled(false);
+      e.preventDefault();
+    }
+  }
+
+  if (!reportMouseEvents) {
+    if (e.type == 'dblclick') {
+      this.screen_.expandSelection(this.document_.getSelection());
+      if (this.copyOnSelect)
+        this.copySelectionToClipboard();
+    }
+
+    if (e.type == 'click' && !e.shiftKey && (e.ctrlKey || e.metaKey)) {
+      // Debounce this event with the dblclick event.  If you try to doubleclick
+      // a URL to open it, Chrome will fire click then dblclick, but we won't
+      // have expanded the selection text at the first click event.
+      clearTimeout(this.timeouts_.openUrl);
+      this.timeouts_.openUrl = setTimeout(this.openSelectedUrl_.bind(this),
+                                          500);
+      return;
+    }
+
+    if (e.type == 'mousedown') {
+      if (e.ctrlKey && e.button == 2 /* right button */) {
+        e.preventDefault();
+        this.contextMenu.show(e, this);
+      } else if (e.button == this.mousePasteButton ||
+          (this.mouseRightClickPaste && e.button == 2 /* right button */)) {
+        if (!this.paste())
+          console.warn('Could not paste manually due to web restrictions');
+      }
+    }
+
+    if (e.type == 'mouseup' && e.button == 0 && this.copyOnSelect &&
+        !this.document_.getSelection().isCollapsed) {
+      this.copySelectionToClipboard();
+    }
+
+    if ((e.type == 'mousemove' || e.type == 'mouseup') &&
+        this.scrollBlockerNode_.engaged) {
+      // Disengage the scroll-blocker after one of these events.
+      this.scrollBlockerNode_.engaged = false;
+      this.scrollBlockerNode_.style.top = '-99px';
+    }
+
+    // Emulate arrow key presses via scroll wheel events.
+    if (this.scrollWheelArrowKeys_ && !e.shiftKey &&
+        this.keyboard.applicationCursor && !this.isPrimaryScreen()) {
+      if (e.type == 'wheel') {
+        const delta = this.scrollPort_.scrollWheelDelta(e);
+
+        // Helper to turn a wheel event delta into a series of key presses.
+        const deltaToArrows = (distance, charSize, arrowPos, arrowNeg) => {
+          if (distance == 0) {
+            return '';
+          }
+
+          // Convert the scroll distance into a number of rows/cols.
+          const cells = lib.f.smartFloorDivide(Math.abs(distance), charSize);
+          const data = '\x1bO' + (distance < 0 ? arrowNeg : arrowPos);
+          return data.repeat(cells);
+        };
+
+        // The order between up/down and left/right doesn't really matter.
+        this.io.sendString(
+            // Up/down arrow keys.
+            deltaToArrows(delta.y, this.scrollPort_.characterSize.height,
+                          'A', 'B') +
+            // Left/right arrow keys.
+            deltaToArrows(delta.x, this.scrollPort_.characterSize.width,
+                          'C', 'D')
+        );
+
+        e.preventDefault();
+      }
+    }
+  } else /* if (this.reportMouseEvents) */ {
+    if (!this.scrollBlockerNode_.engaged) {
+      if (e.type == 'mousedown') {
+        // Move the scroll-blocker into place if we want to keep the scrollport
+        // from scrolling.
+        this.scrollBlockerNode_.engaged = true;
+        this.scrollBlockerNode_.style.top = (e.clientY - 5) + 'px';
+        this.scrollBlockerNode_.style.left = (e.clientX - 5) + 'px';
+      } else if (e.type == 'mousemove') {
+        // Oh.  This means that drag-scroll was disabled AFTER the mouse down,
+        // in which case it's too late to engage the scroll-blocker.
+        this.document_.getSelection().collapseToEnd();
+        e.preventDefault();
+      }
+    }
+
+    this.onMouse(e);
+  }
+
+  if (e.type == 'mouseup' && this.document_.getSelection().isCollapsed) {
+    // Restore this on mouseup in case it was temporarily defeated with a
+    // alt-mousedown.  Only do this when the selection is empty so that
+    // we don't immediately kill the users selection.
+    this.defeatMouseReports_ = false;
+  }
+};
+
+/**
+ * Clients should override this if they care to know about mouse events.
+ *
+ * The event parameter will be a normal DOM mouse click event with additional
+ * 'terminalRow' and 'terminalColumn' properties.
+ *
+ * @param {Event} e The mouse event to handle.
+ */
+hterm.Terminal.prototype.onMouse = function(e) { };
+
+/**
+ * React when focus changes.
+ *
+ * @param {boolean} focused True if focused, false otherwise.
+ */
+hterm.Terminal.prototype.onFocusChange_ = function(focused) {
+  this.cursorNode_.setAttribute('focus', focused);
+  this.restyleCursor_();
+
+  if (this.reportFocus)
+    this.io.sendString(focused === true ? '\x1b[I' : '\x1b[O');
+
+  if (focused === true)
+    this.closeBellNotifications_();
+};
+
+/**
+ * React when the ScrollPort is scrolled.
+ */
+hterm.Terminal.prototype.onScroll_ = function() {
+  this.scheduleSyncCursorPosition_();
+};
+
+/**
+ * React when text is pasted into the scrollPort.
+ *
+ * @param {Event} e The DOM paste event to handle.
+ */
+hterm.Terminal.prototype.onPaste_ = function(e) {
+  var data = e.text.replace(/\n/mg, '\r');
+  if (this.options_.bracketedPaste) {
+    // We strip out most escape sequences as they can cause issues (like
+    // inserting an \x1b[201~ midstream).  We pass through whitespace
+    // though: 0x08:\b 0x09:\t 0x0a:\n 0x0d:\r.
+    // This matches xterm behavior.
+    const filter = (data) => data.replace(/[\x00-\x07\x0b-\x0c\x0e-\x1f]/g, '');
+    data = '\x1b[200~' + filter(data) + '\x1b[201~';
+  }
+
+  this.io.sendString(data);
+};
+
+/**
+ * React when the user tries to copy from the scrollPort.
+ *
+ * @param {Event} e The DOM copy event.
+ */
+hterm.Terminal.prototype.onCopy_ = function(e) {
+  if (!this.useDefaultWindowCopy) {
+    e.preventDefault();
+    setTimeout(this.copySelectionToClipboard.bind(this), 0);
+  }
+};
+
+/**
+ * React when the ScrollPort is resized.
+ *
+ * Note: This function should not directly contain code that alters the internal
+ * state of the terminal.  That kind of code belongs in realizeWidth or
+ * realizeHeight, so that it can be executed synchronously in the case of a
+ * programmatic width change.
+ */
+hterm.Terminal.prototype.onResize_ = function() {
+  var columnCount = Math.floor(this.scrollPort_.getScreenWidth() /
+                               this.scrollPort_.characterSize.width) || 0;
+  var rowCount = lib.f.smartFloorDivide(this.scrollPort_.getScreenHeight(),
+                            this.scrollPort_.characterSize.height) || 0;
+
+  if (columnCount <= 0 || rowCount <= 0) {
+    // We avoid these situations since they happen sometimes when the terminal
+    // gets removed from the document or during the initial load, and we can't
+    // deal with that.
+    // This can also happen if called before the scrollPort calculates the
+    // character size, meaning we dived by 0 above and default to 0 values.
+    return;
+  }
+
+  var isNewSize = (columnCount != this.screenSize.width ||
+                   rowCount != this.screenSize.height);
+
+  // We do this even if the size didn't change, just to be sure everything is
+  // in sync.
+  this.realizeSize_(columnCount, rowCount);
+  this.showZoomWarning_(this.scrollPort_.characterSize.zoomFactor != 1);
+
+  if (isNewSize)
+    this.overlaySize();
+
+  this.restyleCursor_();
+  this.scheduleSyncCursorPosition_();
+};
+
+/**
+ * Service the cursor blink timeout.
+ */
+hterm.Terminal.prototype.onCursorBlink_ = function() {
+  if (!this.options_.cursorBlink) {
+    delete this.timeouts_.cursorBlink;
+    return;
+  }
+
+  if (this.cursorNode_.getAttribute('focus') == 'false' ||
+      this.cursorNode_.style.opacity == '0') {
+    this.cursorNode_.style.opacity = '1';
+    this.timeouts_.cursorBlink = setTimeout(this.myOnCursorBlink_,
+                                            this.cursorBlinkCycle_[0]);
+  } else {
+    this.cursorNode_.style.opacity = '0';
+    this.timeouts_.cursorBlink = setTimeout(this.myOnCursorBlink_,
+                                            this.cursorBlinkCycle_[1]);
+  }
+};
+
+/**
+ * Set the scrollbar-visible mode bit.
+ *
+ * If scrollbar-visible is on, the vertical scrollbar will be visible.
+ * Otherwise it will not.
+ *
+ * Defaults to on.
+ *
+ * @param {boolean} state True to set scrollbar-visible mode, false to unset.
+ */
+hterm.Terminal.prototype.setScrollbarVisible = function(state) {
+  this.scrollPort_.setScrollbarVisible(state);
+};
+
+/**
+ * Set the scroll wheel move multiplier.  This will affect how fast the page
+ * scrolls on wheel events.
+ *
+ * Defaults to 1.
+ *
+ * @param {number} multiplier The multiplier to set.
+ */
+hterm.Terminal.prototype.setScrollWheelMoveMultipler = function(multiplier) {
+  this.scrollPort_.setScrollWheelMoveMultipler(multiplier);
+};
+
+/**
+ * Close all web notifications created by terminal bells.
+ */
+hterm.Terminal.prototype.closeBellNotifications_ = function() {
+  this.bellNotificationList_.forEach(function(n) {
+      n.close();
+    });
+  this.bellNotificationList_.length = 0;
+};
+
+/**
+ * Syncs the cursor position when the scrollport gains focus.
+ */
+hterm.Terminal.prototype.onScrollportFocus_ = function() {
+  // If the cursor is offscreen we set selection to the last row on the screen.
+  const topRowIndex = this.scrollPort_.getTopRowIndex();
+  const bottomRowIndex = this.scrollPort_.getBottomRowIndex(topRowIndex);
+  const selection = this.document_.getSelection();
+  if (!this.syncCursorPosition_() && selection) {
+    selection.collapse(this.getRowNode(bottomRowIndex));
+  }
+};
+// SOURCE FILE: hterm/js/hterm_terminal_io.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Input/Output interface used by commands to communicate with the terminal.
+ *
+ * Commands like `nassh` and `crosh` receive an instance of this class as
+ * part of their argv object.  This allows them to write to and read from the
+ * terminal without exposing them to an entire hterm.Terminal instance.
+ *
+ * The active command must override the onVTKeystroke() and sendString() methods
+ * of this class in order to receive keystrokes and send output to the correct
+ * destination.
+ *
+ * Isolating commands from the terminal provides the following benefits:
+ * - Provides a mechanism to save and restore onVTKeystroke and sendString
+ *   handlers when invoking subcommands (see the push() and pop() methods).
+ * - The isolation makes it easier to make changes in Terminal and supporting
+ *   classes without affecting commands.
+ * - In The Future commands may run in web workers where they would only be able
+ *   to talk to a Terminal instance through an IPC mechanism.
+ *
+ * @param {hterm.Terminal}
+ */
+hterm.Terminal.IO = function(terminal) {
+  this.terminal_ = terminal;
+
+  // The IO object to restore on IO.pop().
+  this.previousIO_ = null;
+
+  // Any data this object accumulated while not active.
+  this.buffered_ = '';
+
+  // Decoder to maintain UTF-8 decode state.
+  this.textDecoder_ = new TextDecoder();
+};
+
+/**
+ * Show the terminal overlay for a given amount of time.
+ *
+ * The terminal overlay appears in inverse video in a large font, centered
+ * over the terminal.  You should probably keep the overlay message brief,
+ * since it's in a large font and you probably aren't going to check the size
+ * of the terminal first.
+ *
+ * @param {string} msg The text (not HTML) message to display in the overlay.
+ * @param {number} opt_timeout The amount of time to wait before fading out
+ *     the overlay.  Defaults to 1.5 seconds.  Pass null to have the overlay
+ *     stay up forever (or until the next overlay).
+ */
+hterm.Terminal.IO.prototype.showOverlay = function(message, opt_timeout) {
+  this.terminal_.showOverlay(message, opt_timeout);
+};
+
+/**
+ * Hide the current overlay immediately.
+ *
+ * Useful when we show an overlay for an event with an unknown end time.
+ */
+hterm.Terminal.IO.prototype.hideOverlay = function() {
+  this.terminal_.hideOverlay();
+};
+
+/**
+ * Open an frame in the current terminal window, pointed to the specified
+ * url.
+ *
+ * Eventually we'll probably need size/position/decoration options.
+ * The user should also be able to move/resize the frame.
+ *
+ * @param {string} url The URL to load in the frame.
+ * @param {Object} opt_options Optional frame options.  Not implemented.
+ */
+hterm.Terminal.IO.prototype.createFrame = function(url, opt_options) {
+  return new hterm.Frame(this.terminal_, url, opt_options);
+};
+
+/**
+ * Change the preference profile for the terminal.
+ *
+ * @param profileName {string} The name of the preference profile to activate.
+ */
+hterm.Terminal.IO.prototype.setTerminalProfile = function(profileName) {
+  this.terminal_.setProfile(profileName);
+};
+
+/**
+ * Create a new hterm.Terminal.IO instance and make it active on the Terminal
+ * object associated with this instance.
+ *
+ * This is used to pass control of the terminal IO off to a subcommand.  The
+ * IO.pop() method can be used to restore control when the subcommand completes.
+ */
+hterm.Terminal.IO.prototype.push = function() {
+  var io = new hterm.Terminal.IO(this.terminal_);
+  io.keyboardCaptured_ = this.keyboardCaptured_;
+
+  io.columnCount = this.columnCount;
+  io.rowCount = this.rowCount;
+
+  io.previousIO_ = this.terminal_.io;
+  this.terminal_.io = io;
+
+  return io;
+};
+
+/**
+ * Restore the Terminal's previous IO object.
+ *
+ * We'll flush out any queued data.
+ */
+hterm.Terminal.IO.prototype.pop = function() {
+  this.terminal_.io = this.previousIO_;
+  this.previousIO_.flush();
+};
+
+/**
+ * Flush accumulated data.
+ *
+ * If we're not the active IO, the connected process might still be writing
+ * data to us, but we won't be displaying it.  Flush any buffered data now.
+ */
+hterm.Terminal.IO.prototype.flush = function() {
+  if (this.buffered_) {
+    this.terminal_.interpret(this.buffered_);
+    this.buffered_ = '';
+  }
+};
+
+/**
+ * Called when data needs to be sent to the current command.
+ *
+ * Clients should override this to receive notification of pending data.
+ *
+ * @param {string} string The data to send.
+ */
+hterm.Terminal.IO.prototype.sendString = function(string) {
+  // Override this.
+  console.log('Unhandled sendString: ' + string);
+};
+
+/**
+ * Called when a terminal keystroke is detected.
+ *
+ * Clients should override this to receive notification of keystrokes.
+ *
+ * @param {string} string The VT key sequence.
+ */
+hterm.Terminal.IO.prototype.onVTKeystroke = function(string) {
+  // Override this.
+  console.log('Unobserverd VT keystroke: ' + JSON.stringify(string));
+};
+
+hterm.Terminal.IO.prototype.onTerminalResize_ = function(width, height) {
+  var obj = this;
+  while (obj) {
+    obj.columnCount = width;
+    obj.rowCount = height;
+    obj = obj.previousIO_;
+  }
+
+  this.onTerminalResize(width, height);
+};
+
+/**
+ * Called when terminal size is changed.
+ *
+ * Clients should override this to receive notification of resize.
+ *
+ * @param {string|integer} terminal width.
+ * @param {string|integer} terminal height.
+ */
+hterm.Terminal.IO.prototype.onTerminalResize = function(width, height) {
+  // Override this.
+};
+
+/**
+ * Write a UTF-8 encoded byte string to the terminal.
+ *
+ * @param {string} string The UTF-8 encoded string to print.
+ */
+hterm.Terminal.IO.prototype.writeUTF8 = function(string) {
+  // We can't use instanceof here on string to see if it's an ArrayBuffer as it
+  // might be constructed in a different runtime context whose ArrayBuffer was
+  // not the same.  See https://crbug.com/930171#5 for more details.
+  if (typeof string == 'string') {
+    if (this.terminal_.characterEncoding != 'raw') {
+      const bytes = lib.codec.stringToCodeUnitArray(string, Uint8Array);
+      string = this.textDecoder_.decode(bytes, {stream: true});
+    }
+  } else {
+    // Handle array buffers & typed arrays by normalizing into a typed array.
+    const u8 = new Uint8Array(string);
+    if (this.terminal_.characterEncoding == 'raw') {
+      string = lib.codec.codeUnitArrayToString(u8);
+    } else {
+      string = this.textDecoder_.decode(u8, {stream: true});
+    }
+  }
+
+  this.print(string);
+};
+
+/**
+ * Write a UTF-8 encoded byte string to the terminal followed by crlf.
+ *
+ * @param {string} string The UTF-8 encoded string to print.
+ */
+hterm.Terminal.IO.prototype.writelnUTF8 = function(string) {
+  this.writeUTF8(string);
+  // We need to use writeUTF8 to make sure we flush the decoder state.
+  this.writeUTF8('\r\n');
+};
+
+/**
+ * Write a UTF-16 JavaScript string to the terminal.
+ *
+ * @param {string} string The string to print.
+ */
+hterm.Terminal.IO.prototype.print =
+hterm.Terminal.IO.prototype.writeUTF16 = function(string) {
+  // If another process has the foreground IO, buffer new data sent to this IO
+  // (since it's in the background).  When we're made the foreground IO again,
+  // we'll flush everything.
+  if (this.terminal_.io != this) {
+    this.buffered_ += string;
+    return;
+  }
+
+  this.terminal_.interpret(string);
+};
+
+/**
+ * Print a UTF-16 JavaScript string to the terminal followed by a newline.
+ *
+ * @param {string} string The string to print.
+ */
+hterm.Terminal.IO.prototype.println =
+hterm.Terminal.IO.prototype.writelnUTF16 = function(string) {
+  this.print(string + '\r\n');
+};
+// SOURCE FILE: hterm/js/hterm_text_attributes.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Constructor for TextAttribute objects.
+ *
+ * These objects manage a set of text attributes such as foreground/
+ * background color, bold, faint, italic, blink, underline, and strikethrough.
+ *
+ * TextAttribute instances can be used to construct a DOM container implementing
+ * the current attributes, or to test an existing DOM container for
+ * compatibility with the current attributes.
+ *
+ * @constructor
+ * @param {HTMLDocument} document The parent document to use when creating
+ *     new DOM containers.
+ */
+hterm.TextAttributes = function(document) {
+  this.document_ = document;
+  // These variables contain the source of the color as either:
+  // SRC_DEFAULT  (use context default)
+  // rgb(...)     (true color form)
+  // number       (representing the index from color palette to use)
+  this.foregroundSource = this.SRC_DEFAULT;
+  this.backgroundSource = this.SRC_DEFAULT;
+  this.underlineSource = this.SRC_DEFAULT;
+
+  // These properties cache the value in the color table, but foregroundSource
+  // and backgroundSource contain the canonical values.
+  this.foreground = this.DEFAULT_COLOR;
+  this.background = this.DEFAULT_COLOR;
+  this.underlineColor = this.DEFAULT_COLOR;
+
+  this.defaultForeground = 'rgb(255, 255, 255)';
+  this.defaultBackground = 'rgb(0, 0, 0)';
+
+  // Any attributes added here that do not default to falsey (e.g. undefined or
+  // null) require a bit more care.  createContainer has to always attach the
+  // attribute so matchesContainer can work correctly.
+  this.bold = false;
+  this.faint = false;
+  this.italic = false;
+  this.blink = false;
+  this.underline = false;
+  this.strikethrough = false;
+  this.inverse = false;
+  this.invisible = false;
+  this.wcNode = false;
+  this.asciiNode = true;
+  this.tileData = null;
+  this.uri = null;
+  this.uriId = null;
+
+  this.colorPalette = null;
+  this.resetColorPalette();
+};
+
+/**
+ * If false, we ignore the bold attribute.
+ *
+ * This is used for fonts that have a bold version that is a different size
+ * than the normal weight version.
+ */
+hterm.TextAttributes.prototype.enableBold = true;
+
+/**
+ * If true, use bright colors (if available) for bold text.
+ *
+ * This setting is independent of the enableBold setting.
+ */
+hterm.TextAttributes.prototype.enableBoldAsBright = true;
+
+/**
+ * A sentinel constant meaning "whatever the default color is in this context".
+ */
+hterm.TextAttributes.prototype.DEFAULT_COLOR = Symbol('DEFAULT_COLOR');
+
+/**
+ * A constant string used to specify that source color is context default.
+ */
+hterm.TextAttributes.prototype.SRC_DEFAULT = Symbol('SRC_DEFAULT');
+
+/**
+ * The document object which should own the DOM nodes created by this instance.
+ *
+ * @param {HTMLDocument} document The parent document.
+ */
+hterm.TextAttributes.prototype.setDocument = function(document) {
+  this.document_ = document;
+};
+
+/**
+ * Create a deep copy of this object.
+ *
+ * @return {hterm.TextAttributes} A deep copy of this object.
+ */
+hterm.TextAttributes.prototype.clone = function() {
+  var rv = new hterm.TextAttributes(null);
+
+  for (var key in this) {
+    rv[key] = this[key];
+  }
+
+  rv.colorPalette = this.colorPalette.concat();
+  return rv;
+};
+
+/**
+ * Reset the current set of attributes.
+ *
+ * This does not affect the palette.  Use resetColorPalette() for that.
+ * It also doesn't affect the tile data, it's not meant to.
+ */
+hterm.TextAttributes.prototype.reset = function() {
+  this.foregroundSource = this.SRC_DEFAULT;
+  this.backgroundSource = this.SRC_DEFAULT;
+  this.underlineSource = this.SRC_DEFAULT;
+  this.foreground = this.DEFAULT_COLOR;
+  this.background = this.DEFAULT_COLOR;
+  this.underlineColor = this.DEFAULT_COLOR;
+  this.bold = false;
+  this.faint = false;
+  this.italic = false;
+  this.blink = false;
+  this.underline = false;
+  this.strikethrough = false;
+  this.inverse = false;
+  this.invisible = false;
+  this.wcNode = false;
+  this.asciiNode = true;
+  this.uri = null;
+  this.uriId = null;
+};
+
+/**
+ * Reset the color palette to the default state.
+ */
+hterm.TextAttributes.prototype.resetColorPalette = function() {
+  this.colorPalette = lib.colors.colorPalette.concat();
+  this.syncColors();
+};
+
+/**
+ * Reset the color.
+ *
+ * @param {integer|string} index The color index in the palette to reset.
+ */
+hterm.TextAttributes.prototype.resetColor = function(index) {
+  index = parseInt(index, 10);
+  if (isNaN(index) || index >= this.colorPalette.length)
+    return;
+
+  this.colorPalette[index] = lib.colors.stockColorPalette[index];
+  this.syncColors();
+};
+
+/**
+ * Test if the current attributes describe unstyled text.
+ *
+ * @return {boolean} True if the current attributes describe unstyled text.
+ */
+hterm.TextAttributes.prototype.isDefault = function() {
+  return (this.foregroundSource == this.SRC_DEFAULT &&
+          this.backgroundSource == this.SRC_DEFAULT &&
+          !this.bold &&
+          !this.faint &&
+          !this.italic &&
+          !this.blink &&
+          !this.underline &&
+          !this.strikethrough &&
+          !this.inverse &&
+          !this.invisible &&
+          !this.wcNode &&
+          this.asciiNode &&
+          this.tileData == null &&
+          this.uri == null);
+};
+
+/**
+ * Create a DOM container (a span or a text node) with a style to match the
+ * current set of attributes.
+ *
+ * This method will create a plain text node if the text is unstyled, or
+ * an HTML span if the text is styled.  Due to lack of monospace wide character
+ * fonts on certain systems (e.g. Chrome OS), we need to put each wide character
+ * in a span of CSS class '.wc-node' which has double column width.
+ * Each vt_tiledata tile is also represented by a span with a single
+ * character, with CSS classes '.tile' and '.tile_<glyph number>'.
+ *
+ * @param {string} opt_textContent Optional text content for the new container.
+ * @return {HTMLNode} An HTML span or text nodes styled to match the current
+ *     attributes.
+ */
+hterm.TextAttributes.prototype.createContainer = function(opt_textContent) {
+  if (this.isDefault()) {
+    // Only attach attributes where we need an explicit default for the
+    // matchContainer logic below.
+    const node = this.document_.createTextNode(opt_textContent);
+    node.asciiNode = true;
+    return node;
+  }
+
+  var span = this.document_.createElement('span');
+  var style = span.style;
+  var classes = [];
+
+  if (this.foreground != this.DEFAULT_COLOR)
+    style.color = this.foreground;
+
+  if (this.background != this.DEFAULT_COLOR)
+    style.backgroundColor = this.background;
+
+  if (this.enableBold && this.bold)
+    style.fontWeight = 'bold';
+
+  if (this.faint)
+    span.faint = true;
+
+  if (this.italic)
+    style.fontStyle = 'italic';
+
+  if (this.blink) {
+    classes.push('blink-node');
+    span.blinkNode = true;
+  }
+
+  let textDecorationLine = '';
+  span.underline = this.underline;
+  if (this.underline) {
+    textDecorationLine += ' underline';
+    style.textDecorationStyle = this.underline;
+  }
+  if (this.underlineColor != this.DEFAULT_COLOR)
+    style.textDecorationColor = this.underlineColor;
+  if (this.strikethrough) {
+    textDecorationLine += ' line-through';
+    span.strikethrough = true;
+  }
+  if (textDecorationLine)
+    style.textDecorationLine = textDecorationLine;
+
+  if (this.wcNode) {
+    classes.push('wc-node');
+    span.wcNode = true;
+  }
+  span.asciiNode = this.asciiNode;
+
+  if (this.tileData != null) {
+    classes.push('tile');
+    classes.push('tile_' + this.tileData);
+    span.tileNode = true;
+  }
+
+  if (opt_textContent)
+    span.textContent = opt_textContent;
+
+  if (this.uri) {
+    classes.push('uri-node');
+    span.uriId = this.uriId;
+    span.title = this.uri;
+    span.addEventListener('click', hterm.openUrl.bind(this, this.uri));
+  }
+
+  if (classes.length)
+    span.className = classes.join(' ');
+
+  return span;
+};
+
+/**
+ * Tests if the provided object (string, span or text node) has the same
+ * style as this TextAttributes instance.
+ *
+ * This indicates that text with these attributes could be inserted directly
+ * into the target DOM node.
+ *
+ * For the purposes of this method, a string is considered a text node.
+ *
+ * @param {string|HTMLNode} obj The object to test.
+ * @return {boolean} True if the provided container has the same style as
+ *     this attributes instance.
+ */
+hterm.TextAttributes.prototype.matchesContainer = function(obj) {
+  if (typeof obj == 'string' || obj.nodeType == Node.TEXT_NODE)
+    return this.isDefault();
+
+  var style = obj.style;
+
+  // We don't want to put multiple characters in a wcNode or a tile.
+  // See the comments in createContainer.
+  // For attributes that default to false, we do not require that obj have them
+  // declared, so always normalize them using !! (to turn undefined into false)
+  // in the compares below.
+  return (!(this.wcNode || obj.wcNode) &&
+          this.asciiNode == obj.asciiNode &&
+          !(this.tileData != null || obj.tileNode) &&
+          this.uriId == obj.uriId &&
+          (this.foreground == this.DEFAULT_COLOR &&
+           style.color == '') &&
+          (this.background == this.DEFAULT_COLOR &&
+           style.backgroundColor == '') &&
+          (this.underlineColor == this.DEFAULT_COLOR &&
+           style.textDecorationColor == '') &&
+          (this.enableBold && this.bold) == !!style.fontWeight &&
+          this.blink == !!obj.blinkNode &&
+          this.italic == !!style.fontStyle &&
+          this.underline == obj.underline &&
+          !!this.strikethrough == !!obj.strikethrough);
+};
+
+hterm.TextAttributes.prototype.setDefaults = function(foreground, background) {
+  this.defaultForeground = foreground;
+  this.defaultBackground = background;
+
+  this.syncColors();
+};
+
+/**
+ * Updates foreground and background properties based on current indices and
+ * other state.
+ *
+ * @param {string} terminalForeground The terminal foreground color for use as
+ *     inverse text background.
+ * @param {string} terminalBackground The terminal background color for use as
+ *     inverse text foreground.
+ *
+ */
+hterm.TextAttributes.prototype.syncColors = function() {
+  function getBrightIndex(i) {
+    if (i < 8) {
+      // If the color is from the lower half of the ANSI 16, add 8.
+      return i + 8;
+    }
+
+    // If it's not from the 16 color palette, ignore bold requests.  This
+    // matches the behavior of gnome-terminal.
+    return i;
+  }
+
+  // Expand the default color as makes sense.
+  const getDefaultColor = (color, defaultColor) => {
+    return color == this.DEFAULT_COLOR ? defaultColor : color;
+  };
+
+  var foregroundSource = this.foregroundSource;
+  var backgroundSource = this.backgroundSource;
+
+  if (this.enableBoldAsBright && this.bold) {
+    if (Number.isInteger(foregroundSource)) {
+      foregroundSource = getBrightIndex(foregroundSource);
+    }
+  }
+
+  if (foregroundSource == this.SRC_DEFAULT)
+    this.foreground = this.DEFAULT_COLOR;
+  else if (Number.isInteger(foregroundSource))
+    this.foreground = this.colorPalette[foregroundSource];
+  else
+    this.foreground = foregroundSource;
+
+  if (this.faint) {
+    const colorToMakeFaint =
+        getDefaultColor(this.foreground, this.defaultForeground);
+    this.foreground = lib.colors.mix(colorToMakeFaint, 'rgb(0, 0, 0)', 0.3333);
+  }
+
+  if (backgroundSource == this.SRC_DEFAULT)
+    this.background = this.DEFAULT_COLOR;
+  else if (Number.isInteger(backgroundSource))
+    this.background = this.colorPalette[backgroundSource];
+  else
+    this.background = backgroundSource;
+
+  // Once we've processed the bold-as-bright and faint attributes, swap.
+  // This matches xterm/gnome-terminal.
+  if (this.inverse) {
+    const swp = getDefaultColor(this.foreground, this.defaultForeground);
+    this.foreground = getDefaultColor(this.background, this.defaultBackground);
+    this.background = swp;
+  }
+
+  // Process invisible settings last to keep it simple.
+  if (this.invisible)
+    this.foreground = this.background;
+
+  if (this.underlineSource == this.SRC_DEFAULT)
+    this.underlineColor = this.DEFAULT_COLOR;
+  else if (Number.isInteger(this.underlineSource))
+    this.underlineColor = this.colorPalette[this.underlineSource];
+  else
+    this.underlineColor = this.underlineSource;
+};
+
+/**
+ * Static method used to test if the provided objects (strings, spans or
+ * text nodes) have the same style.
+ *
+ * For the purposes of this method, a string is considered a text node.
+ *
+ * @param {string|HTMLNode} obj1 An object to test.
+ * @param {string|HTMLNode} obj2 Another object to test.
+ * @return {boolean} True if the containers have the same style.
+ */
+hterm.TextAttributes.containersMatch = function(obj1, obj2) {
+  if (typeof obj1 == 'string')
+    return hterm.TextAttributes.containerIsDefault(obj2);
+
+  if (obj1.nodeType != obj2.nodeType)
+    return false;
+
+  if (obj1.nodeType == Node.TEXT_NODE)
+    return true;
+
+  var style1 = obj1.style;
+  var style2 = obj2.style;
+
+  return (style1.color == style2.color &&
+          style1.backgroundColor == style2.backgroundColor &&
+          style1.backgroundColor == style2.backgroundColor &&
+          style1.fontWeight == style2.fontWeight &&
+          style1.fontStyle == style2.fontStyle &&
+          style1.textDecoration == style2.textDecoration &&
+          style1.textDecorationColor == style2.textDecorationColor &&
+          style1.textDecorationStyle == style2.textDecorationStyle &&
+          style1.textDecorationLine == style2.textDecorationLine);
+};
+
+/**
+ * Static method to test if a given DOM container represents unstyled text.
+ *
+ * For the purposes of this method, a string is considered a text node.
+ *
+ * @param {string|HTMLNode} obj1 An object to test.
+ * @return {boolean} True if the object is unstyled.
+ */
+hterm.TextAttributes.containerIsDefault = function(obj) {
+  return typeof obj == 'string'  || obj.nodeType == Node.TEXT_NODE;
+};
+
+/**
+ * Static method to get the column width of a node's textContent.
+ *
+ * @param {HTMLElement} node The HTML element to get the width of textContent
+ *     from.
+ * @return {integer} The column width of the node's textContent.
+ */
+hterm.TextAttributes.nodeWidth = function(node) {
+  if (!node.asciiNode) {
+    return lib.wc.strWidth(node.textContent);
+  } else {
+    return node.textContent.length;
+  }
+};
+
+/**
+ * Static method to get the substr of a node's textContent.  The start index
+ * and substr width are computed in column width.
+ *
+ * @param {HTMLElement} node The HTML element to get the substr of textContent
+ *     from.
+ * @param {integer} start The starting offset in column width.
+ * @param {integer} width The width to capture in column width.
+ * @return {integer} The extracted substr of the node's textContent.
+ */
+hterm.TextAttributes.nodeSubstr = function(node, start, width) {
+  if (!node.asciiNode) {
+    return lib.wc.substr(node.textContent, start, width);
+  } else {
+    return node.textContent.substr(start, width);
+  }
+};
+
+/**
+ * Static method to get the substring based of a node's textContent.  The
+ * start index of end index are computed in column width.
+ *
+ * @param {HTMLElement} node The HTML element to get the substr of textContent
+ *     from.
+ * @param {integer} start The starting offset in column width.
+ * @param {integer} end The ending offset in column width.
+ * @return {integer} The extracted substring of the node's textContent.
+ */
+hterm.TextAttributes.nodeSubstring = function(node, start, end) {
+  if (!node.asciiNode) {
+    return lib.wc.substring(node.textContent, start, end);
+  } else {
+    return node.textContent.substring(start, end);
+  }
+};
+
+/**
+ * Static method to split a string into contiguous runs of single-width
+ * characters and runs of double-width characters.
+ *
+ * @param {string} str The string to split.
+ * @return {Array} An array of objects that contain substrings of str, where
+ *     each substring is either a contiguous runs of single-width characters
+ *     or a double-width character.  For objects that contain a double-width
+ *     character, its wcNode property is set to true.  For objects that contain
+ *     only ASCII content, its asciiNode property is set to true.
+ */
+hterm.TextAttributes.splitWidecharString = function(str) {
+  const asciiRegex = new RegExp('^[\u0020-\u007f]*$');
+
+  // Optimize for printable ASCII.  This should only take ~1ms/MB, but cuts out
+  // 40ms+/MB when true.  If we're dealing with UTF8, then it's already slow.
+  if (asciiRegex.test(str)) {
+    return [{
+      str: str,
+      wcNode: false,
+      asciiNode: true,
+      wcStrWidth: str.length,
+    }];
+  }
+
+  // Iterate over each grapheme and merge them together in runs of similar
+  // strings.  We want to keep narrow and wide characters separate, and the
+  // fewer overall segments we have, the faster we'll be as processing each
+  // segment in the terminal print code is a bit slow.
+  const segmenter = new Intl.Segmenter(undefined, {type: 'grapheme'});
+  const it = segmenter.segment(str);
+
+  const rv = [];
+  let segment = it.next();
+  while (!segment.done) {
+    const grapheme = segment.value.segment;
+    const isAscii = asciiRegex.test(grapheme);
+    const strWidth = isAscii ? 1 : lib.wc.strWidth(grapheme);
+    const isWideChar =
+        isAscii ? false : (lib.wc.charWidth(grapheme.codePointAt(0)) == 2);
+
+    // Only merge non-wide characters together.  Every wide character needs to
+    // be separate so it can get a unique container.
+    const prev = rv[rv.length - 1];
+    if (prev && !isWideChar && !prev.wcNode) {
+      prev.str += grapheme;
+      prev.wcStrWidth += strWidth;
+      prev.asciiNode = prev.asciiNode && isAscii;
+    } else {
+      rv.push({
+        str: grapheme,
+        wcNode: isWideChar,
+        asciiNode: isAscii,
+        wcStrWidth: strWidth,
+      });
+    }
+
+    segment = it.next();
+  }
+
+  return rv;
+};
+// SOURCE FILE: hterm/js/hterm_vt.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Constructor for the VT escape sequence interpreter.
+ *
+ * The interpreter operates on a terminal object capable of performing cursor
+ * move operations, painting characters, etc.
+ *
+ * This interpreter is intended to be compatible with xterm, though it
+ * ignores some of the more esoteric escape sequences.
+ *
+ * Control sequences are documented in hterm/doc/ControlSequences.md.
+ *
+ * @param {hterm.Terminal} terminal Terminal to use with the interpreter.
+ */
+hterm.VT = function(terminal) {
+  /**
+   * The display terminal object associated with this virtual terminal.
+   */
+  this.terminal = terminal;
+
+  terminal.onMouse = this.onTerminalMouse_.bind(this);
+  this.mouseReport = this.MOUSE_REPORT_DISABLED;
+  this.mouseCoordinates = this.MOUSE_COORDINATES_X10;
+
+  // We only want to report mouse moves between cells, not between pixels.
+  this.lastMouseDragResponse_ = null;
+
+  // Parse state left over from the last parse.  You should use the parseState
+  // instance passed into your parse routine, rather than reading
+  // this.parseState_ directly.
+  this.parseState_ = new hterm.VT.ParseState(this.parseUnknown_);
+
+  // Any "leading modifiers" for the escape sequence, such as '?', ' ', or the
+  // other modifiers handled in this.parseCSI_.
+  this.leadingModifier_ = '';
+
+  // Any "trailing modifiers".  Same character set as a leading modifier,
+  // except these are found after the numeric arguments.
+  this.trailingModifier_ = '';
+
+  // Whether or not to respect the escape codes for setting terminal width.
+  this.allowColumnWidthChanges_ = false;
+
+  // The amount of time we're willing to wait for the end of an OSC sequence.
+  this.oscTimeLimit_ = 20000;
+
+  /**
+   * Whether to accept the 8-bit control characters.
+   *
+   * An 8-bit control character is one with the eighth bit set.  These
+   * didn't work on 7-bit terminals so they all have two byte equivalents.
+   * Most hosts still only use the two-byte versions.
+   *
+   * We ignore 8-bit control codes by default.  This is in order to avoid
+   * issues with "accidental" usage of codes that need to be terminated.
+   * The "accident" usually involves cat'ing binary data.
+   */
+  this.enable8BitControl = false;
+
+  /**
+   * Whether to allow the OSC 52 sequence to write to the system clipboard.
+   */
+  this.enableClipboardWrite = true;
+
+  /**
+   * Respect the host's attempt to change the cursor blink status using
+   * the DEC Private mode 12.
+   */
+  this.enableDec12 = false;
+
+  /**
+   * Respect the host's attempt to clear the scrollback buffer using CSI-J-3.
+   */
+  this.enableCsiJ3 = true;
+
+  /**
+   * The expected encoding method for data received from the host.
+   */
+  this.characterEncoding = 'utf-8';
+
+  /**
+   * If true, emit warnings when we encounter a control character or escape
+   * sequence that we don't recognize or explicitly ignore.
+   *
+   * We disable this by default as the console logging can be expensive when
+   * dumping binary files (e.g. `cat /dev/zero`) to the point where you can't
+   * recover w/out restarting.
+   */
+  this.warnUnimplemented = false;
+
+  /**
+   * The set of available character maps (used by G0...G3 below).
+   */
+  this.characterMaps = new hterm.VT.CharacterMaps();
+
+  /**
+   * The default G0...G3 character maps.
+   * We default to the US/ASCII map everywhere as that aligns with other
+   * terminals, and it makes it harder to accidentally switch to the graphics
+   * character map (Ctrl-N).  Any program that wants to use the graphics map
+   * will usually select it anyways since there's no guarantee what state any
+   * of the maps are in at any particular time.
+   */
+  this.G0 = this.G1 = this.G2 = this.G3 =
+      this.characterMaps.getMap('B');
+
+  /**
+   * The 7-bit visible character set.
+   *
+   * This is a mapping from inbound data to display glyph.  The GL set
+   * contains the 94 bytes from 0x21 to 0x7e.
+   *
+   * The default GL set is 'B', US ASCII.
+   */
+  this.GL = 'G0';
+
+  /**
+   * The 8-bit visible character set.
+   *
+   * This is a mapping from inbound data to display glyph.  The GR set
+   * contains the 94 bytes from 0xa1 to 0xfe.
+   */
+  this.GR = 'G0';
+
+  /**
+   * The current encoding of the terminal.
+   *
+   * We only support ECMA-35 and UTF-8, so go with a boolean here.
+   * The encoding can be locked too.
+   */
+  this.codingSystemUtf8_ = false;
+  this.codingSystemLocked_ = false;
+
+  // Construct a regular expression to match the known one-byte control chars.
+  // This is used in parseUnknown_ to quickly scan a string for the next
+  // control character.
+  this.cc1Pattern_ = null;
+  this.updateEncodingState_();
+};
+
+/**
+ * No mouse events.
+ */
+hterm.VT.prototype.MOUSE_REPORT_DISABLED = 0;
+
+/**
+ * DECSET mode 9.
+ *
+ * Report mouse down events only.
+ */
+hterm.VT.prototype.MOUSE_REPORT_PRESS = 1;
+
+/**
+ * DECSET mode 1000.
+ *
+ * Report mouse down/up events only.
+ */
+hterm.VT.prototype.MOUSE_REPORT_CLICK = 2;
+
+/**
+ * DECSET mode 1002.
+ *
+ * Report mouse down/up and movement while a button is down.
+ */
+hterm.VT.prototype.MOUSE_REPORT_DRAG = 3;
+
+/**
+ * DEC mode for X10 coorindates (the default).
+ */
+hterm.VT.prototype.MOUSE_COORDINATES_X10 = 0;
+
+/**
+ * DEC mode 1005 for UTF-8 coorindates.
+ */
+hterm.VT.prototype.MOUSE_COORDINATES_UTF8 = 1;
+
+/**
+ * DEC mode 1006 for SGR coorindates.
+ */
+hterm.VT.prototype.MOUSE_COORDINATES_SGR = 2;
+
+/**
+ * ParseState constructor.
+ *
+ * This object tracks the current state of the parse.  It has fields for the
+ * current buffer, position in the buffer, and the parse function.
+ *
+ * @param {function} defaultFunc The default parser function.
+ * @param {string} opt_buf Optional string to use as the current buffer.
+ */
+hterm.VT.ParseState = function(defaultFunction, opt_buf) {
+  this.defaultFunction = defaultFunction;
+  this.buf = opt_buf || null;
+  this.pos = 0;
+  this.func = defaultFunction;
+  this.args = [];
+  // Whether any of the arguments in the args array have subarguments.
+  // e.g. All CSI sequences are integer arguments separated by semi-colons,
+  // so subarguments are further colon separated.
+  this.subargs = null;
+};
+
+/**
+ * Reset the parser function, buffer, and position.
+ */
+hterm.VT.ParseState.prototype.reset = function(opt_buf) {
+  this.resetParseFunction();
+  this.resetBuf(opt_buf || '');
+  this.resetArguments();
+};
+
+/**
+ * Reset the parser function only.
+ */
+hterm.VT.ParseState.prototype.resetParseFunction = function() {
+  this.func = this.defaultFunction;
+};
+
+/**
+ * Reset the buffer and position only.
+ *
+ * @param {string} buf Optional new value for buf, defaults to null.
+ */
+hterm.VT.ParseState.prototype.resetBuf = function(opt_buf) {
+  this.buf = (typeof opt_buf == 'string') ? opt_buf : null;
+  this.pos = 0;
+};
+
+/**
+ * Reset the arguments list only.
+ *
+ * Typically we reset arguments before parsing a sequence that uses them rather
+ * than always trying to make sure they're in a good state.  This can lead to
+ * confusion during debugging where args from a previous sequence appear to be
+ * "sticking around" in other sequences (which in reality don't use args).
+ *
+ * @param {string} opt_arg_zero Optional initial value for args[0].
+ */
+hterm.VT.ParseState.prototype.resetArguments = function(opt_arg_zero) {
+  this.args.length = 0;
+  if (typeof opt_arg_zero != 'undefined')
+    this.args[0] = opt_arg_zero;
+};
+
+/**
+ * Parse an argument as an integer.
+ *
+ * This assumes the inputs are already in the proper format.  e.g. This won't
+ * handle non-numeric arguments.
+ *
+ * An "0" argument is treated the same as "" which means the default value will
+ * be applied.  This is what most terminal sequences expect.
+ *
+ * @param {string} argstr The argument to parse directly.
+ * @param {number=} defaultValue Default value if argstr is empty.
+ * @return {number} The parsed value.
+ */
+hterm.VT.ParseState.prototype.parseInt = function(argstr, defaultValue) {
+  if (defaultValue === undefined)
+    defaultValue = 0;
+
+  if (argstr) {
+    const ret = parseInt(argstr, 10);
+    // An argument of zero is treated as the default value.
+    return ret == 0 ? defaultValue : ret;
+  }
+  return defaultValue;
+};
+
+/**
+ * Get an argument as an integer.
+ *
+ * @param {number} argnum The argument number to retrieve.
+ * @param {number=} defaultValue Default value if the argument is empty.
+ * @return {number} The parsed value.
+ */
+hterm.VT.ParseState.prototype.iarg = function(argnum, defaultValue) {
+  return this.parseInt(this.args[argnum], defaultValue);
+};
+
+/**
+ * Check whether an argument has subarguments.
+ *
+ * @param {number} argnum The argument number to check.
+ * @return {number} Whether the argument has subarguments.
+ */
+hterm.VT.ParseState.prototype.argHasSubargs = function(argnum) {
+  return this.subargs && this.subargs[argnum];
+};
+
+/**
+ * Mark an argument as having subarguments.
+ *
+ * @param {number} argnum The argument number that has subarguments.
+ */
+hterm.VT.ParseState.prototype.argSetSubargs = function(argnum) {
+  if (this.subargs === null)
+    this.subargs = {};
+  this.subargs[argnum] = true;
+};
+
+/**
+ * Advance the parse position.
+ *
+ * @param {integer} count The number of bytes to advance.
+ */
+hterm.VT.ParseState.prototype.advance = function(count) {
+  this.pos += count;
+};
+
+/**
+ * Return the remaining portion of the buffer without affecting the parse
+ * position.
+ *
+ * @return {string} The remaining portion of the buffer.
+ */
+hterm.VT.ParseState.prototype.peekRemainingBuf = function() {
+  return this.buf.substr(this.pos);
+};
+
+/**
+ * Return the next single character in the buffer without affecting the parse
+ * position.
+ *
+ * @return {string} The next character in the buffer.
+ */
+hterm.VT.ParseState.prototype.peekChar = function() {
+  return this.buf.substr(this.pos, 1);
+};
+
+/**
+ * Return the next single character in the buffer and advance the parse
+ * position one byte.
+ *
+ * @return {string} The next character in the buffer.
+ */
+hterm.VT.ParseState.prototype.consumeChar = function() {
+  return this.buf.substr(this.pos++, 1);
+};
+
+/**
+ * Return true if the buffer is empty, or the position is past the end.
+ */
+hterm.VT.ParseState.prototype.isComplete = function() {
+  return this.buf == null || this.buf.length <= this.pos;
+};
+
+/**
+ * Reset the VT back to baseline state.
+ */
+hterm.VT.prototype.reset = function() {
+  this.G0 = this.G1 = this.G2 = this.G3 =
+      this.characterMaps.getMap('B');
+
+  this.GL = 'G0';
+  this.GR = 'G0';
+
+  this.mouseReport = this.MOUSE_REPORT_DISABLED;
+  this.mouseCoordinates = this.MOUSE_COORDINATES_X10;
+  this.lastMouseDragResponse_ = null;
+};
+
+/**
+ * Handle terminal mouse events.
+ *
+ * See the "Mouse Tracking" section of [xterm].
+ */
+hterm.VT.prototype.onTerminalMouse_ = function(e) {
+  // Short circuit a few events to avoid unnecessary processing.
+  if (this.mouseReport == this.MOUSE_REPORT_DISABLED)
+    return;
+  else if (this.mouseReport != this.MOUSE_REPORT_DRAG && e.type == 'mousemove')
+    return;
+
+  // Temporary storage for our response.
+  var response;
+
+  // Modifier key state.
+  var mod = 0;
+  if (this.mouseReport != this.MOUSE_REPORT_PRESS) {
+    if (e.shiftKey)
+      mod |= 4;
+    if (e.metaKey || (this.terminal.keyboard.altIsMeta && e.altKey))
+      mod |= 8;
+    if (e.ctrlKey)
+      mod |= 16;
+  }
+
+  // X & Y coordinate reporting.
+  let x;
+  let y;
+  // Normally X10 has a limit of 255, but since we only want to emit UTF-8 valid
+  // streams, we limit ourselves to 127 to avoid setting the 8th bit.  If we do
+  // re-enable this, we should re-enable the hterm_vt_tests.js too.
+  let limit = 127;
+  switch (this.mouseCoordinates) {
+    case this.MOUSE_COORDINATES_UTF8:
+      // UTF-8 mode is the same as X10 but with higher limits.
+      limit = 2047;
+    case this.MOUSE_COORDINATES_X10:
+      // X10 reports coordinates by encoding into strings.
+      x = String.fromCharCode(lib.f.clamp(e.terminalColumn + 32, 32, limit));
+      y = String.fromCharCode(lib.f.clamp(e.terminalRow + 32, 32, limit));
+      break;
+    case this.MOUSE_COORDINATES_SGR:
+      // SGR reports coordinates by transmitting the numbers directly.
+      x = e.terminalColumn;
+      y = e.terminalRow;
+      break;
+  }
+
+  switch (e.type) {
+    case 'wheel':
+      // Mouse wheel is treated as button 1 or 2 plus an additional 64.
+      b = (((e.deltaY * -1) > 0) ? 0 : 1) + 64;
+      b |= mod;
+      if (this.mouseCoordinates == this.MOUSE_COORDINATES_SGR) {
+        response = `\x1b[<${b};${x};${y}M`;
+      } else {
+        // X10 based modes (including UTF8) add 32 for legacy encoding reasons.
+        response = '\x1b[M' + String.fromCharCode(b + 32) + x + y;
+      }
+
+      // Keep the terminal from scrolling.
+      e.preventDefault();
+      break;
+
+    case 'mousedown':
+      // Buttons are encoded as button number.
+      var b = Math.min(e.button, 2);
+      // X10 based modes (including UTF8) add 32 for legacy encoding reasons.
+      if (this.mouseCoordinates != this.MOUSE_COORDINATES_SGR)
+        b += 32;
+
+      // And mix in the modifier keys.
+      b |= mod;
+
+      if (this.mouseCoordinates == this.MOUSE_COORDINATES_SGR)
+        response = `\x1b[<${b};${x};${y}M`;
+      else
+        response = '\x1b[M' + String.fromCharCode(b) + x + y;
+      break;
+
+    case 'mouseup':
+      if (this.mouseReport != this.MOUSE_REPORT_PRESS) {
+        if (this.mouseCoordinates == this.MOUSE_COORDINATES_SGR) {
+          // SGR mode can report the released button.
+          response = `\x1b[<${e.button};${x};${y}m`;
+        } else {
+          // X10 mode has no indication of which button was released.
+          response = '\x1b[M\x23' + x + y;
+        }
+      }
+      break;
+
+    case 'mousemove':
+      if (this.mouseReport == this.MOUSE_REPORT_DRAG && e.buttons) {
+        // Standard button bits.  The XTerm protocol only reports the first
+        // button press (e.g. if left & right are pressed, right is ignored),
+        // and it only supports the first three buttons.  If none of them are
+        // pressed, then XTerm flags it as a release.  We'll do the same.
+        // X10 based modes (including UTF8) add 32 for legacy encoding reasons.
+        b = this.mouseCoordinates == this.MOUSE_COORDINATES_SGR ? 0 : 32;
+
+        // Priority here matches XTerm: left, middle, right.
+        if (e.buttons & 0x1) {
+          // Report left button.
+          b += 0;
+        } else if (e.buttons & 0x4) {
+          // Report middle button.
+          b += 1;
+        } else if (e.buttons & 0x2) {
+          // Report right button.
+          b += 2;
+        } else {
+          // Release higher buttons.
+          b += 3;
+        }
+
+        // Add 32 to indicate mouse motion.
+        b += 32;
+
+        // And mix in the modifier keys.
+        b |= mod;
+
+        if (this.mouseCoordinates == this.MOUSE_COORDINATES_SGR)
+          response = `\x1b[<${b};${x};${y}M`;
+        else
+          response = '\x1b[M' + String.fromCharCode(b) + x + y;
+
+        // If we were going to report the same cell because we moved pixels
+        // within, suppress the report.  This is what xterm does and cuts
+        // down on duplicate messages.
+        if (this.lastMouseDragResponse_ == response)
+          response = '';
+        else
+          this.lastMouseDragResponse_ = response;
+      }
+
+      break;
+
+    case 'click':
+    case 'dblclick':
+      break;
+
+    default:
+      console.error('Unknown mouse event: ' + e.type, e);
+      break;
+  }
+
+  if (response)
+    this.terminal.io.sendString(response);
+};
+
+/**
+ * Interpret a string of characters, displaying the results on the associated
+ * terminal object.
+ *
+ * The buffer will be decoded according to the 'receive-encoding' preference.
+ */
+hterm.VT.prototype.interpret = function(buf) {
+  this.parseState_.resetBuf(buf);
+
+  while (!this.parseState_.isComplete()) {
+    var func = this.parseState_.func;
+    var pos = this.parseState_.pos;
+    var buf = this.parseState_.buf;
+
+    this.parseState_.func.call(this, this.parseState_);
+
+    if (this.parseState_.func == func && this.parseState_.pos == pos &&
+        this.parseState_.buf == buf) {
+      throw 'Parser did not alter the state!';
+    }
+  }
+};
+
+/**
+ * Set the encoding of the terminal.
+ *
+ * @param {string} encoding The name of the encoding to set.
+ */
+hterm.VT.prototype.setEncoding = function(encoding) {
+  switch (encoding) {
+    default:
+      console.warn('Invalid value for "terminal-encoding": ' + encoding);
+      // Fall through.
+    case 'iso-2022':
+      this.codingSystemUtf8_ = false;
+      this.codingSystemLocked_ = false;
+      break;
+    case 'utf-8-locked':
+      this.codingSystemUtf8_ = true;
+      this.codingSystemLocked_ = true;
+      break;
+    case 'utf-8':
+      this.codingSystemUtf8_ = true;
+      this.codingSystemLocked_ = false;
+      break;
+  }
+
+  this.updateEncodingState_();
+};
+
+/**
+ * Refresh internal state when the encoding changes.
+ */
+hterm.VT.prototype.updateEncodingState_ = function() {
+  // If we're in UTF8 mode, don't suport 8-bit escape sequences as we'll never
+  // see those -- everything should be UTF8!
+  var cc1 = Object.keys(hterm.VT.CC1)
+      .filter((e) => !this.codingSystemUtf8_ || e.charCodeAt() < 0x80)
+      .map((e) => '\\x' + lib.f.zpad(e.charCodeAt().toString(16), 2))
+      .join('');
+  this.cc1Pattern_ = new RegExp(`[${cc1}]`);
+};
+
+/**
+ * The default parse function.
+ *
+ * This will scan the string for the first 1-byte control character (C0/C1
+ * characters from [CTRL]).  Any plain text coming before the code will be
+ * printed to the terminal, then the control character will be dispatched.
+ */
+hterm.VT.prototype.parseUnknown_ = function(parseState) {
+  var self = this;
+
+  function print(str) {
+    if (!self.codingSystemUtf8_ && self[self.GL].GL)
+      str = self[self.GL].GL(str);
+
+    self.terminal.print(str);
+  }
+
+  // Search for the next contiguous block of plain text.
+  var buf = parseState.peekRemainingBuf();
+  var nextControl = buf.search(this.cc1Pattern_);
+
+  if (nextControl == 0) {
+    // We've stumbled right into a control character.
+    this.dispatch('CC1', buf.substr(0, 1), parseState);
+    parseState.advance(1);
+    return;
+  }
+
+  if (nextControl == -1) {
+    // There are no control characters in this string.
+    print(buf);
+    parseState.reset();
+    return;
+  }
+
+  print(buf.substr(0, nextControl));
+  this.dispatch('CC1', buf.substr(nextControl, 1), parseState);
+  parseState.advance(nextControl + 1);
+};
+
+/**
+ * Parse a Control Sequence Introducer code and dispatch it.
+ *
+ * See [CSI] for some useful information about these codes.
+ */
+hterm.VT.prototype.parseCSI_ = function(parseState) {
+  var ch = parseState.peekChar();
+  var args = parseState.args;
+
+  const finishParsing = () => {
+    // Resetting the arguments isn't strictly necessary, but it makes debugging
+    // less confusing (otherwise args will stick around until the next sequence
+    // that needs arguments).
+    parseState.resetArguments();
+    // We need to clear subargs since we explicitly set it.
+    parseState.subargs = null;
+    parseState.resetParseFunction();
+  };
+
+  if (ch >= '@' && ch <= '~') {
+    // This is the final character.
+    this.dispatch('CSI', this.leadingModifier_ + this.trailingModifier_ + ch,
+                  parseState);
+    finishParsing();
+
+  } else if (ch == ';') {
+    // Parameter delimiter.
+    if (this.trailingModifier_) {
+      // Parameter delimiter after the trailing modifier.  That's a paddlin'.
+      finishParsing();
+
+    } else {
+      if (!args.length) {
+        // They omitted the first param, we need to supply it.
+        args.push('');
+      }
+
+      args.push('');
+    }
+
+  } else if (ch >= '0' && ch <= '9' || ch == ':') {
+    // Next byte in the current parameter.
+
+    if (this.trailingModifier_) {
+      // Numeric parameter after the trailing modifier.  That's a paddlin'.
+      finishParsing();
+    } else {
+      if (!args.length) {
+        args[0] = ch;
+      } else {
+        args[args.length - 1] += ch;
+      }
+
+      // Possible sub-parameters.
+      if (ch == ':')
+        parseState.argSetSubargs(args.length - 1);
+    }
+
+  } else if (ch >= ' ' && ch <= '?') {
+    // Modifier character.
+    if (!args.length) {
+      this.leadingModifier_ += ch;
+    } else {
+      this.trailingModifier_ += ch;
+    }
+
+  } else if (this.cc1Pattern_.test(ch)) {
+    // Control character.
+    this.dispatch('CC1', ch, parseState);
+
+  } else {
+    // Unexpected character in sequence, bail out.
+    finishParsing();
+  }
+
+  parseState.advance(1);
+};
+
+/**
+ * Skip over the string until the next String Terminator (ST, 'ESC \') or
+ * Bell (BEL, '\x07').
+ *
+ * The string is accumulated in parseState.args[0].  Make sure to reset the
+ * arguments (with parseState.resetArguments) before starting the parse.
+ *
+ * You can detect that parsing in complete by checking that the parse
+ * function has changed back to the default parse function.
+ *
+ * @return {boolean} If true, parsing is ongoing or complete.  If false, we've
+ *     exceeded the max string sequence.
+ */
+hterm.VT.prototype.parseUntilStringTerminator_ = function(parseState) {
+  var buf = parseState.peekRemainingBuf();
+  var args = parseState.args;
+  // Since we might modify parse state buffer locally, if we want to advance
+  // the parse state buffer later on, we need to know how many chars we added.
+  let bufInserted = 0;
+
+  if (!args.length) {
+    args[0] = '';
+    args[1] = new Date();
+  } else {
+    // If our saved buffer ends with an escape, it's because we were hoping
+    // it's an ST split across two buffers.  Move it from our saved buffer
+    // to the start of our current buffer for processing anew.
+    if (args[0].slice(-1) == '\x1b') {
+      args[0] = args[0].slice(0, -1);
+      buf = '\x1b' + buf;
+      bufInserted = 1;
+    }
+  }
+
+  const nextTerminator = buf.search(/[\x1b\x07]/);
+  const terminator = buf[nextTerminator];
+  let foundTerminator;
+
+  // If the next escape we see is not a start of a ST, fall through.  This will
+  // either be invalid (embedded escape), or we'll queue it up (wait for \\).
+  if (terminator == '\x1b' && buf[nextTerminator + 1] != '\\')
+    foundTerminator = false;
+  else
+    foundTerminator = (nextTerminator != -1);
+
+  if (!foundTerminator) {
+    // No terminator here, have to wait for the next string.
+
+    args[0] += buf;
+
+    var abortReason;
+
+    // Special case: If our buffering happens to split the ST (\e\\), we have to
+    // buffer the content temporarily.  So don't reject a trailing escape here,
+    // instead we let it timeout or be rejected in the next pass.
+    if (terminator == '\x1b' && nextTerminator != buf.length - 1)
+      abortReason = 'embedded escape: ' + nextTerminator;
+
+    if (new Date() - args[1] > this.oscTimeLimit_)
+      abortReason = 'timeout expired: ' + (new Date() - args[1]);
+
+    if (abortReason) {
+      if (this.warnUnimplemented)
+        console.log('parseUntilStringTerminator_: aborting: ' + abortReason,
+                    args[0]);
+      parseState.reset(args[0]);
+      return false;
+    }
+
+    parseState.advance(buf.length - bufInserted);
+    return true;
+  }
+
+  args[0] += buf.substr(0, nextTerminator);
+
+  parseState.resetParseFunction();
+  parseState.advance(nextTerminator +
+                     (terminator == '\x1b' ? 2 : 1) - bufInserted);
+
+  return true;
+};
+
+/**
+ * Dispatch to the function that handles a given CC1, ESC, or CSI or VT52 code.
+ */
+hterm.VT.prototype.dispatch = function(type, code, parseState) {
+  var handler = hterm.VT[type][code];
+  if (!handler) {
+    if (this.warnUnimplemented)
+      console.warn('Unknown ' + type + ' code: ' + JSON.stringify(code));
+    return;
+  }
+
+  if (handler == hterm.VT.ignore) {
+    if (this.warnUnimplemented)
+      console.warn('Ignored ' + type + ' code: ' + JSON.stringify(code));
+    return;
+  }
+
+  if (parseState.subargs && !handler.supportsSubargs) {
+    if (this.warnUnimplemented)
+      console.warn('Ignored ' + type + ' code w/subargs: ' + JSON.stringify(code));
+    return;
+  }
+
+  if (type == 'CC1' && code > '\x7f' && !this.enable8BitControl) {
+    // It's kind of a hack to put this here, but...
+    //
+    // If we're dispatching a 'CC1' code, and it's got the eighth bit set,
+    // but we're not supposed to handle 8-bit codes?  Just ignore it.
+    //
+    // This prevents an errant (DCS, '\x90'), (OSC, '\x9d'), (PM, '\x9e') or
+    // (APC, '\x9f') from locking up the terminal waiting for its expected
+    // (ST, '\x9c') or (BEL, '\x07').
+    console.warn('Ignoring 8-bit control code: 0x' +
+                 code.charCodeAt(0).toString(16));
+    return;
+  }
+
+  handler.apply(this, [parseState, code]);
+};
+
+/**
+ * Set one of the ANSI defined terminal mode bits.
+ *
+ * Invoked in response to SM/RM.
+ *
+ * Unexpected and unimplemented values are silently ignored.
+ */
+hterm.VT.prototype.setANSIMode = function(code, state) {
+  if (code == 4) {  // Insert Mode (IRM)
+    this.terminal.setInsertMode(state);
+  } else if (code == 20) {  // Automatic Newline (LNM)
+    this.terminal.setAutoCarriageReturn(state);
+  } else if (this.warnUnimplemented) {
+    console.warn('Unimplemented ANSI Mode: ' + code);
+  }
+};
+
+/**
+ * Set or reset one of the DEC Private modes.
+ *
+ * Invoked in response to DECSET/DECRST.
+ */
+hterm.VT.prototype.setDECMode = function(code, state) {
+  switch (parseInt(code, 10)) {
+    case 1:  // DECCKM
+      this.terminal.keyboard.applicationCursor = state;
+      break;
+
+    case 3:  // DECCOLM
+      if (this.allowColumnWidthChanges_) {
+        this.terminal.setWidth(state ? 132 : 80);
+
+        this.terminal.clearHome();
+        this.terminal.setVTScrollRegion(null, null);
+      }
+      break;
+
+    case 5:  // DECSCNM
+      this.terminal.setReverseVideo(state);
+      break;
+
+    case 6:  // DECOM
+      this.terminal.setOriginMode(state);
+      break;
+
+    case 7:  // DECAWM
+      this.terminal.setWraparound(state);
+      break;
+
+    case 9:  // Report on mouse down events only (X10).
+      this.mouseReport = (
+          state ? this.MOUSE_REPORT_PRESS : this.MOUSE_REPORT_DISABLED);
+      this.terminal.syncMouseStyle();
+      break;
+
+    case 12:  // Start blinking cursor
+      if (this.enableDec12)
+        this.terminal.setCursorBlink(state);
+      break;
+
+    case 25:  // DECTCEM
+      this.terminal.setCursorVisible(state);
+      break;
+
+    case 30:  // Show scrollbar
+      this.terminal.setScrollbarVisible(state);
+      break;
+
+    case 40:  // Allow 80 - 132 (DECCOLM) Mode
+      this.terminal.allowColumnWidthChanges_ = state;
+      break;
+
+    case 45:  // Reverse-wraparound Mode
+      this.terminal.setReverseWraparound(state);
+      break;
+
+    case 67:  // Backarrow key sends backspace (DECBKM)
+      this.terminal.keyboard.backspaceSendsBackspace = state;
+      break;
+
+    case 1000:  // Report on mouse clicks only (X11).
+      this.mouseReport = (
+          state ? this.MOUSE_REPORT_CLICK : this.MOUSE_REPORT_DISABLED);
+      this.terminal.syncMouseStyle();
+      break;
+
+    case 1002:  // Report on mouse clicks and drags
+      this.mouseReport = (
+          state ? this.MOUSE_REPORT_DRAG : this.MOUSE_REPORT_DISABLED);
+      this.terminal.syncMouseStyle();
+      break;
+
+    case 1004:  // Report on window focus change.
+      this.terminal.reportFocus = state;
+      break;
+
+    case 1005:  // Extended coordinates in UTF-8 mode.
+      this.mouseCoordinates = (
+          state ? this.MOUSE_COORDINATES_UTF8 : this.MOUSE_COORDINATES_X10);
+      break;
+
+    case 1006:  // Extended coordinates in SGR mode.
+      this.mouseCoordinates = (
+          state ? this.MOUSE_COORDINATES_SGR : this.MOUSE_COORDINATES_X10);
+      break;
+
+    case 1007:  // Enable Alternate Scroll Mode.
+      this.terminal.scrollWheelArrowKeys_ = state;
+      break;
+
+    case 1010:  // Scroll to bottom on tty output
+      this.terminal.scrollOnOutput = state;
+      break;
+
+    case 1011:  // Scroll to bottom on key press
+      this.terminal.scrollOnKeystroke = state;
+      break;
+
+    case 1036:  // Send ESC when Meta modifies a key
+      this.terminal.keyboard.metaSendsEscape = state;
+      break;
+
+    case 1039:  // Send ESC when Alt modifies a key
+      if (state) {
+        if (!this.terminal.keyboard.previousAltSendsWhat_) {
+          this.terminal.keyboard.previousAltSendsWhat_ =
+              this.terminal.keyboard.altSendsWhat;
+          this.terminal.keyboard.altSendsWhat = 'escape';
+        }
+      } else if (this.terminal.keyboard.previousAltSendsWhat_) {
+        this.terminal.keyboard.altSendsWhat =
+            this.terminal.keyboard.previousAltSendsWhat_;
+        this.terminal.keyboard.previousAltSendsWhat_ = null;
+      }
+      break;
+
+    case 47:  // Use Alternate Screen Buffer
+    case 1047:
+      this.terminal.setAlternateMode(state);
+      break;
+
+    case 1048:  // Save cursor as in DECSC.
+      if (state)
+        this.terminal.saveCursorAndState();
+      else
+        this.terminal.restoreCursorAndState();
+      break;
+
+    case 1049:  // 1047 + 1048 + clear.
+      if (state) {
+        this.terminal.saveCursorAndState();
+        this.terminal.setAlternateMode(state);
+        this.terminal.clear();
+      } else {
+        this.terminal.setAlternateMode(state);
+        this.terminal.restoreCursorAndState();
+      }
+
+      break;
+
+    case 2004:  // Bracketed paste mode.
+      this.terminal.setBracketedPaste(state);
+      break;
+
+    default:
+      if (this.warnUnimplemented)
+        console.warn('Unimplemented DEC Private Mode: ' + code);
+      break;
+  }
+};
+
+/**
+ * Function shared by control characters and escape sequences that are
+ * ignored.
+ */
+hterm.VT.ignore = function() {};
+
+/**
+ * Collection of control characters expressed in a single byte.
+ *
+ * This includes the characters from the C0 and C1 sets (see [CTRL]) that we
+ * care about.  Two byte versions of the C1 codes are defined in the
+ * hterm.VT.ESC collection.
+ *
+ * The 'CC1' mnemonic here refers to the fact that these are one-byte Control
+ * Codes.  It's only used in this source file and not defined in any of the
+ * referenced documents.
+ */
+hterm.VT.CC1 = {};
+
+/**
+ * Collection of two-byte and three-byte sequences starting with ESC.
+ */
+hterm.VT.ESC = {};
+
+/**
+ * Collection of CSI (Control Sequence Introducer) sequences.
+ *
+ * These sequences begin with 'ESC [', and may take zero or more arguments.
+ */
+hterm.VT.CSI = {};
+
+/**
+ * Collection of OSC (Operating System Control) sequences.
+ *
+ * These sequences begin with 'ESC ]', followed by a function number and a
+ * string terminated by either ST or BEL.
+ */
+hterm.VT.OSC = {};
+
+/**
+ * Collection of VT52 sequences.
+ *
+ * When in VT52 mode, other sequences are disabled.
+ */
+hterm.VT.VT52 = {};
+
+/**
+ * Null (NUL).
+ *
+ * Silently ignored.
+ */
+hterm.VT.CC1['\x00'] = hterm.VT.ignore;
+
+/**
+ * Enquiry (ENQ).
+ *
+ * Transmit answerback message.
+ *
+ * The default answerback message in xterm is an empty string, so we just
+ * ignore this.
+ */
+hterm.VT.CC1['\x05'] = hterm.VT.ignore;
+
+/**
+ * Ring Bell (BEL).
+ */
+hterm.VT.CC1['\x07'] = function() {
+  this.terminal.ringBell();
+};
+
+/**
+ * Backspace (BS).
+ *
+ * Move the cursor to the left one character position, unless it is at the
+ * left margin, in which case no action occurs.
+ */
+hterm.VT.CC1['\x08'] = function() {
+  this.terminal.cursorLeft(1);
+};
+
+/**
+ * Horizontal Tab (HT).
+ *
+ * Move the cursor to the next tab stop, or to the right margin if no further
+ * tab stops are present on the line.
+ */
+hterm.VT.CC1['\x09'] = function() {
+  this.terminal.forwardTabStop();
+};
+
+/**
+ * Line Feed (LF).
+ *
+ * This code causes a line feed or a new line operation.  See Automatic
+ * Newline (LNM).
+ */
+hterm.VT.CC1['\x0a'] = function() {
+  this.terminal.formFeed();
+};
+
+/**
+ * Vertical Tab (VT).
+ *
+ * Interpreted as LF.
+ */
+hterm.VT.CC1['\x0b'] = hterm.VT.CC1['\x0a'];
+
+/**
+ * Form Feed (FF).
+ *
+ * Interpreted as LF.
+ */
+hterm.VT.CC1['\x0c'] = hterm.VT.CC1['\x0a'];
+
+/**
+ * Carriage Return (CR).
+ *
+ * Move cursor to the left margin on the current line.
+ */
+hterm.VT.CC1['\x0d'] = function() {
+  this.terminal.setCursorColumn(0);
+};
+
+/**
+ * Shift Out (SO), aka Lock Shift 0 (LS1).
+ *
+ * Invoke G1 character set in GL.
+ */
+hterm.VT.CC1['\x0e'] = function() {
+  this.GL = 'G1';
+};
+
+/**
+ * Shift In (SI), aka Lock Shift 0 (LS0).
+ *
+ * Invoke G0 character set in GL.
+ */
+hterm.VT.CC1['\x0f'] = function() {
+  this.GL = 'G0';
+};
+
+/**
+ * Transmit On (XON).
+ *
+ * Not currently implemented.
+ *
+ * TODO(rginda): Implement?
+ */
+hterm.VT.CC1['\x11'] = hterm.VT.ignore;
+
+/**
+ * Transmit Off (XOFF).
+ *
+ * Not currently implemented.
+ *
+ * TODO(rginda): Implement?
+ */
+hterm.VT.CC1['\x13'] = hterm.VT.ignore;
+
+/**
+ * Cancel (CAN).
+ *
+ * If sent during a control sequence, the sequence is immediately terminated
+ * and not executed.
+ *
+ * It also causes the error character to be displayed.
+ */
+hterm.VT.CC1['\x18'] = function(parseState) {
+  // If we've shifted in the G1 character set, shift it back out to
+  // the default character set.
+  if (this.GL == 'G1') {
+    this.GL = 'G0';
+  }
+  parseState.resetParseFunction();
+  this.terminal.print('?');
+};
+
+/**
+ * Substitute (SUB).
+ *
+ * Interpreted as CAN.
+ */
+hterm.VT.CC1['\x1a'] = hterm.VT.CC1['\x18'];
+
+/**
+ * Escape (ESC).
+ */
+hterm.VT.CC1['\x1b'] = function(parseState) {
+  function parseESC(parseState) {
+    var ch = parseState.consumeChar();
+
+    if (ch == '\x1b')
+      return;
+
+    this.dispatch('ESC', ch, parseState);
+
+    if (parseState.func == parseESC)
+      parseState.resetParseFunction();
+  }
+
+  parseState.func = parseESC;
+};
+
+/**
+ * Delete (DEL).
+ */
+hterm.VT.CC1['\x7f'] = hterm.VT.ignore;
+
+// 8 bit control characters and their two byte equivalents, below...
+
+/**
+ * Index (IND).
+ *
+ * Like newline, only keep the X position
+ */
+hterm.VT.CC1['\x84'] =
+hterm.VT.ESC['D'] = function() {
+  this.terminal.lineFeed();
+};
+
+/**
+ * Next Line (NEL).
+ *
+ * Like newline, but doesn't add lines.
+ */
+hterm.VT.CC1['\x85'] =
+hterm.VT.ESC['E'] = function() {
+  this.terminal.setCursorColumn(0);
+  this.terminal.cursorDown(1);
+};
+
+/**
+ * Horizontal Tabulation Set (HTS).
+ */
+hterm.VT.CC1['\x88'] =
+hterm.VT.ESC['H'] = function() {
+  this.terminal.setTabStop(this.terminal.getCursorColumn());
+};
+
+/**
+ * Reverse Index (RI).
+ *
+ * Move up one line.
+ */
+hterm.VT.CC1['\x8d'] =
+hterm.VT.ESC['M'] = function() {
+  this.terminal.reverseLineFeed();
+};
+
+/**
+ * Single Shift 2 (SS2).
+ *
+ * Select of G2 Character Set for the next character only.
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CC1['\x8e'] =
+hterm.VT.ESC['N'] = hterm.VT.ignore;
+
+/**
+ * Single Shift 3 (SS3).
+ *
+ * Select of G3 Character Set for the next character only.
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CC1['\x8f'] =
+hterm.VT.ESC['O'] = hterm.VT.ignore;
+
+/**
+ * Device Control String (DCS).
+ *
+ * Indicate a DCS sequence.  See Device-Control functions in [XTERM].
+ * Not currently implemented.
+ *
+ * TODO(rginda): Consider implementing DECRQSS, the rest don't seem applicable.
+ */
+hterm.VT.CC1['\x90'] =
+hterm.VT.ESC['P'] = function(parseState) {
+  parseState.resetArguments();
+  parseState.func = this.parseUntilStringTerminator_;
+};
+
+/**
+ * Start of Guarded Area (SPA).
+ *
+ * Will not implement.
+ */
+hterm.VT.CC1['\x96'] =
+hterm.VT.ESC['V'] = hterm.VT.ignore;
+
+/**
+ * End of Guarded Area (EPA).
+ *
+ * Will not implement.
+ */
+hterm.VT.CC1['\x97'] =
+hterm.VT.ESC['W'] = hterm.VT.ignore;
+
+/**
+ * Start of String (SOS).
+ *
+ * Will not implement.
+ */
+hterm.VT.CC1['\x98'] =
+hterm.VT.ESC['X'] = hterm.VT.ignore;
+
+/**
+ * Single Character Introducer (SCI, also DECID).
+ *
+ * Return Terminal ID.  Obsolete form of 'ESC [ c' (DA).
+ */
+hterm.VT.CC1['\x9a'] =
+hterm.VT.ESC['Z'] = function() {
+  this.terminal.io.sendString('\x1b[?1;2c');
+};
+
+/**
+ * Control Sequence Introducer (CSI).
+ *
+ * The lead into most escape sequences.  See [CSI].
+ */
+hterm.VT.CC1['\x9b'] =
+hterm.VT.ESC['['] = function(parseState) {
+  parseState.resetArguments();
+  this.leadingModifier_ = '';
+  this.trailingModifier_ = '';
+  parseState.func = this.parseCSI_;
+};
+
+/**
+ * String Terminator (ST).
+ *
+ * Used to terminate DCS/OSC/PM/APC commands which may take string arguments.
+ *
+ * We don't directly handle it here, as it's only used to terminate other
+ * sequences.  See the 'parseUntilStringTerminator_' method.
+ */
+hterm.VT.CC1['\x9c'] =
+hterm.VT.ESC['\\'] = hterm.VT.ignore;
+
+/**
+ * Operating System Command (OSC).
+ *
+ * Commands relating to the operating system.
+ */
+hterm.VT.CC1['\x9d'] =
+hterm.VT.ESC[']'] = function(parseState) {
+  parseState.resetArguments();
+
+  function parseOSC(parseState) {
+    if (!this.parseUntilStringTerminator_(parseState)) {
+      // The string sequence was too long.
+      return;
+    }
+
+    if (parseState.func == parseOSC) {
+      // We're not done parsing the string yet.
+      return;
+    }
+
+    // We're done.
+    var ary = parseState.args[0].match(/^(\d+);?(.*)$/);
+    if (ary) {
+      parseState.args[0] = ary[2];
+      this.dispatch('OSC', ary[1], parseState);
+    } else {
+      console.warn('Invalid OSC: ' + JSON.stringify(parseState.args[0]));
+    }
+
+    // Resetting the arguments isn't strictly necessary, but it makes debugging
+    // less confusing (otherwise args will stick around until the next sequence
+    // that needs arguments).
+    parseState.resetArguments();
+  }
+
+  parseState.func = parseOSC;
+};
+
+/**
+ * Privacy Message (PM).
+ *
+ * Will not implement.
+ */
+hterm.VT.CC1['\x9e'] =
+hterm.VT.ESC['^'] = function(parseState) {
+  parseState.resetArguments();
+  parseState.func = this.parseUntilStringTerminator_;
+};
+
+/**
+ * Application Program Control (APC).
+ *
+ * Will not implement.
+ */
+hterm.VT.CC1['\x9f'] =
+hterm.VT.ESC['_'] = function(parseState) {
+  parseState.resetArguments();
+  parseState.func = this.parseUntilStringTerminator_;
+};
+
+/**
+ * ESC \x20 - Unclear to me where these originated, possibly in xterm.
+ *
+ * Not currently implemented:
+ *   ESC \x20 F - Select 7 bit escape codes in responses (S7C1T).
+ *   ESC \x20 G - Select 8 bit escape codes in responses (S8C1T).
+ *                NB: We currently assume S7C1T always.
+ *
+ * Will not implement:
+ *   ESC \x20 L - Set ANSI conformance level 1.
+ *   ESC \x20 M - Set ANSI conformance level 2.
+ *   ESC \x20 N - Set ANSI conformance level 3.
+ */
+hterm.VT.ESC['\x20'] = function(parseState) {
+  parseState.func = function(parseState) {
+    var ch = parseState.consumeChar();
+    if (this.warnUnimplemented)
+      console.warn('Unimplemented sequence: ESC 0x20 ' + ch);
+    parseState.resetParseFunction();
+  };
+};
+
+/**
+ * DEC 'ESC #' sequences.
+ */
+hterm.VT.ESC['#'] = function(parseState) {
+  parseState.func = function(parseState) {
+    var ch = parseState.consumeChar();
+    if (ch == '8') {
+      // DEC Screen Alignment Test (DECALN).
+      this.terminal.setCursorPosition(0, 0);
+      this.terminal.fill('E');
+    }
+
+    parseState.resetParseFunction();
+  };
+};
+
+/**
+ * Designate Other Coding System (DOCS).
+ */
+hterm.VT.ESC['%'] = function(parseState) {
+  parseState.func = function(parseState) {
+    var ch = parseState.consumeChar();
+
+    // If we've locked the encoding, then just eat the bytes and return.
+    if (this.codingSystemLocked_) {
+      if (ch == '/')
+        parseState.consumeChar();
+      parseState.resetParseFunction();
+      return;
+    }
+
+    // Process the encoding requests.
+    switch (ch) {
+      case '@':
+        // Switch to ECMA 35.
+        this.setEncoding('iso-2022');
+        break;
+
+      case 'G':
+        // Switch to UTF-8.
+        this.setEncoding('utf-8');
+        break;
+
+      case '/':
+        // One way transition to something else.
+        ch = parseState.consumeChar();
+        switch (ch) {
+          case 'G':  // UTF-8 Level 1.
+          case 'H':  // UTF-8 Level 2.
+          case 'I':  // UTF-8 Level 3.
+            // We treat all UTF-8 levels the same.
+            this.setEncoding('utf-8-locked');
+            break;
+
+          default:
+            if (this.warnUnimplemented)
+              console.warn('Unknown ESC % / argument: ' + JSON.stringify(ch));
+            break;
+        }
+        break;
+
+      default:
+        if (this.warnUnimplemented)
+          console.warn('Unknown ESC % argument: ' + JSON.stringify(ch));
+        break;
+    }
+
+    parseState.resetParseFunction();
+  };
+};
+
+/**
+ * Character Set Selection (SCS).
+ *
+ *   ESC ( Ps - Set G0 character set (VT100).
+ *   ESC ) Ps - Set G1 character set (VT220).
+ *   ESC * Ps - Set G2 character set (VT220).
+ *   ESC + Ps - Set G3 character set (VT220).
+ *   ESC - Ps - Set G1 character set (VT300).
+ *   ESC . Ps - Set G2 character set (VT300).
+ *   ESC / Ps - Set G3 character set (VT300).
+ *
+ * All other sequences are echoed to the terminal.
+ */
+hterm.VT.ESC['('] =
+hterm.VT.ESC[')'] =
+hterm.VT.ESC['*'] =
+hterm.VT.ESC['+'] =
+hterm.VT.ESC['-'] =
+hterm.VT.ESC['.'] =
+hterm.VT.ESC['/'] = function(parseState, code) {
+  parseState.func = function(parseState) {
+    var ch = parseState.consumeChar();
+    if (ch == '\x1b') {
+      parseState.resetParseFunction();
+      parseState.func();
+      return;
+    }
+
+    var map = this.characterMaps.getMap(ch);
+    if (map !== undefined) {
+      if (code == '(') {
+        this.G0 = map;
+      } else if (code == ')' || code == '-') {
+        this.G1 = map;
+      } else if (code == '*' || code == '.') {
+        this.G2 = map;
+      } else if (code == '+' || code == '/') {
+        this.G3 = map;
+      }
+    } else if (this.warnUnimplemented) {
+      console.log('Invalid character set for "' + code + '": ' + ch);
+    }
+
+    parseState.resetParseFunction();
+  };
+};
+
+/**
+ * Back Index (DECBI).
+ *
+ * VT420 and up.  Not currently implemented.
+ */
+hterm.VT.ESC['6'] = hterm.VT.ignore;
+
+/**
+ * Save Cursor (DECSC).
+ */
+hterm.VT.ESC['7'] = function() {
+  this.terminal.saveCursorAndState();
+};
+
+/**
+ * Restore Cursor (DECRC).
+ */
+hterm.VT.ESC['8'] = function() {
+  this.terminal.restoreCursorAndState();
+};
+
+/**
+ * Forward Index (DECFI).
+ *
+ * VT210 and up.  Not currently implemented.
+ */
+hterm.VT.ESC['9'] = hterm.VT.ignore;
+
+/**
+ * Application keypad (DECKPAM).
+ */
+hterm.VT.ESC['='] = function() {
+  this.terminal.keyboard.applicationKeypad = true;
+};
+
+/**
+ * Normal keypad (DECKPNM).
+ */
+hterm.VT.ESC['>'] = function() {
+  this.terminal.keyboard.applicationKeypad = false;
+};
+
+/**
+ * Cursor to lower left corner of screen.
+ *
+ * Will not implement.
+ *
+ * This is only recognized by xterm when the hpLowerleftBugCompat resource is
+ * set.
+ */
+hterm.VT.ESC['F'] = hterm.VT.ignore;
+
+/**
+ * Full Reset (RIS).
+ */
+hterm.VT.ESC['c'] = function() {
+  this.terminal.reset();
+};
+
+/**
+ * Memory lock/unlock.
+ *
+ * Will not implement.
+ */
+hterm.VT.ESC['l'] =
+hterm.VT.ESC['m'] = hterm.VT.ignore;
+
+/**
+ * Lock Shift 2 (LS2)
+ *
+ * Invoke the G2 Character Set as GL.
+ */
+hterm.VT.ESC['n'] = function() {
+  this.GL = 'G2';
+};
+
+/**
+ * Lock Shift 3 (LS3)
+ *
+ * Invoke the G3 Character Set as GL.
+ */
+hterm.VT.ESC['o'] = function() {
+  this.GL = 'G3';
+};
+
+/**
+ * Lock Shift 2, Right (LS3R)
+ *
+ * Invoke the G3 Character Set as GR.
+ */
+hterm.VT.ESC['|'] = function() {
+  this.GR = 'G3';
+};
+
+/**
+ * Lock Shift 2, Right (LS2R)
+ *
+ * Invoke the G2 Character Set as GR.
+ */
+hterm.VT.ESC['}'] = function() {
+  this.GR = 'G2';
+};
+
+/**
+ * Lock Shift 1, Right (LS1R)
+ *
+ * Invoke the G1 Character Set as GR.
+ */
+hterm.VT.ESC['~'] = function() {
+  this.GR = 'G1';
+};
+
+/**
+ * Change icon name and window title.
+ *
+ * We only change the window title.
+ */
+hterm.VT.OSC['0'] = function(parseState) {
+  this.terminal.setWindowTitle(parseState.args[0]);
+};
+
+/**
+ * Change window title.
+ */
+hterm.VT.OSC['2'] = hterm.VT.OSC['0'];
+
+/**
+ * Set/read color palette.
+ */
+hterm.VT.OSC['4'] = function(parseState) {
+  // Args come in as a single 'index1;rgb1 ... ;indexN;rgbN' string.
+  // We split on the semicolon and iterate through the pairs.
+  var args = parseState.args[0].split(';');
+
+  var pairCount = parseInt(args.length / 2);
+  var colorPalette = this.terminal.getTextAttributes().colorPalette;
+  var responseArray = [];
+
+  for (var pairNumber = 0; pairNumber < pairCount; ++pairNumber) {
+    var colorIndex = parseInt(args[pairNumber * 2]);
+    var colorValue = args[pairNumber * 2 + 1];
+
+    if (colorIndex >= colorPalette.length)
+      continue;
+
+    if (colorValue == '?') {
+      // '?' means we should report back the current color value.
+      colorValue = lib.colors.rgbToX11(colorPalette[colorIndex]);
+      if (colorValue)
+        responseArray.push(colorIndex + ';' + colorValue);
+
+      continue;
+    }
+
+    colorValue = lib.colors.x11ToCSS(colorValue);
+    if (colorValue)
+      colorPalette[colorIndex] = colorValue;
+  }
+
+  if (responseArray.length)
+    this.terminal.io.sendString('\x1b]4;' + responseArray.join(';') + '\x07');
+};
+
+/**
+ * Hyperlinks.
+ *
+ * The first argument is optional and colon separated:
+ *   id=<id>
+ * The second argument is the link itself.
+ *
+ * Calling with a non-blank URI starts it.  A blank URI stops it.
+ *
+ * https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
+ */
+hterm.VT.OSC['8'] = function(parseState) {
+  const args = parseState.args[0].split(';');
+  let id = null;
+  let uri = null;
+
+  if (args.length != 2 || args[1].length == 0) {
+    // Reset link.
+  } else {
+    // Pull out any colon separated parameters in the first argument.
+    const params = args[0].split(':');
+    id = '';
+    params.forEach((param) => {
+      const idx = param.indexOf('=');
+      if (idx == -1)
+        return;
+
+      const key = param.slice(0, idx);
+      const value = param.slice(idx + 1);
+      switch (key) {
+        case 'id':
+          id = value;
+          break;
+        default:
+          // Ignore unknown keys.
+          break;
+      }
+    });
+
+    // The URI is in the second argument.
+    uri = args[1];
+  }
+
+  const attrs = this.terminal.getTextAttributes();
+  attrs.uri = uri;
+  attrs.uriId = id;
+};
+
+/**
+ * iTerm2 growl notifications.
+ */
+hterm.VT.OSC['9'] = function(parseState) {
+  // This just dumps the entire string as the message.
+  hterm.notify({'body': parseState.args[0]});
+};
+
+/**
+ * Change VT100 text foreground color.
+ */
+hterm.VT.OSC['10'] = function(parseState) {
+  // Args come in as a single string, but extra args will chain to the following
+  // OSC sequences.
+  var args = parseState.args[0].split(';');
+  if (!args)
+    return;
+
+  var colorArg;
+  var colorX11 = lib.colors.x11ToCSS(args.shift());
+  if (colorX11)
+    this.terminal.setForegroundColor(colorX11);
+
+  if (args.length > 0) {
+    parseState.args[0] = args.join(';');
+    hterm.VT.OSC['11'].apply(this, [parseState]);
+  }
+};
+
+/**
+ * Change VT100 text background color.
+ */
+hterm.VT.OSC['11'] = function(parseState) {
+  // Args come in as a single string, but extra args will chain to the following
+  // OSC sequences.
+  var args = parseState.args[0].split(';');
+  if (!args)
+    return;
+
+  var colorArg;
+  var colorX11 = lib.colors.x11ToCSS(args.shift());
+  if (colorX11)
+    this.terminal.setBackgroundColor(colorX11);
+
+  if (args.length > 0) {
+    parseState.args[0] = args.join(';');
+    hterm.VT.OSC['12'].apply(this, [parseState]);
+  }
+};
+
+/**
+ * Change text cursor color.
+ */
+hterm.VT.OSC['12'] = function(parseState) {
+  // Args come in as a single string, but extra args will chain to the following
+  // OSC sequences.
+  var args = parseState.args[0].split(';');
+  if (!args)
+    return;
+
+  var colorArg;
+  var colorX11 = lib.colors.x11ToCSS(args.shift());
+  if (colorX11)
+    this.terminal.setCursorColor(colorX11);
+
+  /* Note: If we support OSC 13+, we'd chain it here.
+  if (args.length > 0) {
+    parseState.args[0] = args.join(';');
+    hterm.VT.OSC['13'].apply(this, [parseState]);
+  }
+  */
+};
+
+/**
+ * Set the cursor shape.
+ *
+ * Parameter is expected to be in the form "CursorShape=number", where number is
+ * one of:
+ *
+ *   0 - Block
+ *   1 - I-Beam
+ *   2 - Underline
+ *
+ * This is a bit of a de-facto standard supported by iTerm 2 and Konsole.  See
+ * also: DECSCUSR.
+ *
+ * Invalid numbers will restore the cursor to the block shape.
+ */
+hterm.VT.OSC['50'] = function(parseState) {
+  var args = parseState.args[0].match(/CursorShape=(.)/i);
+  if (!args) {
+    console.warn('Could not parse OSC 50 args: ' + parseState.args[0]);
+    return;
+  }
+
+  switch (args[1]) {
+    case '1':  // CursorShape=1: I-Beam.
+      this.terminal.setCursorShape(hterm.Terminal.cursorShape.BEAM);
+      break;
+
+    case '2':  // CursorShape=2: Underline.
+      this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE);
+      break;
+
+    default:  // CursorShape=0: Block.
+      this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK);
+  }
+};
+
+/**
+ * Set/read system clipboard.
+ *
+ * Read is not implemented due to security considerations.  A remote app
+ * that is able to both write and read to the clipboard could essentially
+ * take over your session.
+ *
+ * The clipboard data will be decoded according to the 'receive-encoding'
+ * preference.
+ */
+hterm.VT.OSC['52'] = function(parseState) {
+  if (!this.enableClipboardWrite)
+    return;
+
+  // Args come in as a single 'clipboard;b64-data' string.  The clipboard
+  // parameter is used to select which of the X clipboards to address.  Since
+  // we're not integrating with X, we treat them all the same.
+  var args = parseState.args[0].match(/^[cps01234567]*;(.*)/);
+  if (!args)
+    return;
+
+  let data;
+  try {
+    data = window.atob(args[1]);
+  } catch (e) {
+    // If the user sent us invalid base64 content, silently ignore it.
+    return;
+  }
+  if (this.characterEncoding == 'utf-8') {
+    const decoder = new TextDecoder();
+    const bytes = lib.codec.stringToCodeUnitArray(data, Uint8Array);
+    data = decoder.decode(bytes);
+  }
+  if (data)
+    this.terminal.copyStringToClipboard(data);
+};
+
+/**
+ * Reset color palette.
+ */
+hterm.VT.OSC['104'] = function(parseState) {
+  const attrs = this.terminal.getTextAttributes();
+
+  // If there are no args, we reset the entire palette.
+  if (!parseState.args[0]) {
+    attrs.resetColorPalette();
+    return;
+  }
+
+  // Args come in as a single 'index1;index2;...;indexN' string.
+  // Split on the semicolon and iterate through the colors.
+  const args = parseState.args[0].split(';');
+  args.forEach((c) => attrs.resetColor(c));
+};
+
+/**
+ * Reset foreground color.
+ */
+hterm.VT.OSC['110'] = function(parseState) {
+  this.terminal.setForegroundColor();
+};
+
+/**
+ * Reset background color.
+ */
+hterm.VT.OSC['111'] = function(parseState) {
+  this.terminal.setBackgroundColor();
+};
+
+/**
+ * Reset text cursor color.
+ */
+hterm.VT.OSC['112'] = function(parseState) {
+  this.terminal.setCursorColor();
+};
+
+/**
+ * iTerm2 extended sequences.
+ *
+ * We only support image display atm.
+ */
+hterm.VT.OSC['1337'] = function(parseState) {
+  // Args come in as a set of key value pairs followed by data.
+  // File=name=<base64>;size=123;inline=1:<base64 data>
+  let args = parseState.args[0].match(/^File=([^:]*):([\s\S]*)$/m);
+  if (!args) {
+    if (this.warnUnimplemented)
+      console.log(`iTerm2 1337: unsupported sequence: ${args[1]}`);
+    return;
+  }
+
+  const options = {
+    name: '',
+    size: 0,
+    preserveAspectRatio: true,
+    inline: false,
+    width: 'auto',
+    height: 'auto',
+    align: 'left',
+    type: '',
+    buffer: lib.codec.stringToCodeUnitArray(atob(args[2]), Uint8Array).buffer,
+  };
+  // Walk the "key=value;" sets.
+  args[1].split(';').forEach((ele) => {
+    const kv = ele.match(/^([^=]+)=(.*)$/m);
+    if (!kv)
+      return;
+
+    // Sanitize values nicely.
+    switch (kv[1]) {
+      case 'name':
+        try {
+          options.name = window.atob(kv[2]);
+        } catch (e) {}
+        break;
+      case 'size':
+        try {
+          options.size = parseInt(kv[2]);
+        } catch (e) {}
+        break;
+      case 'width':
+        options.width = kv[2];
+        break;
+      case 'height':
+        options.height = kv[2];
+        break;
+      case 'preserveAspectRatio':
+        options.preserveAspectRatio = !(kv[2] == '0');
+        break;
+      case 'inline':
+        options.inline = !(kv[2] == '0');
+        break;
+      // hterm-specific keys.
+      case 'align':
+        options.align = kv[2];
+        break;
+      case 'type':
+        options.type = kv[2];
+        break;
+      default:
+        // Ignore unknown keys.  Don't want remote stuffing our JS env.
+        break;
+    }
+  });
+
+  // This is a bit of a hack.  If the buffer has data following the image, we
+  // need to delay processing of it until after we've finished with the image.
+  // Otherwise while we wait for the the image to load asynchronously, the new
+  // text data will intermingle with the image.
+  if (options.inline) {
+    const io = this.terminal.io;
+    const queued = parseState.peekRemainingBuf();
+    parseState.advance(queued.length);
+    this.terminal.displayImage(options);
+    io.print(queued);
+  } else
+    this.terminal.displayImage(options);
+};
+
+/**
+ * URxvt perl modules.
+ *
+ * This is the escape system used by rxvt-unicode and its perl modules.
+ * Obviously we don't support perl or custom modules, so we list a few common
+ * ones that we find useful.
+ *
+ * Technically there is no format here, but most modules obey:
+ * <module name>;<module args, usually ; delimited>
+ */
+hterm.VT.OSC['777'] = function(parseState) {
+  var ary;
+  var urxvtMod = parseState.args[0].split(';', 1)[0];
+
+  switch (urxvtMod) {
+    case 'notify':
+      // Format:
+      // notify;title;message
+      var title, message;
+      ary = parseState.args[0].match(/^[^;]+;([^;]*)(;([\s\S]*))?$/);
+      if (ary) {
+        title = ary[1];
+        message = ary[3];
+      }
+      hterm.notify({'title': title, 'body': message});
+      break;
+
+    default:
+      console.warn('Unknown urxvt module: ' + parseState.args[0]);
+      break;
+  }
+};
+
+/**
+ * Insert (blank) characters (ICH).
+ */
+hterm.VT.CSI['@'] = function(parseState) {
+  this.terminal.insertSpace(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Up (CUU).
+ */
+hterm.VT.CSI['A'] = function(parseState) {
+  this.terminal.cursorUp(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Down (CUD).
+ */
+hterm.VT.CSI['B'] = function(parseState) {
+  this.terminal.cursorDown(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Forward (CUF).
+ */
+hterm.VT.CSI['C'] = function(parseState) {
+  this.terminal.cursorRight(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Backward (CUB).
+ */
+hterm.VT.CSI['D'] = function(parseState) {
+  this.terminal.cursorLeft(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Next Line (CNL).
+ *
+ * This is like Cursor Down, except the cursor moves to the beginning of the
+ * line as well.
+ */
+hterm.VT.CSI['E'] = function(parseState) {
+  this.terminal.cursorDown(parseState.iarg(0, 1));
+  this.terminal.setCursorColumn(0);
+};
+
+/**
+ * Cursor Preceding Line (CPL).
+ *
+ * This is like Cursor Up, except the cursor moves to the beginning of the
+ * line as well.
+ */
+hterm.VT.CSI['F'] = function(parseState) {
+  this.terminal.cursorUp(parseState.iarg(0, 1));
+  this.terminal.setCursorColumn(0);
+};
+
+/**
+ * Cursor Horizontal Absolute (CHA).
+ *
+ * Xterm calls this Cursor Character Absolute.
+ */
+hterm.VT.CSI['G'] = function(parseState) {
+  this.terminal.setCursorColumn(parseState.iarg(0, 1) - 1);
+};
+
+/**
+ * Cursor Position (CUP).
+ */
+hterm.VT.CSI['H'] = function(parseState) {
+  this.terminal.setCursorPosition(parseState.iarg(0, 1) - 1,
+                                  parseState.iarg(1, 1) - 1);
+};
+
+/**
+ * Cursor Forward Tabulation (CHT).
+ */
+hterm.VT.CSI['I'] = function(parseState) {
+  var count = parseState.iarg(0, 1);
+  count = lib.f.clamp(count, 1, this.terminal.screenSize.width);
+  for (var i = 0; i < count; i++) {
+    this.terminal.forwardTabStop();
+  }
+};
+
+/**
+ * Erase in Display (ED, DECSED).
+ */
+hterm.VT.CSI['J'] =
+hterm.VT.CSI['?J'] = function(parseState, code) {
+  var arg = parseState.args[0];
+
+  if (!arg || arg == 0) {
+    this.terminal.eraseBelow();
+  } else if (arg == 1) {
+    this.terminal.eraseAbove();
+  } else if (arg == 2) {
+    this.terminal.clear();
+  } else if (arg == 3) {
+    if (this.enableCsiJ3) {
+      this.terminal.clearScrollback();
+    }
+  }
+};
+
+/**
+ * Erase in line (EL, DECSEL).
+ */
+hterm.VT.CSI['K'] =
+hterm.VT.CSI['?K'] = function(parseState, code) {
+  var arg = parseState.args[0];
+
+  if (!arg || arg == 0) {
+    this.terminal.eraseToRight();
+  } else if (arg == 1) {
+    this.terminal.eraseToLeft();
+  } else if (arg == 2) {
+    this.terminal.eraseLine();
+  }
+};
+
+/**
+ * Insert Lines (IL).
+ */
+hterm.VT.CSI['L'] = function(parseState) {
+  this.terminal.insertLines(parseState.iarg(0, 1));
+};
+
+/**
+ * Delete Lines (DL).
+ */
+hterm.VT.CSI['M'] = function(parseState) {
+  this.terminal.deleteLines(parseState.iarg(0, 1));
+};
+
+/**
+ * Delete Characters (DCH).
+ *
+ * This command shifts the line contents left, starting at the cursor position.
+ */
+hterm.VT.CSI['P'] = function(parseState) {
+  this.terminal.deleteChars(parseState.iarg(0, 1));
+};
+
+/**
+ * Scroll Up (SU).
+ */
+hterm.VT.CSI['S'] = function(parseState) {
+  this.terminal.vtScrollUp(parseState.iarg(0, 1));
+};
+
+/**
+ * Scroll Down (SD).
+ * Also 'Initiate highlight mouse tracking'.  Will not implement this part.
+ */
+hterm.VT.CSI['T'] = function(parseState) {
+  if (parseState.args.length <= 1)
+    this.terminal.vtScrollDown(parseState.iarg(0, 1));
+};
+
+/**
+ * Reset one or more features of the title modes to the default value.
+ *
+ *   ESC [ > Ps T
+ *
+ * Normally, "reset" disables the feature. It is possible to disable the
+ * ability to reset features by compiling a different default for the title
+ * modes into xterm.
+ *
+ * Ps values:
+ *   0 - Do not set window/icon labels using hexadecimal.
+ *   1 - Do not query window/icon labels using hexadecimal.
+ *   2 - Do not set window/icon labels using UTF-8.
+ *   3 - Do not query window/icon labels using UTF-8.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['>T'] = hterm.VT.ignore;
+
+/**
+ * Erase Characters (ECH).
+ */
+hterm.VT.CSI['X'] = function(parseState) {
+  this.terminal.eraseToRight(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Backward Tabulation (CBT).
+ */
+hterm.VT.CSI['Z'] = function(parseState) {
+  var count = parseState.iarg(0, 1);
+  count = lib.f.clamp(count, 1, this.terminal.screenSize.width);
+  for (var i = 0; i < count; i++) {
+    this.terminal.backwardTabStop();
+  }
+};
+
+/**
+ * Character Position Absolute (HPA).
+ *
+ * Same as Cursor Horizontal Absolute (CHA).
+ */
+hterm.VT.CSI['`'] = hterm.VT.CSI['G'];
+
+/**
+ * Character Position Relative (HPR).
+ */
+hterm.VT.CSI['a'] = function(parseState) {
+  this.terminal.setCursorColumn(this.terminal.getCursorColumn() +
+                                parseState.iarg(0, 1));
+};
+
+/**
+ * Repeat the preceding graphic character.
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['b'] = hterm.VT.ignore;
+
+/**
+ * Send Device Attributes (Primary DA).
+ *
+ * TODO(rginda): This is hardcoded to send back 'VT100 with Advanced Video
+ * Option', but it may be more correct to send a VT220 response once
+ * we fill out the 'Not currently implemented' parts.
+ */
+hterm.VT.CSI['c'] = function(parseState) {
+  if (!parseState.args[0] || parseState.args[0] == 0) {
+    this.terminal.io.sendString('\x1b[?1;2c');
+  }
+};
+
+/**
+ * Send Device Attributes (Secondary DA).
+ *
+ * TODO(rginda): This is hardcoded to send back 'VT100' but it may be more
+ * correct to send a VT220 response once we fill out more 'Not currently
+ * implemented' parts.
+ */
+hterm.VT.CSI['>c'] = function(parseState) {
+  this.terminal.io.sendString('\x1b[>0;256;0c');
+};
+
+/**
+ * Line Position Absolute (VPA).
+ */
+hterm.VT.CSI['d'] = function(parseState) {
+  this.terminal.setAbsoluteCursorRow(parseState.iarg(0, 1) - 1);
+};
+
+/**
+ * Horizontal and Vertical Position (HVP).
+ *
+ * Same as Cursor Position (CUP).
+ */
+hterm.VT.CSI['f'] = hterm.VT.CSI['H'];
+
+/**
+ * Tab Clear (TBC).
+ */
+hterm.VT.CSI['g'] = function(parseState) {
+  if (!parseState.args[0] || parseState.args[0] == 0) {
+    // Clear tab stop at cursor.
+    this.terminal.clearTabStopAtCursor(false);
+  } else if (parseState.args[0] == 3) {
+    // Clear all tab stops.
+    this.terminal.clearAllTabStops();
+  }
+};
+
+/**
+ * Set Mode (SM).
+ */
+hterm.VT.CSI['h'] = function(parseState) {
+  for (var i = 0; i < parseState.args.length; i++) {
+    this.setANSIMode(parseState.args[i], true);
+  }
+};
+
+/**
+ * DEC Private Mode Set (DECSET).
+ */
+hterm.VT.CSI['?h'] = function(parseState) {
+  for (var i = 0; i < parseState.args.length; i++) {
+    this.setDECMode(parseState.args[i], true);
+  }
+};
+
+/**
+ * Media Copy (MC).
+ * Media Copy (MC, DEC Specific).
+ *
+ * These commands control the printer.  Will not implement.
+ */
+hterm.VT.CSI['i'] =
+hterm.VT.CSI['?i'] = hterm.VT.ignore;
+
+/**
+ * Reset Mode (RM).
+ */
+hterm.VT.CSI['l'] = function(parseState) {
+  for (var i = 0; i < parseState.args.length; i++) {
+    this.setANSIMode(parseState.args[i], false);
+  }
+};
+
+/**
+ * DEC Private Mode Reset (DECRST).
+ */
+hterm.VT.CSI['?l'] = function(parseState) {
+  for (var i = 0; i < parseState.args.length; i++) {
+    this.setDECMode(parseState.args[i], false);
+  }
+};
+
+/**
+ * Parse extended SGR 38/48 sequences.
+ *
+ * This deals with the various ISO 8613-6 forms, and with legacy xterm forms
+ * that are common in the wider application world.
+ *
+ * @param {hterm.VT.ParseState} parseState The current input state.
+ * @param {number} i The argument in parseState to start processing.
+ * @param {hterm.TextAttributes} attrs The current text attributes.
+ * @return {Object} The skipCount member defines how many arguments to skip
+ *     (i.e. how many were processed), and the color member is the color that
+ *     was successfully processed, or undefined if not.
+ */
+hterm.VT.prototype.parseSgrExtendedColors = function(parseState, i, attrs) {
+  let ary;
+  let usedSubargs;
+
+  if (parseState.argHasSubargs(i)) {
+    // The ISO 8613-6 compliant form.
+    // e.g. 38:[color choice]:[arg1]:[arg2]:...
+    ary = parseState.args[i].split(':');
+    ary.shift();  // Remove "38".
+    usedSubargs = true;
+  } else if (parseState.argHasSubargs(i + 1)) {
+    // The xterm form which isn't ISO 8613-6 compliant.  Not many emulators
+    // support this, and others actively do not want to.  We'll ignore it so
+    // at least the rest of the stream works correctly.  e.g. 38;2:R:G:B
+    // We return 0 here so we only skip the "38" ... we can't be confident the
+    // next arg is actually supposed to be part of it vs a typo where the next
+    // arg is legit.
+    return {skipCount: 0};
+  } else {
+    // The xterm form which isn't ISO 8613-6 compliant, but many emulators
+    // support, and many applications rely on.
+    // e.g. 38;2;R;G;B
+    ary = parseState.args.slice(i + 1);
+    usedSubargs = false;
+  }
+
+  // Figure out which form to parse.
+  switch (parseInt(ary[0])) {
+    default:  // Unknown.
+    case 0:  // Implementation defined.  We ignore it.
+      return {skipCount: 0};
+
+    case 1: {  // Transparent color.
+      // Require ISO 8613-6 form.
+      if (!usedSubargs)
+        return {skipCount: 0};
+
+      return {
+        color: 'rgba(0, 0, 0, 0)',
+        skipCount: 0,
+      };
+    }
+
+    case 2: {  // RGB color.
+      // Skip over the color space identifier, if it exists.
+      let start;
+      if (usedSubargs) {
+        // The ISO 8613-6 compliant form:
+        //   38:2:<color space id>:R:G:B[:...]
+        // The xterm form isn't ISO 8613-6 compliant.
+        //   38:2:R:G:B
+        // Since the ISO 8613-6 form requires at least 5 arguments,
+        // we can still support the xterm form unambiguously.
+        if (ary.length == 4)
+          start = 1;
+        else
+          start = 2;
+      } else {
+        // The legacy xterm form: 38;2;R;G;B
+        start = 1;
+      }
+
+      // We need at least 3 args for RGB.  If we don't have them, assume this
+      // sequence is corrupted, so don't eat anything more.
+      // We ignore more than 3 args on purpose since ISO 8613-6 defines some,
+      // and we don't care about them.
+      if (ary.length < start + 3)
+        return {skipCount: 0};
+
+      const r = parseState.parseInt(ary[start + 0]);
+      const g = parseState.parseInt(ary[start + 1]);
+      const b = parseState.parseInt(ary[start + 2]);
+      return {
+        color: `rgb(${r}, ${g}, ${b})`,
+        skipCount: usedSubargs ? 0 : 4,
+      };
+    }
+
+    case 3: {  // CMY color.
+      // No need to support xterm/legacy forms as xterm doesn't support CMY.
+      if (!usedSubargs)
+        return {skipCount: 0};
+
+      // We need at least 4 args for CMY.  If we don't have them, assume
+      // this sequence is corrupted.  We ignore the color space identifier,
+      // tolerance, etc...
+      if (ary.length < 4)
+        return {skipCount: 0};
+
+      // TODO: See CMYK below.
+      const c = parseState.parseInt(ary[1]);
+      const m = parseState.parseInt(ary[2]);
+      const y = parseState.parseInt(ary[3]);
+      return {skipCount: 0};
+    }
+
+    case 4: {  // CMYK color.
+      // No need to support xterm/legacy forms as xterm doesn't support CMYK.
+      if (!usedSubargs)
+        return {skipCount: 0};
+
+      // We need at least 5 args for CMYK.  If we don't have them, assume
+      // this sequence is corrupted.  We ignore the color space identifier,
+      // tolerance, etc...
+      if (ary.length < 5)
+        return {skipCount: 0};
+
+      // TODO: Implement this.
+      // Might wait until CSS4 is adopted for device-cmyk():
+      // https://www.w3.org/TR/css-color-4/#cmyk-colors
+      // Or normalize it to RGB ourselves:
+      // https://www.w3.org/TR/css-color-4/#cmyk-rgb
+      const c = parseState.parseInt(ary[1]);
+      const m = parseState.parseInt(ary[2]);
+      const y = parseState.parseInt(ary[3]);
+      const k = parseState.parseInt(ary[4]);
+      return {skipCount: 0};
+    }
+
+    case 5: {  // Color palette index.
+      // If we're short on args, assume this sequence is corrupted, so don't
+      // eat anything more.
+      if (ary.length < 2)
+        return {skipCount: 0};
+
+      // Support 38:5:P (ISO 8613-6) and 38;5;P (xterm/legacy).
+      // We also ignore extra args with 38:5:P:[...], but more for laziness.
+      const ret = {
+        skipCount: usedSubargs ? 0 : 2,
+      };
+      const color = parseState.parseInt(ary[1]);
+      if (color < attrs.colorPalette.length)
+        ret.color = color;
+      return ret;
+    }
+  }
+};
+
+/**
+ * Character Attributes (SGR).
+ *
+ * Iterate through the list of arguments, applying the attribute changes based
+ * on the argument value...
+ */
+hterm.VT.CSI['m'] = function(parseState) {
+  var attrs = this.terminal.getTextAttributes();
+
+  if (!parseState.args.length) {
+    attrs.reset();
+    return;
+  }
+
+  for (var i = 0; i < parseState.args.length; i++) {
+    // If this argument has subargs (i.e. it has args followed by colons),
+    // the iarg logic will implicitly truncate that off for us.
+    var arg = parseState.iarg(i, 0);
+
+    if (arg < 30) {
+      if (arg == 0) {  // Normal (default).
+        attrs.reset();
+      } else if (arg == 1) {  // Bold.
+        attrs.bold = true;
+      } else if (arg == 2) {  // Faint.
+        attrs.faint = true;
+      } else if (arg == 3) {  // Italic.
+        attrs.italic = true;
+      } else if (arg == 4) {  // Underline.
+        if (parseState.argHasSubargs(i)) {
+          const uarg = parseState.args[i].split(':')[1];
+          if (uarg == 0)
+            attrs.underline = false;
+          else if (uarg == 1)
+            attrs.underline = 'solid';
+          else if (uarg == 2)
+            attrs.underline = 'double';
+          else if (uarg == 3)
+            attrs.underline = 'wavy';
+          else if (uarg == 4)
+            attrs.underline = 'dotted';
+          else if (uarg == 5)
+            attrs.underline = 'dashed';
+        } else {
+          attrs.underline = 'solid';
+        }
+      } else if (arg == 5) {  // Blink.
+        attrs.blink = true;
+      } else if (arg == 7) {  // Inverse.
+        attrs.inverse = true;
+      } else if (arg == 8) {  // Invisible.
+        attrs.invisible = true;
+      } else if (arg == 9) {  // Crossed out.
+        attrs.strikethrough = true;
+      } else if (arg == 21) {  // Double underlined.
+        attrs.underline = 'double';
+      } else if (arg == 22) {  // Not bold & not faint.
+        attrs.bold = false;
+        attrs.faint = false;
+      } else if (arg == 23) {  // Not italic.
+        attrs.italic = false;
+      } else if (arg == 24) {  // Not underlined.
+        attrs.underline = false;
+      } else if (arg == 25) {  // Not blink.
+        attrs.blink = false;
+      } else if (arg == 27) {  // Steady.
+        attrs.inverse = false;
+      } else if (arg == 28) {  // Visible.
+        attrs.invisible = false;
+      } else if (arg == 29) {  // Not crossed out.
+        attrs.strikethrough = false;
+      }
+
+    } else if (arg < 50) {
+      // Select fore/background color from bottom half of 16 color palette
+      // or from the 256 color palette or alternative specify color in fully
+      // qualified rgb(r, g, b) form.
+      if (arg < 38) {
+        attrs.foregroundSource = arg - 30;
+
+      } else if (arg == 38) {
+        const result = this.parseSgrExtendedColors(parseState, i, attrs);
+        if (result.color !== undefined)
+          attrs.foregroundSource = result.color;
+        i += result.skipCount;
+
+      } else if (arg == 39) {
+        attrs.foregroundSource = attrs.SRC_DEFAULT;
+
+      } else if (arg < 48) {
+        attrs.backgroundSource = arg - 40;
+
+      } else if (arg == 48) {
+        const result = this.parseSgrExtendedColors(parseState, i, attrs);
+        if (result.color !== undefined)
+          attrs.backgroundSource = result.color;
+        i += result.skipCount;
+
+      } else {
+        attrs.backgroundSource = attrs.SRC_DEFAULT;
+      }
+
+    } else if (arg == 58) {  // Underline coloring.
+      const result = this.parseSgrExtendedColors(parseState, i, attrs);
+      if (result.color !== undefined)
+        attrs.underlineSource = result.color;
+      i += result.skipCount;
+
+    } else if (arg == 59) {  // Disable underline coloring.
+      attrs.underlineSource = attrs.SRC_DEFAULT;
+
+    } else if (arg >= 90 && arg <= 97) {
+      attrs.foregroundSource = arg - 90 + 8;
+
+    } else if (arg >= 100 && arg <= 107) {
+      attrs.backgroundSource = arg - 100 + 8;
+    }
+  }
+
+  attrs.setDefaults(this.terminal.getForegroundColor(),
+                    this.terminal.getBackgroundColor());
+};
+
+// SGR calls can handle subargs.
+hterm.VT.CSI['m'].supportsSubargs = true;
+
+/**
+ * Set xterm-specific keyboard modes.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['>m'] = hterm.VT.ignore;
+
+/**
+ * Device Status Report (DSR, DEC Specific).
+ *
+ * 5 - Status Report. Result (OK) is CSI 0 n
+ * 6 - Report Cursor Position (CPR) [row;column]. Result is CSI r ; c R
+ */
+hterm.VT.CSI['n'] = function(parseState) {
+  if (parseState.args[0] == 5) {
+    this.terminal.io.sendString('\x1b0n');
+  } else if (parseState.args[0] == 6) {
+    var row = this.terminal.getCursorRow() + 1;
+    var col = this.terminal.getCursorColumn() + 1;
+    this.terminal.io.sendString('\x1b[' + row + ';' + col + 'R');
+  }
+};
+
+/**
+ * Disable modifiers which may be enabled via CSI['>m'].
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['>n'] = hterm.VT.ignore;
+
+/**
+ * Device Status Report (DSR, DEC Specific).
+ *
+ * 6  - Report Cursor Position (CPR) [row;column] as CSI ? r ; c R
+ * 15 - Report Printer status as CSI ? 1 0 n (ready) or
+ *      CSI ? 1 1 n (not ready).
+ * 25 - Report UDK status as CSI ? 2 0 n (unlocked) or CSI ? 2 1 n (locked).
+ * 26 - Report Keyboard status as CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).
+ *      The last two parameters apply to VT400 & up, and denote keyboard ready
+ *      and LK01 respectively.
+ * 53 - Report Locator status as CSI ? 5 3 n Locator available, if compiled-in,
+ *      or CSI ? 5 0 n No Locator, if not.
+ */
+hterm.VT.CSI['?n'] = function(parseState) {
+  if (parseState.args[0] == 6) {
+    var row = this.terminal.getCursorRow() + 1;
+    var col = this.terminal.getCursorColumn() + 1;
+    this.terminal.io.sendString('\x1b[' + row + ';' + col + 'R');
+  } else if (parseState.args[0] == 15) {
+    this.terminal.io.sendString('\x1b[?11n');
+  } else if (parseState.args[0] == 25) {
+    this.terminal.io.sendString('\x1b[?21n');
+  } else if (parseState.args[0] == 26) {
+    this.terminal.io.sendString('\x1b[?12;1;0;0n');
+  } else if (parseState.args[0] == 53) {
+    this.terminal.io.sendString('\x1b[?50n');
+  }
+};
+
+/**
+ * This is used by xterm to decide whether to hide the pointer cursor as the
+ * user types.
+ *
+ * Valid values for the parameter:
+ *   0 - Never hide the pointer.
+ *   1 - Hide if the mouse tracking mode is not enabled.
+ *   2 - Always hide the pointer.
+ *
+ * If no parameter is given, xterm uses the default, which is 1.
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['>p'] = hterm.VT.ignore;
+
+/**
+ * Soft terminal reset (DECSTR).
+ */
+hterm.VT.CSI['!p'] = function() {
+  this.terminal.softReset();
+};
+
+/**
+ * Request ANSI Mode (DECRQM).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['$p'] = hterm.VT.ignore;
+hterm.VT.CSI['?$p'] = hterm.VT.ignore;
+
+/**
+ * Set conformance level (DECSCL).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['"p'] = hterm.VT.ignore;
+
+/**
+ * Load LEDs (DECLL).
+ *
+ * Not currently implemented.  Could be implemented as virtual LEDs overlaying
+ * the terminal if anyone cares.
+ */
+hterm.VT.CSI['q'] = hterm.VT.ignore;
+
+/**
+ * Set cursor style (DECSCUSR, VT520).
+ */
+hterm.VT.CSI[' q'] = function(parseState) {
+  var arg = parseState.args[0];
+
+  if (arg == 0 || arg == 1) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK);
+    this.terminal.setCursorBlink(true);
+  } else if (arg == 2) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK);
+    this.terminal.setCursorBlink(false);
+  } else if (arg == 3) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE);
+    this.terminal.setCursorBlink(true);
+  } else if (arg == 4) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE);
+    this.terminal.setCursorBlink(false);
+  } else if (arg == 5) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.BEAM);
+    this.terminal.setCursorBlink(true);
+  } else if (arg == 6) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.BEAM);
+    this.terminal.setCursorBlink(false);
+  } else {
+    console.warn('Unknown cursor style: ' + arg);
+  }
+};
+
+/**
+ * Select character protection attribute (DECSCA).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['"q'] = hterm.VT.ignore;
+
+/**
+ * Set Scrolling Region (DECSTBM).
+ */
+hterm.VT.CSI['r'] = function(parseState) {
+  var args = parseState.args;
+  var scrollTop = args[0] ? parseInt(args[0], 10) -1 : null;
+  var scrollBottom = args[1] ? parseInt(args[1], 10) - 1 : null;
+  this.terminal.setVTScrollRegion(scrollTop, scrollBottom);
+  this.terminal.setCursorPosition(0, 0);
+};
+
+/**
+ * Restore DEC Private Mode Values.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['?r'] = hterm.VT.ignore;
+
+/**
+ * Change Attributes in Rectangular Area (DECCARA)
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$r'] = hterm.VT.ignore;
+
+/**
+ * Save cursor (ANSI.SYS)
+ */
+hterm.VT.CSI['s'] = function() {
+  this.terminal.saveCursorAndState();
+};
+
+/**
+ * Save DEC Private Mode Values.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['?s'] = hterm.VT.ignore;
+
+/**
+ * Window manipulation (from dtterm, as well as extensions).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['t'] = hterm.VT.ignore;
+
+/**
+ * Reverse Attributes in Rectangular Area (DECRARA).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$t'] = hterm.VT.ignore;
+
+/**
+ * Set one or more features of the title modes.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['>t'] = hterm.VT.ignore;
+
+/**
+ * Set warning-bell volume (DECSWBV, VT520).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI[' t'] = hterm.VT.ignore;
+
+/**
+ * Restore cursor (ANSI.SYS).
+ */
+hterm.VT.CSI['u'] = function() {
+  this.terminal.restoreCursorAndState();
+};
+
+/**
+ * Set margin-bell volume (DECSMBV, VT520).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI[' u'] = hterm.VT.ignore;
+
+/**
+ * Copy Rectangular Area (DECCRA, VT400 and up).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$v'] = hterm.VT.ignore;
+
+/**
+ * Enable Filter Rectangle (DECEFR).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['\'w'] = hterm.VT.ignore;
+
+/**
+ * Request Terminal Parameters (DECREQTPARM).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['x'] = hterm.VT.ignore;
+
+/**
+ * Select Attribute Change Extent (DECSACE).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['*x'] = hterm.VT.ignore;
+
+/**
+ * Fill Rectangular Area (DECFRA), VT420 and up.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$x'] = hterm.VT.ignore;
+
+/**
+ * vt_tiledata (as used by NAOhack and UnNetHack)
+ * (see https://nethackwiki.com/wiki/Vt_tiledata for more info)
+ *
+ * Implemented as far as we care (start a glyph and end a glyph).
+ */
+hterm.VT.CSI['z'] = function(parseState) {
+  if (parseState.args.length < 1)
+    return;
+  var arg = parseState.args[0];
+  if (arg == 0) {
+    // Start a glyph (one parameter, the glyph number).
+    if (parseState.args.length < 2)
+      return;
+    this.terminal.getTextAttributes().tileData = parseState.args[1];
+  } else if (arg == 1) {
+    // End a glyph.
+    this.terminal.getTextAttributes().tileData = null;
+  }
+};
+
+/**
+ * Enable Locator Reporting (DECELR).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['\'z'] = hterm.VT.ignore;
+
+/**
+ * Erase Rectangular Area (DECERA), VT400 and up.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$z'] = hterm.VT.ignore;
+
+/**
+ * Select Locator Events (DECSLE).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['\'{'] = hterm.VT.ignore;
+
+/**
+ * Request Locator Position (DECRQLP).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['\'|'] = hterm.VT.ignore;
+
+/**
+ * Insert Columns (DECIC), VT420 and up.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['\'}'] = hterm.VT.ignore;
+
+/**
+ * Delete P s Columns (DECDC), VT420 and up.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['\'~'] = hterm.VT.ignore;
+// SOURCE FILE: hterm/js/hterm_vt_character_map.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Character map object.
+ *
+ * Mapping from received to display character, used depending on the active
+ * VT character set.
+ *
+ * GR maps are not currently supported.
+ *
+ * @param {string} description A human readable description of this map.
+ * @param {Object} glmap The GL mapping from input to output characters.
+ */
+hterm.VT.CharacterMap = function(description, glmap) {
+  /**
+   * Short description for this character set, useful for debugging.
+   */
+  this.description = description;
+
+  /**
+   * The function to call to when this map is installed in GL.
+   */
+  this.GL = null;
+
+  // Always keep an unmodified reference to the map.
+  // This allows us to sanely reset back to the original state.
+  this.glmapBase_ = glmap;
+
+  // Now sync the internal state as needed.
+  this.sync_();
+};
+
+/**
+ * Internal helper for resyncing internal state.
+ *
+ * Used when the mappings change.
+ *
+ * @param {Object?} opt_glmap Additional mappings to overlay on top of the
+ *     base mapping.
+ */
+hterm.VT.CharacterMap.prototype.sync_ = function(opt_glmap) {
+  // If there are no maps, then reset the state back.
+  if (!this.glmapBase_ && !opt_glmap) {
+    this.GL = null;
+    delete this.glmap_;
+    delete this.glre_;
+    return;
+  }
+
+  // Set the the GL mapping.  If we're given a custom mapping, then create a
+  // new object to hold the merged map.  This way we can cleanly reset back.
+  if (opt_glmap)
+    this.glmap_ = Object.assign({}, this.glmapBase_, opt_glmap);
+  else
+    this.glmap_ = this.glmapBase_;
+
+  var glchars = Object.keys(this.glmap_).map((key) =>
+      '\\x' + lib.f.zpad(key.charCodeAt(0).toString(16)));
+  this.glre_ = new RegExp('[' + glchars.join('') + ']', 'g');
+
+  this.GL = (str) => str.replace(this.glre_, (ch) => this.glmap_[ch]);
+};
+
+/**
+ * Reset map back to original mappings (discarding runtime updates).
+ *
+ * Specifically, any calls to setOverrides will be discarded.
+ */
+hterm.VT.CharacterMap.prototype.reset = function() {
+  // If we haven't been given a custom mapping, then there's nothing to reset.
+  if (this.glmap_ !== this.glmapBase_)
+    this.sync_();
+};
+
+/**
+ * Merge custom changes to this map.
+ *
+ * The input map need not duplicate the existing mappings as it is merged with
+ * the existing base map (what was created with).  Subsequent calls to this
+ * will throw away previous override settings.
+ *
+ * @param {Object} glmap The custom map to override existing mappings.
+ */
+hterm.VT.CharacterMap.prototype.setOverrides = function(glmap) {
+  this.sync_(glmap);
+};
+
+/**
+ * Return a copy of this mapping.
+ *
+ * @return {hterm.VT.CharacterMap} A new hterm.VT.CharacterMap instance.
+ */
+hterm.VT.CharacterMap.prototype.clone = function() {
+  var map = new hterm.VT.CharacterMap(this.description, this.glmapBase_);
+  if (this.glmap_ !== this.glmapBase_)
+    map.setOverrides(this.glmap_);
+  return map;
+};
+
+/**
+ * Table of character maps.
+ */
+hterm.VT.CharacterMaps = function() {
+  this.maps_ = hterm.VT.CharacterMaps.DefaultMaps;
+
+  // Always keep an unmodified reference to the map.
+  // This allows us to sanely reset back to the original state.
+  this.mapsBase_ = this.maps_;
+};
+
+/**
+ * Look up a previously registered map.
+ *
+ * @param {String} name The name of the map to lookup.
+ * @return {hterm.VT.CharacterMap} The map, if it's been registered.
+ */
+hterm.VT.CharacterMaps.prototype.getMap = function(name) {
+  if (this.maps_.hasOwnProperty(name))
+    return this.maps_[name];
+  else
+    return undefined;
+};
+
+/**
+ * Register a new map.
+ *
+ * Any previously registered maps by this name will be discarded.
+ *
+ * @param {String} name The name of the map.
+ * @param {hterm.VT.CharacterMap} map The map to register.
+ */
+hterm.VT.CharacterMaps.prototype.addMap = function(name, map) {
+  if (this.maps_ === this.mapsBase_)
+    this.maps_ = Object.assign({}, this.mapsBase_);
+  this.maps_[name] = map;
+};
+
+/**
+ * Reset the table and all its maps back to original state.
+ */
+hterm.VT.CharacterMaps.prototype.reset = function() {
+  if (this.maps_ !== hterm.VT.CharacterMaps.DefaultMaps)
+    this.maps_ = hterm.VT.CharacterMaps.DefaultMaps;
+};
+
+/**
+ * Merge custom changes to this table.
+ *
+ * @param {Object} maps A set of hterm.VT.CharacterMap objects.
+ */
+hterm.VT.CharacterMaps.prototype.setOverrides = function(maps) {
+  if (this.maps_ === this.mapsBase_)
+    this.maps_ = Object.assign({}, this.mapsBase_);
+
+  for (var name in maps) {
+    var map = this.getMap(name);
+    if (map !== undefined) {
+      this.maps_[name] = map.clone();
+      this.maps_[name].setOverrides(maps[name]);
+    } else
+      this.addMap(name, new hterm.VT.CharacterMap('user ' + name, maps[name]));
+  }
+};
+
+/**
+ * The default set of supported character maps.
+ */
+hterm.VT.CharacterMaps.DefaultMaps = {};
+
+/**
+ * VT100 Graphic character map.
+ * http://vt100.net/docs/vt220-rm/table2-4.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['0'] = new hterm.VT.CharacterMap(
+    'graphic', {
+      '\x60':'\u25c6',  // ` -> diamond
+      '\x61':'\u2592',  // a -> grey-box
+      '\x62':'\u2409',  // b -> h/t
+      '\x63':'\u240c',  // c -> f/f
+      '\x64':'\u240d',  // d -> c/r
+      '\x65':'\u240a',  // e -> l/f
+      '\x66':'\u00b0',  // f -> degree
+      '\x67':'\u00b1',  // g -> +/-
+      '\x68':'\u2424',  // h -> n/l
+      '\x69':'\u240b',  // i -> v/t
+      '\x6a':'\u2518',  // j -> bottom-right
+      '\x6b':'\u2510',  // k -> top-right
+      '\x6c':'\u250c',  // l -> top-left
+      '\x6d':'\u2514',  // m -> bottom-left
+      '\x6e':'\u253c',  // n -> line-cross
+      '\x6f':'\u23ba',  // o -> scan1
+      '\x70':'\u23bb',  // p -> scan3
+      '\x71':'\u2500',  // q -> scan5
+      '\x72':'\u23bc',  // r -> scan7
+      '\x73':'\u23bd',  // s -> scan9
+      '\x74':'\u251c',  // t -> left-tee
+      '\x75':'\u2524',  // u -> right-tee
+      '\x76':'\u2534',  // v -> bottom-tee
+      '\x77':'\u252c',  // w -> top-tee
+      '\x78':'\u2502',  // x -> vertical-line
+      '\x79':'\u2264',  // y -> less-equal
+      '\x7a':'\u2265',  // z -> greater-equal
+      '\x7b':'\u03c0',  // { -> pi
+      '\x7c':'\u2260',  // | -> not-equal
+      '\x7d':'\u00a3',  // } -> british-pound
+      '\x7e':'\u00b7',  // ~ -> dot
+    });
+
+/**
+ * British character map.
+ * http://vt100.net/docs/vt220-rm/table2-5.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['A'] = new hterm.VT.CharacterMap(
+    'british', {
+      '\x23': '\u00a3',  // # -> british-pound
+    });
+
+/**
+ * US ASCII map, no changes.
+ */
+hterm.VT.CharacterMaps.DefaultMaps['B'] = new hterm.VT.CharacterMap(
+    'us', null);
+
+/**
+ * Dutch character map.
+ * http://vt100.net/docs/vt220-rm/table2-6.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['4'] = new hterm.VT.CharacterMap(
+    'dutch', {
+      '\x23': '\u00a3',  // # -> british-pound
+
+      '\x40': '\u00be',  // @ -> 3/4
+
+      '\x5b': '\u0132',  // [ -> 'ij' ligature (xterm goes with \u00ff?)
+      '\x5c': '\u00bd',  // \ -> 1/2
+      '\x5d': '\u007c',  // ] -> vertical bar
+
+      '\x7b': '\u00a8',  // { -> two dots
+      '\x7c': '\u0066',  // | -> f
+      '\x7d': '\u00bc',  // } -> 1/4
+      '\x7e': '\u00b4',  // ~ -> acute
+    });
+
+/**
+ * Finnish character map.
+ * http://vt100.net/docs/vt220-rm/table2-7.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['C'] =
+hterm.VT.CharacterMaps.DefaultMaps['5'] = new hterm.VT.CharacterMap(
+    'finnish', {
+      '\x5b': '\u00c4',  // [ -> 'A' umlaut
+      '\x5c': '\u00d6',  // \ -> 'O' umlaut
+      '\x5d': '\u00c5',  // ] -> 'A' ring
+      '\x5e': '\u00dc',  // ~ -> 'u' umlaut
+
+      '\x60': '\u00e9',  // ` -> 'e' acute
+
+      '\x7b': '\u00e4',  // { -> 'a' umlaut
+      '\x7c': '\u00f6',  // | -> 'o' umlaut
+      '\x7d': '\u00e5',  // } -> 'a' ring
+      '\x7e': '\u00fc',  // ~ -> 'u' umlaut
+    });
+
+/**
+ * French character map.
+ * http://vt100.net/docs/vt220-rm/table2-8.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['R'] = new hterm.VT.CharacterMap(
+    'french', {
+      '\x23': '\u00a3',  // # -> british-pound
+
+      '\x40': '\u00e0',  // @ -> 'a' grave
+
+      '\x5b': '\u00b0',  // [ -> ring
+      '\x5c': '\u00e7',  // \ -> 'c' cedilla
+      '\x5d': '\u00a7',  // ] -> section symbol (double s)
+
+      '\x7b': '\u00e9',  // { -> 'e' acute
+      '\x7c': '\u00f9',  // | -> 'u' grave
+      '\x7d': '\u00e8',  // } -> 'e' grave
+      '\x7e': '\u00a8',  // ~ -> umlaut
+    });
+
+/**
+ * French Canadian character map.
+ * http://vt100.net/docs/vt220-rm/table2-9.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['Q'] = new hterm.VT.CharacterMap(
+    'french canadian', {
+      '\x40': '\u00e0',  // @ -> 'a' grave
+
+      '\x5b': '\u00e2',  // [ -> 'a' circumflex
+      '\x5c': '\u00e7',  // \ -> 'c' cedilla
+      '\x5d': '\u00ea',  // ] -> 'e' circumflex
+      '\x5e': '\u00ee',  // ^ -> 'i' circumflex
+
+      '\x60': '\u00f4',  // ` -> 'o' circumflex
+
+      '\x7b': '\u00e9',  // { -> 'e' acute
+      '\x7c': '\u00f9',  // | -> 'u' grave
+      '\x7d': '\u00e8',  // } -> 'e' grave
+      '\x7e': '\u00fb',  // ~ -> 'u' circumflex
+    });
+
+/**
+ * German character map.
+ * http://vt100.net/docs/vt220-rm/table2-10.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['K'] = new hterm.VT.CharacterMap(
+    'german', {
+      '\x40': '\u00a7',  // @ -> section symbol (double s)
+
+      '\x5b': '\u00c4',  // [ -> 'A' umlaut
+      '\x5c': '\u00d6',  // \ -> 'O' umlaut
+      '\x5d': '\u00dc',  // ] -> 'U' umlaut
+
+      '\x7b': '\u00e4',  // { -> 'a' umlaut
+      '\x7c': '\u00f6',  // | -> 'o' umlaut
+      '\x7d': '\u00fc',  // } -> 'u' umlaut
+      '\x7e': '\u00df',  // ~ -> eszett
+    });
+
+/**
+ * Italian character map.
+ * http://vt100.net/docs/vt220-rm/table2-11.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['Y'] = new hterm.VT.CharacterMap(
+    'italian', {
+      '\x23': '\u00a3',  // # -> british-pound
+
+      '\x40': '\u00a7',  // @ -> section symbol (double s)
+
+      '\x5b': '\u00b0',  // [ -> ring
+      '\x5c': '\u00e7',  // \ -> 'c' cedilla
+      '\x5d': '\u00e9',  // ] -> 'e' acute
+
+      '\x60': '\u00f9',  // ` -> 'u' grave
+
+      '\x7b': '\u00e0',  // { -> 'a' grave
+      '\x7c': '\u00f2',  // | -> 'o' grave
+      '\x7d': '\u00e8',  // } -> 'e' grave
+      '\x7e': '\u00ec',  // ~ -> 'i' grave
+    });
+
+/**
+ * Norwegian/Danish character map.
+ * http://vt100.net/docs/vt220-rm/table2-12.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['E'] =
+hterm.VT.CharacterMaps.DefaultMaps['6'] = new hterm.VT.CharacterMap(
+    'norwegian/danish', {
+      '\x40': '\u00c4',  // @ -> 'A' umlaut
+
+      '\x5b': '\u00c6',  // [ -> 'AE' ligature
+      '\x5c': '\u00d8',  // \ -> 'O' stroke
+      '\x5d': '\u00c5',  // ] -> 'A' ring
+      '\x5e': '\u00dc',  // ^ -> 'U' umlaut
+
+      '\x60': '\u00e4',  // ` -> 'a' umlaut
+
+      '\x7b': '\u00e6',  // { -> 'ae' ligature
+      '\x7c': '\u00f8',  // | -> 'o' stroke
+      '\x7d': '\u00e5',  // } -> 'a' ring
+      '\x7e': '\u00fc',  // ~ -> 'u' umlaut
+    });
+
+/**
+ * Spanish character map.
+ * http://vt100.net/docs/vt220-rm/table2-13.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['Z'] = new hterm.VT.CharacterMap(
+    'spanish', {
+      '\x23': '\u00a3',  // # -> british-pound
+
+      '\x40': '\u00a7',  // @ -> section symbol (double s)
+
+      '\x5b': '\u00a1',  // [ -> '!' inverted
+      '\x5c': '\u00d1',  // \ -> 'N' tilde
+      '\x5d': '\u00bf',  // ] -> '?' inverted
+
+      '\x7b': '\u00b0',  // { -> ring
+      '\x7c': '\u00f1',  // | -> 'n' tilde
+      '\x7d': '\u00e7',  // } -> 'c' cedilla
+    });
+
+/**
+ * Swedish character map.
+ * http://vt100.net/docs/vt220-rm/table2-14.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['7'] =
+hterm.VT.CharacterMaps.DefaultMaps['H'] = new hterm.VT.CharacterMap(
+    'swedish', {
+      '\x40': '\u00c9',  // @ -> 'E' acute
+
+      '\x5b': '\u00c4',  // [ -> 'A' umlaut
+      '\x5c': '\u00d6',  // \ -> 'O' umlaut
+      '\x5d': '\u00c5',  // ] -> 'A' ring
+      '\x5e': '\u00dc',  // ^ -> 'U' umlaut
+
+      '\x60': '\u00e9',  // ` -> 'e' acute
+
+      '\x7b': '\u00e4',  // { -> 'a' umlaut
+      '\x7c': '\u00f6',  // | -> 'o' umlaut
+      '\x7d': '\u00e5',  // } -> 'a' ring
+      '\x7e': '\u00fc',  // ~ -> 'u' umlaut
+    });
+
+/**
+ * Swiss character map.
+ * http://vt100.net/docs/vt220-rm/table2-15.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['='] = new hterm.VT.CharacterMap(
+    'swiss', {
+      '\x23': '\u00f9',  // # -> 'u' grave
+
+      '\x40': '\u00e0',  // @ -> 'a' grave
+
+      '\x5b': '\u00e9',  // [ -> 'e' acute
+      '\x5c': '\u00e7',  // \ -> 'c' cedilla
+      '\x5d': '\u00ea',  // ] -> 'e' circumflex
+      '\x5e': '\u00ee',  // ^ -> 'i' circumflex
+      '\x5f': '\u00e8',  // _ -> 'e' grave
+
+      '\x60': '\u00f4',  // ` -> 'o' circumflex
+
+      '\x7b': '\u00e4',  // { -> 'a' umlaut
+      '\x7c': '\u00f6',  // | -> 'o' umlaut
+      '\x7d': '\u00fc',  // } -> 'u' umlaut
+      '\x7e': '\u00fb',  // ~ -> 'u' circumflex
+    });
+lib.resource.add('hterm/audio/bell', 'audio/ogg;base64',
+'T2dnUwACAAAAAAAAAADhqW5KAAAAAMFvEjYBHgF2b3JiaXMAAAAAAYC7AAAAAAAAAHcBAAAAAAC4' +
+'AU9nZ1MAAAAAAAAAAAAA4aluSgEAAAAAesI3EC3//////////////////8kDdm9yYmlzHQAAAFhp' +
+'cGguT3JnIGxpYlZvcmJpcyBJIDIwMDkwNzA5AAAAAAEFdm9yYmlzKUJDVgEACAAAADFMIMWA0JBV' +
+'AAAQAABgJCkOk2ZJKaWUoSh5mJRISSmllMUwiZiUicUYY4wxxhhjjDHGGGOMIDRkFQAABACAKAmO' +
+'o+ZJas45ZxgnjnKgOWlOOKcgB4pR4DkJwvUmY26mtKZrbs4pJQgNWQUAAAIAQEghhRRSSCGFFGKI' +
+'IYYYYoghhxxyyCGnnHIKKqigggoyyCCDTDLppJNOOumoo4466ii00EILLbTSSkwx1VZjrr0GXXxz' +
+'zjnnnHPOOeecc84JQkNWAQAgAAAEQgYZZBBCCCGFFFKIKaaYcgoyyIDQkFUAACAAgAAAAABHkRRJ' +
+'sRTLsRzN0SRP8ixREzXRM0VTVE1VVVVVdV1XdmXXdnXXdn1ZmIVbuH1ZuIVb2IVd94VhGIZhGIZh' +
+'GIZh+H3f933f930gNGQVACABAKAjOZbjKaIiGqLiOaIDhIasAgBkAAAEACAJkiIpkqNJpmZqrmmb' +
+'tmirtm3LsizLsgyEhqwCAAABAAQAAAAAAKBpmqZpmqZpmqZpmqZpmqZpmqZpmmZZlmVZlmVZlmVZ' +
+'lmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZQGjIKgBAAgBAx3Ecx3EkRVIkx3IsBwgNWQUAyAAA' +
+'CABAUizFcjRHczTHczzHczxHdETJlEzN9EwPCA1ZBQAAAgAIAAAAAABAMRzFcRzJ0SRPUi3TcjVX' +
+'cz3Xc03XdV1XVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVYHQkFUAAAQAACGdZpZq' +
+'gAgzkGEgNGQVAIAAAAAYoQhDDAgNWQUAAAQAAIih5CCa0JrzzTkOmuWgqRSb08GJVJsnuamYm3PO' +
+'OeecbM4Z45xzzinKmcWgmdCac85JDJqloJnQmnPOeRKbB62p0ppzzhnnnA7GGWGcc85p0poHqdlY' +
+'m3POWdCa5qi5FJtzzomUmye1uVSbc84555xzzjnnnHPOqV6czsE54Zxzzonam2u5CV2cc875ZJzu' +
+'zQnhnHPOOeecc84555xzzglCQ1YBAEAAAARh2BjGnYIgfY4GYhQhpiGTHnSPDpOgMcgppB6NjkZK' +
+'qYNQUhknpXSC0JBVAAAgAACEEFJIIYUUUkghhRRSSCGGGGKIIaeccgoqqKSSiirKKLPMMssss8wy' +
+'y6zDzjrrsMMQQwwxtNJKLDXVVmONteaec645SGultdZaK6WUUkoppSA0ZBUAAAIAQCBkkEEGGYUU' +
+'UkghhphyyimnoIIKCA1ZBQAAAgAIAAAA8CTPER3RER3RER3RER3RER3P8RxREiVREiXRMi1TMz1V' +
+'VFVXdm1Zl3Xbt4Vd2HXf133f141fF4ZlWZZlWZZlWZZlWZZlWZZlCUJDVgEAIAAAAEIIIYQUUkgh' +
+'hZRijDHHnINOQgmB0JBVAAAgAIAAAAAAR3EUx5EcyZEkS7IkTdIszfI0T/M00RNFUTRNUxVd0RV1' +
+'0xZlUzZd0zVl01Vl1XZl2bZlW7d9WbZ93/d93/d93/d93/d939d1IDRkFQAgAQCgIzmSIimSIjmO' +
+'40iSBISGrAIAZAAABACgKI7iOI4jSZIkWZImeZZniZqpmZ7pqaIKhIasAgAAAQAEAAAAAACgaIqn' +
+'mIqniIrniI4oiZZpiZqquaJsyq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7rukBo' +
+'yCoAQAIAQEdyJEdyJEVSJEVyJAcIDVkFAMgAAAgAwDEcQ1Ikx7IsTfM0T/M00RM90TM9VXRFFwgN' +
+'WQUAAAIACAAAAAAAwJAMS7EczdEkUVIt1VI11VItVVQ9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV' +
+'VVVVVVVVVVVV1TRN0zSB0JCVAAAZAAAjQQYZhBCKcpBCbj1YCDHmJAWhOQahxBiEpxAzDDkNInSQ' +
+'QSc9uJI5wwzz4FIoFURMg40lN44gDcKmXEnlOAhCQ1YEAFEAAIAxyDHEGHLOScmgRM4xCZ2UyDkn' +
+'pZPSSSktlhgzKSWmEmPjnKPSScmklBhLip2kEmOJrQAAgAAHAIAAC6HQkBUBQBQAAGIMUgophZRS' +
+'zinmkFLKMeUcUko5p5xTzjkIHYTKMQadgxAppRxTzinHHITMQeWcg9BBKAAAIMABACDAQig0ZEUA' +
+'ECcA4HAkz5M0SxQlSxNFzxRl1xNN15U0zTQ1UVRVyxNV1VRV2xZNVbYlTRNNTfRUVRNFVRVV05ZN' +
+'VbVtzzRl2VRV3RZV1bZl2xZ+V5Z13zNNWRZV1dZNVbV115Z9X9ZtXZg0zTQ1UVRVTRRV1VRV2zZV' +
+'17Y1UXRVUVVlWVRVWXZlWfdVV9Z9SxRV1VNN2RVVVbZV2fVtVZZ94XRVXVdl2fdVWRZ+W9eF4fZ9' +
+'4RhV1dZN19V1VZZ9YdZlYbd13yhpmmlqoqiqmiiqqqmqtm2qrq1bouiqoqrKsmeqrqzKsq+rrmzr' +
+'miiqrqiqsiyqqiyrsqz7qizrtqiquq3KsrCbrqvrtu8LwyzrunCqrq6rsuz7qizruq3rxnHrujB8' +
+'pinLpqvquqm6um7runHMtm0co6rqvirLwrDKsu/rui+0dSFRVXXdlF3jV2VZ921fd55b94WybTu/' +
+'rfvKceu60vg5z28cubZtHLNuG7+t+8bzKz9hOI6lZ5q2baqqrZuqq+uybivDrOtCUVV9XZVl3zdd' +
+'WRdu3zeOW9eNoqrquirLvrDKsjHcxm8cuzAcXds2jlvXnbKtC31jyPcJz2vbxnH7OuP2daOvDAnH' +
+'jwAAgAEHAIAAE8pAoSErAoA4AQAGIecUUxAqxSB0EFLqIKRUMQYhc05KxRyUUEpqIZTUKsYgVI5J' +
+'yJyTEkpoKZTSUgehpVBKa6GU1lJrsabUYu0gpBZKaS2U0lpqqcbUWowRYxAy56RkzkkJpbQWSmkt' +
+'c05K56CkDkJKpaQUS0otVsxJyaCj0kFIqaQSU0mptVBKa6WkFktKMbYUW24x1hxKaS2kEltJKcYU' +
+'U20txpojxiBkzknJnJMSSmktlNJa5ZiUDkJKmYOSSkqtlZJSzJyT0kFIqYOOSkkptpJKTKGU1kpK' +
+'sYVSWmwx1pxSbDWU0lpJKcaSSmwtxlpbTLV1EFoLpbQWSmmttVZraq3GUEprJaUYS0qxtRZrbjHm' +
+'GkppraQSW0mpxRZbji3GmlNrNabWam4x5hpbbT3WmnNKrdbUUo0txppjbb3VmnvvIKQWSmktlNJi' +
+'ai3G1mKtoZTWSiqxlZJabDHm2lqMOZTSYkmpxZJSjC3GmltsuaaWamwx5ppSi7Xm2nNsNfbUWqwt' +
+'xppTS7XWWnOPufVWAADAgAMAQIAJZaDQkJUAQBQAAEGIUs5JaRByzDkqCULMOSepckxCKSlVzEEI' +
+'JbXOOSkpxdY5CCWlFksqLcVWaykptRZrLQAAoMABACDABk2JxQEKDVkJAEQBACDGIMQYhAYZpRiD' +
+'0BikFGMQIqUYc05KpRRjzknJGHMOQioZY85BKCmEUEoqKYUQSkklpQIAAAocAAACbNCUWByg0JAV' +
+'AUAUAABgDGIMMYYgdFQyKhGETEonqYEQWgutddZSa6XFzFpqrbTYQAithdYySyXG1FpmrcSYWisA' +
+'AOzAAQDswEIoNGQlAJAHAEAYoxRjzjlnEGLMOegcNAgx5hyEDirGnIMOQggVY85BCCGEzDkIIYQQ' +
+'QuYchBBCCKGDEEIIpZTSQQghhFJK6SCEEEIppXQQQgihlFIKAAAqcAAACLBRZHOCkaBCQ1YCAHkA' +
+'AIAxSjkHoZRGKcYglJJSoxRjEEpJqXIMQikpxVY5B6GUlFrsIJTSWmw1dhBKaS3GWkNKrcVYa64h' +
+'pdZirDXX1FqMteaaa0otxlprzbkAANwFBwCwAxtFNicYCSo0ZCUAkAcAgCCkFGOMMYYUYoox55xD' +
+'CCnFmHPOKaYYc84555RijDnnnHOMMeecc845xphzzjnnHHPOOeecc44555xzzjnnnHPOOeecc845' +
+'55xzzgkAACpwAAAIsFFkc4KRoEJDVgIAqQAAABFWYowxxhgbCDHGGGOMMUYSYowxxhhjbDHGGGOM' +
+'McaYYowxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHG' +
+'GFtrrbXWWmuttdZaa6211lprrQBAvwoHAP8HG1ZHOCkaCyw0ZCUAEA4AABjDmHOOOQYdhIYp6KSE' +
+'DkIIoUNKOSglhFBKKSlzTkpKpaSUWkqZc1JSKiWlllLqIKTUWkottdZaByWl1lJqrbXWOgiltNRa' +
+'a6212EFIKaXWWostxlBKSq212GKMNYZSUmqtxdhirDGk0lJsLcYYY6yhlNZaazHGGGstKbXWYoy1' +
+'xlprSam11mKLNdZaCwDgbnAAgEiwcYaVpLPC0eBCQ1YCACEBAARCjDnnnHMQQgghUoox56CDEEII' +
+'IURKMeYcdBBCCCGEjDHnoIMQQgghhJAx5hx0EEIIIYQQOucchBBCCKGEUkrnHHQQQgghlFBC6SCE' +
+'EEIIoYRSSikdhBBCKKGEUkopJYQQQgmllFJKKaWEEEIIoYQSSimllBBCCKWUUkoppZQSQgghlFJK' +
+'KaWUUkIIoZRQSimllFJKCCGEUkoppZRSSgkhhFBKKaWUUkopIYQSSimllFJKKaUAAIADBwCAACPo' +
+'JKPKImw04cIDUGjISgCADAAAcdhq6ynWyCDFnISWS4SQchBiLhFSijlHsWVIGcUY1ZQxpRRTUmvo' +
+'nGKMUU+dY0oxw6yUVkookYLScqy1dswBAAAgCAAwECEzgUABFBjIAIADhAQpAKCwwNAxXAQE5BIy' +
+'CgwKx4Rz0mkDABCEyAyRiFgMEhOqgaJiOgBYXGDIB4AMjY20iwvoMsAFXdx1IIQgBCGIxQEUkICD' +
+'E2544g1PuMEJOkWlDgIAAAAA4AAAHgAAkg0gIiKaOY4Ojw+QEJERkhKTE5QAAAAAALABgA8AgCQF' +
+'iIiIZo6jw+MDJERkhKTE5AQlAAAAAAAAAAAACAgIAAAAAAAEAAAACAhPZ2dTAAQYOwAAAAAAAOGp' +
+'bkoCAAAAmc74DRgyNjM69TAzOTk74dnLubewsbagmZiNp4d0KbsExSY/I3XUTwJgkeZdn1HY4zoj' +
+'33/q9DFtv3Ui1/jmx7lCUtPt18/sYf9MkgAsAGRBd3gMGP4sU+qCPYBy9VrA3YqJosW3W2/ef1iO' +
+'/u3cg8ZG/57jU+pPmbGEJUgkfnaI39DbPqxddZphbMRmCc5rKlkUMkyx8iIoug5dJv1OYH9a59c+' +
+'3Gevqc7Z2XFdDjL/qHztRfjWEWxJ/aiGezjohu9HsCZdQBKbiH0VtU/3m85lDG2T/+xkZcYnX+E+' +
+'aqzv/xTgOoTFG+x7SNqQ4N+oAABSxuVXw77Jd5bmmTmuJakX7509HH0kGYKvARPpwfOSAPySPAc2' +
+'EkneDwB2HwAAJlQDYK5586N79GJCjx4+p6aDUd27XSvRyXLJkIC5YZ1jLv5lpOhZTz0s+DmnF1di' +
+'ptrnM6UDgIW11Xh8cHTd0/SmbgOAdxcyWwMAAGIrZ3fNSfZbzKiYrK4+tPqtnMVLOeWOG2kVvUY+' +
+'p2PJ/hkCl5aFRO4TLGYPZcIU3vYM1hohS4jHFlnyW/2T5J7kGsShXWT8N05V+3C/GPqJ1QdWisGP' +
+'xEzHqXISBPIinWDUt7IeJv/f5OtzBxpTzZZQ+CYEhHXfqG4aABQli72GJhN4oJv+hXcApAJSErAW' +
+'8G2raAX4NUcABnVt77CzZAB+LsHcVe+Q4h+QB1wh/ZrJTPxSBdI8mgTeAdTsQOoFUEng9BHcVPhx' +
+'SRRYkKWZJXOFYP6V4AEripJoEjXgA2wJRZHSExmJDm8F0A6gEXsg5a4ZsALItrMB7+fh7UKLvYWS' +
+'dtsDwFf1mzYzS1F82N1h2Oyt2e76B1QdS0SAsQigLPMOgJS9JRC7hFXA6kUsLFNKD5cA5cTRvgSq' +
+'Pc3Fl99xW3QTi/MHR8DEm6WnvaVQATwRqRKjywQ9BrrhugR2AKTsPQeQckrAOgDOhbTESyrXQ50C' +
+'kNpXdtWjW7W2/3UjeX3U95gIdalfRAoAmqUEiwp53hCdcCwlg47fcbfzlmQMAgaBkh7c+fcDgF+i' +
+'fwDXfzegLPcLYJsAAJQArTXjnh/uXGy3v1Hk3pV6/3t5ruW81f6prfbM2Q3WNVy98BwUtbCwhFhA' +
+'WuPev6Oe/4ZaFQUcgKrVs4defzh1TADA1DEh5b3VlDaECw5b+bPfkKos3tIAue3vJZOih3ga3l6O' +
+'3PSfIkrLv0PAS86PPdL7g8oc2KteNFKKzKRehOv2gJoFLBPXmaXvPBQILgJon0bbWBszrYZYYwE7' +
+'jl2j+vTdU7Vpk21LiU0QajPkywAAHqbUC0/YsYOdb4e6BOp7E0cCi04Ao/TgD8ZVAMid6h/A8IeB' +
+'Nkp6/xsAACZELEYIk+yvI6Qz1NN6lIftB/6IMWjWJNOqPTMedAmyaj6Es0QBklJpiSWWHnQ2CoYb' +
+'GWAmt+0gLQBFKCBnp2QUUQZ/1thtZDBJUpFWY82z34ocorB62oX7qB5y0oPAv/foxH25wVmgIHf2' +
+'xFOr8leZcBq1Kx3ZvCq9Bga639AxuHuPNL/71YCF4EywJpqHFAX6XF0sjVbuANnvvdLcrufYwOM/' +
+'iDa6iA468AYAAB6mNBMXcgTD8HSRqJ4vw8CjAlCEPACASlX/APwPOJKl9xQAAAPmnev2eWp33Xgy' +
+'w3Dvfz6myGk3oyP8YTKsCOvzAgALQi0o1c6Nzs2O2Pg2h4ACIJAgAGP0aNn5x0BDgVfH7u2TtyfD' +
+'cRIuYAyQhBF/lvSRAttgA6TPbWZA9gaUrZWAUEAA+Dx47Q3/r87HxUUqZmB0BmUuMlojFjHt1gDu' +
+'nnvuX8MImsjSq5WkzSzGS62OEIlOufWWezxWpv6FBgDgJVltfXFYtNAAnqU0xQoD0YLiXo5cF5QV' +
+'4CnY1tBLAkZCOABAhbk/AM+/AwSCCdlWAAAMcFjS7owb8GVDzveDiZvznbt2tF4bL5odN1YKl88T' +
+'AEABCZvufq9YCTBtMwVAQUEAwGtNltzSaHvADYC3TxLVjqiRA+OZAMhzcqEgRcAOwoCgvdTxsTHL' +
+'QEF6+oOb2+PAI8ciPQcXg7pOY+LjxQSv2fjmFuj34gGwz310/bGK6z3xgT887eomWULEaDd04wHe' +
+'tYxdjcgV2SxvSwn0VoZXJRqkRC5ASQ/muVoAUsX7AgAQMBNaVwAAlABRxT/1PmfqLqSRNDbhXb07' +
+'berpB3b94jpuWEZjBCD2OcdXFpCKEgCDfcFPMw8AAADUwT4lnUm50lmwrpMMhPQIKj6u0E8fr2vG' +
+'BngMNdIlrZsigjahljud6AFVg+tzXwUnXL3TJLpajaWKA4VAAAAMiFfqJgKAZ08XrtS3dxtQNYcp' +
+'PvYEG8ClvrQRJgBephwnNWJjtGqmp6VEPSvBe7EBiU3qgJbQAwD4Le8LAMDMhHbNAAAlgK+tFs5O' +
+'+YyJc9yCnJa3rxLPulGnxwsXV9Fsk2k4PisCAHC8FkwbGE9gJQAAoMnyksj0CdFMZLLgoz8M+Fxz' +
+'iwYBgIx+zHiCBAKAlBKNpF1sO9JpVcyEi9ar15YlHgrut5fPJnkdJ6vEwZPyAHQBIEDUrlMcBAAd' +
+'2KAS0Qq+JwRsE4AJZtMnAD6GnOYwYlOIZvtzUNdjreB7fiMkWI0CmBB6AIAKc38A9osEFlTSGECB' +
+'+cbeRDC0aRpLHqNPplcK/76Lxn2rpmqyXsYJWRi/FQAAAKBQk9MCAOibrQBQADCDsqpooPutd+05' +
+'Ce9g6iEdiYXgVmQAI4+4wskEBEiBloNQ6Ki0/KTQ0QjWfjxzi+AeuXKoMjEVfQOZzr0y941qLgM2' +
+'AExvbZOqcxZ6J6krlrj4y2j9AdgKDx6GnJsVLhbc42uq584+ouSdNBpoCiCVHrz+WzUA/DDtD8AT' +
+'gA3h0lMCAAzcFv+S+fSSNkeYWlTpb34mf2RfmqqJeMeklhHAfu7VoAEACgAApKRktL+KkQDWMwYC' +
+'UAAAAHCKsp80xhp91UjqQBw3x45cetqkjQEyu3G9B6N+R650Uq8OVig7wOm6Wun0ea4lKDPoabJs' +
+'6aLqgbhPzpv4KR4iODilw88ZpY7q1IOMcbASAOAVtmcCnobcrkG4KGS7/ZnskVWRNF9J0RUHKOnB' +
+'yy9WA8Dv6L4AAARMCQUA4GritfVM2lcZfH3Q3T/vZ47J2YHhcmBazjfdyuV25gLAzrc0cwAAAAAY' +
+'Ch6PdwAAAGyWjFW4yScjaWa2mGcofHxWxewKALglWBpLUvwwk+UOh5eNGyUOs1/EF+pZr+ud5Ozo' +
+'GwYdAABg2p52LiSgAY/ZVlOmilEgHn6G3OcwYjzI7vOj1t6xsx4S3lBY96EUQBF6AIBAmPYH4PoG' +
+'YCoJAADWe+OZJZi7/x76/yH7Lzf9M5XzRKnFPmveMsilQHwVAAAAAKB3LQD8PCIAAADga0QujBLy' +
+'wzeJ4a6Z/ERVBAUlAEDqvoM7BQBAuAguzFqILtmjH3Kd4wfKobnOhA3z85qWoRPm9hwoOHoDAAlC' +
+'bwDAA56FHAuXflHo3fe2ttG9XUDeA9YmYCBQ0oPr/1QC8IvuCwAAApbUAQCK22MmE3O78VAbHQT9' +
+'PIPNoT9zNc3l2Oe7TAVLANBufT8MAQAAAGzT4PS8AQAAoELGHb2uaCwwEv1EWhFriUkbAaAZ27/f' +
+'VZnTZXbWz3BwWpjUaMZKRj7dZ0J//gUeTdpVEwAAZOFsNxKAjQSgA+ABPoY8Jj5y2wje81jsXc/1' +
+'TOQWTDYZBmAkNDiqVwuA2NJ9AQAAEBKAt9Vrsfs/2N19MO91S9rd8EHTZHnzC5MYmfQEACy/FBcA' +
+'AADA5c4gi4z8RANs/m6FNXVo9DV46JG1BBDukqlw/Va5G7QbuGVSI+2aZaoLXJrdVj2zlC9Z5QEA' +
+'EFz/5QzgVZwAAAAA/oXcxyC6WfTu+09Ve/c766J4VTAGUFmA51+VANKi/QPoPwYgYAkA715OH4S0' +
+'s5KDHvj99MMq8TPFc3roKZnGOoT1bmIhVgc7XAMBAAAAAMAW1VbQw3gapzOpJd+Kd2fc4iSO62fJ' +
+'v9+movui1wUNPAj059N3OVxzk4gV73PmE8FIA2F5mRq37Evc76vLXfF4rD5UJJAw46hW6LZCb5sN' +
+'Ldx+kzMCAAB+hfy95+965ZCLP7B3/VlTHCvDEKtQhTm4KiCgAEAbrfbWTPssAAAAXpee1tVrozYY' +
+'n41wD1aeYtkKfswN5/SXPO0JDnhO/4laUortv/s412fybe/nONdncoCHnBVliu0CQGBWlPY/5Kwo' +
+'m2L/kruPM6Q7oz4tvDQy+bZ3HzOi+gNHA4DZEgA='
+);
+
+lib.resource.add('hterm/images/icon-96', 'image/png;base64',
+'iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAStklEQVR42u1dBXjrupL+RzIGmjIf' +
+'vAcu42NmZub3lpmZmZmZmRkuMzPDYaYyJG0Sa9b2p2z1eQtp7bzefpv/nKnkkSw7Gg1IshNsDtpo' +
+'o4022mijDWp/tlTgzbpJSqYvMoFTC9vjRD5JLb9RYaRkpk22SS28P8pacAaPdZ41KYMCI89YB6wN' +
+'3JzQJM3UIGqurfTlKQTAZtqENid5SlNdU804VmbbWQtA6HMkAAdADsBeAJ7mxwIhIhFSXJ9iRPw4' +
+'JYDEcqmGWEp1HhCI8gAtpXF7scB1ZRH9E3HObANCNy1AoGTegNDnCdE41tfQDH2t+CINQEpJ9Xp9' +
+'7oUDh3+nXK48DYAMIWQmANIkNTn6vP69e3d/zctfeu0nXNexmVn3F0gDAMxMlBoHuht0qnsEEekC' +
+'42SdGHmNxgVjgk4bPN04Yui8bhc534cQBH35RKrPN9sGdLnB1/Wuv+HW4f+6/tZvBHAaAJvmKr0A' +
+'jJGvyQMw8pLrrvqeT378Ax8UwrKeevoFgEhfjcGGO2JO+iuTt1SW5DHzyraDExyTlWwHjCQ/CAJc' +
+'ecU+XHn5xWDmVCGQFAKljsLbx8Ynvv3Bhx7/EQCzurimU04jADLsvK3r73/7W1//g1/6hU++uVqt' +
+'0X/dcBcKxRIsy9Ji34DPow2et6FzgcXFKk6fOY83vu4VEFKkDiYHB3roSz73sc+Oj08eOHzk+B9o' +
+'MyQABGk0gCIyOt9xHPvaD3/wnT/5VV/+meumpmbwD/98A0qdvVEBNhvMDCJaVXtM01GtVlEs+LBt' +
+'C1ngzW98tX/m7Llv/emf+83HarX6vbrfGECQRgBmlLP9Ix961499+zd/5XVj45P407/8FxQ7uiGl' +
+'QK1Ww1ZCvR6gXq3AsgQ8zwYzUkMIgXe+/Q1Dd9x5/6duv/P+R7QjprQaIHQd/8orLvnCJz/2/pfm' +
+'cj7+6rf+DK5XgOu6sT3dQtBawqjW6lhYXIRlSTAjE/T39eLSS/ZeEwqgE8CiYUV4vQIgTULTyFve' +
+'9Or3WJZN/3n9HTh3fgrFjhJmZmawFaGUwkJlEffc9xh83wMYqcFg7Noxinw+l9OBikirAabz7eju' +
+'6sxJKTE7W4bn5+D7PrYmtI/gAFJasCwb4IzaBMHzXE8LgBJC4I1GQRKAa4Xo6upEsZiH53nIRYLe' +
+'olDMCIIq+nq70dFRAGckgFKpAD+UgBaAgfRRkGvbliwUcoh8ABHFYSfWMnBrxOzL12PwKufzSvV5' +
+'5Tpmi5a0IASBQCgWcujs7ABn5AQic+b5rhNlAVAmTliTEwnA990wIxEEdUQYnxjHidMnAUIcBYAB' +
+'RqNDdC7BM8t0VtfTnGRd8FKdRIjJcVlCsAbPPA5UAK4rXLJjP7aNbkO9XoPrOrEQWHEm69Kua0ca' +
+'YEspvCBQ5toSp9EASCkt27ZF1PlCxBOZOPo5feY0Xpg8jHe/7V3YNjhqjDRac3mMVl1Oo40vtREt' +
+'W+2FYwdw/S03YHJ6EkODQ1hcXIQUcaeBlUIWsCwZ+QDLdZxcubKAtBpgNmzZliUa6yLMKiRGoBR2' +
+'79yN6666FlJYABgvRhAIncUSHn/iCdQrAZjjSAiKFQQRVEhZIRJASJEACICmlAKQUtqhBETjw5ij' +
+'uFqr4oWjBwHmF7/jVUHc6aRNXxAoZA3PdYXruvlldJfTaIATaQA4KU/CzNwMDp84DOYXf+hZXiij' +
+'hJz+DK0QAEd+RYTOOAcgMw0g24oskNYAIoCXxDpbnsOxM8fB5qacwKZD+3WQcS+VxQrYYXNVNGMh' +
+'I1odiIRQSHb8BmbCpgZYjmVLYi0ANmxQNKpOj50FFOB3WnDzEpOnFkGbuOXPimG5Ap0jLqZOLiKo' +
+'MyIsVhfB9lLEpFSQ+S26jh2Fo/n0YagRCUlLRhpAAIMIyWl9vBinAkbfoIPXf+0wnrlxAs/dPInK' +
+'VB1CUOsFkdhD6Nnp49oP98EvWfjvnzqGak0hVlwwFJsaoADK9vq2Y0eOOKUGJLTAjjQgFgBAy/gT' +
+'vbGIyXC0nX66jJd+YgC7X1nCo39/AccfmUVQU1F5y0d9rsvGJW/txuXv7oGqMx7+2/OoVxWIzE5S' +
+'OkfaBBGyhGPHc4G8YYjT+wDLDgUgJbQPWDGuL0/VcefvnMLRB2dw3Uf78dZv345D90zjsX++gPGj' +
+'C7peC8yNI7DjpSVcE476rlEPB++awmP/dCEaEMtqbAP1Fqzkhn0VaUAegMzABJkaIMG8epNEiE3R' +
+'0funce75Mi4NR+MV7+3B6NUFPPnvY3jupslISJkKoW9PDld/sA+7Xt6B8SMV3Pjzx3Di0TkENQaJ' +
+'5A1qM8VRljKPgpg58pcNHyCz0ADSTnhNDTBBglCZruPhvz+PY4/M4Jqwg6772AB2vqwDd/zmKYwd' +
+'WQAJpMalb+vGSz81AA6Ah/76HJ69KfI7tej6K7RPUKwaWQT1FmiAlJEJykXZZh5cE02FoaEJkpYE' +
+'wGsKwNQGAnDhQAUP/915TJ5YwPCleZSG3WwWvwgYvryAYr8Tm5wn/2Mc5cm481c9RzXWobQPyBpS' +
+'ikgDGgJAVvMARzY0AARwc7Y5Ckn3vK4TV7+/D5YncN+fnsWpJ+cgsnDICnj0n85DSOCSUBO6Rl08' +
+'8g8XcObZ+VgjSKweKRG1xgcIEQnA9QE46aMgwwlHAmBuOFFepeMRd8rI1cU4FBzYn8exh2bw6D9e' +
+'wNihCjgrR0wI21vAzb9yIrT/pfha7/y+nXj+5gk8EWrDzJlF/WxQUgMUwEtREGW/5RlpgJdaABq0' +
+'pAGicYFVFaBzxMGV7+vFvtd3YfpsFbf+6ok4KqovxqFoph+YBBAsMg7cPonTT83jsnd247J39IQR' +
+'UUcceR28cxrVcrBUX2sAa1Nar7dCAwhevCkDN7UADB9gSyEBaBVYYeT37PTw9u/aAbcg8Pi/XMAz' +
+'109gfqLhFAktgX46LbrOg395DscemAnD0X68+suGQ+3L4Y7fOhVHRA00nDBRa3wAEGuAA8DbqABI' +
+'kyEA2xFSrBHHM2xf4Ozz82HIOb5kbgSh1TDv69wLZdz0S8dxUTgRHLwkD2HRkgCIdBi6NBPmVpgg' +
+'L7krBkrnA6xIA0Qjfl4x9Bw7XInDzHo1hblJbZYoNkvP3zqFw/fPIKgqGNC7aNoEtUQDEJkg23Ec' +
+'v1qtrhkFiWYeTYzCUCEEeI15QDTSgjpnMerTmyUB1CsKrGACyvABQb1VAnAt13V8NAHRxGqotEMI' +
+'QUbJFgGtMhNuqQa4Ui9HbEgDKFknioKIhC4kbGUwFBhsOGHO/AqhCxAh5dOsBZFBMoqCGhpARJv7' +
+'ihul35oEt84E6U0ZCv1APp0T1tACsIhEpquZQhJsT2C9UAGjtqA2vDnPzOD/NUEqymcOJ94TcPJZ' +
+'zYSFHYKIjHlA+iXk/kvyeO1XDENYtK6J16kn53H375+OBbFukBkFtWoewHAdJ1qQKwAQWcyEtQaQ' +
+'4QPSmk6KZ6gXDlVAcn0x9vTpxTSjdhkBcOYmSO+KNTZlKK0GWHYoASJkZoJIABPHFnDbb5zEFxts' +
+'hqEtMkG2rfcEtAZsJAoimBpgGRqg062KVmsAmBH2V2NfWKZ1woxYAyIBwFABXma+nE30wytV4rU/' +
+'OK9xLWaGUmpJAHE+awEDUsrGnoCERsooyJYALfPaOEHNByBl7BGwKQsy8kYLUZ1kOTXyZprgUYJH' +
+'SBzrctLHDZ6huflCLt61qtWDWAMawsgOWgCe5+v+JYN4vT6AtAbIpSCIGuEcRoaG8TrXRcwzCeZ7' +
+'u2gcm4QIZn0QEudC5wGYdYxUt2PyjRSAyWsc6mvW6hW0CnpXzAdgQ6NZAdByJsgKBQAQGCp+oQFQ' +
+'8ePdhUIBxWJxXfrJYKQHNRUMMK9kuwhzc3O4eO+eeLQqpbLfFfMaAgAnhdDccrSpAZYtAUApxujI' +
+'EN725lfg3//7bvT19cOyLJhg44/ZCTo1y40yI79qmT4/5un2jTx0+XLtmAOAlUJXVx6ve83LdFkr' +
+'dsWMTZkUTpikjFyAJUxHFr6oDc918cDDT6KyMB8xzVFpmBpAGGZHiCgVZgoRphSlQkCQTvXxEhFk' +
+'lMolXnyseY28NMtlIjXaCzsHO7aPoFDIQ6nWCMDzXS2AdJvybMl4HiaSLyK89S2vxRte/wrU6vXG' +
+'IFrzOxdWTZcaMNtCgq15a9vNtWyTMjUncwEguSu2ISesO3vp3YDkE2ZSypiyQMO0JO331gTFryoJ' +
+'IXylVLrFOCtEpAHmaG5jbQ3Qb8r45XKFN2qCOCJpSUsxi/n5SlOP8rXB0WpoUgC8HgGwQYqI7AMH' +
+'j1G9zk2Ea20wgI5iPhqs8dMk6/26GrOyiqharc16nlffvn3EaWtAc/BcBw8+/Ojc+PjkKaMvuWkN' +
+'ME+YnZ17+rnnDxweHOi9iCM+gzbLOXLrG8piu46JIO5/4NHD9XpwbEPfEqjJ01R0XecDYcz8lvhF' +
+'MSEkwJIBaU76AZA+SsST5oHOmidqvsHQieYk6ya/ucysT/pPon6yLum/5tXN4uV45ocAKHEeWFdQ' +
+'YcpKKb4wNnH/xMTUjwGYArBofLHfuhfjeO+eXbu+/ms+946JyWl16NAxWmV80AZGImW+M0z/dxWU' +
+'NbvJNQzaqNK4ro13v/NN9C//doP4gz/+mxKAWWNQb2hHzL/s0n1XDfT3W3fe8wRAVmLytCE56HM3' +
+'LL/E+bRqb+niFZ9rSvD0nnHzd2Y+M3vs5Ckwc/S9QQMABgGc0cvS9fU8migi0uUDey7asfvQ4eMQ' +
+'louuzs74Am0sL4TZQhHHTpzG8FB/qdRR3DU9M/sUgJqmphfjhJaa9H1v9/Ztw/1PPn0QtWoNs7Oz' +
+'WBltATiOixMnzuCS/bvtgTBwCQXg6s5fNLdTmnkuSAKww0WrS7q6St7E5Ax6egbWWHpow3EcnDs/' +
+'EX8v6fDw4J4XDhzxASwAEOvSAF2Wu2j3jssAQqVSQ6+ULTQ/W3+pQy/dYHauEi9Sbhsd2gGgqB2x' +
+'BEDN+gCpy3rCCGjP5OQ0FHO0idGeDTexHRkoxvjEJHZsGxkE0APgnO5TYc6x1hKAIKJtu3dtGzp1' +
+'+hyKxY5oB6wpDWibIRenTp3D6OhQl5RyMAiC5w0TRCtpACW+rM8aGR7cPzTYX3ziqQPw/dzmm4gt' +
+'YOaYGZ7n4cTJs3jVK67xw++l23723AVtURLhaFIDEuGnG47+S33fo8mpWZQ6XUxPT6ONtfeD7dgR' +
+'j6NQyNHQ0MCOUAA2ANmMBpAhhGJo//eFy6lgFsjn823zsw6cnhyHUhw74kcfe8ozfMCKAkjOAYb2' +
+'7tk5cubsBTiuF3v35h1w2xwpRmgxZrBj+/AIgA4AY7pfsZYGyIi6uzv3hHOArocefQbMwNTUVFsD' +
+'mjdDIUmcDgfv6OhwH4CIjie0gJfVAF3J2bVjWzgB65TnL0ygs7NrnROwthZUqzWcPHUOV1y2txiu' +
+'JA/Pzc0/spYJEob5ye/Zs/NiZka5XEVPr4821gfP9xAN3nA9yB4c6Nt+cG5eLvPGDCdNUKNS7769' +
+'u3ZGX1NfqwfR+s//C/PDnH5TRq+kxun8fBkdxQJGhgd2Hjx01BBAwgQl7L/I5fyd4RJE3+TUdNjI' +
+'PKSc0AJg/T+JxNNnK5Uly3VuterJOpzh3hmts5DWKExy3/j6l2J4eAAjI4PbjG9UF6YQrMaBWRCu' +
+'fu4fHRn0Bvp7USzkUS4vmD9as+IP3cSHWL5eXGTUizk6v/IDubodM7+++qs+ENbsg2RxLlE/5pr1' +
+'Ew8H25aFnp6u2CFvGx0e0JHQGdMEJTWgkTo7d4xe3NfXg1KpiLe86TWg9ONtc3eKuVX3yatei5m1' +
+'AIa6pRT9QaCeb2YporBzx7Zd0chnRkgKbaSLsMLZcK6/rzecU53n5TSAEkw/HPkFy86BpJtq3LRB' +
+'IK6jq7NDhPOqPi0A0+cuuxq6EMas5bGJaVQWFWgTbrqVTdEX9f4ZvmfB9/3Il5bW2hNmnZbDB4om' +
+'Lpw/h7n5RYCa+3E0ToY4Jp9XiGSYk/WMvHmlxDEn7yN5ffN4mTzrM808G+0leJqVbG81njbfjFJH' +
+'Hr4no4lZ3fjRT06GoWxQ+eFHn7rTz/1Tv5QSrBQpZrAmfVMaQJyNOXHOPESjztJfs54uxFJWl5q1' +
+'zYuZRzD+RzAPEufoJFln2TyMv8axwUheJPGRVSMFEHe4ZckqMy8cOXLin5f7xVUyyPypwhKAHp13' +
+'IjJCVW4iHGAz30Q5mmx3I+dwyvbWE36x0ck1AFW9Gb+g06qmWkMQVuLEQEtuVldyjR/vFJqyjxNb' +
+'6+mTA6DV96HMvkx0ej2pAZZxoBL5QJ8oDKIW3jxnfA5twj1xUhPMjjd9wGpOOEgIgUzaxFG8RZ4F' +
+'Tgxos9N1atajtd+S1LytA26p8NKbQE7/0+BtpNakNtpoo4022vgf7lRPtKCE39oAAAAASUVORK5C' +
+'YII='
+);
+
+lib.resource.add('hterm/concat/date', 'text/plain',
+'Thu, 05 Dec 2019 19:56:15 +0000'
+);
+
+lib.resource.add('hterm/changelog/version', 'text/plain',
+'1.86'
+);
+
+lib.resource.add('hterm/changelog/date', 'text/plain',
+'2019-08-06'
+);
+
+lib.resource.add('hterm/git/HEAD', 'text/plain',
+'907ca35fa514dd9bf7b41a82d07d46b412ffa91a'
+);
+
diff --git a/htdocs/dist/1.87/hterm_all.js b/htdocs/dist/1.87/hterm_all.js
new file mode 100644
index 0000000..dac78f9
--- /dev/null
+++ b/htdocs/dist/1.87/hterm_all.js
@@ -0,0 +1,21569 @@
+// This file was generated by libdot/bin/concat.sh.
+// It has been marked read-only for your safety.  Rather than
+// edit it directly, please modify one of these source files.
+//
+// libdot/js/lib.js
+// libdot/js/lib_polyfill.js
+// libdot/js/lib_array.js
+// libdot/js/lib_codec.js
+// libdot/js/lib_colors.js
+// libdot/js/lib_f.js
+// libdot/js/lib_i18n.js
+// libdot/js/lib_message_manager.js
+// libdot/js/lib_preference_manager.js
+// libdot/js/lib_resource.js
+// libdot/js/lib_storage.js
+// libdot/js/lib_storage_chrome.js
+// libdot/js/lib_storage_local.js
+// libdot/js/lib_storage_memory.js
+// libdot/js/lib_storage_terminal_private.js
+// libdot/third_party/fast-text-encoding/text.js
+// libdot/third_party/intl-segmenter/intl-segmenter.js
+// libdot/third_party/wcwidth/lib_wc.js
+// hterm/js/hterm.js
+// hterm/js/hterm_accessibility_reader.js
+// hterm/js/hterm_contextmenu.js
+// hterm/js/hterm_frame.js
+// hterm/js/hterm_keyboard.js
+// hterm/js/hterm_keyboard_bindings.js
+// hterm/js/hterm_keyboard_keymap.js
+// hterm/js/hterm_keyboard_keypattern.js
+// hterm/js/hterm_options.js
+// hterm/js/hterm_parser.js
+// hterm/js/hterm_parser_identifiers.js
+// hterm/js/hterm_preference_manager.js
+// hterm/js/hterm_pubsub.js
+// hterm/js/hterm_screen.js
+// hterm/js/hterm_scrollport.js
+// hterm/js/hterm_terminal.js
+// hterm/js/hterm_terminal_io.js
+// hterm/js/hterm_text_attributes.js
+// hterm/js/hterm_vt.js
+// hterm/js/hterm_vt_character_map.js
+// hterm/audio/bell.ogg
+// hterm/images/icon-96.png
+
+'use strict';
+
+// SOURCE FILE: libdot/js/lib.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+const lib = {};
+
+/**
+ * List of functions that need to be invoked during library initialization.
+ *
+ * Each element in the initCallbacks_ array is itself a two-element array.
+ * Element 0 is a short string describing the owner of the init routine, useful
+ * for debugging.  Element 1 is the callback function.
+ */
+lib.initCallbacks_ = [];
+
+/**
+ * Register an initialization function.
+ *
+ * The initialization functions are invoked in registration order when
+ * lib.init() is invoked.  Each function will receive a single parameter, which
+ * is a function to be invoked when it completes its part of the initialization.
+ *
+ * @param {string} name A short descriptive name of the init routine useful for
+ *     debugging.
+ * @param {function(function())} callback The initialization function to
+ *     register.
+ * @return {function(function())} The callback parameter.
+ */
+lib.registerInit = function(name, callback) {
+  lib.initCallbacks_.push([name, callback]);
+  return callback;
+};
+
+/**
+ * Initialize the library.
+ *
+ * This will ensure that all registered runtime dependencies are met, and
+ * invoke any registered initialization functions.
+ *
+ * Initialization is asynchronous.  The library is not ready for use until
+ * the onInit function is invoked.
+ *
+ * @param {function()} onInit The function to invoke when initialization is
+ *     complete.
+ * @param {function(*)=} logFunction An optional function to send initialization
+ *     related log messages to.
+ */
+lib.init = function(onInit, logFunction) {
+  var ary = lib.initCallbacks_;
+
+  var initNext = function() {
+    if (ary.length) {
+      var rec = ary.shift();
+      if (logFunction) {
+        logFunction(`init: ${rec[0]}`);
+      }
+      rec[1](initNext);
+    } else {
+      onInit();
+    }
+  };
+
+  if (typeof onInit != 'function')
+    throw new Error('Missing or invalid argument: onInit');
+
+  setTimeout(initNext, 0);
+};
+
+/**
+ * Verify |condition| is truthy else throw Error.
+ *
+ * This function is primarily for satisfying the JS compiler and should be
+ * used only when you are certain that your condition is true.  The function is
+ * designed to have a version that throws Errors in tests if condition fails,
+ * and a nop version for production code.  It configures itself the first time
+ * it runs.
+ *
+ * @param {boolean} condition A condition to check.
+ * @closurePrimitive {asserts.truthy}
+ */
+lib.assert = function(condition) {
+  if (window.chai) {
+    lib.assert = window.chai.assert;
+  } else {
+    lib.assert = function(condition) {};
+  }
+  lib.assert(condition);
+};
+
+/**
+ * Verify |value| is not null and return |value| if so, else throw Error.
+ * See lib.assert.
+ *
+ * @template T
+ * @param {T} value A value to check for null.
+ * @return {T} A non-null |value|.
+ * @closurePrimitive {asserts.truthy}
+ */
+lib.notNull = function(value) {
+  lib.assert(value !== null);
+  return value;
+};
+
+/**
+ * Verify |value| is not undefined and return |value| if so, else throw Error.
+ * See lib.assert.
+ *
+ * @template T
+ * @param {T} value A value to check for null.
+ * @return {T} A non-undefined |value|.
+ * @closurePrimitive {asserts.truthy}
+ */
+lib.notUndefined = function(value) {
+  lib.assert(value !== undefined);
+  return value;
+};
+// SOURCE FILE: libdot/js/lib_polyfill.js
+// Copyright 2017 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Polyfills for ES2016+ features we want to use.
+ * @suppress {duplicate} This file redefines many functions.
+ */
+
+/** @const */
+lib.polyfill = {};
+
+/**
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
+ */
+lib.polyfill.stringPadStart = function() {
+  /**
+   * @param {number} targetLength
+   * @param {string=} padString
+   * @return {string}
+   */
+  String.prototype.padStart = function(targetLength, padString) {
+    // If the string is already long enough, nothing to do!
+    targetLength -= this.length;
+    if (targetLength <= 0)
+      return String(this);
+
+    if (padString === undefined)
+      padString = ' ';
+
+    // In case the pad is multiple chars long.
+    if (targetLength > padString.length)
+      padString = padString.repeat((targetLength / padString.length) + 1);
+
+    return padString.slice(0, targetLength) + String(this);
+  };
+};
+
+if (!String.prototype.padStart) {
+  lib.polyfill.stringPadStart();
+}
+
+/**
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
+ */
+lib.polyfill.stringPadEnd = function() {
+  /**
+   * @param {number} targetLength
+   * @param {string=} padString
+   * @return {string}
+   */
+  String.prototype.padEnd = function(targetLength, padString) {
+    // If the string is already long enough, nothing to do!
+    targetLength -= this.length;
+    if (targetLength <= 0)
+      return String(this);
+
+    if (padString === undefined)
+      padString = ' ';
+
+    // In case the pad is multiple chars long.
+    if (targetLength > padString.length)
+      padString = padString.repeat((targetLength / padString.length) + 1);
+
+    return String(this) + padString.slice(0, targetLength);
+  };
+};
+
+if (!String.prototype.padEnd) {
+  lib.polyfill.stringPadEnd();
+}
+
+/**
+ * https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Object/values
+ * https://github.com/tc39/proposal-object-values-entries/blob/master/polyfill.js
+ */
+lib.polyfill.object = function() {
+  const reduce = Function.bind.call(Function.call, Array.prototype.reduce);
+  const isEnumerable = Function.bind.call(Function.call,
+      Object.prototype.propertyIsEnumerable);
+  const concat = Function.bind.call(Function.call, Array.prototype.concat);
+
+  if (!Object.values) {
+    /**
+     * @param {!Object} O
+     * @return {!Array}
+     */
+    Object.values = function values(O) {
+      return reduce(Reflect.ownKeys(O), (v, k) => concat(v,
+          typeof k === 'string' && isEnumerable(O, k) ? [O[k]] : []), []);
+    };
+  }
+
+  if (!Object.entries) {
+    /**
+     * @param {!Object} O
+     * @return {!Array<!Array<string>>}
+     */
+    Object.entries = function entries(O) {
+      return reduce(Reflect.ownKeys(O), (e, k) => concat(e,
+          typeof k === 'string' && isEnumerable(O, k) ? [[k, O[k]]] : []), []);
+    };
+  }
+};
+
+if (!Object.values || !Object.entries) {
+  lib.polyfill.object();
+}
+
+/**
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally
+ * https://github.com/tc39/proposal-promise-finally/blob/master/polyfill.js
+ */
+lib.polyfill.promiseFinally = function() {
+  /**
+   * @param {!Object} O
+   * @param {!Function} defaultConstructor
+   * @return {!Function}
+   */
+  const speciesConstructor = function(O, defaultConstructor) {
+    if (!O || (typeof O !== 'object' && typeof O !== 'function')) {
+      throw new TypeError('Assertion failed: Type(O) is not Object');
+    }
+    const C = O.constructor;
+    if (typeof C === 'undefined') {
+      return defaultConstructor;
+    }
+    if (!C || (typeof C !== 'object' && typeof C !== 'function')) {
+      throw new TypeError('O.constructor is not an Object');
+    }
+    const S =
+        typeof Symbol === 'function' && typeof Symbol.species === 'symbol' ?
+        C[Symbol.species] : undefined;
+    if (S == null) {
+      return defaultConstructor;
+    }
+    if (typeof S === 'function' && S.prototype) {
+      return S;
+    }
+    throw new TypeError('no constructor found');
+  };
+
+  /**
+   * @param {function()} onFinally
+   * @return {!Promise}
+   */
+  function finallyFn(onFinally) {
+    const promise = this;
+    if (typeof promise !== 'object' || promise === null) {
+      throw new TypeError('"this" value is not an Object');
+    }
+    const C = speciesConstructor(promise, Promise);
+    if (typeof onFinally !== 'function') {
+      return Promise.prototype.then.call(promise, onFinally, onFinally);
+    }
+    return Promise.prototype.then.call(
+      promise,
+      x => new C(resolve => resolve(onFinally())).then(() => x),
+      e => new C(resolve => resolve(onFinally())).then(() => { throw e; })
+    );
+  }
+  Object.defineProperty(Promise.prototype, 'finally', {
+    configurable: true, writable: true, value: finallyFn,
+  });
+};
+
+if (typeof Promise.prototype.finally !== 'function') {
+  lib.polyfill.promiseFinally();
+}
+
+/**
+ * https://developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer
+ *
+ * @return {!Promise<!ArrayBuffer>}
+ */
+lib.polyfill.BlobArrayBuffer = function() {
+  return new Promise((resolve, reject) => {
+    const reader = new FileReader();
+    reader.onload = () => resolve(reader.result);
+    reader.onabort = reader.onerror = () => reject(reader);
+    reader.readAsArrayBuffer(this);
+  });
+};
+
+if (typeof Blob.prototype.arrayBuffer != 'function') {
+  Blob.prototype.arrayBuffer = lib.polyfill.BlobArrayBuffer;
+}
+
+/**
+ * https://developer.mozilla.org/en-US/docs/Web/API/Blob/text
+ *
+ * @return {!Promise<string>}
+ */
+lib.polyfill.BlobText = function() {
+  return new Promise((resolve, reject) => {
+    const reader = new FileReader();
+    reader.onload = () => resolve(reader.result);
+    reader.onabort = reader.onerror = () => reject(reader);
+    reader.readAsText(this);
+  });
+};
+
+if (typeof Blob.prototype.arrayBuffer != 'function') {
+  Blob.prototype.text = lib.polyfill.BlobText;
+}
+// SOURCE FILE: libdot/js/lib_array.js
+// Copyright 2017 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Helper functions for (typed) arrays.
+ */
+
+lib.array = {};
+
+/**
+ * Concatenate an arbitrary number of typed arrays of the same type into a new
+ * typed array of this type.
+ *
+ * @template TYPED_ARRAY
+ * @param {...!TYPED_ARRAY} arrays
+ * @return {!TYPED_ARRAY}
+ */
+lib.array.concatTyped = function(...arrays) {
+  let resultLength = 0;
+  for (const array of arrays) {
+    resultLength += array.length;
+  }
+  const result = new arrays[0].constructor(resultLength);
+  let pos = 0;
+  for (const array of arrays) {
+    result.set(array, pos);
+    pos += array.length;
+  }
+  return result;
+};
+
+/**
+ * Compare two array-like objects entrywise.
+ *
+ * @template ARRAY_LIKE
+ * @param {?ARRAY_LIKE} a The first array to compare.
+ * @param {?ARRAY_LIKE} b The second array to compare.
+ * @return {boolean} true if both arrays are null or they agree entrywise;
+ *     false otherwise.
+ */
+lib.array.compare = function(a, b) {
+  if (a === null || b === null) {
+    return a === null && b === null;
+  }
+
+  if (a.length !== b.length) {
+    return false;
+  }
+
+  for (let i = 0; i < a.length; i++) {
+    if (a[i] !== b[i]) {
+      return false;
+    }
+  }
+  return true;
+};
+// SOURCE FILE: libdot/js/lib_codec.js
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+lib.codec = {};
+
+/**
+ * Join an array of code units to a string.
+ *
+ * The code units must not be larger than 65535.  The individual code units may
+ * be for UTF-8 or UTF-16 -- it doesn't matter since UTF-16 can handle all UTF-8
+ * code units.
+ *
+ * The input array type may be an Array or a typed Array (e.g. Uint8Array).
+ *
+ * @param {!Uint8Array|!Array<number>} array The code units to generate for
+ *     the string.
+ * @return {string} A UTF-16 encoded string.
+ */
+lib.codec.codeUnitArrayToString = function(array) {
+  // String concat is faster than Array.join.
+  //
+  // String.fromCharCode.apply is faster than this if called less frequently
+  // and with smaller array sizes (like <32K).  But it's a recursive call so
+  // larger arrays will blow the stack and fail.  We also seem to be faster
+  // (or at least more constant time) when called frequently.
+  let ret = '';
+  for (let i = 0; i < array.length; ++i) {
+    ret += String.fromCharCode(array[i]);
+  }
+  return ret;
+};
+
+/**
+ * Create an array of code units from a UTF-16 encoded string.
+ *
+ * @param {string} str The string to extract code units from.
+ * @param {!ArrayBufferView=} ret The buffer to hold the result.  If not set, a
+ *     new Uint8Array is created.
+ * @return {!ArrayBufferView} The array of code units.
+ */
+lib.codec.stringToCodeUnitArray = function(
+    str, ret = new Uint8Array(str.length)) {
+  // Indexing string directly is faster than Array.map.
+  for (let i = 0; i < str.length; ++i) {
+    ret[i] = str.charCodeAt(i);
+  }
+  return ret;
+};
+// SOURCE FILE: libdot/js/lib_colors.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Namespace for color utilities.
+ */
+lib.colors = {};
+
+/**
+ * First, some canned regular expressions we're going to use in this file.
+ *
+ *
+ *                              BRACE YOURSELF
+ *
+ *                                 ,~~~~.
+ *                                 |>_< ~~
+ *                                3`---'-/.
+ *                                3:::::\v\
+ *                               =o=:::::\,\
+ *                                | :::::\,,\
+ *
+ *                        THE REGULAR EXPRESSIONS
+ *                               ARE COMING.
+ *
+ * There's no way to break long RE literals in JavaScript.  Fix that why don't
+ * you?  Oh, and also there's no way to write a string that doesn't interpret
+ * escapes.
+ *
+ * Instead, we stoop to this .replace() trick.
+ */
+lib.colors.re_ = {
+  // CSS hex color, #RGB or RGBA.
+  hex16: /^#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?$/i,
+
+  // CSS hex color, #RRGGBB or #RRGGBBAA.
+  hex24: /^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?$/i,
+
+  // CSS rgb color, rgb(rrr,ggg,bbb).
+  rgb: new RegExp(
+      ('^/s*rgb/s*/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*,' +
+       '/s*(/d{1,3})/s*/)/s*$'
+       ).replace(/\//g, '\\'), 'i'),
+
+  // CSS rgb color, rgba(rrr,ggg,bbb,aaa).
+  rgba: new RegExp(
+      ('^/s*rgba/s*' +
+       '/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*,/s*(/d{1,3})/s*' +
+       '(?:,/s*(/d+(?:/./d+)?)/s*)/)/s*$'
+       ).replace(/\//g, '\\'), 'i'),
+
+  // Either RGB or RGBA.
+  rgbx: new RegExp(
+      ('^/s*rgba?/s*' +
+       '/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*,/s*(/d{1,3})/s*' +
+       '(?:,/s*(/d+(?:/./d+)?)/s*)?/)/s*$'
+       ).replace(/\//g, '\\'), 'i'),
+
+  // CSS hsl color, hsl(hhh,sss%,lll%).
+  hsl: new RegExp(
+      ('^/s*hsl/s*' +
+       '/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*%/s*,/s*(/d{1,3})/s*%/s*/)/s*$'
+       ).replace(/\//g, '\\'), 'i'),
+
+  // CSS hsl color, hsla(hhh,sss%,lll%,aaa).
+  hsla: new RegExp(
+      ('^/s*hsla/s*' +
+       '/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*%/s*,/s*(/d{1,3})/s*%/s*' +
+       '(?:,/s*(/d+(?:/./d+)?)/s*)/)/s*$'
+       ).replace(/\//g, '\\'), 'i'),
+
+  // Either HSL or HSLA.
+  hslx: new RegExp(
+      ('^/s*hsla?/s*' +
+       '/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*%/s*,/s*(/d{1,3})/s*%/s*' +
+       '(?:,/s*(/d+(?:/./d+)?)/s*)?/)/s*$'
+       ).replace(/\//g, '\\'), 'i'),
+
+  // An X11 "rgb:dddd/dddd/dddd" value.
+  x11rgb: /^\s*rgb:([a-f0-9]{1,4})\/([a-f0-9]{1,4})\/([a-f0-9]{1,4})\s*$/i,
+
+  // English color name.
+  name: /[a-z][a-z0-9\s]+/,
+};
+
+/**
+ * Convert a CSS rgb(ddd,ddd,ddd) color value into an X11 color value.
+ *
+ * Other CSS color values are ignored to ensure sanitary data handling.
+ *
+ * Each 'ddd' component is a one byte value specified in decimal.
+ *
+ * @param {string} value The CSS color value to convert.
+ * @return {?string} The X11 color value or null if the value could not be
+ *     converted.
+ */
+lib.colors.rgbToX11 = function(value) {
+  function scale(v) {
+    v = (Math.min(v, 255) * 257).toString(16);
+    return lib.f.zpad(v, 4);
+  }
+
+  var ary = value.match(lib.colors.re_.rgbx);
+  if (!ary)
+    return null;
+
+  return 'rgb:' + scale(ary[1]) + '/' + scale(ary[2]) + '/' + scale(ary[3]);
+};
+
+/**
+ * Convert a legacy X11 color value into an CSS rgb(...) color value.
+ *
+ * They take the form:
+ * 12 bit: #RGB          -> #R000G000B000
+ * 24 bit: #RRGGBB       -> #RR00GG00BB00
+ * 36 bit: #RRRGGGBBB    -> #RRR0GGG0BBB0
+ * 48 bit: #RRRRGGGGBBBB
+ * These are the most significant bits.
+ *
+ * Truncate values back down to 24 bit since that's all CSS supports.
+ *
+ * @param {string} v The X11 hex color value to convert.
+ * @return {?string} The CSS color value or null if the value could not be
+ *     converted.
+ */
+lib.colors.x11HexToCSS = function(v) {
+  if (!v.startsWith('#'))
+    return null;
+  // Strip the leading # off.
+  v = v.substr(1);
+
+  // Reject unknown sizes.
+  if ([3, 6, 9, 12].indexOf(v.length) == -1)
+    return null;
+
+  // Reject non-hex values.
+  if (v.match(/[^a-f0-9]/i))
+    return null;
+
+  // Split the colors out.
+  var size = v.length / 3;
+  var r = v.substr(0, size);
+  var g = v.substr(size, size);
+  var b = v.substr(size + size, size);
+
+  // Normalize to 16 bits.
+  function norm16(v) {
+    v = parseInt(v, 16);
+    return size == 2 ? v :         // 16 bit
+           size == 1 ? v << 4 :    // 8 bit
+           v >> (4 * (size - 2));  // 24 or 32 bit
+  }
+  return lib.colors.arrayToRGBA([r, g, b].map(norm16));
+};
+
+/**
+ * Convert an X11 color value into an CSS rgb(...) color value.
+ *
+ * The X11 value may be an X11 color name, or an RGB value of the form
+ * rgb:hhhh/hhhh/hhhh.  If a component value is less than 4 digits it is
+ * padded out to 4, then scaled down to fit in a single byte.
+ *
+ * @param {string} v The X11 color value to convert.
+ * @return {?string} The CSS color value or null if the value could not be
+ *     converted.
+ */
+lib.colors.x11ToCSS = function(v) {
+  function scale(v) {
+    // Pad out values with less than four digits.  This padding (probably)
+    // matches xterm.  It's difficult to say for sure since xterm seems to
+    // arrive at a padded value and then perform some combination of
+    // gamma correction, color space transformation, and quantization.
+
+    if (v.length == 1) {
+      // Single digits pad out to four by repeating the character.  "f" becomes
+      // "ffff".  Scaling down a hex value of this pattern by 257 is the same
+      // as cutting off one byte.  We skip the middle step and just double
+      // the character.
+      return parseInt(v + v, 16);
+    }
+
+    if (v.length == 2) {
+      // Similar deal here.  X11 pads two digit values by repeating the
+      // byte (or scale up by 257).  Since we're going to scale it back
+      // down anyway, we can just return the original value.
+      return parseInt(v, 16);
+    }
+
+    if (v.length == 3) {
+      // Three digit values seem to be padded by repeating the final digit.
+      // e.g. 10f becomes 10ff.
+      v = v + v.substr(2);
+    }
+
+    // Scale down the 2 byte value.
+    return Math.round(parseInt(v, 16) / 257);
+  }
+
+  var ary = v.match(lib.colors.re_.x11rgb);
+  if (!ary) {
+    // Handle the legacy format.
+    if (v.startsWith('#'))
+      return lib.colors.x11HexToCSS(v);
+    else
+      return lib.colors.nameToRGB(v);
+  }
+
+  ary.splice(0, 1);
+  return lib.colors.arrayToRGBA(ary.map(scale));
+};
+
+/**
+ * Converts one or more CSS '#RRGGBB' or '#RRGGBBAA' color values into their
+ * rgb(...) or rgba(...) form respectively.
+ *
+ * Arrays are converted in place. If a value cannot be converted, it is
+ * replaced with null.
+ *
+ * @param {string} hex A single RGB or RGBA value to convert.
+ * @return {?string} The converted value.
+ */
+lib.colors.hexToRGB = function(hex) {
+  const hex16 = lib.colors.re_.hex16;
+  const hex24 = lib.colors.re_.hex24;
+
+  if (hex16.test(hex)) {
+    // Convert from RGB to RRGGBB and from RGBA to RRGGBBAA.
+    hex = `#${hex.match(/[a-f0-9]/gi).map(x => `${x}${x}`).join('')}`;
+  }
+
+  const ary = hex.match(hex24);
+  if (!ary) {
+    return null;
+  }
+
+  const val = (index) => parseInt(ary[index + 1], 16);
+  return ary[4] === undefined || val(3) === 255
+      ? `rgb(${val(0)}, ${val(1)}, ${val(2)})`
+      : `rgba(${val(0)}, ${val(1)}, ${val(2)}, ${val(3) / 255})`;
+};
+
+/**
+ * Converts one or more CSS rgb(...) or rgba(...) forms into their '#RRGGBB' or
+ * '#RRGGBBAA' color values respectively.
+ *
+ * Arrays are converted in place. If a value cannot be converted, it is
+ * replaced with null.
+ *
+ * @param {string} rgb A single rgb(...) or rgba(...) value to convert.
+ * @return {?string} The converted value.
+ */
+lib.colors.rgbToHex = function(rgb) {
+  const ary = lib.colors.crackRGB(rgb);
+  if (!ary) {
+    return null;
+  }
+
+  const hex = '#' + lib.f.zpad((
+      (parseInt(ary[0], 10) << 16) |
+      (parseInt(ary[1], 10) <<  8) |
+      (parseInt(ary[2], 10) <<  0)).toString(16), 6);
+  return ary[3] === undefined || ary[3] === '1'
+      ? hex
+      : `${hex}${lib.f.zpad(Math.round(255 * ary[3]).toString(16), 2)}`;
+};
+
+/**
+ * Split an hsl/hsla color into an array of its components.
+ *
+ * On success, a 4 element array will be returned.  For hsl values, the alpha
+ * will be set to 1.
+ *
+ * @param {string} color The HSL/HSLA CSS color spec.
+ * @return {?Array<string>} The HSL/HSLA values split out.
+ */
+lib.colors.crackHSL = function(color) {
+  if (color.startsWith('hsla')) {
+    const ary = color.match(lib.colors.re_.hsla);
+    if (ary) {
+      ary.shift();
+      return Array.from(ary);
+    }
+  } else {
+    const ary = color.match(lib.colors.re_.hsl);
+    if (ary) {
+      ary.shift();
+      ary.push('1');
+      return Array.from(ary);
+    }
+  }
+
+  console.error(`Couldn't crack: ${color}`);
+  return null;
+};
+
+/**
+ * Converts hslx array to rgba array.
+ *
+ * The returned alpha component defaults to 1 if it isn't present in the input.
+ *
+ * The returned values are not rounded to preserve precision for computations,
+ * rounded before they are used in CSS strings.
+ *
+ * @param {?Array<string|number>} hslx The HSL or HSLA elements to convert.
+ * @return {!Array<number>} The RGBA values.
+ */
+lib.colors.hslxArrayToRgbaArray = function(hslx) {
+  const hue = hslx[0] / 60;
+  const sat = hslx[1] / 100;
+  const light = hslx[2] / 100;
+
+  // The following algorithm has been adapted from:
+  //     https://www.w3.org/TR/css-color-4/#hsl-to-rgb
+  const hueToRgb = (t1, t2, hue) => {
+    if (hue < 0) {
+      hue += 6;
+    }
+    if (hue >= 6) {
+      hue -= 6;
+    }
+
+    if (hue < 1) {
+      return (t2 - t1) * hue + t1;
+    } else if (hue < 3) {
+      return t2;
+    } else if (hue < 4) {
+      return (t2 - t1) * (4 - hue) + t1;
+    } else {
+      return t1;
+    }
+  };
+
+  const t2 = light <= 0.5 ?  light * (sat + 1) : light + sat - (light * sat);
+  const t1 = light * 2 - t2;
+
+  return [
+    255 * hueToRgb(t1, t2, hue + 2),
+    255 * hueToRgb(t1, t2, hue),
+    255 * hueToRgb(t1, t2, hue - 2),
+    hslx[3] !== undefined ? +hslx[3] : 1
+  ];
+};
+
+/**
+ * Converts one or more CSS hsl(...) or hsla(...) forms into their rgb(...) or
+ * rgba(...) color values respectively.
+ *
+ * Arrays are converted in place. If a value cannot be converted, it is
+ * replaced with null.
+ *
+ * @param {string} hsl A single hsl(...) or hsla(...) value to convert.
+ * @return {?string} The converted value.
+ */
+lib.colors.hslToRGB = function(hsl) {
+  const ary = lib.colors.crackHSL(hsl);
+  if (!ary) {
+    return null;
+  }
+
+  const [r, g, b, a] = lib.colors.hslxArrayToRgbaArray(ary);
+
+  const rgb = [r, g, b].map(Math.round).join(', ');
+
+  return a === 1 ? `rgb(${rgb})` : `rgba(${rgb}, ${a})`;
+};
+
+/**
+ * Converts rgbx array to hsla array.
+ *
+ * The returned alpha component defaults to 1 if it isn't present in the input.
+ *
+ * The returned values are not rounded to preserve precision for computations,
+ * so should be rounded before they are used in CSS strings.
+ *
+ * @param {?Array<string|number>} rgbx The RGB or RGBA elements to convert.
+ * @return {!Array<number>} The HSLA values.
+ */
+lib.colors.rgbxArrayToHslaArray = function(rgbx) {
+  const r = rgbx[0] / 255;
+  const g = rgbx[1] / 255;
+  const b = rgbx[2] / 255;
+
+  const min = Math.min(r, g, b);
+  const max = Math.max(r, g, b);
+  const spread = max - min;
+
+  const l = (max + min) / 2;
+
+  if (spread == 0) {
+    return [0, 0, 100 * l, rgbx[3] !== undefined ? +rgbx[3] : 1];
+  }
+
+  let h = (() => {
+    switch (max) {
+      case r: return ((g - b) / spread) % 6;
+      case g: return (b - r) / spread + 2;
+      case b: return (r - g) / spread + 4;
+    }
+  })();
+  h *= 60;
+  if (h < 0) {
+    h += 360;
+  }
+
+  const s = spread / (1 - Math.abs(2 * l - 1));
+
+  return [h, 100 * s, 100 * l, rgbx[3] !== undefined ? +rgbx[3] : 1];
+};
+
+/**
+ * Converts one or more CSS rgb(...) or rgba(...) forms into their hsl(...) or
+ * hsla(...) color values respectively.
+ *
+ * Arrays are converted in place. If a value cannot be converted, it is
+ * replaced with null.
+ *
+ * @param {string} rgb A single rgb(...) or rgba(...) value to convert.
+ * @return {?string} The converted value.
+ */
+lib.colors.rgbToHsl = function(rgb) {
+  const ary = lib.colors.crackRGB(rgb);
+  if (!ary) {
+    return null;
+  }
+
+  let [h, s, l, a] = lib.colors.rgbxArrayToHslaArray(ary);
+  h = Math.round(h);
+  s = Math.round(s);
+  l = Math.round(l);
+
+  return a === 1 ? `hsl(${h}, ${s}%, ${l}%)` : `hsla(${h}, ${s}%, ${l}%, ${a})`;
+};
+
+/**
+ * Take any valid css color definition and turn it into an rgb or rgba value.
+ *
+ * @param {string} def The CSS color spec to normalize.
+ * @return {?string} The converted value.
+ */
+lib.colors.normalizeCSS = function(def) {
+  if (def.startsWith('#')) {
+    return lib.colors.hexToRGB(def);
+  }
+
+  if (lib.colors.re_.rgbx.test(def)) {
+    return def;
+  }
+
+  if (lib.colors.re_.hslx.test(def)) {
+    return lib.colors.hslToRGB(def);
+  }
+
+  return lib.colors.nameToRGB(def);
+};
+
+/**
+ * Convert a 3 or 4 element array into an rgba(...) string.
+ *
+ * @param {?Array<string|number>} ary The RGB or RGBA elements to convert.
+ * @return {string} The normalized CSS color spec.
+ */
+lib.colors.arrayToRGBA = function(ary) {
+  var alpha = (ary.length > 3) ? ary[3] : 1;
+  return 'rgba(' + ary[0] + ', ' + ary[1] + ', ' + ary[2] + ', ' + alpha + ')';
+};
+
+/**
+ * Overwrite the alpha channel of an rgb/rgba color.
+ *
+ * @param {string} rgb The normalized CSS color spec.
+ * @param {number} alpha The alpha channel.
+ * @return {string} The normalized CSS color spec with updated alpha channel.
+ */
+lib.colors.setAlpha = function(rgb, alpha) {
+  var ary = lib.colors.crackRGB(rgb);
+  ary[3] = alpha.toString();
+  return lib.colors.arrayToRGBA(ary);
+};
+
+/**
+ * Mix a percentage of a tint color into a base color.
+ *
+ * @param  {string} base The normalized CSS base color spec.
+ * @param  {string} tint The normalized CSS color to tint with.
+ * @param  {number} percent The percentage of the tinting.
+ * @return {string} The new tinted CSS color spec.
+ */
+lib.colors.mix = function(base, tint, percent) {
+  var ary1 = lib.colors.crackRGB(base);
+  var ary2 = lib.colors.crackRGB(tint);
+
+  for (var i = 0; i < 4; ++i) {
+    var diff = ary2[i] - ary1[i];
+    ary1[i] = Math.round(parseInt(ary1[i], 10) + diff * percent).toString();
+  }
+
+  return lib.colors.arrayToRGBA(ary1);
+};
+
+/**
+ * Split an rgb/rgba color into an array of its components.
+ *
+ * On success, a 4 element array will be returned.  For rgb values, the alpha
+ * will be set to 1.
+ *
+ * @param {string} color The RGB/RGBA CSS color spec.
+ * @return {?Array<string>} The RGB/RGBA values split out.
+ */
+lib.colors.crackRGB = function(color) {
+  if (color.startsWith('rgba')) {
+    var ary = color.match(lib.colors.re_.rgba);
+    if (ary) {
+      ary.shift();
+      return Array.from(ary);
+    }
+  } else {
+    var ary = color.match(lib.colors.re_.rgb);
+    if (ary) {
+      ary.shift();
+      ary.push('1');
+      return Array.from(ary);
+    }
+  }
+
+  console.error('Couldn\'t crack: ' + color);
+  return null;
+};
+
+/**
+ * Convert an X11 color name into a CSS rgb(...) value.
+ *
+ * Names are stripped of spaces and converted to lowercase.  If the name is
+ * unknown, null is returned.
+ *
+ * This list of color name to RGB mapping is derived from the stock X11
+ * rgb.txt file.
+ *
+ * @param {string} name The color name to convert.
+ * @return {?string} The corresponding CSS rgb(...) value.
+ */
+lib.colors.nameToRGB = function(name) {
+  if (name in lib.colors.colorNames)
+    return lib.colors.colorNames[name];
+
+  name = name.toLowerCase();
+  if (name in lib.colors.colorNames)
+    return lib.colors.colorNames[name];
+
+  name = name.replace(/\s+/g, '');
+  if (name in lib.colors.colorNames)
+    return lib.colors.colorNames[name];
+
+  return null;
+};
+
+/**
+ * The stock color palette.
+ *
+ * @type {!Array<string>}
+ */
+lib.colors.stockColorPalette = [
+     // The "ANSI 16"...
+    '#000000', '#CC0000', '#4E9A06', '#C4A000',
+    '#3465A4', '#75507B', '#06989A', '#D3D7CF',
+    '#555753', '#EF2929', '#00BA13', '#FCE94F',
+    '#729FCF', '#F200CB', '#00B5BD', '#EEEEEC',
+
+    // The 6x6 color cubes...
+    '#000000', '#00005F', '#000087', '#0000AF', '#0000D7', '#0000FF',
+    '#005F00', '#005F5F', '#005F87', '#005FAF', '#005FD7', '#005FFF',
+    '#008700', '#00875F', '#008787', '#0087AF', '#0087D7', '#0087FF',
+    '#00AF00', '#00AF5F', '#00AF87', '#00AFAF', '#00AFD7', '#00AFFF',
+    '#00D700', '#00D75F', '#00D787', '#00D7AF', '#00D7D7', '#00D7FF',
+    '#00FF00', '#00FF5F', '#00FF87', '#00FFAF', '#00FFD7', '#00FFFF',
+
+    '#5F0000', '#5F005F', '#5F0087', '#5F00AF', '#5F00D7', '#5F00FF',
+    '#5F5F00', '#5F5F5F', '#5F5F87', '#5F5FAF', '#5F5FD7', '#5F5FFF',
+    '#5F8700', '#5F875F', '#5F8787', '#5F87AF', '#5F87D7', '#5F87FF',
+    '#5FAF00', '#5FAF5F', '#5FAF87', '#5FAFAF', '#5FAFD7', '#5FAFFF',
+    '#5FD700', '#5FD75F', '#5FD787', '#5FD7AF', '#5FD7D7', '#5FD7FF',
+    '#5FFF00', '#5FFF5F', '#5FFF87', '#5FFFAF', '#5FFFD7', '#5FFFFF',
+
+    '#870000', '#87005F', '#870087', '#8700AF', '#8700D7', '#8700FF',
+    '#875F00', '#875F5F', '#875F87', '#875FAF', '#875FD7', '#875FFF',
+    '#878700', '#87875F', '#878787', '#8787AF', '#8787D7', '#8787FF',
+    '#87AF00', '#87AF5F', '#87AF87', '#87AFAF', '#87AFD7', '#87AFFF',
+    '#87D700', '#87D75F', '#87D787', '#87D7AF', '#87D7D7', '#87D7FF',
+    '#87FF00', '#87FF5F', '#87FF87', '#87FFAF', '#87FFD7', '#87FFFF',
+
+    '#AF0000', '#AF005F', '#AF0087', '#AF00AF', '#AF00D7', '#AF00FF',
+    '#AF5F00', '#AF5F5F', '#AF5F87', '#AF5FAF', '#AF5FD7', '#AF5FFF',
+    '#AF8700', '#AF875F', '#AF8787', '#AF87AF', '#AF87D7', '#AF87FF',
+    '#AFAF00', '#AFAF5F', '#AFAF87', '#AFAFAF', '#AFAFD7', '#AFAFFF',
+    '#AFD700', '#AFD75F', '#AFD787', '#AFD7AF', '#AFD7D7', '#AFD7FF',
+    '#AFFF00', '#AFFF5F', '#AFFF87', '#AFFFAF', '#AFFFD7', '#AFFFFF',
+
+    '#D70000', '#D7005F', '#D70087', '#D700AF', '#D700D7', '#D700FF',
+    '#D75F00', '#D75F5F', '#D75F87', '#D75FAF', '#D75FD7', '#D75FFF',
+    '#D78700', '#D7875F', '#D78787', '#D787AF', '#D787D7', '#D787FF',
+    '#D7AF00', '#D7AF5F', '#D7AF87', '#D7AFAF', '#D7AFD7', '#D7AFFF',
+    '#D7D700', '#D7D75F', '#D7D787', '#D7D7AF', '#D7D7D7', '#D7D7FF',
+    '#D7FF00', '#D7FF5F', '#D7FF87', '#D7FFAF', '#D7FFD7', '#D7FFFF',
+
+    '#FF0000', '#FF005F', '#FF0087', '#FF00AF', '#FF00D7', '#FF00FF',
+    '#FF5F00', '#FF5F5F', '#FF5F87', '#FF5FAF', '#FF5FD7', '#FF5FFF',
+    '#FF8700', '#FF875F', '#FF8787', '#FF87AF', '#FF87D7', '#FF87FF',
+    '#FFAF00', '#FFAF5F', '#FFAF87', '#FFAFAF', '#FFAFD7', '#FFAFFF',
+    '#FFD700', '#FFD75F', '#FFD787', '#FFD7AF', '#FFD7D7', '#FFD7FF',
+    '#FFFF00', '#FFFF5F', '#FFFF87', '#FFFFAF', '#FFFFD7', '#FFFFFF',
+
+    // The greyscale ramp...
+    '#080808', '#121212', '#1C1C1C', '#262626', '#303030', '#3A3A3A',
+    '#444444', '#4E4E4E', '#585858', '#626262', '#6C6C6C', '#767676',
+    '#808080', '#8A8A8A', '#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2',
+    '#BCBCBC', '#C6C6C6', '#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE'
+   ].map(lib.colors.hexToRGB);
+
+/**
+ * The current color palette, possibly with user changes.
+ */
+lib.colors.colorPalette = lib.colors.stockColorPalette;
+
+/**
+ * Named colors according to the stock X11 rgb.txt file.
+ */
+lib.colors.colorNames = {
+  "aliceblue": "rgb(240, 248, 255)",
+  "antiquewhite": "rgb(250, 235, 215)",
+  "antiquewhite1": "rgb(255, 239, 219)",
+  "antiquewhite2": "rgb(238, 223, 204)",
+  "antiquewhite3": "rgb(205, 192, 176)",
+  "antiquewhite4": "rgb(139, 131, 120)",
+  "aquamarine": "rgb(127, 255, 212)",
+  "aquamarine1": "rgb(127, 255, 212)",
+  "aquamarine2": "rgb(118, 238, 198)",
+  "aquamarine3": "rgb(102, 205, 170)",
+  "aquamarine4": "rgb(69, 139, 116)",
+  "azure": "rgb(240, 255, 255)",
+  "azure1": "rgb(240, 255, 255)",
+  "azure2": "rgb(224, 238, 238)",
+  "azure3": "rgb(193, 205, 205)",
+  "azure4": "rgb(131, 139, 139)",
+  "beige": "rgb(245, 245, 220)",
+  "bisque": "rgb(255, 228, 196)",
+  "bisque1": "rgb(255, 228, 196)",
+  "bisque2": "rgb(238, 213, 183)",
+  "bisque3": "rgb(205, 183, 158)",
+  "bisque4": "rgb(139, 125, 107)",
+  "black": "rgb(0, 0, 0)",
+  "blanchedalmond": "rgb(255, 235, 205)",
+  "blue": "rgb(0, 0, 255)",
+  "blue1": "rgb(0, 0, 255)",
+  "blue2": "rgb(0, 0, 238)",
+  "blue3": "rgb(0, 0, 205)",
+  "blue4": "rgb(0, 0, 139)",
+  "blueviolet": "rgb(138, 43, 226)",
+  "brown": "rgb(165, 42, 42)",
+  "brown1": "rgb(255, 64, 64)",
+  "brown2": "rgb(238, 59, 59)",
+  "brown3": "rgb(205, 51, 51)",
+  "brown4": "rgb(139, 35, 35)",
+  "burlywood": "rgb(222, 184, 135)",
+  "burlywood1": "rgb(255, 211, 155)",
+  "burlywood2": "rgb(238, 197, 145)",
+  "burlywood3": "rgb(205, 170, 125)",
+  "burlywood4": "rgb(139, 115, 85)",
+  "cadetblue": "rgb(95, 158, 160)",
+  "cadetblue1": "rgb(152, 245, 255)",
+  "cadetblue2": "rgb(142, 229, 238)",
+  "cadetblue3": "rgb(122, 197, 205)",
+  "cadetblue4": "rgb(83, 134, 139)",
+  "chartreuse": "rgb(127, 255, 0)",
+  "chartreuse1": "rgb(127, 255, 0)",
+  "chartreuse2": "rgb(118, 238, 0)",
+  "chartreuse3": "rgb(102, 205, 0)",
+  "chartreuse4": "rgb(69, 139, 0)",
+  "chocolate": "rgb(210, 105, 30)",
+  "chocolate1": "rgb(255, 127, 36)",
+  "chocolate2": "rgb(238, 118, 33)",
+  "chocolate3": "rgb(205, 102, 29)",
+  "chocolate4": "rgb(139, 69, 19)",
+  "coral": "rgb(255, 127, 80)",
+  "coral1": "rgb(255, 114, 86)",
+  "coral2": "rgb(238, 106, 80)",
+  "coral3": "rgb(205, 91, 69)",
+  "coral4": "rgb(139, 62, 47)",
+  "cornflowerblue": "rgb(100, 149, 237)",
+  "cornsilk": "rgb(255, 248, 220)",
+  "cornsilk1": "rgb(255, 248, 220)",
+  "cornsilk2": "rgb(238, 232, 205)",
+  "cornsilk3": "rgb(205, 200, 177)",
+  "cornsilk4": "rgb(139, 136, 120)",
+  "cyan": "rgb(0, 255, 255)",
+  "cyan1": "rgb(0, 255, 255)",
+  "cyan2": "rgb(0, 238, 238)",
+  "cyan3": "rgb(0, 205, 205)",
+  "cyan4": "rgb(0, 139, 139)",
+  "darkblue": "rgb(0, 0, 139)",
+  "darkcyan": "rgb(0, 139, 139)",
+  "darkgoldenrod": "rgb(184, 134, 11)",
+  "darkgoldenrod1": "rgb(255, 185, 15)",
+  "darkgoldenrod2": "rgb(238, 173, 14)",
+  "darkgoldenrod3": "rgb(205, 149, 12)",
+  "darkgoldenrod4": "rgb(139, 101, 8)",
+  "darkgray": "rgb(169, 169, 169)",
+  "darkgreen": "rgb(0, 100, 0)",
+  "darkgrey": "rgb(169, 169, 169)",
+  "darkkhaki": "rgb(189, 183, 107)",
+  "darkmagenta": "rgb(139, 0, 139)",
+  "darkolivegreen": "rgb(85, 107, 47)",
+  "darkolivegreen1": "rgb(202, 255, 112)",
+  "darkolivegreen2": "rgb(188, 238, 104)",
+  "darkolivegreen3": "rgb(162, 205, 90)",
+  "darkolivegreen4": "rgb(110, 139, 61)",
+  "darkorange": "rgb(255, 140, 0)",
+  "darkorange1": "rgb(255, 127, 0)",
+  "darkorange2": "rgb(238, 118, 0)",
+  "darkorange3": "rgb(205, 102, 0)",
+  "darkorange4": "rgb(139, 69, 0)",
+  "darkorchid": "rgb(153, 50, 204)",
+  "darkorchid1": "rgb(191, 62, 255)",
+  "darkorchid2": "rgb(178, 58, 238)",
+  "darkorchid3": "rgb(154, 50, 205)",
+  "darkorchid4": "rgb(104, 34, 139)",
+  "darkred": "rgb(139, 0, 0)",
+  "darksalmon": "rgb(233, 150, 122)",
+  "darkseagreen": "rgb(143, 188, 143)",
+  "darkseagreen1": "rgb(193, 255, 193)",
+  "darkseagreen2": "rgb(180, 238, 180)",
+  "darkseagreen3": "rgb(155, 205, 155)",
+  "darkseagreen4": "rgb(105, 139, 105)",
+  "darkslateblue": "rgb(72, 61, 139)",
+  "darkslategray": "rgb(47, 79, 79)",
+  "darkslategray1": "rgb(151, 255, 255)",
+  "darkslategray2": "rgb(141, 238, 238)",
+  "darkslategray3": "rgb(121, 205, 205)",
+  "darkslategray4": "rgb(82, 139, 139)",
+  "darkslategrey": "rgb(47, 79, 79)",
+  "darkturquoise": "rgb(0, 206, 209)",
+  "darkviolet": "rgb(148, 0, 211)",
+  "debianred": "rgb(215, 7, 81)",
+  "deeppink": "rgb(255, 20, 147)",
+  "deeppink1": "rgb(255, 20, 147)",
+  "deeppink2": "rgb(238, 18, 137)",
+  "deeppink3": "rgb(205, 16, 118)",
+  "deeppink4": "rgb(139, 10, 80)",
+  "deepskyblue": "rgb(0, 191, 255)",
+  "deepskyblue1": "rgb(0, 191, 255)",
+  "deepskyblue2": "rgb(0, 178, 238)",
+  "deepskyblue3": "rgb(0, 154, 205)",
+  "deepskyblue4": "rgb(0, 104, 139)",
+  "dimgray": "rgb(105, 105, 105)",
+  "dimgrey": "rgb(105, 105, 105)",
+  "dodgerblue": "rgb(30, 144, 255)",
+  "dodgerblue1": "rgb(30, 144, 255)",
+  "dodgerblue2": "rgb(28, 134, 238)",
+  "dodgerblue3": "rgb(24, 116, 205)",
+  "dodgerblue4": "rgb(16, 78, 139)",
+  "firebrick": "rgb(178, 34, 34)",
+  "firebrick1": "rgb(255, 48, 48)",
+  "firebrick2": "rgb(238, 44, 44)",
+  "firebrick3": "rgb(205, 38, 38)",
+  "firebrick4": "rgb(139, 26, 26)",
+  "floralwhite": "rgb(255, 250, 240)",
+  "forestgreen": "rgb(34, 139, 34)",
+  "gainsboro": "rgb(220, 220, 220)",
+  "ghostwhite": "rgb(248, 248, 255)",
+  "gold": "rgb(255, 215, 0)",
+  "gold1": "rgb(255, 215, 0)",
+  "gold2": "rgb(238, 201, 0)",
+  "gold3": "rgb(205, 173, 0)",
+  "gold4": "rgb(139, 117, 0)",
+  "goldenrod": "rgb(218, 165, 32)",
+  "goldenrod1": "rgb(255, 193, 37)",
+  "goldenrod2": "rgb(238, 180, 34)",
+  "goldenrod3": "rgb(205, 155, 29)",
+  "goldenrod4": "rgb(139, 105, 20)",
+  "gray": "rgb(190, 190, 190)",
+  "gray0": "rgb(0, 0, 0)",
+  "gray1": "rgb(3, 3, 3)",
+  "gray10": "rgb(26, 26, 26)",
+  "gray100": "rgb(255, 255, 255)",
+  "gray11": "rgb(28, 28, 28)",
+  "gray12": "rgb(31, 31, 31)",
+  "gray13": "rgb(33, 33, 33)",
+  "gray14": "rgb(36, 36, 36)",
+  "gray15": "rgb(38, 38, 38)",
+  "gray16": "rgb(41, 41, 41)",
+  "gray17": "rgb(43, 43, 43)",
+  "gray18": "rgb(46, 46, 46)",
+  "gray19": "rgb(48, 48, 48)",
+  "gray2": "rgb(5, 5, 5)",
+  "gray20": "rgb(51, 51, 51)",
+  "gray21": "rgb(54, 54, 54)",
+  "gray22": "rgb(56, 56, 56)",
+  "gray23": "rgb(59, 59, 59)",
+  "gray24": "rgb(61, 61, 61)",
+  "gray25": "rgb(64, 64, 64)",
+  "gray26": "rgb(66, 66, 66)",
+  "gray27": "rgb(69, 69, 69)",
+  "gray28": "rgb(71, 71, 71)",
+  "gray29": "rgb(74, 74, 74)",
+  "gray3": "rgb(8, 8, 8)",
+  "gray30": "rgb(77, 77, 77)",
+  "gray31": "rgb(79, 79, 79)",
+  "gray32": "rgb(82, 82, 82)",
+  "gray33": "rgb(84, 84, 84)",
+  "gray34": "rgb(87, 87, 87)",
+  "gray35": "rgb(89, 89, 89)",
+  "gray36": "rgb(92, 92, 92)",
+  "gray37": "rgb(94, 94, 94)",
+  "gray38": "rgb(97, 97, 97)",
+  "gray39": "rgb(99, 99, 99)",
+  "gray4": "rgb(10, 10, 10)",
+  "gray40": "rgb(102, 102, 102)",
+  "gray41": "rgb(105, 105, 105)",
+  "gray42": "rgb(107, 107, 107)",
+  "gray43": "rgb(110, 110, 110)",
+  "gray44": "rgb(112, 112, 112)",
+  "gray45": "rgb(115, 115, 115)",
+  "gray46": "rgb(117, 117, 117)",
+  "gray47": "rgb(120, 120, 120)",
+  "gray48": "rgb(122, 122, 122)",
+  "gray49": "rgb(125, 125, 125)",
+  "gray5": "rgb(13, 13, 13)",
+  "gray50": "rgb(127, 127, 127)",
+  "gray51": "rgb(130, 130, 130)",
+  "gray52": "rgb(133, 133, 133)",
+  "gray53": "rgb(135, 135, 135)",
+  "gray54": "rgb(138, 138, 138)",
+  "gray55": "rgb(140, 140, 140)",
+  "gray56": "rgb(143, 143, 143)",
+  "gray57": "rgb(145, 145, 145)",
+  "gray58": "rgb(148, 148, 148)",
+  "gray59": "rgb(150, 150, 150)",
+  "gray6": "rgb(15, 15, 15)",
+  "gray60": "rgb(153, 153, 153)",
+  "gray61": "rgb(156, 156, 156)",
+  "gray62": "rgb(158, 158, 158)",
+  "gray63": "rgb(161, 161, 161)",
+  "gray64": "rgb(163, 163, 163)",
+  "gray65": "rgb(166, 166, 166)",
+  "gray66": "rgb(168, 168, 168)",
+  "gray67": "rgb(171, 171, 171)",
+  "gray68": "rgb(173, 173, 173)",
+  "gray69": "rgb(176, 176, 176)",
+  "gray7": "rgb(18, 18, 18)",
+  "gray70": "rgb(179, 179, 179)",
+  "gray71": "rgb(181, 181, 181)",
+  "gray72": "rgb(184, 184, 184)",
+  "gray73": "rgb(186, 186, 186)",
+  "gray74": "rgb(189, 189, 189)",
+  "gray75": "rgb(191, 191, 191)",
+  "gray76": "rgb(194, 194, 194)",
+  "gray77": "rgb(196, 196, 196)",
+  "gray78": "rgb(199, 199, 199)",
+  "gray79": "rgb(201, 201, 201)",
+  "gray8": "rgb(20, 20, 20)",
+  "gray80": "rgb(204, 204, 204)",
+  "gray81": "rgb(207, 207, 207)",
+  "gray82": "rgb(209, 209, 209)",
+  "gray83": "rgb(212, 212, 212)",
+  "gray84": "rgb(214, 214, 214)",
+  "gray85": "rgb(217, 217, 217)",
+  "gray86": "rgb(219, 219, 219)",
+  "gray87": "rgb(222, 222, 222)",
+  "gray88": "rgb(224, 224, 224)",
+  "gray89": "rgb(227, 227, 227)",
+  "gray9": "rgb(23, 23, 23)",
+  "gray90": "rgb(229, 229, 229)",
+  "gray91": "rgb(232, 232, 232)",
+  "gray92": "rgb(235, 235, 235)",
+  "gray93": "rgb(237, 237, 237)",
+  "gray94": "rgb(240, 240, 240)",
+  "gray95": "rgb(242, 242, 242)",
+  "gray96": "rgb(245, 245, 245)",
+  "gray97": "rgb(247, 247, 247)",
+  "gray98": "rgb(250, 250, 250)",
+  "gray99": "rgb(252, 252, 252)",
+  "green": "rgb(0, 255, 0)",
+  "green1": "rgb(0, 255, 0)",
+  "green2": "rgb(0, 238, 0)",
+  "green3": "rgb(0, 205, 0)",
+  "green4": "rgb(0, 139, 0)",
+  "greenyellow": "rgb(173, 255, 47)",
+  "grey": "rgb(190, 190, 190)",
+  "grey0": "rgb(0, 0, 0)",
+  "grey1": "rgb(3, 3, 3)",
+  "grey10": "rgb(26, 26, 26)",
+  "grey100": "rgb(255, 255, 255)",
+  "grey11": "rgb(28, 28, 28)",
+  "grey12": "rgb(31, 31, 31)",
+  "grey13": "rgb(33, 33, 33)",
+  "grey14": "rgb(36, 36, 36)",
+  "grey15": "rgb(38, 38, 38)",
+  "grey16": "rgb(41, 41, 41)",
+  "grey17": "rgb(43, 43, 43)",
+  "grey18": "rgb(46, 46, 46)",
+  "grey19": "rgb(48, 48, 48)",
+  "grey2": "rgb(5, 5, 5)",
+  "grey20": "rgb(51, 51, 51)",
+  "grey21": "rgb(54, 54, 54)",
+  "grey22": "rgb(56, 56, 56)",
+  "grey23": "rgb(59, 59, 59)",
+  "grey24": "rgb(61, 61, 61)",
+  "grey25": "rgb(64, 64, 64)",
+  "grey26": "rgb(66, 66, 66)",
+  "grey27": "rgb(69, 69, 69)",
+  "grey28": "rgb(71, 71, 71)",
+  "grey29": "rgb(74, 74, 74)",
+  "grey3": "rgb(8, 8, 8)",
+  "grey30": "rgb(77, 77, 77)",
+  "grey31": "rgb(79, 79, 79)",
+  "grey32": "rgb(82, 82, 82)",
+  "grey33": "rgb(84, 84, 84)",
+  "grey34": "rgb(87, 87, 87)",
+  "grey35": "rgb(89, 89, 89)",
+  "grey36": "rgb(92, 92, 92)",
+  "grey37": "rgb(94, 94, 94)",
+  "grey38": "rgb(97, 97, 97)",
+  "grey39": "rgb(99, 99, 99)",
+  "grey4": "rgb(10, 10, 10)",
+  "grey40": "rgb(102, 102, 102)",
+  "grey41": "rgb(105, 105, 105)",
+  "grey42": "rgb(107, 107, 107)",
+  "grey43": "rgb(110, 110, 110)",
+  "grey44": "rgb(112, 112, 112)",
+  "grey45": "rgb(115, 115, 115)",
+  "grey46": "rgb(117, 117, 117)",
+  "grey47": "rgb(120, 120, 120)",
+  "grey48": "rgb(122, 122, 122)",
+  "grey49": "rgb(125, 125, 125)",
+  "grey5": "rgb(13, 13, 13)",
+  "grey50": "rgb(127, 127, 127)",
+  "grey51": "rgb(130, 130, 130)",
+  "grey52": "rgb(133, 133, 133)",
+  "grey53": "rgb(135, 135, 135)",
+  "grey54": "rgb(138, 138, 138)",
+  "grey55": "rgb(140, 140, 140)",
+  "grey56": "rgb(143, 143, 143)",
+  "grey57": "rgb(145, 145, 145)",
+  "grey58": "rgb(148, 148, 148)",
+  "grey59": "rgb(150, 150, 150)",
+  "grey6": "rgb(15, 15, 15)",
+  "grey60": "rgb(153, 153, 153)",
+  "grey61": "rgb(156, 156, 156)",
+  "grey62": "rgb(158, 158, 158)",
+  "grey63": "rgb(161, 161, 161)",
+  "grey64": "rgb(163, 163, 163)",
+  "grey65": "rgb(166, 166, 166)",
+  "grey66": "rgb(168, 168, 168)",
+  "grey67": "rgb(171, 171, 171)",
+  "grey68": "rgb(173, 173, 173)",
+  "grey69": "rgb(176, 176, 176)",
+  "grey7": "rgb(18, 18, 18)",
+  "grey70": "rgb(179, 179, 179)",
+  "grey71": "rgb(181, 181, 181)",
+  "grey72": "rgb(184, 184, 184)",
+  "grey73": "rgb(186, 186, 186)",
+  "grey74": "rgb(189, 189, 189)",
+  "grey75": "rgb(191, 191, 191)",
+  "grey76": "rgb(194, 194, 194)",
+  "grey77": "rgb(196, 196, 196)",
+  "grey78": "rgb(199, 199, 199)",
+  "grey79": "rgb(201, 201, 201)",
+  "grey8": "rgb(20, 20, 20)",
+  "grey80": "rgb(204, 204, 204)",
+  "grey81": "rgb(207, 207, 207)",
+  "grey82": "rgb(209, 209, 209)",
+  "grey83": "rgb(212, 212, 212)",
+  "grey84": "rgb(214, 214, 214)",
+  "grey85": "rgb(217, 217, 217)",
+  "grey86": "rgb(219, 219, 219)",
+  "grey87": "rgb(222, 222, 222)",
+  "grey88": "rgb(224, 224, 224)",
+  "grey89": "rgb(227, 227, 227)",
+  "grey9": "rgb(23, 23, 23)",
+  "grey90": "rgb(229, 229, 229)",
+  "grey91": "rgb(232, 232, 232)",
+  "grey92": "rgb(235, 235, 235)",
+  "grey93": "rgb(237, 237, 237)",
+  "grey94": "rgb(240, 240, 240)",
+  "grey95": "rgb(242, 242, 242)",
+  "grey96": "rgb(245, 245, 245)",
+  "grey97": "rgb(247, 247, 247)",
+  "grey98": "rgb(250, 250, 250)",
+  "grey99": "rgb(252, 252, 252)",
+  "honeydew": "rgb(240, 255, 240)",
+  "honeydew1": "rgb(240, 255, 240)",
+  "honeydew2": "rgb(224, 238, 224)",
+  "honeydew3": "rgb(193, 205, 193)",
+  "honeydew4": "rgb(131, 139, 131)",
+  "hotpink": "rgb(255, 105, 180)",
+  "hotpink1": "rgb(255, 110, 180)",
+  "hotpink2": "rgb(238, 106, 167)",
+  "hotpink3": "rgb(205, 96, 144)",
+  "hotpink4": "rgb(139, 58, 98)",
+  "indianred": "rgb(205, 92, 92)",
+  "indianred1": "rgb(255, 106, 106)",
+  "indianred2": "rgb(238, 99, 99)",
+  "indianred3": "rgb(205, 85, 85)",
+  "indianred4": "rgb(139, 58, 58)",
+  "ivory": "rgb(255, 255, 240)",
+  "ivory1": "rgb(255, 255, 240)",
+  "ivory2": "rgb(238, 238, 224)",
+  "ivory3": "rgb(205, 205, 193)",
+  "ivory4": "rgb(139, 139, 131)",
+  "khaki": "rgb(240, 230, 140)",
+  "khaki1": "rgb(255, 246, 143)",
+  "khaki2": "rgb(238, 230, 133)",
+  "khaki3": "rgb(205, 198, 115)",
+  "khaki4": "rgb(139, 134, 78)",
+  "lavender": "rgb(230, 230, 250)",
+  "lavenderblush": "rgb(255, 240, 245)",
+  "lavenderblush1": "rgb(255, 240, 245)",
+  "lavenderblush2": "rgb(238, 224, 229)",
+  "lavenderblush3": "rgb(205, 193, 197)",
+  "lavenderblush4": "rgb(139, 131, 134)",
+  "lawngreen": "rgb(124, 252, 0)",
+  "lemonchiffon": "rgb(255, 250, 205)",
+  "lemonchiffon1": "rgb(255, 250, 205)",
+  "lemonchiffon2": "rgb(238, 233, 191)",
+  "lemonchiffon3": "rgb(205, 201, 165)",
+  "lemonchiffon4": "rgb(139, 137, 112)",
+  "lightblue": "rgb(173, 216, 230)",
+  "lightblue1": "rgb(191, 239, 255)",
+  "lightblue2": "rgb(178, 223, 238)",
+  "lightblue3": "rgb(154, 192, 205)",
+  "lightblue4": "rgb(104, 131, 139)",
+  "lightcoral": "rgb(240, 128, 128)",
+  "lightcyan": "rgb(224, 255, 255)",
+  "lightcyan1": "rgb(224, 255, 255)",
+  "lightcyan2": "rgb(209, 238, 238)",
+  "lightcyan3": "rgb(180, 205, 205)",
+  "lightcyan4": "rgb(122, 139, 139)",
+  "lightgoldenrod": "rgb(238, 221, 130)",
+  "lightgoldenrod1": "rgb(255, 236, 139)",
+  "lightgoldenrod2": "rgb(238, 220, 130)",
+  "lightgoldenrod3": "rgb(205, 190, 112)",
+  "lightgoldenrod4": "rgb(139, 129, 76)",
+  "lightgoldenrodyellow": "rgb(250, 250, 210)",
+  "lightgray": "rgb(211, 211, 211)",
+  "lightgreen": "rgb(144, 238, 144)",
+  "lightgrey": "rgb(211, 211, 211)",
+  "lightpink": "rgb(255, 182, 193)",
+  "lightpink1": "rgb(255, 174, 185)",
+  "lightpink2": "rgb(238, 162, 173)",
+  "lightpink3": "rgb(205, 140, 149)",
+  "lightpink4": "rgb(139, 95, 101)",
+  "lightsalmon": "rgb(255, 160, 122)",
+  "lightsalmon1": "rgb(255, 160, 122)",
+  "lightsalmon2": "rgb(238, 149, 114)",
+  "lightsalmon3": "rgb(205, 129, 98)",
+  "lightsalmon4": "rgb(139, 87, 66)",
+  "lightseagreen": "rgb(32, 178, 170)",
+  "lightskyblue": "rgb(135, 206, 250)",
+  "lightskyblue1": "rgb(176, 226, 255)",
+  "lightskyblue2": "rgb(164, 211, 238)",
+  "lightskyblue3": "rgb(141, 182, 205)",
+  "lightskyblue4": "rgb(96, 123, 139)",
+  "lightslateblue": "rgb(132, 112, 255)",
+  "lightslategray": "rgb(119, 136, 153)",
+  "lightslategrey": "rgb(119, 136, 153)",
+  "lightsteelblue": "rgb(176, 196, 222)",
+  "lightsteelblue1": "rgb(202, 225, 255)",
+  "lightsteelblue2": "rgb(188, 210, 238)",
+  "lightsteelblue3": "rgb(162, 181, 205)",
+  "lightsteelblue4": "rgb(110, 123, 139)",
+  "lightyellow": "rgb(255, 255, 224)",
+  "lightyellow1": "rgb(255, 255, 224)",
+  "lightyellow2": "rgb(238, 238, 209)",
+  "lightyellow3": "rgb(205, 205, 180)",
+  "lightyellow4": "rgb(139, 139, 122)",
+  "limegreen": "rgb(50, 205, 50)",
+  "linen": "rgb(250, 240, 230)",
+  "magenta": "rgb(255, 0, 255)",
+  "magenta1": "rgb(255, 0, 255)",
+  "magenta2": "rgb(238, 0, 238)",
+  "magenta3": "rgb(205, 0, 205)",
+  "magenta4": "rgb(139, 0, 139)",
+  "maroon": "rgb(176, 48, 96)",
+  "maroon1": "rgb(255, 52, 179)",
+  "maroon2": "rgb(238, 48, 167)",
+  "maroon3": "rgb(205, 41, 144)",
+  "maroon4": "rgb(139, 28, 98)",
+  "mediumaquamarine": "rgb(102, 205, 170)",
+  "mediumblue": "rgb(0, 0, 205)",
+  "mediumorchid": "rgb(186, 85, 211)",
+  "mediumorchid1": "rgb(224, 102, 255)",
+  "mediumorchid2": "rgb(209, 95, 238)",
+  "mediumorchid3": "rgb(180, 82, 205)",
+  "mediumorchid4": "rgb(122, 55, 139)",
+  "mediumpurple": "rgb(147, 112, 219)",
+  "mediumpurple1": "rgb(171, 130, 255)",
+  "mediumpurple2": "rgb(159, 121, 238)",
+  "mediumpurple3": "rgb(137, 104, 205)",
+  "mediumpurple4": "rgb(93, 71, 139)",
+  "mediumseagreen": "rgb(60, 179, 113)",
+  "mediumslateblue": "rgb(123, 104, 238)",
+  "mediumspringgreen": "rgb(0, 250, 154)",
+  "mediumturquoise": "rgb(72, 209, 204)",
+  "mediumvioletred": "rgb(199, 21, 133)",
+  "midnightblue": "rgb(25, 25, 112)",
+  "mintcream": "rgb(245, 255, 250)",
+  "mistyrose": "rgb(255, 228, 225)",
+  "mistyrose1": "rgb(255, 228, 225)",
+  "mistyrose2": "rgb(238, 213, 210)",
+  "mistyrose3": "rgb(205, 183, 181)",
+  "mistyrose4": "rgb(139, 125, 123)",
+  "moccasin": "rgb(255, 228, 181)",
+  "navajowhite": "rgb(255, 222, 173)",
+  "navajowhite1": "rgb(255, 222, 173)",
+  "navajowhite2": "rgb(238, 207, 161)",
+  "navajowhite3": "rgb(205, 179, 139)",
+  "navajowhite4": "rgb(139, 121, 94)",
+  "navy": "rgb(0, 0, 128)",
+  "navyblue": "rgb(0, 0, 128)",
+  "oldlace": "rgb(253, 245, 230)",
+  "olivedrab": "rgb(107, 142, 35)",
+  "olivedrab1": "rgb(192, 255, 62)",
+  "olivedrab2": "rgb(179, 238, 58)",
+  "olivedrab3": "rgb(154, 205, 50)",
+  "olivedrab4": "rgb(105, 139, 34)",
+  "orange": "rgb(255, 165, 0)",
+  "orange1": "rgb(255, 165, 0)",
+  "orange2": "rgb(238, 154, 0)",
+  "orange3": "rgb(205, 133, 0)",
+  "orange4": "rgb(139, 90, 0)",
+  "orangered": "rgb(255, 69, 0)",
+  "orangered1": "rgb(255, 69, 0)",
+  "orangered2": "rgb(238, 64, 0)",
+  "orangered3": "rgb(205, 55, 0)",
+  "orangered4": "rgb(139, 37, 0)",
+  "orchid": "rgb(218, 112, 214)",
+  "orchid1": "rgb(255, 131, 250)",
+  "orchid2": "rgb(238, 122, 233)",
+  "orchid3": "rgb(205, 105, 201)",
+  "orchid4": "rgb(139, 71, 137)",
+  "palegoldenrod": "rgb(238, 232, 170)",
+  "palegreen": "rgb(152, 251, 152)",
+  "palegreen1": "rgb(154, 255, 154)",
+  "palegreen2": "rgb(144, 238, 144)",
+  "palegreen3": "rgb(124, 205, 124)",
+  "palegreen4": "rgb(84, 139, 84)",
+  "paleturquoise": "rgb(175, 238, 238)",
+  "paleturquoise1": "rgb(187, 255, 255)",
+  "paleturquoise2": "rgb(174, 238, 238)",
+  "paleturquoise3": "rgb(150, 205, 205)",
+  "paleturquoise4": "rgb(102, 139, 139)",
+  "palevioletred": "rgb(219, 112, 147)",
+  "palevioletred1": "rgb(255, 130, 171)",
+  "palevioletred2": "rgb(238, 121, 159)",
+  "palevioletred3": "rgb(205, 104, 137)",
+  "palevioletred4": "rgb(139, 71, 93)",
+  "papayawhip": "rgb(255, 239, 213)",
+  "peachpuff": "rgb(255, 218, 185)",
+  "peachpuff1": "rgb(255, 218, 185)",
+  "peachpuff2": "rgb(238, 203, 173)",
+  "peachpuff3": "rgb(205, 175, 149)",
+  "peachpuff4": "rgb(139, 119, 101)",
+  "peru": "rgb(205, 133, 63)",
+  "pink": "rgb(255, 192, 203)",
+  "pink1": "rgb(255, 181, 197)",
+  "pink2": "rgb(238, 169, 184)",
+  "pink3": "rgb(205, 145, 158)",
+  "pink4": "rgb(139, 99, 108)",
+  "plum": "rgb(221, 160, 221)",
+  "plum1": "rgb(255, 187, 255)",
+  "plum2": "rgb(238, 174, 238)",
+  "plum3": "rgb(205, 150, 205)",
+  "plum4": "rgb(139, 102, 139)",
+  "powderblue": "rgb(176, 224, 230)",
+  "purple": "rgb(160, 32, 240)",
+  "purple1": "rgb(155, 48, 255)",
+  "purple2": "rgb(145, 44, 238)",
+  "purple3": "rgb(125, 38, 205)",
+  "purple4": "rgb(85, 26, 139)",
+  "red": "rgb(255, 0, 0)",
+  "red1": "rgb(255, 0, 0)",
+  "red2": "rgb(238, 0, 0)",
+  "red3": "rgb(205, 0, 0)",
+  "red4": "rgb(139, 0, 0)",
+  "rosybrown": "rgb(188, 143, 143)",
+  "rosybrown1": "rgb(255, 193, 193)",
+  "rosybrown2": "rgb(238, 180, 180)",
+  "rosybrown3": "rgb(205, 155, 155)",
+  "rosybrown4": "rgb(139, 105, 105)",
+  "royalblue": "rgb(65, 105, 225)",
+  "royalblue1": "rgb(72, 118, 255)",
+  "royalblue2": "rgb(67, 110, 238)",
+  "royalblue3": "rgb(58, 95, 205)",
+  "royalblue4": "rgb(39, 64, 139)",
+  "saddlebrown": "rgb(139, 69, 19)",
+  "salmon": "rgb(250, 128, 114)",
+  "salmon1": "rgb(255, 140, 105)",
+  "salmon2": "rgb(238, 130, 98)",
+  "salmon3": "rgb(205, 112, 84)",
+  "salmon4": "rgb(139, 76, 57)",
+  "sandybrown": "rgb(244, 164, 96)",
+  "seagreen": "rgb(46, 139, 87)",
+  "seagreen1": "rgb(84, 255, 159)",
+  "seagreen2": "rgb(78, 238, 148)",
+  "seagreen3": "rgb(67, 205, 128)",
+  "seagreen4": "rgb(46, 139, 87)",
+  "seashell": "rgb(255, 245, 238)",
+  "seashell1": "rgb(255, 245, 238)",
+  "seashell2": "rgb(238, 229, 222)",
+  "seashell3": "rgb(205, 197, 191)",
+  "seashell4": "rgb(139, 134, 130)",
+  "sienna": "rgb(160, 82, 45)",
+  "sienna1": "rgb(255, 130, 71)",
+  "sienna2": "rgb(238, 121, 66)",
+  "sienna3": "rgb(205, 104, 57)",
+  "sienna4": "rgb(139, 71, 38)",
+  "skyblue": "rgb(135, 206, 235)",
+  "skyblue1": "rgb(135, 206, 255)",
+  "skyblue2": "rgb(126, 192, 238)",
+  "skyblue3": "rgb(108, 166, 205)",
+  "skyblue4": "rgb(74, 112, 139)",
+  "slateblue": "rgb(106, 90, 205)",
+  "slateblue1": "rgb(131, 111, 255)",
+  "slateblue2": "rgb(122, 103, 238)",
+  "slateblue3": "rgb(105, 89, 205)",
+  "slateblue4": "rgb(71, 60, 139)",
+  "slategray": "rgb(112, 128, 144)",
+  "slategray1": "rgb(198, 226, 255)",
+  "slategray2": "rgb(185, 211, 238)",
+  "slategray3": "rgb(159, 182, 205)",
+  "slategray4": "rgb(108, 123, 139)",
+  "slategrey": "rgb(112, 128, 144)",
+  "snow": "rgb(255, 250, 250)",
+  "snow1": "rgb(255, 250, 250)",
+  "snow2": "rgb(238, 233, 233)",
+  "snow3": "rgb(205, 201, 201)",
+  "snow4": "rgb(139, 137, 137)",
+  "springgreen": "rgb(0, 255, 127)",
+  "springgreen1": "rgb(0, 255, 127)",
+  "springgreen2": "rgb(0, 238, 118)",
+  "springgreen3": "rgb(0, 205, 102)",
+  "springgreen4": "rgb(0, 139, 69)",
+  "steelblue": "rgb(70, 130, 180)",
+  "steelblue1": "rgb(99, 184, 255)",
+  "steelblue2": "rgb(92, 172, 238)",
+  "steelblue3": "rgb(79, 148, 205)",
+  "steelblue4": "rgb(54, 100, 139)",
+  "tan": "rgb(210, 180, 140)",
+  "tan1": "rgb(255, 165, 79)",
+  "tan2": "rgb(238, 154, 73)",
+  "tan3": "rgb(205, 133, 63)",
+  "tan4": "rgb(139, 90, 43)",
+  "thistle": "rgb(216, 191, 216)",
+  "thistle1": "rgb(255, 225, 255)",
+  "thistle2": "rgb(238, 210, 238)",
+  "thistle3": "rgb(205, 181, 205)",
+  "thistle4": "rgb(139, 123, 139)",
+  "tomato": "rgb(255, 99, 71)",
+  "tomato1": "rgb(255, 99, 71)",
+  "tomato2": "rgb(238, 92, 66)",
+  "tomato3": "rgb(205, 79, 57)",
+  "tomato4": "rgb(139, 54, 38)",
+  "turquoise": "rgb(64, 224, 208)",
+  "turquoise1": "rgb(0, 245, 255)",
+  "turquoise2": "rgb(0, 229, 238)",
+  "turquoise3": "rgb(0, 197, 205)",
+  "turquoise4": "rgb(0, 134, 139)",
+  "violet": "rgb(238, 130, 238)",
+  "violetred": "rgb(208, 32, 144)",
+  "violetred1": "rgb(255, 62, 150)",
+  "violetred2": "rgb(238, 58, 140)",
+  "violetred3": "rgb(205, 50, 120)",
+  "violetred4": "rgb(139, 34, 82)",
+  "wheat": "rgb(245, 222, 179)",
+  "wheat1": "rgb(255, 231, 186)",
+  "wheat2": "rgb(238, 216, 174)",
+  "wheat3": "rgb(205, 186, 150)",
+  "wheat4": "rgb(139, 126, 102)",
+  "white": "rgb(255, 255, 255)",
+  "whitesmoke": "rgb(245, 245, 245)",
+  "yellow": "rgb(255, 255, 0)",
+  "yellow1": "rgb(255, 255, 0)",
+  "yellow2": "rgb(238, 238, 0)",
+  "yellow3": "rgb(205, 205, 0)",
+  "yellow4": "rgb(139, 139, 0)",
+  "yellowgreen": "rgb(154, 205, 50)"
+};
+// SOURCE FILE: libdot/js/lib_f.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Grab bag of utility functions.
+ */
+lib.f = {};
+
+/**
+ * Replace variable references in a string.
+ *
+ * Variables are of the form %FUNCTION(VARNAME).  FUNCTION is an optional
+ * escape function to apply to the value.
+ *
+ * For example
+ *   lib.f.replaceVars("%(greeting), %encodeURIComponent(name)",
+ *                     { greeting: "Hello",
+ *                       name: "Google+" });
+ *
+ * Will result in "Hello, Google%2B".
+ *
+ * @param {string} str String containing variable references.
+ * @param {!Object<string, string>} vars Variables to substitute in.
+ * @return {string} String with references substituted.
+ */
+lib.f.replaceVars = function(str, vars) {
+  return str.replace(/%([a-z]*)\(([^\)]+)\)/gi, function(match, fn, varname) {
+      if (typeof vars[varname] == 'undefined')
+        throw 'Unknown variable: ' + varname;
+
+      var rv = vars[varname];
+
+      if (fn in lib.f.replaceVars.functions) {
+        rv = lib.f.replaceVars.functions[fn](rv);
+      } else if (fn) {
+        throw 'Unknown escape function: ' + fn;
+      }
+
+      return rv;
+    });
+};
+
+/**
+ * Functions that can be used with replaceVars.
+ *
+ * Clients can add to this list to extend lib.f.replaceVars().
+ */
+lib.f.replaceVars.functions = {
+  encodeURI: encodeURI,
+  encodeURIComponent: encodeURIComponent,
+  escapeHTML: function(str) {
+    var map = {
+      '<': '&lt;',
+      '>': '&gt;',
+      '&': '&amp;',
+      '"': '&quot;',
+      "'": '&#39;'
+    };
+
+    return str.replace(/[<>&\"\']/g, (m) => map[m]);
+  }
+};
+
+/**
+ * Convert a relative path to a fully qulified URI.
+ *
+ * @param {string} path Relative path
+ * @return {string} Fully qualified URI.
+ */
+lib.f.getURL = function(path) {
+  if (lib.f.getURL.chromeSupported())
+    return chrome.runtime.getURL(path);
+
+  return path;
+};
+
+/**
+ * Determine whether the runtime is Chrome (or equiv).
+ *
+ * @return {boolean} True if chrome.runtime.getURL is supported.
+ */
+lib.f.getURL.chromeSupported = function() {
+  return window.chrome && chrome.runtime && chrome.runtime.getURL;
+};
+
+/**
+ * Clamp a given integer to a specified range.
+ *
+ * @param {number} v The value to be clamped.
+ * @param {number} min The minimum acceptable value.
+ * @param {number} max The maximum acceptable value.
+ * @return {number} The clamped value.
+ */
+lib.f.clamp = function(v, min, max) {
+  if (v < min)
+    return min;
+  if (v > max)
+    return max;
+  return v;
+};
+
+/**
+ * Left pad a number to a given length with leading zeros.
+ *
+ * @param {string|number} number The number to pad.
+ * @param {number} length The desired length.
+ * @return {string} The padded number as a string.
+ */
+lib.f.zpad = function(number, length) {
+  return String(number).padStart(length, '0');
+};
+
+/**
+ * Return the current call stack after skipping a given number of frames.
+ *
+ * This method is intended to be used for debugging only.  It returns an
+ * Object instead of an Array, because the console stringifies arrays by
+ * default and that's not what we want.
+ *
+ * A typical call might look like...
+ *
+ *    console.log('Something wicked this way came', lib.f.getStack());
+ *    //                         Notice the comma ^
+ *
+ * This would print the message to the js console, followed by an object
+ * which can be clicked to reveal the stack.
+ *
+ * @param {number=} ignoreFrames How many inner stack frames to ignore.  The
+ *     innermost 'getStack' call is always ignored.
+ * @param {number=} count How many frames to return.
+ * @return {!Array<string>} The stack frames.
+ */
+lib.f.getStack = function(ignoreFrames = 0, count = undefined) {
+  const stackArray = (new Error()).stack.split('\n');
+
+  // Always ignore the Error() object and getStack call itself.
+  // [0] = 'Error'
+  // [1] = '    at Object.lib.f.getStack (file:///.../lib_f.js:267:23)'
+  ignoreFrames += 2;
+
+  const max = stackArray.length - ignoreFrames;
+  if (count === undefined)
+    count = max;
+  else
+    count = lib.f.clamp(count, 0, max);
+
+  // Remove the leading spaces and "at" from each line:
+  // '    at window.onload (file:///.../lib_test.js:11:18)'
+  const stackObject = new Array();
+  for (let i = ignoreFrames; i < count + ignoreFrames; ++i)
+    stackObject.push(stackArray[i].replace(/^\s*at\s+/, ''));
+
+  return stackObject;
+};
+
+/**
+ * Divides the two numbers and floors the results, unless the remainder is less
+ * than an incredibly small value, in which case it returns the ceiling.
+ * This is useful when the number are truncated approximations of longer
+ * values, and so doing division with these numbers yields a result incredibly
+ * close to a whole number.
+ *
+ * @param {number} numerator
+ * @param {number} denominator
+ * @return {number}
+ */
+lib.f.smartFloorDivide = function(numerator,  denominator) {
+  var val = numerator / denominator;
+  var ceiling = Math.ceil(val);
+  if (ceiling - val < .0001) {
+    return ceiling;
+  } else {
+    return Math.floor(val);
+  }
+};
+
+/**
+ * Get a random integer in a range (inclusive).
+ *
+ * @param {number} min The lowest integer in the range.
+ * @param {number} max The highest integer in the range.
+ * @return {number} A random number between min & max.
+ */
+lib.f.randomInt = function(min, max) {
+  return Math.floor(Math.random() * (max - min + 1)) + min;
+};
+
+/**
+ * Get the current OS.
+ *
+ * @return {!Promise<string>} A promise that resolves to a constant in
+ *     runtime.PlatformOs.
+ */
+lib.f.getOs = function() {
+  // Try the brower extensions API.
+  if (window.browser && browser.runtime && browser.runtime.getPlatformInfo)
+    return browser.runtime.getPlatformInfo().then((info) => info.os);
+
+  // Use the native Chrome API if available.
+  if (window.chrome && chrome.runtime && chrome.runtime.getPlatformInfo) {
+    return new Promise((resolve, reject) =>
+        chrome.runtime.getPlatformInfo((info) => resolve(info.os)));
+  }
+
+  // Fallback logic.  Capture the major OS's.  The rest should support the
+  // browser API above.
+  if (window.navigator && navigator.userAgent) {
+    const ua = navigator.userAgent;
+    if (ua.includes('Mac OS X'))
+      return Promise.resolve('mac');
+    else if (ua.includes('CrOS'))
+      return Promise.resolve('cros');
+    else if (ua.includes('Linux'))
+      return Promise.resolve('linux');
+    else if (ua.includes('Android'))
+      return Promise.resolve('android');
+    else if (ua.includes('Windows'))
+      return Promise.resolve('windows');
+  }
+
+  // Probe node environment.
+  if (typeof process != 'undefined') {
+    return Promise.resolve('node');
+  }
+
+  // Still here?  No idea.
+  return Promise.reject(null);
+};
+
+/**
+ * Get the current Chrome milestone version.
+ *
+ * @return {number} The milestone number if we're running on Chrome, else NaN.
+ */
+lib.f.getChromeMilestone = function() {
+  if (window.navigator && navigator.userAgent) {
+    const ary = navigator.userAgent.match(/\sChrome\/(\d+)/);
+    if (ary)
+      return parseInt(ary[1], 10);
+  }
+
+  // Returning NaN will make all number comparisons fail.
+  return NaN;
+};
+
+/**
+ * Return the lastError string in the browser.
+ *
+ * This object might live in different locations, and it isn't always defined
+ * (if there hasn't been a "last error").  Wrap all that ugliness here.
+ *
+ * @param {?string=} defaultMsg The default message if no error is found.
+ * @return {?string} The last error message from the browser.
+ */
+lib.f.lastError = function(defaultMsg = null) {
+  let lastError;
+  if (window.browser && browser.runtime)
+    lastError = browser.runtime.lastError;
+  else if (window.chrome && chrome.runtime)
+    lastError = chrome.runtime.lastError;
+
+  if (lastError && lastError.message)
+    return lastError.message;
+  else
+    return defaultMsg;
+};
+
+/**
+ * Just like window.open, but enforce noopener.
+ *
+ * If we're not careful, the website we open will have access to use via its
+ * window.opener field.  Newer browser support putting 'noopener' into the
+ * features argument, but there are many which still don't.  So hack it.
+ *
+ * @param {string=} url The URL to point the new window to.
+ * @param {string=} name The name of the new window.
+ * @param {string=} features The window features to enable.
+ * @return {?Window} The newly opened window.
+ */
+lib.f.openWindow = function(url, name=undefined, features=undefined) {
+  // We create the window first without the URL loaded.
+  const win = window.open(undefined, name, features);
+
+  // If the system is blocking window.open, don't crash.
+  if (win !== null) {
+    // Clear the opener setting before redirecting.
+    win.opener = null;
+
+    // Now it's safe to redirect.  Skip this step if the url is not set so we
+    // mimic the window.open behavior more precisely.
+    if (url) {
+      win.location = url;
+    }
+  }
+
+  return win;
+};
+// SOURCE FILE: libdot/js/lib_i18n.js
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Wrappers over the browser i18n helpers.
+ *
+ * Arguably some of these functions should be l10n, but oh well.
+ */
+lib.i18n = {};
+
+/**
+ * Convenience shortcut to the browser i18n object.
+ */
+lib.i18n.browser_ =
+    window.browser && browser.i18n ? browser.i18n :
+    window.chrome && chrome.i18n ? chrome.i18n :
+    null;
+
+/**
+ * Return whether the browser supports i18n natively.
+ *
+ * @return {boolean} True if browser.i18n or chrome.i18n exists.
+ */
+lib.i18n.browserSupported = function() {
+  return lib.i18n.browser_ !== null;
+};
+
+/**
+ * Get the list of accepted UI languages.
+ *
+ * https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/i18n/getAcceptLanguages
+ *
+ * @param {function(!Array<string>)} callback Function to invoke with the
+ *     results.  The parameter is a list of locale names.
+ */
+lib.i18n.getAcceptLanguages = function(callback) {
+  if (lib.i18n.browser_) {
+    lib.i18n.browser_.getAcceptLanguages(callback);
+  } else {
+    setTimeout(function() {
+        callback([navigator.language.replace(/-/g, '_')]);
+      }, 0);
+  }
+};
+
+/**
+ * Get a message by name, optionally replacing arguments too.
+ *
+ * https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/i18n/getMessage
+ *
+ * @param {string} msgname The id for this localized string.
+ * @param {?Array<string>=} substitutions Any replacements in the string.
+ * @param {string=} fallback Translation if the message wasn't found.
+ * @return {string} The translated message.
+ */
+lib.i18n.getMessage = function(msgname, substitutions = [], fallback = '') {
+  // First let the native browser APIs handle everything for us.
+  if (lib.i18n.browser_) {
+    const message = lib.i18n.browser_.getMessage(msgname, substitutions);
+    if (message)
+      return message;
+  }
+
+  // Do our best to get something reasonable.
+  return lib.i18n.replaceReferences(fallback, substitutions);
+};
+
+/**
+ * Replace $1...$n references with the elements of the args array.
+ *
+ * This largely behaves like Chrome's getMessage helper.  The $# references are
+ * always replaced/removed regardless of the specified substitutions.
+ *
+ * @param {string} msg String containing the message and argument references.
+ * @param {?Array<string>=} args Array containing the argument values.
+ * @return {string} The message with replacements expanded.
+ */
+lib.i18n.replaceReferences = function(msg, args = []) {
+  // The Chrome API allows a single substitution as a string rather than array.
+  if (args === null) {
+    args = [];
+  }
+  if (!(args instanceof Array)) {
+    args = [args];
+  }
+
+  return msg.replace(/\$(\d+)/g, (m, index) => {
+    return index <= args.length ? args[index - 1] : '';
+  });
+};
+// SOURCE FILE: libdot/js/lib_message_manager.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * MessageManager class handles internationalized strings.
+ *
+ * Note: chrome.i18n isn't sufficient because...
+ *     1. There's a bug in chrome that makes it unavailable in iframes:
+ *        https://crbug.com/130200
+ *     2. The client code may not be packaged in a Chrome extension.
+ *     3. The client code may be part of a library packaged in a third-party
+ *        Chrome extension.
+ *
+ * @param {!Array<string>} languages List of languages to load, in the order
+ *     they are preferred.  The first language found will be used.  'en' is
+ *     automatically added as the last language if it is not already present.
+ * @param {boolean=} useCrlf If true, '\n' in messages are substituted for
+ *     '\r\n'.  This fixes the translation process which discards '\r'
+ *     characters.
+ * @constructor
+ */
+lib.MessageManager = function(languages, useCrlf = false) {
+  this.languages_ = languages.map((el) => el.replace(/-/g, '_'));
+
+  if (this.languages_.indexOf('en') == -1)
+    this.languages_.push('en');
+
+  this.useCrlf = useCrlf;
+
+  /**
+   * @private {!Object<string, string>}
+   * @const
+   */
+  this.messages_ = {};
+};
+
+/**
+ * @typedef {!Object<string, {
+ *     message: string,
+ *     description: (string|undefined),
+ *     placeholders: ({content: string, example: string}|undefined),
+ * }>}
+ */
+lib.MessageManager.Messages;
+
+/**
+ * Add message definitions to the message manager.
+ *
+ * This takes an object of the same format of a Chrome messages.json file.  See
+ * <https://developer.chrome.com/extensions/i18n-messages>.
+ *
+ * @param {!lib.MessageManager.Messages} defs The message to add to the
+ *     database.
+ */
+lib.MessageManager.prototype.addMessages = function(defs) {
+  for (var key in defs) {
+    var def = defs[key];
+
+    if (!def.placeholders) {
+      // Upper case key into this.messages_ since our translated
+      // bundles are lower case, but we request msg as upper.
+      this.messages_[key.toUpperCase()] = def.message;
+    } else {
+      // Replace "$NAME$" placeholders with "$1", etc.
+      this.messages_[key.toUpperCase()] =
+          def.message.replace(/\$([a-z][^\s\$]+)\$/ig, function(m, name) {
+            return defs[key].placeholders[name.toLowerCase()].content;
+          });
+    }
+  }
+};
+
+/**
+ * Load the first available language message bundle.
+ *
+ * @param {string} pattern A url pattern containing a "$1" where the locale
+ *     name should go.
+ */
+lib.MessageManager.prototype.findAndLoadMessages = async function(pattern) {
+  if (lib.i18n.browserSupported()) {
+    return;
+  }
+
+  for (const lang of this.languages_) {
+    const url = lib.i18n.replaceReferences(pattern, lang);
+    try {
+      await this.loadMessages(url);
+      return;
+    } catch (e) {
+      console.warn(
+          `Error fetching ${lang} messages at ${url}`, e,
+          'Trying all languages:', this.languages_);
+    }
+  }
+};
+
+/**
+ * Load messages from a messages.json file.
+ *
+ * @param {string} url The URL to load the messages from.
+ * @return {!Promise<void>}
+ */
+lib.MessageManager.prototype.loadMessages = function(url) {
+  return new Promise((resolve, reject) => {
+    const xhr = new XMLHttpRequest();
+    xhr.onload = () => {
+      try {
+        this.addMessages(/** @type {!lib.MessageManager.Messages} */ (
+            JSON.parse(xhr.responseText)));
+        resolve();
+      } catch (e) {
+        // Error parsing JSON.
+        reject(e);
+      }
+    };
+    xhr.onerror = () => reject(xhr);
+
+    xhr.open('GET', url);
+    xhr.send();
+  });
+};
+
+/**
+ * Get a message by name, optionally replacing arguments too.
+ *
+ * @param {string} msgname String containing the name of the message to get.
+ * @param {!Array<string>=} args Optional array containing the argument values.
+ * @param {string=} fallback Optional value to return if the msgname is not
+ *     found.  Returns the message name by default.
+ * @return {string} The formatted translation.
+ */
+lib.MessageManager.prototype.get = function(msgname, args, fallback) {
+  // First try the integrated browser getMessage.  We prefer that over any
+  // registered messages as only the browser supports translations.
+  let message = lib.i18n.getMessage(msgname, args);
+  if (!message) {
+    // Look it up in the registered cache next.
+    message = this.messages_[msgname];
+    if (!message) {
+      console.warn('Unknown message: ' + msgname);
+      message = fallback === undefined ? msgname : fallback;
+      // Register the message with the default to avoid multiple warnings.
+      this.messages_[msgname] = message;
+    }
+    message = lib.i18n.replaceReferences(message, args);
+  }
+  if (this.useCrlf) {
+    message = message.replace(/\n/g, '\r\n');
+  }
+  return message;
+};
+
+/**
+ * Process all of the "i18n" html attributes found in a given element.
+ *
+ * The real work happens in processI18nAttribute.
+ *
+ * @param {!Element} node The element whose nodes will be translated.
+ */
+lib.MessageManager.prototype.processI18nAttributes = function(node) {
+  var nodes = node.querySelectorAll('[i18n]');
+
+  for (var i = 0; i < nodes.length; i++)
+    this.processI18nAttribute(nodes[i]);
+};
+
+/**
+ * Process the "i18n" attribute in the specified node.
+ *
+ * The i18n attribute should contain a JSON object.  The keys are taken to
+ * be attribute names, and the values are message names.
+ *
+ * If the JSON object has a "_" (underscore) key, its value is used as the
+ * textContent of the element.
+ *
+ * Message names can refer to other attributes on the same element with by
+ * prefixing with a dollar sign.  For example...
+ *
+ *   <button id='send-button'
+ *           i18n='{"aria-label": "$id", "_": "SEND_BUTTON_LABEL"}'
+ *           ></button>
+ *
+ * The aria-label message name will be computed as "SEND_BUTTON_ARIA_LABEL".
+ * Notice that the "id" attribute was appended to the target attribute, and
+ * the result converted to UPPER_AND_UNDER style.
+ *
+ * @param {!Element} node The element to translate.
+ */
+lib.MessageManager.prototype.processI18nAttribute = function(node) {
+  // Convert the "lower-and-dashes" attribute names into
+  // "UPPER_AND_UNDER" style.
+  const thunk = (str) => str.replace(/-/g, '_').toUpperCase();
+
+  var i18n = node.getAttribute('i18n');
+  if (!i18n)
+    return;
+
+  try {
+    i18n = JSON.parse(i18n);
+  } catch (ex) {
+    console.error('Can\'t parse ' + node.tagName + '#' + node.id + ': ' + i18n);
+    throw ex;
+  }
+
+  // Load all the messages specified in the i18n attributes.
+  for (var key in i18n) {
+    // The node attribute we'll be setting.
+    var attr = key;
+
+    var msgname = i18n[key];
+    // For "=foo", re-use the referenced message name.
+    if (msgname.startsWith('=')) {
+      key = msgname.substr(1);
+      msgname = i18n[key];
+    }
+
+    // For "$foo", calculate the message name.
+    if (msgname.startsWith('$'))
+      msgname = thunk(node.getAttribute(msgname.substr(1)) + '_' + key);
+
+    // Finally load the message.
+    var msg = this.get(msgname);
+    if (attr == '_')
+      node.textContent = msg;
+    else
+      node.setAttribute(attr, msg);
+  }
+};
+// SOURCE FILE: libdot/js/lib_preference_manager.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Constructor for lib.PreferenceManager objects.
+ *
+ * These objects deal with persisting changes to stable storage and notifying
+ * consumers when preferences change.
+ *
+ * It is intended that the backing store could be something other than HTML5
+ * storage, but there aren't any use cases at the moment.  In the future there
+ * may be a chrome api to store sync-able name/value pairs, and we'd want
+ * that.
+ *
+ * @param {!lib.Storage} storage The storage object to use as a backing
+ *     store.
+ * @param {string=} prefix The optional prefix to be used for all preference
+ *     names.  The '/' character should be used to separate levels of hierarchy,
+ *     if you're going to have that kind of thing.  If provided, the prefix
+ *     should start with a '/'.  If not provided, it defaults to '/'.
+ * @constructor
+ */
+lib.PreferenceManager = function(storage, prefix = '/') {
+  this.storage = storage;
+  this.storageObserver_ = this.onStorageChange_.bind(this);
+
+  this.isActive_ = false;
+  this.activate();
+
+  this.trace = false;
+
+  if (!prefix.endsWith('/'))
+    prefix += '/';
+
+  this.prefix = prefix;
+
+  // Internal state for when we're doing a bulk import from JSON and we want
+  // to elide redundant storage writes (for quota reasons).
+  this.isImportingJson_ = false;
+
+  /** @type {!Object<string, !lib.PreferenceManager.Record>} */
+  this.prefRecords_ = {};
+  this.globalObservers_ = [];
+
+  this.childFactories_ = {};
+
+  // Map of list-name to {map of child pref managers}
+  // As in...
+  //
+  //  this.childLists_ = {
+  //    'profile-ids': {
+  //      'one': PreferenceManager,
+  //      'two': PreferenceManager,
+  //      ...
+  //    },
+  //
+  //    'frob-ids': {
+  //      ...
+  //    }
+  //  }
+  this.childLists_ = {};
+};
+
+/**
+ * Used internally to indicate that the current value of the preference should
+ * be taken from the default value defined with the preference.
+ *
+ * Equality tests against this value MUST use '===' or '!==' to be accurate.
+ *
+ * @type {symbol}
+ */
+lib.PreferenceManager.prototype.DEFAULT_VALUE = Symbol('DEFAULT_VALUE');
+
+/**
+ * An individual preference.
+ *
+ * These objects are managed by the PreferenceManager, you shouldn't need to
+ * handle them directly.
+ *
+ * @param {string} name The name of the new preference (used for indexing).
+ * @param {*} defaultValue The default value for this preference.
+ * @constructor
+ */
+lib.PreferenceManager.Record = function(name, defaultValue) {
+  this.name = name;
+  this.defaultValue = defaultValue;
+  this.currentValue = this.DEFAULT_VALUE;
+  this.observers = [];
+};
+
+/**
+ * A local copy of the DEFAULT_VALUE constant to make it less verbose.
+ *
+ * @type {symbol}
+ */
+lib.PreferenceManager.Record.prototype.DEFAULT_VALUE =
+    lib.PreferenceManager.prototype.DEFAULT_VALUE;
+
+/**
+ * Register a callback to be invoked when this preference changes.
+ *
+ * @param {function(string, string, !lib.PreferenceManager)} observer The
+ *     function to invoke.  It will receive the new value, the name of the
+ *     preference, and a reference to the PreferenceManager as parameters.
+ */
+lib.PreferenceManager.Record.prototype.addObserver = function(observer) {
+  this.observers.push(observer);
+};
+
+/**
+ * Unregister an observer callback.
+ *
+ * @param {function()} observer A previously registered callback.
+ */
+lib.PreferenceManager.Record.prototype.removeObserver = function(observer) {
+  var i = this.observers.indexOf(observer);
+  if (i >= 0)
+    this.observers.splice(i, 1);
+};
+
+/**
+ * Fetch the value of this preference.
+ *
+ * @return {*} The value for this preference.
+ */
+lib.PreferenceManager.Record.prototype.get = function() {
+  if (this.currentValue === this.DEFAULT_VALUE) {
+    if (/^(string|number)$/.test(typeof this.defaultValue))
+      return this.defaultValue;
+
+    if (typeof this.defaultValue == 'object') {
+      // We want to return a COPY of the default value so that users can
+      // modify the array or object without changing the default value.
+      return JSON.parse(JSON.stringify(this.defaultValue));
+    }
+
+    return this.defaultValue;
+  }
+
+  return this.currentValue;
+};
+
+/**
+ * Stop this preference manager from tracking storage changes.
+ *
+ * Call this if you're going to swap out one preference manager for another so
+ * that you don't get notified about irrelevant changes.
+ */
+lib.PreferenceManager.prototype.deactivate = function() {
+  if (!this.isActive_)
+    throw new Error('Not activated');
+
+  this.isActive_ = false;
+  this.storage.removeObserver(this.storageObserver_);
+};
+
+/**
+ * Start tracking storage changes.
+ *
+ * If you previously deactivated this preference manager, you can reactivate it
+ * with this method.  You don't need to call this at initialization time, as
+ * it's automatically called as part of the constructor.
+ */
+lib.PreferenceManager.prototype.activate = function() {
+  if (this.isActive_)
+    throw new Error('Already activated');
+
+  this.isActive_ = true;
+  this.storage.addObserver(this.storageObserver_);
+};
+
+/**
+ * Read the backing storage for these preferences.
+ *
+ * You should do this once at initialization time to prime the local cache
+ * of preference values.  The preference manager will monitor the backing
+ * storage for changes, so you should not need to call this more than once.
+ *
+ * This function recursively reads storage for all child preference managers as
+ * well.
+ *
+ * This function is asynchronous, if you need to read preference values, you
+ * *must* wait for the callback.
+ *
+ * @param {function()=} opt_callback Optional function to invoke when the read
+ *     has completed.
+ */
+lib.PreferenceManager.prototype.readStorage = function(opt_callback) {
+  var pendingChildren = 0;
+
+  function onChildComplete() {
+    if (--pendingChildren == 0 && opt_callback)
+      opt_callback();
+  }
+
+  var keys = Object.keys(this.prefRecords_).map((el) => this.prefix + el);
+
+  if (this.trace)
+    console.log('Preferences read: ' + this.prefix);
+
+  this.storage.getItems(keys, function(items) {
+      var prefixLength = this.prefix.length;
+
+      for (var key in items) {
+        var value = items[key];
+        var name = key.substr(prefixLength);
+        var needSync = (name in this.childLists_ &&
+                        (JSON.stringify(value) !=
+                         JSON.stringify(this.prefRecords_[name].currentValue)));
+
+        this.prefRecords_[name].currentValue = value;
+
+        if (needSync) {
+          pendingChildren++;
+          this.syncChildList(name, onChildComplete);
+        }
+      }
+
+      if (pendingChildren == 0 && opt_callback)
+        setTimeout(opt_callback);
+    }.bind(this));
+};
+
+/**
+ * Define a preference.
+ *
+ * This registers a name, default value, and onChange handler for a preference.
+ *
+ * @param {string} name The name of the preference.  This will be prefixed by
+ *     the prefix of this PreferenceManager before written to local storage.
+ * @param {string|number|boolean|!Object|!Array|null} value The default value of
+ *     this preference.  Anything that can be represented in JSON is a valid
+ *     default value.
+ * @param {function(*, string, !lib.PreferenceManager)=} opt_onChange A
+ *     function to invoke when the preference changes.  It will receive the new
+ *     value, the name of the preference, and a reference to the
+ *     PreferenceManager as parameters.
+ */
+lib.PreferenceManager.prototype.definePreference = function(
+    name, value, opt_onChange) {
+
+  var record = this.prefRecords_[name];
+  if (record) {
+    this.changeDefault(name, value);
+  } else {
+    record = this.prefRecords_[name] =
+        new lib.PreferenceManager.Record(name, value);
+  }
+
+  if (opt_onChange)
+    record.addObserver(opt_onChange);
+};
+
+/**
+ * Define multiple preferences with a single function call.
+ *
+ * @param {!Array<*>} defaults An array of 3-element arrays.  Each three element
+ *     array should contain the [key, value, onChange] parameters for a
+ *     preference.
+ */
+lib.PreferenceManager.prototype.definePreferences = function(defaults) {
+  for (var i = 0; i < defaults.length; i++) {
+    this.definePreference(defaults[i][0], defaults[i][1], defaults[i][2]);
+  }
+};
+
+/**
+ * Define an ordered list of child preferences.
+ *
+ * Child preferences are different from just storing an array of JSON objects
+ * in that each child is an instance of a preference manager.  This means you
+ * can observe changes to individual child preferences, and get some validation
+ * that you're not reading or writing to an undefined child preference value.
+ *
+ * @param {string} listName A name for the list of children.  This must be
+ *     unique in this preference manager.  The listName will become a
+ *     preference on this PreferenceManager used to store the ordered list of
+ *     child ids.  It is also used in get/add/remove operations to identify the
+ *     list of children to operate on.
+ * @param {function(!lib.PreferenceManager, string)} childFactory A function
+ *     that will be used to generate instances of these children.  The factory
+ *     function will receive the parent lib.PreferenceManager object and a
+ *     unique id for the new child preferences.
+ */
+lib.PreferenceManager.prototype.defineChildren = function(
+    listName, childFactory) {
+
+  // Define a preference to hold the ordered list of child ids.
+  this.definePreference(listName, [],
+                        this.onChildListChange_.bind(this, listName));
+  this.childFactories_[listName] = childFactory;
+  this.childLists_[listName] = {};
+};
+
+/**
+ * Register to observe preference changes.
+ *
+ * @param {string} name The name of preference you wish to observe..
+ * @param {function()} observer The callback.
+ */
+lib.PreferenceManager.prototype.addObserver = function(name, observer) {
+  if (!(name in this.prefRecords_)) {
+    throw new Error(`Unknown preference: ${name}`);
+  }
+
+  this.prefRecords_[name].addObserver(observer);
+};
+
+/**
+ * Register to observe preference changes.
+ *
+ * @param {?function()} global A callback that will happen for every preference.
+ *     Pass null if you don't need one.
+ * @param {!Object} map A map of preference specific callbacks.  Pass null if
+ *     you don't need any.
+ */
+lib.PreferenceManager.prototype.addObservers = function(global, map) {
+  if (global && typeof global != 'function')
+    throw new Error('Invalid param: globals');
+
+  if (global)
+    this.globalObservers_.push(global);
+
+  if (!map)
+    return;
+
+  for (var name in map) {
+    this.addObserver(name, map[name]);
+  }
+};
+
+/**
+ * Remove preference observer.
+ *
+ * @param {string} name The name of preference you wish to stop observing.
+ * @param {function()} observer The observer to remove.
+ */
+lib.PreferenceManager.prototype.removeObserver = function(name, observer) {
+  if (!(name in this.prefRecords_)) {
+    throw new Error(`Unknown preference: ${name}`);
+  }
+
+  this.prefRecords_[name].removeObserver(observer);
+};
+
+/**
+ * Dispatch the change observers for all known preferences.
+ *
+ * It may be useful to call this after readStorage completes, in order to
+ * get application state in sync with user preferences.
+ *
+ * This can be used if you've changed a preference manager out from under
+ * a live object, for example when switching to a different prefix.
+ */
+lib.PreferenceManager.prototype.notifyAll = function() {
+  for (var name in this.prefRecords_) {
+    this.notifyChange_(name);
+  }
+};
+
+/**
+ * Notify the change observers for a given preference.
+ *
+ * @param {string} name The name of the preference that changed.
+ */
+lib.PreferenceManager.prototype.notifyChange_ = function(name) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  var currentValue = record.get();
+
+  for (var i = 0; i < this.globalObservers_.length; i++)
+    this.globalObservers_[i](name, currentValue);
+
+  for (var i = 0; i < record.observers.length; i++) {
+    record.observers[i](currentValue, name, this);
+  }
+};
+
+/**
+ * Create a new child PreferenceManager for the given child list.
+ *
+ * The optional hint parameter is an opaque prefix added to the auto-generated
+ * unique id for this child.  Your child factory can parse out the prefix
+ * and use it.
+ *
+ * @param {string} listName The child list to create the new instance from.
+ * @param {?string=} opt_hint Optional hint to include in the child id.
+ * @param {string=} opt_id Optional id to override the generated id.
+ * @return {!lib.PreferenceManager} The new child preference manager.
+ */
+lib.PreferenceManager.prototype.createChild = function(listName, opt_hint,
+                                                       opt_id) {
+  var ids = this.get(listName);
+  var id;
+
+  if (opt_id) {
+    id = opt_id;
+    if (ids.indexOf(id) != -1)
+      throw new Error('Duplicate child: ' + listName + ': ' + id);
+
+  } else {
+    // Pick a random, unique 4-digit hex identifier for the new profile.
+    while (!id || ids.indexOf(id) != -1) {
+      id = lib.f.randomInt(1, 0xffff).toString(16);
+      id = lib.f.zpad(id, 4);
+      if (opt_hint)
+        id = opt_hint + ':' + id;
+    }
+  }
+
+  var childManager = this.childFactories_[listName](this, id);
+  childManager.trace = this.trace;
+  childManager.resetAll();
+
+  this.childLists_[listName][id] = childManager;
+
+  ids.push(id);
+  this.set(listName, ids, undefined, !this.isImportingJson_);
+
+  return childManager;
+};
+
+/**
+ * Remove a child preferences instance.
+ *
+ * Removes a child preference manager and clears any preferences stored in it.
+ *
+ * @param {string} listName The name of the child list containing the child to
+ *     remove.
+ * @param {string} id The child ID.
+ */
+lib.PreferenceManager.prototype.removeChild = function(listName, id) {
+  var prefs = this.getChild(listName, id);
+  prefs.resetAll();
+
+  var ids = this.get(listName);
+  var i = ids.indexOf(id);
+  if (i != -1) {
+    ids.splice(i, 1);
+    this.set(listName, ids, undefined, !this.isImportingJson_);
+  }
+
+  delete this.childLists_[listName][id];
+};
+
+/**
+ * Return a child PreferenceManager instance for a given id.
+ *
+ * If the child list or child id is not known this will return the specified
+ * default value or throw an exception if no default value is provided.
+ *
+ * @param {string} listName The child list to look in.
+ * @param {string} id The child ID.
+ * @param {!lib.PreferenceManager=} opt_default The value to return if the child
+ *     is not found.
+ * @return {!lib.PreferenceManager} The specified child PreferenceManager.
+ */
+lib.PreferenceManager.prototype.getChild = function(listName, id, opt_default) {
+  if (!(listName in this.childLists_))
+    throw new Error('Unknown child list: ' + listName);
+
+  var childList = this.childLists_[listName];
+  if (!(id in childList)) {
+    if (typeof opt_default == 'undefined')
+      throw new Error('Unknown "' + listName + '" child: ' + id);
+
+    return opt_default;
+  }
+
+  return childList[id];
+};
+
+/**
+ * Synchronize a list of child PreferenceManagers instances with the current
+ * list stored in prefs.
+ *
+ * This will instantiate any missing managers and read current preference values
+ * from storage.  Any active managers that no longer appear in preferences will
+ * be deleted.
+ *
+ * @param {string} listName The child list to synchronize.
+ * @param {function()=} opt_callback Function to invoke when the sync finishes.
+ */
+lib.PreferenceManager.prototype.syncChildList = function(
+    listName, opt_callback) {
+
+  var pendingChildren = 0;
+  function onChildStorage() {
+    if (--pendingChildren == 0 && opt_callback)
+      opt_callback();
+  }
+
+  // The list of child ids that we *should* have a manager for.
+  var currentIds = this.get(listName);
+
+  // The known managers at the start of the sync.  Any manager still in this
+  // list at the end should be discarded.
+  var oldIds = Object.keys(this.childLists_[listName]);
+
+  for (var i = 0; i < currentIds.length; i++) {
+    var id = currentIds[i];
+
+    var managerIndex = oldIds.indexOf(id);
+    if (managerIndex >= 0)
+      oldIds.splice(managerIndex, 1);
+
+    if (!this.childLists_[listName][id]) {
+      var childManager = this.childFactories_[listName](this, id);
+      if (!childManager) {
+        console.warn('Unable to restore child: ' + listName + ': ' + id);
+        continue;
+      }
+
+      childManager.trace = this.trace;
+      this.childLists_[listName][id] = childManager;
+      pendingChildren++;
+      childManager.readStorage(onChildStorage);
+    }
+  }
+
+  for (var i = 0; i < oldIds.length; i++) {
+    delete this.childLists_[listName][oldIds[i]];
+  }
+
+  if (!pendingChildren && opt_callback)
+    setTimeout(opt_callback);
+};
+
+/**
+ * Reset a preference to its default state.
+ *
+ * This will dispatch the onChange handler if the preference value actually
+ * changes.
+ *
+ * @param {string} name The preference to reset.
+ */
+lib.PreferenceManager.prototype.reset = function(name) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  this.storage.removeItem(this.prefix + name);
+
+  if (record.currentValue !== this.DEFAULT_VALUE) {
+    record.currentValue = this.DEFAULT_VALUE;
+    this.notifyChange_(name);
+  }
+};
+
+/**
+ * Reset all preferences back to their default state.
+ */
+lib.PreferenceManager.prototype.resetAll = function() {
+  var changed = [];
+
+  for (var listName in this.childLists_) {
+    var childList = this.childLists_[listName];
+    for (var id in childList) {
+      childList[id].resetAll();
+    }
+  }
+
+  for (var name in this.prefRecords_) {
+    if (this.prefRecords_[name].currentValue !== this.DEFAULT_VALUE) {
+      this.prefRecords_[name].currentValue = this.DEFAULT_VALUE;
+      changed.push(name);
+    }
+  }
+
+  var keys = Object.keys(this.prefRecords_).map(function(el) {
+      return this.prefix + el;
+  }.bind(this));
+
+  this.storage.removeItems(keys);
+
+  changed.forEach(this.notifyChange_.bind(this));
+};
+
+/**
+ * Return true if two values should be considered not-equal.
+ *
+ * If both values are the same scalar type and compare equal this function
+ * returns false (no difference), otherwise return true.
+ *
+ * This is used in places where we want to check if a preference has changed.
+ * Rather than take the time to compare complex values we just consider them
+ * to always be different.
+ *
+ * @param {*} a A value to compare.
+ * @param {*} b A value to compare.
+ * @return {boolean} Whether the two are not equal.
+ */
+lib.PreferenceManager.prototype.diff = function(a, b) {
+  // If the types are different.
+  if ((typeof a) !== (typeof b)) {
+    return true;
+  }
+
+  // Or if the type is not a simple primitive one.
+  if (!(/^(undefined|boolean|number|string)$/.test(typeof a))) {
+    // Special case the null object.
+    if (a === null && b === null) {
+      return false;
+    } else {
+      return true;
+    }
+  }
+
+  // Do a normal compare for primitive types.
+  return a !== b;
+};
+
+/**
+ * Change the default value of a preference.
+ *
+ * This is useful when subclassing preference managers.
+ *
+ * The function does not alter the current value of the preference, unless
+ * it has the old default value.  When that happens, the change observers
+ * will be notified.
+ *
+ * @param {string} name The name of the parameter to change.
+ * @param {*} newValue The new default value for the preference.
+ */
+lib.PreferenceManager.prototype.changeDefault = function(name, newValue) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  if (!this.diff(record.defaultValue, newValue)) {
+    // Default value hasn't changed.
+    return;
+  }
+
+  if (record.currentValue !== this.DEFAULT_VALUE) {
+    // This pref has a specific value, just change the default and we're done.
+    record.defaultValue = newValue;
+    return;
+  }
+
+  record.defaultValue = newValue;
+
+  this.notifyChange_(name);
+};
+
+/**
+ * Change the default value of multiple preferences.
+ *
+ * @param {!Object} map A map of name -> value pairs specifying the new default
+ *     values.
+ */
+lib.PreferenceManager.prototype.changeDefaults = function(map) {
+  for (var key in map) {
+    this.changeDefault(key, map[key]);
+  }
+};
+
+/**
+ * Set a preference to a specific value.
+ *
+ * This will dispatch the onChange handler if the preference value actually
+ * changes.
+ *
+ * @param {string} name The preference to set.
+ * @param {*} newValue The value to set.  Anything that can be represented in
+ *     JSON is a valid value.
+ * @param {function()=} onComplete Callback when the set call completes.
+ * @param {boolean=} saveToStorage Whether to commit the change to the backing
+ *     storage or only the in-memory record copy.
+ * @return {!Promise<void>} Promise which resolves once all observers are
+ *     notified.
+ */
+lib.PreferenceManager.prototype.set = function(
+    name, newValue, onComplete=undefined, saveToStorage=true) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  var oldValue = record.get();
+
+  if (!this.diff(oldValue, newValue))
+    return Promise.resolve();
+
+  if (this.diff(record.defaultValue, newValue)) {
+    record.currentValue = newValue;
+    if (saveToStorage)
+      this.storage.setItem(this.prefix + name, newValue, onComplete);
+  } else {
+    record.currentValue = this.DEFAULT_VALUE;
+    if (saveToStorage)
+      this.storage.removeItem(this.prefix + name, onComplete);
+  }
+
+  // We need to manually send out the notification on this instance.  If we
+  // The storage event won't fire a notification because we've already changed
+  // the currentValue, so it won't see a difference.  If we delayed changing
+  // currentValue until the storage event, a pref read immediately after a write
+  // would return the previous value.
+  //
+  // The notification is async so clients don't accidentally depend on
+  // a synchronous notification.
+  return Promise.resolve().then(() => {
+    this.notifyChange_(name);
+  });
+};
+
+/**
+ * Get the value of a preference.
+ *
+ * @param {string} name The preference to get.
+ * @return {*} The preference's value.
+ */
+lib.PreferenceManager.prototype.get = function(name) {
+  var record = this.prefRecords_[name];
+  if (!record)
+    throw new Error('Unknown preference: ' + name);
+
+  return record.get();
+};
+
+/**
+ * Get the boolean value of a preference.
+ *
+ * @param {string} name The preference to get.
+ * @return {boolean}
+ */
+lib.PreferenceManager.prototype.getBoolean = function(name) {
+  const result = this.get(name);
+  lib.assert(typeof result == 'boolean');
+  return result;
+};
+
+/**
+ * Get the number value of a preference.
+ *
+ * @param {string} name The preference to get.
+ * @return {number}
+ */
+lib.PreferenceManager.prototype.getNumber = function(name) {
+  const result = this.get(name);
+  lib.assert(typeof result == 'number');
+  return result;
+};
+
+/**
+ * Get the string value of a preference.
+ *
+ * @param {string} name The preference to get.
+ * @return {string}
+ */
+lib.PreferenceManager.prototype.getString = function(name) {
+  const result = this.get(name);
+  lib.assert(typeof result == 'string');
+  return result;
+};
+
+/**
+ * Return all non-default preferences as a JSON object.
+ *
+ * This includes any nested preference managers as well.
+ *
+ * @return {!Object} The JSON preferences.
+ */
+lib.PreferenceManager.prototype.exportAsJson = function() {
+  var rv = {};
+
+  for (var name in this.prefRecords_) {
+    if (name in this.childLists_) {
+      rv[name] = [];
+      var childIds = this.get(name);
+      for (var i = 0; i < childIds.length; i++) {
+        var id = childIds[i];
+        rv[name].push({id: id, json: this.getChild(name, id).exportAsJson()});
+      }
+
+    } else {
+      var record = this.prefRecords_[name];
+      if (record.currentValue != this.DEFAULT_VALUE)
+        rv[name] = record.currentValue;
+    }
+  }
+
+  return rv;
+};
+
+/**
+ * Import a JSON blob of preferences previously generated with exportAsJson.
+ *
+ * This will create nested preference managers as well.
+ *
+ * @param {!Object} json The JSON settings to import.
+ * @param {function()=} onComplete Callback when all imports have finished.
+ */
+lib.PreferenceManager.prototype.importFromJson = function(json, onComplete) {
+  this.isImportingJson_ = true;
+
+  let pendingWrites = 0;
+  const onWriteStorage = () => {
+    if (--pendingWrites < 1) {
+      if (onComplete) {
+        onComplete();
+      }
+
+      // We've delayed updates to the child arrays, so flush them now.
+      for (let name in json)
+        if (name in this.childLists_)
+          this.set(name, this.get(name));
+
+      this.isImportingJson_ = false;
+    }
+  };
+
+  for (var name in json) {
+    if (name in this.childLists_) {
+      var childList = json[name];
+      for (var i = 0; i < childList.length; i++) {
+        var id = childList[i].id;
+
+        var childPrefManager = this.childLists_[name][id];
+        if (!childPrefManager)
+          childPrefManager = this.createChild(name, null, id);
+
+        childPrefManager.importFromJson(childList[i].json, onWriteStorage);
+        pendingWrites++;
+      }
+
+    } else {
+      // The set is synchronous.
+      this.set(name, json[name]);
+    }
+  }
+
+  // If we didn't update any children, no async work has been queued, so make
+  // the completion callback directly.
+  if (pendingWrites == 0 && onComplete) {
+    onComplete();
+  }
+};
+
+/**
+ * Called when one of the child list preferences changes.
+ *
+ * @param {string} listName The child list to synchronize.
+ */
+lib.PreferenceManager.prototype.onChildListChange_ = function(listName) {
+  this.syncChildList(listName);
+};
+
+/**
+ * Called when a key in the storage changes.
+ *
+ * @param {!Object} map Dictionary of changed settings.
+ */
+lib.PreferenceManager.prototype.onStorageChange_ = function(map) {
+  for (var key in map) {
+    if (this.prefix) {
+      if (key.lastIndexOf(this.prefix, 0) != 0)
+        continue;
+    }
+
+    var name = key.substr(this.prefix.length);
+
+    if (!(name in this.prefRecords_)) {
+      // Sometimes we'll get notified about prefs that are no longer defined.
+      continue;
+    }
+
+    var record = this.prefRecords_[name];
+
+    var newValue = map[key].newValue;
+    var currentValue = record.currentValue;
+    if (currentValue === record.DEFAULT_VALUE)
+      currentValue = undefined;
+
+    if (this.diff(currentValue, newValue)) {
+      if (typeof newValue == 'undefined' || newValue === null) {
+        record.currentValue = record.DEFAULT_VALUE;
+      } else {
+        record.currentValue = newValue;
+      }
+
+      this.notifyChange_(name);
+    }
+  }
+};
+// SOURCE FILE: libdot/js/lib_resource.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Storage for canned resources.
+ *
+ * These are usually non-JavaScript things that are collected during a build
+ * step and converted into a series of 'lib.resource.add(...)' calls.  See
+ * the "@resource" directive from libdot/bin/concat for the canonical use
+ * case.
+ *
+ * This is global storage, so you should prefix your resource names to avoid
+ * collisions.
+ */
+lib.resource = {
+  resources_: {}
+};
+
+/** @typedef {{type: string, name: string, data: *}} */
+lib.resource.ResourceRecord;
+
+/**
+ * Add a resource.
+ *
+ * @param {string} name A name for the resource.  You should prefix this to
+ *     avoid collisions with resources from a shared library.
+ * @param {string} type A mime type for the resource, or "raw" if not
+ *     applicable.
+ * @param {*} data The value of the resource.
+ */
+lib.resource.add = function(name, type, data) {
+  lib.resource.resources_[name] = {
+    type: type,
+    name: name,
+    data: data
+  };
+};
+
+/**
+ * Retrieve a resource record.
+ *
+ * The resource data is stored on the "data" property of the returned object.
+ *
+ * @param {string} name The name of the resource to get.
+ * @param {!lib.resource.ResourceRecord=} defaultValue The value to return if
+ *     the resource is not defined.
+ * @return {!lib.resource.ResourceRecord} The matching resource if it exists.
+ */
+lib.resource.get = function(name, defaultValue) {
+  if (!(name in lib.resource.resources_)) {
+    lib.assert(defaultValue !== undefined);
+    return defaultValue;
+  }
+
+  return lib.resource.resources_[name];
+};
+
+/**
+ * Retrieve resource data.
+ *
+ * @param {string} name The name of the resource to get.
+ * @param {*=} defaultValue The value to return if the resource is not defined.
+ * @return {*} The resource data.
+ */
+lib.resource.getData = function(name, defaultValue) {
+  if (!(name in lib.resource.resources_)) {
+    return defaultValue;
+  }
+
+  return lib.resource.resources_[name].data;
+};
+
+/**
+ * Retrieve resource as a data: url.
+ *
+ * @param {string} name The name of the resource to get.
+ * @param {!lib.resource.ResourceRecord=} defaultValue The value to return if
+ *     the resource is not defined.
+ * @return {string} A data: url encoded version of the resource.
+ */
+lib.resource.getDataUrl = function(name, defaultValue) {
+  var resource = lib.resource.get(name, defaultValue);
+  return 'data:' + resource.type + ',' + resource.data;
+};
+// SOURCE FILE: libdot/js/lib_storage.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Namespace for implementations of persistent, possibly cloud-backed
+ * storage.
+ *
+ * @interface
+ */
+lib.Storage = function() {};
+
+/**
+ * Register a function to observe storage changes.
+ *
+ * @param {function(!Object)} callback The function to invoke when the storage
+ *     changes.
+ */
+lib.Storage.prototype.addObserver = function(callback) {};
+
+/**
+ * Unregister a change observer.
+ *
+ * @param {function(!Object)} callback A previously registered callback.
+ */
+lib.Storage.prototype.removeObserver = function(callback) {};
+
+/**
+ * Delete everything in this storage.
+ *
+ * @param {function()=} callback The function to invoke when the delete has
+ *     completed.
+ */
+lib.Storage.prototype.clear = function(callback) {};
+
+/**
+ * Return the current value of a storage item.
+ *
+ * @param {string} key The key to look up.
+ * @param {function(*)} callback The function to invoke when the value has
+ *     been retrieved.
+ */
+lib.Storage.prototype.getItem = function(key, callback) {};
+
+/**
+ * Fetch the values of multiple storage items.
+ *
+ * @param {?Array<string>} keys The keys to look up.  Pass null for all keys.
+ * @param {function(!Object)} callback The function to invoke when the values
+ *     have been retrieved.
+ */
+lib.Storage.prototype.getItems = function(keys, callback) {};
+
+/**
+ * Set a value in storage.
+ *
+ * @param {string} key The key for the value to be stored.
+ * @param {*} value The value to be stored.  Anything that can be serialized
+ *     with JSON is acceptable.
+ * @param {function()=} callback Function to invoke when the set is complete.
+ *     You don't have to wait for the set to complete in order to read the value
+ *     since the local cache is updated synchronously.
+ */
+lib.Storage.prototype.setItem = function(key, value, callback) {};
+
+/**
+ * Set multiple values in storage.
+ *
+ * @param {!Object} obj A map of key/values to set in storage.
+ * @param {function()=} callback Function to invoke when the set is complete.
+ *     You don't have to wait for the set to complete in order to read the value
+ *     since the local cache is updated synchronously.
+ */
+lib.Storage.prototype.setItems = function(obj, callback) {};
+
+/**
+ * Remove an item from storage.
+ *
+ * @param {string} key The key to be removed.
+ * @param {function()=} callback Function to invoke when the remove is complete.
+ *     You don't have to wait for the set to complete in order to read the value
+ *     since the local cache is updated synchronously.
+ */
+lib.Storage.prototype.removeItem = function(key, callback) {};
+
+/**
+ * Remove multiple items from storage.
+ *
+ * @param {!Array<string>} ary The keys to be removed.
+ * @param {function()=} callback Function to invoke when the remove is complete.
+ *     You don't have to wait for the set to complete in order to read the value
+ *     since the local cache is updated synchronously.
+ */
+lib.Storage.prototype.removeItems = function(ary, callback) {};
+// SOURCE FILE: libdot/js/lib_storage_chrome.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * chrome.storage based class with an async interface that is interchangeable
+ * with other lib.Storage.* implementations.
+ *
+ * @param {!StorageArea} storage The backing storage.
+ * @implements {lib.Storage}
+ * @constructor
+ */
+lib.Storage.Chrome = function(storage) {
+  this.storage_ = storage;
+  this.observers_ = [];
+
+  chrome.storage.onChanged.addListener(this.onChanged_.bind(this));
+};
+
+/**
+ * Called by the storage implementation when the storage is modified.
+ *
+ * @param {!Array<*>} changes Object mapping each key that changed to its
+ *     corresponding storage.StorageChange for that item.
+ * @param {string} areaname The name of the storage area ("sync", "local",
+ *     or "managed") the changes are for.
+ */
+lib.Storage.Chrome.prototype.onChanged_ = function(changes, areaname) {
+  if (chrome.storage[areaname] != this.storage_)
+    return;
+
+  for (var i = 0; i < this.observers_.length; i++) {
+    this.observers_[i](changes);
+  }
+};
+
+/**
+ * Register a function to observe storage changes.
+ *
+ * @param {function(!Object)} callback The function to invoke when the storage
+ *     changes.
+ * @override
+ */
+lib.Storage.Chrome.prototype.addObserver = function(callback) {
+  this.observers_.push(callback);
+};
+
+/**
+ * Unregister a change observer.
+ *
+ * @param {function(!Object)} callback A previously registered callback.
+ * @override
+ */
+lib.Storage.Chrome.prototype.removeObserver = function(callback) {
+  var i = this.observers_.indexOf(callback);
+  if (i != -1)
+    this.observers_.splice(i, 1);
+};
+
+/**
+ * Delete everything in this storage.
+ *
+ * @param {function()=} callback The function to invoke when the delete has
+ *     completed.
+ * @override
+ */
+lib.Storage.Chrome.prototype.clear = function(callback) {
+  this.storage_.clear();
+
+  if (callback) {
+    setTimeout(callback, 0);
+  }
+};
+
+/**
+ * Return the current value of a storage item.
+ *
+ * @param {string} key The key to look up.
+ * @param {function(*)} callback The function to invoke when the value has
+ *     been retrieved.
+ * @override
+ */
+lib.Storage.Chrome.prototype.getItem = function(key, callback) {
+  this.storage_.get(key, callback);
+};
+
+/**
+ * Fetch the values of multiple storage items.
+ *
+ * @param {?Array<string>} keys The keys to look up.  Pass null for all keys.
+ * @param {function(!Object)} callback The function to invoke when the values
+ *     have been retrieved.
+ * @override
+ */
+lib.Storage.Chrome.prototype.getItems = function(keys, callback) {
+  this.storage_.get(keys, callback);
+};
+
+/**
+ * Set a value in storage.
+ *
+ * @param {string} key The key for the value to be stored.
+ * @param {*} value The value to be stored.  Anything that can be serialized
+ *     with JSON is acceptable.
+ * @param {function()=} callback Function to invoke when the set is complete.
+ *     You don't have to wait for the set to complete in order to read the
+ *     value since the local cache is updated synchronously.
+ * @override
+ */
+lib.Storage.Chrome.prototype.setItem = function(key, value, callback) {
+  const onComplete = () => {
+    const err = lib.f.lastError();
+    if (err) {
+      // Doesn't seem to be any better way of handling this.
+      // https://crbug.com/764759
+      if (err.indexOf('MAX_WRITE_OPERATIONS')) {
+        console.warn(`Will retry save of ${key} after exceeding quota: ${err}`);
+        setTimeout(() => this.setItem(key, value, onComplete), 1000);
+        return;
+      } else {
+        console.error(`Unknown runtime error: ${err}`);
+      }
+    }
+
+    if (callback) {
+      callback();
+    }
+  };
+
+  var obj = {};
+  obj[key] = value;
+  this.storage_.set(obj, onComplete);
+};
+
+/**
+ * Set multiple values in storage.
+ *
+ * @param {!Object} obj A map of key/values to set in storage.
+ * @param {function()=} callback Function to invoke when the set is complete.
+ *     You don't have to wait for the set to complete in order to read the
+ *     value since the local cache is updated synchronously.
+ * @override
+ */
+lib.Storage.Chrome.prototype.setItems = function(obj, callback) {
+  this.storage_.set(obj, callback);
+};
+
+/**
+ * Remove an item from storage.
+ *
+ * @param {string} key The key to be removed.
+ * @param {function()=} callback Function to invoke when the remove is complete.
+ *     You don't have to wait for the set to complete in order to read the value
+ *     since the local cache is updated synchronously.
+ * @override
+ */
+lib.Storage.Chrome.prototype.removeItem = function(key, callback) {
+  this.storage_.remove(key, callback);
+};
+
+/**
+ * Remove multiple items from storage.
+ *
+ * @param {!Array<string>} keys The keys to be removed.
+ * @param {function()=} callback Function to invoke when the remove is complete.
+ *     You don't have to wait for the set to complete in order to read the value
+ *     since the local cache is updated synchronously.
+ * @override
+ */
+lib.Storage.Chrome.prototype.removeItems = function(keys, callback) {
+  this.storage_.remove(keys, callback);
+};
+// SOURCE FILE: libdot/js/lib_storage_local.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * window.localStorage based class with an async interface that is
+ * interchangeable with other lib.Storage.* implementations.
+ *
+ * @implements {lib.Storage}
+ * @constructor
+ */
+lib.Storage.Local = function() {
+  this.observers_ = [];
+  this.storage_ = window.localStorage;
+  window.addEventListener('storage', this.onStorage_.bind(this));
+};
+
+/**
+ * Called by the storage implementation when the storage is modified.
+ *
+ * @param {!Event} e The setting that has changed.
+ */
+lib.Storage.Local.prototype.onStorage_ = function(e) {
+  if (e.storageArea != this.storage_)
+    return;
+
+  // JS throws an exception if JSON.parse is given an empty string. So here we
+  // only parse if the value is truthy. This mean the empty string, undefined
+  // and null will not be parsed.
+  var prevValue = e.oldValue ? JSON.parse(e.oldValue) : e.oldValue;
+  var curValue = e.newValue ? JSON.parse(e.newValue) : e.newValue;
+  var o = {};
+  o[e.key] = {
+    oldValue: prevValue,
+    newValue: curValue
+  };
+
+  for (var i = 0; i < this.observers_.length; i++) {
+    this.observers_[i](o);
+  }
+};
+
+/**
+ * Register a function to observe storage changes.
+ *
+ * @param {function(!Object)} callback The function to invoke when the storage
+ *     changes.
+ * @override
+ */
+lib.Storage.Local.prototype.addObserver = function(callback) {
+  this.observers_.push(callback);
+};
+
+/**
+ * Unregister a change observer.
+ *
+ * @param {function(!Object)} callback A previously registered callback.
+ * @override
+ */
+lib.Storage.Local.prototype.removeObserver = function(callback) {
+  var i = this.observers_.indexOf(callback);
+  if (i != -1)
+    this.observers_.splice(i, 1);
+};
+
+/**
+ * Delete everything in this storage.
+ *
+ * @param {function()=} callback The function to invoke when the delete has
+ *     completed.
+ * @override
+ */
+lib.Storage.Local.prototype.clear = function(callback) {
+  this.storage_.clear();
+
+  if (callback) {
+    setTimeout(callback, 0);
+  }
+};
+
+/**
+ * Return the current value of a storage item.
+ *
+ * @param {string} key The key to look up.
+ * @param {function(*)} callback The function to invoke when the value has
+ *     been retrieved.
+ * @override
+ */
+lib.Storage.Local.prototype.getItem = function(key, callback) {
+  var value = this.storage_.getItem(key);
+
+  if (typeof value == 'string') {
+    try {
+      value = JSON.parse(value);
+    } catch (e) {
+      // If we can't parse the value, just return it unparsed.
+    }
+  }
+
+  setTimeout(callback.bind(null, value), 0);
+};
+
+/**
+ * Fetch the values of multiple storage items.
+ *
+ * @param {?Array<string>} keys The keys to look up.  Pass null for all keys.
+ * @param {function(!Object)} callback The function to invoke when the values
+ *     have been retrieved.
+ * @override
+ */
+lib.Storage.Local.prototype.getItems = function(keys, callback) {
+  var rv = {};
+  if (!keys) {
+    keys = [];
+    for (let i = 0; i < this.storage_.length; i++) {
+      keys.push(this.storage_.key(i));
+    }
+  }
+
+  for (var i = keys.length - 1; i >= 0; i--) {
+    var key = keys[i];
+    var value = this.storage_.getItem(key);
+    if (typeof value == 'string') {
+      try {
+        rv[key] = JSON.parse(value);
+      } catch (e) {
+        // If we can't parse the value, just return it unparsed.
+        rv[key] = value;
+      }
+    } else {
+      keys.splice(i, 1);
+    }
+  }
+
+  setTimeout(callback.bind(null, rv), 0);
+};
+
+/**
+ * Set a value in storage.
+ *
+ * @param {string} key The key for the value to be stored.
+ * @param {*} value The value to be stored.  Anything that can be serialized
+ *     with JSON is acceptable.
+ * @param {function()=} callback Function to invoke when the set is complete.
+ *     You don't have to wait for the set to complete in order to read the value
+ *     since the local cache is updated synchronously.
+ * @override
+ */
+lib.Storage.Local.prototype.setItem = function(key, value, callback) {
+  this.storage_.setItem(key, JSON.stringify(value));
+
+  if (callback) {
+    setTimeout(callback, 0);
+  }
+};
+
+/**
+ * Set multiple values in storage.
+ *
+ * @param {!Object} obj A map of key/values to set in storage.
+ * @param {function()=} callback Function to invoke when the set is complete.
+ *     You don't have to wait for the set to complete in order to read the value
+ *     since the local cache is updated synchronously.
+ * @override
+ */
+lib.Storage.Local.prototype.setItems = function(obj, callback) {
+  for (var key in obj) {
+    this.storage_.setItem(key, JSON.stringify(obj[key]));
+  }
+
+  if (callback) {
+    setTimeout(callback, 0);
+  }
+};
+
+/**
+ * Remove an item from storage.
+ *
+ * @param {string} key The key to be removed.
+ * @param {function()=} callback Function to invoke when the remove is complete.
+ *     You don't have to wait for the set to complete in order to read the value
+ *     since the local cache is updated synchronously.
+ * @override
+ */
+lib.Storage.Local.prototype.removeItem = function(key, callback) {
+  this.storage_.removeItem(key);
+
+  if (callback) {
+    setTimeout(callback, 0);
+  }
+};
+
+/**
+ * Remove multiple items from storage.
+ *
+ * @param {!Array<string>} ary The keys to be removed.
+ * @param {function()=} callback Function to invoke when the remove is complete.
+ *     You don't have to wait for the set to complete in order to read the value
+ *     since the local cache is updated synchronously.
+ * @override
+ */
+lib.Storage.Local.prototype.removeItems = function(ary, callback) {
+  for (var i = 0; i < ary.length; i++) {
+    this.storage_.removeItem(ary[i]);
+  }
+
+  if (callback) {
+    setTimeout(callback, 0);
+  }
+};
+// SOURCE FILE: libdot/js/lib_storage_memory.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * In-memory storage class with an async interface that is interchangeable with
+ * other lib.Storage.* implementations.
+ *
+ * @constructor
+ * @implements {lib.Storage}
+ */
+lib.Storage.Memory = function() {
+  this.observers_ = [];
+  this.storage_ = {};
+};
+
+/**
+ * Register a function to observe storage changes.
+ *
+ * @param {function(!Object)} callback The function to invoke when the storage
+ *     changes.
+ * @override
+ */
+lib.Storage.Memory.prototype.addObserver = function(callback) {
+  this.observers_.push(callback);
+};
+
+/**
+ * Unregister a change observer.
+ *
+ * @param {function(!Object)} callback A previously registered callback.
+ * @override
+ */
+lib.Storage.Memory.prototype.removeObserver = function(callback) {
+  var i = this.observers_.indexOf(callback);
+  if (i != -1)
+    this.observers_.splice(i, 1);
+};
+
+/**
+ * Delete everything in this storage.
+ *
+ * @param {function()=} callback The function to invoke when the delete has
+ *     completed.
+ * @override
+ */
+lib.Storage.Memory.prototype.clear = function(callback) {
+  var e = {};
+  for (var key in this.storage_) {
+    e[key] = {oldValue: this.storage_[key], newValue: undefined};
+  }
+
+  this.storage_ = {};
+
+  setTimeout(function() {
+    for (var i = 0; i < this.observers_.length; i++) {
+      this.observers_[i](e);
+    }
+  }.bind(this), 0);
+
+  if (callback) {
+    setTimeout(callback, 0);
+  }
+};
+
+/**
+ * Return the current value of a storage item.
+ *
+ * @param {string} key The key to look up.
+ * @param {function(*)} callback The function to invoke when the value has
+ *     been retrieved.
+ * @override
+ */
+lib.Storage.Memory.prototype.getItem = function(key, callback) {
+  var value = this.storage_[key];
+
+  if (typeof value == 'string') {
+    try {
+      value = JSON.parse(value);
+    } catch (e) {
+      // If we can't parse the value, just return it unparsed.
+    }
+  }
+
+  setTimeout(callback.bind(null, value), 0);
+};
+
+/**
+ * Fetch the values of multiple storage items.
+ *
+ * @param {?Array<string>} keys The keys to look up.  Pass null for all keys.
+ * @param {function(!Object)} callback The function to invoke when the values
+ *     have been retrieved.
+ * @override
+ */
+lib.Storage.Memory.prototype.getItems = function(keys, callback) {
+  var rv = {};
+  if (!keys) {
+    keys = Object.keys(this.storage_);
+  }
+
+  for (var i = keys.length - 1; i >= 0; i--) {
+    var key = keys[i];
+    var value = this.storage_[key];
+    if (typeof value == 'string') {
+      try {
+        rv[key] = JSON.parse(value);
+      } catch (e) {
+        // If we can't parse the value, just return it unparsed.
+        rv[key] = value;
+      }
+    } else {
+      keys.splice(i, 1);
+    }
+  }
+
+  setTimeout(callback.bind(null, rv), 0);
+};
+
+/**
+ * Set a value in storage.
+ *
+ * @param {string} key The key for the value to be stored.
+ * @param {*} value The value to be stored.  Anything that can be serialized
+ *     with JSON is acceptable.
+ * @param {function()=} callback Function to invoke when the set is complete.
+ *     You don't have to wait for the set to complete in order to read the value
+ *     since the local cache is updated synchronously.
+ * @override
+ */
+lib.Storage.Memory.prototype.setItem = function(key, value, callback) {
+  var oldValue = this.storage_[key];
+  this.storage_[key] = JSON.stringify(value);
+
+  var e = {};
+  e[key] = {oldValue: oldValue, newValue: value};
+
+  setTimeout(function() {
+    for (var i = 0; i < this.observers_.length; i++) {
+      this.observers_[i](e);
+    }
+  }.bind(this), 0);
+
+  if (callback) {
+    setTimeout(callback, 0);
+  }
+};
+
+/**
+ * Set multiple values in storage.
+ *
+ * @param {!Object} obj A map of key/values to set in storage.
+ * @param {function()=} callback Function to invoke when the set is complete.
+ *     You don't have to wait for the set to complete in order to read the value
+ *     since the local cache is updated synchronously.
+ * @override
+ */
+lib.Storage.Memory.prototype.setItems = function(obj, callback) {
+  var e = {};
+
+  for (var key in obj) {
+    e[key] = {oldValue: this.storage_[key], newValue: obj[key]};
+    this.storage_[key] = JSON.stringify(obj[key]);
+  }
+
+  setTimeout(function() {
+    for (var i = 0; i < this.observers_.length; i++) {
+      this.observers_[i](e);
+    }
+  }.bind(this));
+
+  if (callback) {
+    setTimeout(callback, 0);
+  }
+};
+
+/**
+ * Remove an item from storage.
+ *
+ * @param {string} key The key to be removed.
+ * @param {function()=} callback Function to invoke when the remove is complete.
+ *     The local cache is updated synchronously, so reads will immediately
+ *     return undefined for this item even before removeItem completes.
+ * @override
+ */
+lib.Storage.Memory.prototype.removeItem = function(key, callback) {
+  delete this.storage_[key];
+
+  if (callback) {
+    setTimeout(callback, 0);
+  }
+};
+
+/**
+ * Remove multiple items from storage.
+ *
+ * @param {!Array<string>} ary The keys to be removed.
+ * @param {function()=} callback Function to invoke when the remove is complete.
+ *     The local cache is updated synchronously, so reads will immediately
+ *     return undefined for these items even before removeItems completes.
+ * @override
+ */
+lib.Storage.Memory.prototype.removeItems = function(ary, callback) {
+  for (var i = 0; i < ary.length; i++) {
+    delete this.storage_[ary[i]];
+  }
+
+  if (callback) {
+    setTimeout(callback, 0);
+  }
+};
+// SOURCE FILE: libdot/js/lib_storage_terminal_private.js
+// Copyright 2019 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Storage implementation using chrome.settingsPrivate.
+ *
+ * @param {function()} callback Callback invoked when object is ready.
+ * @constructor
+ * @implements {lib.Storage}
+ */
+lib.Storage.TerminalPrivate = function(callback) {
+  /**
+   * @const
+   * @private
+   */
+  this.observers_ = [];
+  /** @private {!Object<string, *>} */
+  this.prefValue_ = {};
+
+  // Load.
+  chrome.terminalPrivate.getSettings((settings) => {
+    if (chrome.runtime.lastError) {
+      console.error(chrome.runtime.lastError.message);
+    } else {
+      this.prefValue_ = settings;
+    }
+    chrome.terminalPrivate.onSettingsChanged.addListener(
+        this.onSettingsChanged_.bind(this));
+    callback();
+  });
+};
+
+/**
+ * Called when settings change.
+ *
+ * @param {!Object<string, *>} settings
+ * @private
+ */
+lib.Storage.TerminalPrivate.prototype.onSettingsChanged_ = function(settings) {
+  // Check what is deleted.
+  const e = {};
+  for (const key in this.prefValue_) {
+    if (!settings.hasOwnProperty(key)) {
+      e[key] = {oldValue: this.prefValue_[key], newValue: undefined};
+    }
+  }
+  // Check what has changed.
+  for (const key in settings) {
+    const oldValue = this.prefValue_[key];
+    const newValue = settings[key];
+    if (newValue === oldValue ||
+        JSON.stringify(newValue) === JSON.stringify(oldValue)) {
+      continue;
+    }
+    e[key] = {oldValue, newValue};
+  }
+
+  setTimeout(() => {
+    for (const observer of this.observers_) {
+      observer(e);
+    }
+  }, 0);
+};
+
+/**
+ * Set pref then run callback.
+ *
+ * @param {function()=} callback Callback to run once pref is set.
+ * @private
+ */
+lib.Storage.TerminalPrivate.prototype.setPref_ = function(callback) {
+  chrome.terminalPrivate.setSettings(this.prefValue_, () => {
+    if (chrome.runtime.lastError) {
+      console.error(chrome.runtime.lastError.message);
+    }
+    if (callback) {
+      callback();
+    }
+  });
+};
+
+/**
+ * Register a function to observe storage changes.
+ *
+ * @param {function(!Object)} callback The function to invoke when the storage
+ *     changes.
+ * @override
+ */
+lib.Storage.TerminalPrivate.prototype.addObserver = function(callback) {
+  this.observers_.push(callback);
+};
+
+/**
+ * Unregister a change observer.
+ *
+ * @param {function(!Object)} callback A previously registered callback.
+ * @override
+ */
+lib.Storage.TerminalPrivate.prototype.removeObserver = function(callback) {
+  const i = this.observers_.indexOf(callback);
+  if (i !== -1) {
+    this.observers_.splice(i, 1);
+  }
+};
+
+/**
+ * Delete everything in this storage.
+ *
+ * @param {function()=} callback The function to invoke when the delete has
+ *     completed.
+ * @override
+ */
+lib.Storage.TerminalPrivate.prototype.clear = function(callback) {
+  this.prefValue_= {};
+  this.setPref_(callback);
+};
+
+/**
+ * Return the current value of a storage item.
+ *
+ * @param {string} key The key to look up.
+ * @param {function(*)} callback The function to invoke when the value has
+ *     been retrieved.
+ * @override
+ */
+lib.Storage.TerminalPrivate.prototype.getItem = function(key, callback) {
+  setTimeout(() => callback(this.prefValue_[key]), 0);
+};
+
+/**
+ * Fetch the values of multiple storage items.
+ *
+ * @param {?Array<string>} keys The keys to look up.  Pass null for all keys.
+ * @param {function(!Object)} callback The function to invoke when the values
+ *     have been retrieved.
+ * @override
+ */
+lib.Storage.TerminalPrivate.prototype.getItems = function(keys, callback) {
+  const rv = {};
+  if (!keys) {
+    keys = Object.keys(this.prefValue_);
+  }
+
+  for (const key of keys) {
+    if (this.prefValue_.hasOwnProperty(key)) {
+      rv[key] = this.prefValue_[key];
+    }
+  }
+
+  setTimeout(() => callback(rv), 0);
+};
+
+/**
+ * Set a value in storage.
+ *
+ * @param {string} key The key for the value to be stored.
+ * @param {*} value The value to be stored.  Anything that can be serialized
+ *     with JSON is acceptable.
+ * @param {function()=} callback Function to invoke when the set is complete.
+ *     You don't have to wait for the set to complete in order to read the value
+ *     since the local cache is updated synchronously.
+ * @override
+ */
+lib.Storage.TerminalPrivate.prototype.setItem = function(key, value, callback) {
+  this.setItems({[key]: value}, callback);
+};
+
+/**
+ * Set multiple values in storage.
+ *
+ * @param {!Object} obj A map of key/values to set in storage.
+ * @param {function()=} callback Function to invoke when the set is complete.
+ *     You don't have to wait for the set to complete in order to read the value
+ *     since the local cache is updated synchronously.
+ * @override
+ */
+lib.Storage.TerminalPrivate.prototype.setItems = function(obj, callback) {
+  const e = {};
+
+  for (const key in obj) {
+    e[key] = {oldValue: this.prefValue_[key], newValue: obj[key]};
+    this.prefValue_[key] = obj[key];
+  }
+
+  setTimeout(() => {
+    for (const observer of this.observers_) {
+      observer(e);
+    }
+  });
+
+  this.setPref_(callback);
+};
+
+/**
+ * Remove an item from storage.
+ *
+ * @param {string} key The key to be removed.
+ * @param {function()=} callback Function to invoke when the remove is complete.
+ *     The local cache is updated synchronously, so reads will immediately
+ *     return undefined for this item even before removeItem completes.
+ * @override
+ */
+lib.Storage.TerminalPrivate.prototype.removeItem = function(key, callback) {
+  this.removeItems([key], callback);
+};
+
+/**
+ * Remove multiple items from storage.
+ *
+ * @param {!Array<string>} keys The keys to be removed.
+ * @param {function()=} callback Function to invoke when the remove is complete.
+ *     The local cache is updated synchronously, so reads will immediately
+ *     return undefined for these items even before removeItems completes.
+ * @override
+ */
+lib.Storage.TerminalPrivate.prototype.removeItems = function(keys, callback) {
+  for (const key of keys) {
+    delete this.prefValue_[key];
+  }
+  this.setPref_(callback);
+};
+// SOURCE FILE: libdot/third_party/fast-text-encoding/text.js
+/*
+ * Copyright 2017 Sam Thorogood. All rights reserved.
+ *
+ * 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
+ *
+ *     https://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.
+ */
+
+/**
+ * @fileoverview Polyfill for TextEncoder and TextDecoder.
+ *
+ * You probably want `text.min.js`, and not this file directly.
+ */
+
+(function(scope) {
+'use strict';
+
+// fail early
+if (scope['TextEncoder'] && scope['TextDecoder']) {
+  return false;
+}
+
+/**
+ * @constructor
+ * @param {string=} utfLabel
+ */
+function FastTextEncoder(utfLabel='utf-8') {
+  if (utfLabel !== 'utf-8') {
+    throw new RangeError(
+        `Failed to construct 'TextEncoder': ` +
+        `The encoding label provided ('${utfLabel}') is invalid.`);
+  }
+}
+
+Object.defineProperty(FastTextEncoder.prototype, 'encoding', {value: 'utf-8'});
+
+/**
+ * @param {string} string
+ * @param {{stream: boolean}=} options
+ * @return {!Uint8Array}
+ */
+FastTextEncoder.prototype.encode = function(string, options={stream: false}) {
+  if (options.stream) {
+    throw new Error(`Failed to encode: the 'stream' option is unsupported.`);
+  }
+
+  let pos = 0;
+  const len = string.length;
+
+  let at = 0;  // output position
+  let tlen = Math.max(32, len + (len >> 1) + 7);  // 1.5x size
+  let target = new Uint8Array((tlen >> 3) << 3);  // ... but at 8 byte offset
+
+  while (pos < len) {
+    let value = string.charCodeAt(pos++);
+    if (value >= 0xd800 && value <= 0xdbff) {
+      // high surrogate
+      if (pos < len) {
+        const extra = string.charCodeAt(pos);
+        if ((extra & 0xfc00) === 0xdc00) {
+          ++pos;
+          value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
+        }
+      }
+      if (value >= 0xd800 && value <= 0xdbff) {
+        continue;  // drop lone surrogate
+      }
+    }
+
+    // expand the buffer if we couldn't write 4 bytes
+    if (at + 4 > target.length) {
+      tlen += 8;  // minimum extra
+      tlen *= (1.0 + (pos / string.length) * 2);  // take 2x the remaining
+      tlen = (tlen >> 3) << 3;  // 8 byte offset
+
+      const update = new Uint8Array(tlen);
+      update.set(target);
+      target = update;
+    }
+
+    if ((value & 0xffffff80) === 0) {  // 1-byte
+      target[at++] = value;  // ASCII
+      continue;
+    } else if ((value & 0xfffff800) === 0) {  // 2-byte
+      target[at++] = ((value >>  6) & 0x1f) | 0xc0;
+    } else if ((value & 0xffff0000) === 0) {  // 3-byte
+      target[at++] = ((value >> 12) & 0x0f) | 0xe0;
+      target[at++] = ((value >>  6) & 0x3f) | 0x80;
+    } else if ((value & 0xffe00000) === 0) {  // 4-byte
+      target[at++] = ((value >> 18) & 0x07) | 0xf0;
+      target[at++] = ((value >> 12) & 0x3f) | 0x80;
+      target[at++] = ((value >>  6) & 0x3f) | 0x80;
+    } else {
+      // TODO: do we care
+      continue;
+    }
+
+    target[at++] = (value & 0x3f) | 0x80;
+  }
+
+  return target.slice(0, at);
+};
+
+/**
+ * @constructor
+ * @param {string=} utfLabel
+ * @param {{fatal: boolean}=} options
+ */
+function FastTextDecoder(utfLabel='utf-8', options={fatal: false}) {
+  if (utfLabel !== 'utf-8') {
+    throw new RangeError(
+        `Failed to construct 'TextDecoder': ` +
+        `The encoding label provided ('${utfLabel}') is invalid.`);
+  }
+  if (options.fatal) {
+    throw new Error(
+        `Failed to construct 'TextDecoder': ` +
+        `the 'fatal' option is unsupported.`);
+  }
+}
+
+Object.defineProperty(FastTextDecoder.prototype, 'encoding', {value: 'utf-8'});
+
+Object.defineProperty(FastTextDecoder.prototype, 'fatal', {value: false});
+
+Object.defineProperty(FastTextDecoder.prototype, 'ignoreBOM', {value: false});
+
+/**
+ * @param {(!ArrayBuffer|!ArrayBufferView)} buffer
+ * @param {{stream: boolean}=} options
+ * @return {string}
+ */
+FastTextDecoder.prototype.decode = function(buffer, options={stream: false}) {
+  if (options['stream']) {
+    throw new Error(`Failed to decode: the 'stream' option is unsupported.`);
+  }
+
+  const bytes = new Uint8Array(buffer);
+  let pos = 0;
+  const len = bytes.length;
+  const out = [];
+
+  while (pos < len) {
+    const byte1 = bytes[pos++];
+    if (byte1 === 0) {
+      break;  // NULL
+    }
+
+    if ((byte1 & 0x80) === 0) {  // 1-byte
+      out.push(byte1);
+    } else if ((byte1 & 0xe0) === 0xc0) {  // 2-byte
+      const byte2 = bytes[pos++] & 0x3f;
+      out.push(((byte1 & 0x1f) << 6) | byte2);
+    } else if ((byte1 & 0xf0) === 0xe0) {
+      const byte2 = bytes[pos++] & 0x3f;
+      const byte3 = bytes[pos++] & 0x3f;
+      out.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);
+    } else if ((byte1 & 0xf8) === 0xf0) {
+      const byte2 = bytes[pos++] & 0x3f;
+      const byte3 = bytes[pos++] & 0x3f;
+      const byte4 = bytes[pos++] & 0x3f;
+
+      // this can be > 0xffff, so possibly generate surrogates
+      let codepoint =
+          ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
+      if (codepoint > 0xffff) {
+        // codepoint &= ~0x10000;
+        codepoint -= 0x10000;
+        out.push((codepoint >>> 10) & 0x3ff | 0xd800);
+        codepoint = 0xdc00 | codepoint & 0x3ff;
+      }
+      out.push(codepoint);
+    } else {
+      // TODO: we're ignoring this
+    }
+  }
+
+  return String.fromCharCode.apply(null, out);
+};
+
+scope['TextEncoder'] = FastTextEncoder;
+scope['TextDecoder'] = FastTextDecoder;
+}(typeof window !== 'undefined' ?
+      window :
+      (typeof global !== 'undefined' ? global : this)));
+// SOURCE FILE: libdot/third_party/intl-segmenter/intl-segmenter.js
+// Rough polyfill for Intl.Segmenter proposal
+//
+// https://github.com/tc39/proposal-intl-segmenter/blob/master/README.md
+//
+// Caveats and Limitations
+//  * granularity: 'line': 'strictness' option is not supported (ignored)
+//  * In Chrome, uses v8BreakIterator
+//  * Otherwise, uses very simplistic rules
+//    * Ignores locale; only "usable" on English
+//    * granularity: 'grapheme' does not understand combining characters
+//    * granularity: 'sentence' does not understand decimals
+
+(function(global) {
+  if ('Intl' in global && 'Segmenter' in global.Intl)
+    return;
+
+  global.Intl = global.Intl || {};
+
+  const GRANULARITIES = ['grapheme', 'word','sentence', 'line'];
+
+  // TODO: Implement https://www.unicode.org/reports/tr29/
+  const RULES = {
+    grapheme: {
+      grapheme: /^(.|\n)/
+    },
+    word: {
+      letter: /^[a-z](?:'?[a-z])*/i,
+      number: /^\d+([,.]\d+)*/
+    },
+    sentence: {
+      terminator: /^[^.?!\r\n]+[.?!]+[\r\n]?/,
+      separator: /^[^.?!\r\n]+[\r\n]?/
+    },
+    line: {
+      hard: /^\S*[\r\n]/,
+      soft: /^\S*\s*/
+    }
+  };
+
+  // Work around bug in v8BreakIterator where ICU's UWordBreak enum is
+  // used even if granularity is not "word". See the code in
+  // Runtime_BreakIteratorBreakType in runtime/runtime-i18n.cc for
+  // details.
+  function fixBreakType(value, granularity) {
+    // Undo the mapping of UWordBreak to string
+    const ruleStatus = {
+      none: 0, // UBRK_WORD_NONE
+      number: 100, // UBRK_WORD_NUMBER
+      letter: 200, // UBRK_WORD_LETTER
+      kana: 300, // UBRK_WORD_KANA
+      ideo: 400, // UBRK_WORD_IDEO
+      unknown: -1
+    }[value] || 0;
+
+
+    switch (granularity) {
+    case 'character':
+      return undefined;
+    case 'word':
+      return value;
+    case 'sentence':
+      // Map ULineBreakTag rule status to string.
+      return {
+        0: 'terminator',
+        100: 'separator'
+      }[ruleStatus] || value;
+    case 'line':
+      // Map ULineBreakTag rule status to string.
+      return {
+        0: 'soft',
+        100: 'hard'
+      }[ruleStatus] || value;
+    default:
+      return value;
+    }
+  }
+
+  function segment(locale, granularity, string) {
+    const breaks = [];
+    if ('v8BreakIterator' in global.Intl) {
+      if (granularity === 'grapheme')
+        granularity = 'character';
+      const vbi = new global.Intl.v8BreakIterator(locale, {type: granularity});
+      vbi.adoptText(string);
+      let last = 0;
+      let pos = vbi.next();
+      while (pos !== -1) {
+        breaks.push({
+          pos: vbi.current(),
+          segment: string.slice(last, pos),
+          breakType: fixBreakType(vbi.breakType(), granularity)
+        });
+        last = pos;
+        pos = vbi.next();
+      }
+    } else {
+      const rules = RULES[granularity];
+      let pos = 0;
+      while (pos < string.length) {
+        let found = false;
+        for (let rule of Object.keys(rules)) {
+          const re = rules[rule];
+          const m = string.slice(pos).match(re);
+          if (m) {
+            pos += m[0].length;
+            breaks.push({
+              pos: pos,
+              segment: m[0],
+              breakType: granularity === 'grapheme' ? undefined : rule
+            });
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          breaks.push({
+            pos: pos + 1,
+            segment: string.slice(pos, ++pos),
+            breakType: 'none'
+          });
+        }
+      }
+    }
+    breaks.initial = 0;
+    return breaks;
+  }
+
+  class $SegmentIterator$ {
+    constructor(string, breaks) {
+      this._cur = -1;
+      this._type = undefined;
+      this._breaks = breaks;
+    }
+
+    [Symbol.iterator]() { return this; }
+
+    next() {
+      if (this._cur < this._breaks.length)
+        ++this._cur;
+
+      if (this._cur >= this._breaks.length) {
+        this._type = undefined;
+        return {done: true, value: undefined};
+      }
+
+      this._type = this._breaks[this._cur].breakType;
+      return {
+        done: false,
+        value: {
+          segment: this._breaks[this._cur].segment,
+          breakType: this._breaks[this._cur].breakType
+        }
+      };
+    }
+
+    following(index = undefined) {
+      if (!this._breaks.length)
+        return true;
+      if (index === undefined) {
+        if (this._cur < this._breaks.length)
+          ++this._cur;
+      } else {
+        // TODO: binary search
+        for (this._cur = 0;
+             this._cur < this._breaks.length
+             && this._breaks[this._cur].pos < index;
+             ++this._cur) {}
+      }
+
+      this._type = this._cur < this._breaks.length
+        ? this._breaks[this._cur].breakType : undefined;
+      return this._cur + 1 >= this._breaks.length;
+    }
+
+    preceding(index = undefined) {
+      if (!this._breaks.length)
+        return true;
+      if (index === undefined) {
+        if (this._cur >= this._breaks.length)
+          --this._cur;
+        if (this._cur >= 0)
+          --this._cur;
+      } else {
+        // TODO: binary search
+        for (this._cur = this._breaks.length - 1;
+             this._cur >= 0
+             && this._breaks[this._cur].pos >= index;
+             --this._cur) {}
+      }
+
+      this._type =
+        this._cur + 1 >= this._breaks.length ? undefined :
+        this._breaks[this._cur + 1].breakType;
+      return this._cur < 0;
+    }
+
+    get position() {
+      if (this._cur < 0 || !this._breaks.length)
+        return this._breaks.initial;
+      if (this._cur >= this._breaks.length)
+        return this._breaks[this._breaks.length - 1].pos;
+      return this._breaks[this._cur].pos;
+    }
+
+    get breakType() {
+      return this._type;
+    }
+  }
+
+  global.Intl.Segmenter = class Segmenter {
+    constructor(locale, options) {
+      this._locale = Array.isArray(locale)
+        ? locale.map(s => String(s)) : String(locale || navigator.language);
+      options = Object.assign({granularity: 'grapheme'}, options);
+      this._granularity = GRANULARITIES.includes(options.granularity)
+        ? options.granularity : 'grapheme';
+    }
+
+    segment(string) {
+      return new $SegmentIterator$(
+        string, segment(this._locale, this._granularity, string));
+    }
+  };
+}(typeof window !== 'undefined' ?
+      window :
+      (typeof global !== 'undefined' ? global : this)));
+// SOURCE FILE: libdot/third_party/wcwidth/lib_wc.js
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of lib.wc source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview
+ * This JavaScript library is ported from the wcwidth.js module of node.js.
+ * The original implementation can be found at:
+ * https://npmjs.org/package/wcwidth.js
+ */
+
+/**
+ * JavaScript porting of Markus Kuhn's wcwidth() implementation
+ *
+ * The following explanation comes from the original C implementation:
+ *
+ * This is an implementation of wcwidth() and wcswidth() (defined in
+ * IEEE Std 1002.1-2001) for Unicode.
+ *
+ * https://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
+ * https://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
+ *
+ * In fixed-width output devices, Latin characters all occupy a single
+ * "cell" position of equal width, whereas ideographic CJK characters
+ * occupy two such cells. Interoperability between terminal-line
+ * applications and (teletype-style) character terminals using the
+ * UTF-8 encoding requires agreement on which character should advance
+ * the cursor by how many cell positions. No established formal
+ * standards exist at present on which Unicode character shall occupy
+ * how many cell positions on character terminals. These routines are
+ * a first attempt of defining such behavior based on simple rules
+ * applied to data provided by the Unicode Consortium.
+ *
+ * For some graphical characters, the Unicode standard explicitly
+ * defines a character-cell width via the definition of the East Asian
+ * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
+ * In all these cases, there is no ambiguity about which width a
+ * terminal shall use. For characters in the East Asian Ambiguous (A)
+ * class, the width choice depends purely on a preference of backward
+ * compatibility with either historic CJK or Western practice.
+ * Choosing single-width for these characters is easy to justify as
+ * the appropriate long-term solution, as the CJK practice of
+ * displaying these characters as double-width comes from historic
+ * implementation simplicity (8-bit encoded characters were displayed
+ * single-width and 16-bit ones double-width, even for Greek,
+ * Cyrillic, etc.) and not any typographic considerations.
+ *
+ * Much less clear is the choice of width for the Not East Asian
+ * (Neutral) class. Existing practice does not dictate a width for any
+ * of these characters. It would nevertheless make sense
+ * typographically to allocate two character cells to characters such
+ * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
+ * represented adequately with a single-width glyph. The following
+ * routines at present merely assign a single-cell width to all
+ * neutral characters, in the interest of simplicity. This is not
+ * entirely satisfactory and should be reconsidered before
+ * establishing a formal standard in lib.wc area. At the moment, the
+ * decision which Not East Asian (Neutral) characters should be
+ * represented by double-width glyphs cannot yet be answered by
+ * applying a simple rule from the Unicode database content. Setting
+ * up a proper standard for the behavior of UTF-8 character terminals
+ * will require a careful analysis not only of each Unicode character,
+ * but also of each presentation form, something the author of these
+ * routines has avoided to do so far.
+ *
+ * https://www.unicode.org/unicode/reports/tr11/
+ *
+ * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
+ *
+ * Permission to use, copy, modify, and distribute lib.wc software
+ * for any purpose and without fee is hereby granted. The author
+ * disclaims all warranties with regard to lib.wc software.
+ *
+ * Latest version: https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
+ */
+
+/**
+ * The following function defines the column width of an ISO 10646 character
+ * as follows:
+ *
+ *  - The null character (U+0000) has a column width of 0.
+ *  - Other C0/C1 control characters and DEL will lead to a return value of -1.
+ *  - Non-spacing and enclosing combining characters (general category code Mn
+ *    or Me in the Unicode database) have a column width of 0.
+ *  - SOFT HYPHEN (U+00AD) has a column width of 1.
+ *  - Other format characters (general category code Cf in the Unicode database)
+ *    and ZERO WIDTH SPACE (U+200B) have a column width of 0.
+ *  - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) have a
+ *    column width of 0.
+ *  - Spacing characters in the East Asian Wide (W) or East Asian Full-width (F)
+ *    category as defined in Unicode Technical Report #11 have a column width of
+ *    2.
+ *  - East Asian Ambiguous characters are taken into account if
+ *    regardCjkAmbiguous flag is enabled. They have a column width of 2.
+ *  - All remaining characters (including all printable ISO 8859-1 and WGL4
+ *    characters, Unicode control characters, etc.) have a column width of 1.
+ *
+ * This implementation assumes that characters are encoded in ISO 10646.
+ */
+
+lib.wc = {};
+
+// Width of a nul character.
+lib.wc.nulWidth = 0;
+
+// Width of a control character.
+lib.wc.controlWidth = 0;
+
+// Flag whether to consider East Asian Ambiguous characters.
+lib.wc.regardCjkAmbiguous = false;
+
+// Width of an East Asian Ambiguous character.
+lib.wc.cjkAmbiguousWidth = 2;
+
+// Sorted list of non-overlapping intervals of non-spacing characters
+// generated by the `./ranges.py` helper.
+lib.wc.combining = [
+    [0x00ad, 0x00ad], [0x0300, 0x036f], [0x0483, 0x0489],
+    [0x0591, 0x05bd], [0x05bf, 0x05bf], [0x05c1, 0x05c2],
+    [0x05c4, 0x05c5], [0x05c7, 0x05c7], [0x0610, 0x061a],
+    [0x061c, 0x061c], [0x064b, 0x065f], [0x0670, 0x0670],
+    [0x06d6, 0x06dc], [0x06df, 0x06e4], [0x06e7, 0x06e8],
+    [0x06ea, 0x06ed], [0x0711, 0x0711], [0x0730, 0x074a],
+    [0x07a6, 0x07b0], [0x07eb, 0x07f3], [0x07fd, 0x07fd],
+    [0x0816, 0x0819], [0x081b, 0x0823], [0x0825, 0x0827],
+    [0x0829, 0x082d], [0x0859, 0x085b], [0x08d3, 0x08e1],
+    [0x08e3, 0x0902], [0x093a, 0x093a], [0x093c, 0x093c],
+    [0x0941, 0x0948], [0x094d, 0x094d], [0x0951, 0x0957],
+    [0x0962, 0x0963], [0x0981, 0x0981], [0x09bc, 0x09bc],
+    [0x09c1, 0x09c4], [0x09cd, 0x09cd], [0x09e2, 0x09e3],
+    [0x09fe, 0x09fe], [0x0a01, 0x0a02], [0x0a3c, 0x0a3c],
+    [0x0a41, 0x0a42], [0x0a47, 0x0a48], [0x0a4b, 0x0a4d],
+    [0x0a51, 0x0a51], [0x0a70, 0x0a71], [0x0a75, 0x0a75],
+    [0x0a81, 0x0a82], [0x0abc, 0x0abc], [0x0ac1, 0x0ac5],
+    [0x0ac7, 0x0ac8], [0x0acd, 0x0acd], [0x0ae2, 0x0ae3],
+    [0x0afa, 0x0aff], [0x0b01, 0x0b01], [0x0b3c, 0x0b3c],
+    [0x0b3f, 0x0b3f], [0x0b41, 0x0b44], [0x0b4d, 0x0b4d],
+    [0x0b56, 0x0b56], [0x0b62, 0x0b63], [0x0b82, 0x0b82],
+    [0x0bc0, 0x0bc0], [0x0bcd, 0x0bcd], [0x0c00, 0x0c00],
+    [0x0c04, 0x0c04], [0x0c3e, 0x0c40], [0x0c46, 0x0c48],
+    [0x0c4a, 0x0c4d], [0x0c55, 0x0c56], [0x0c62, 0x0c63],
+    [0x0c81, 0x0c81], [0x0cbc, 0x0cbc], [0x0cbf, 0x0cbf],
+    [0x0cc6, 0x0cc6], [0x0ccc, 0x0ccd], [0x0ce2, 0x0ce3],
+    [0x0d00, 0x0d01], [0x0d3b, 0x0d3c], [0x0d41, 0x0d44],
+    [0x0d4d, 0x0d4d], [0x0d62, 0x0d63], [0x0dca, 0x0dca],
+    [0x0dd2, 0x0dd4], [0x0dd6, 0x0dd6], [0x0e31, 0x0e31],
+    [0x0e34, 0x0e3a], [0x0e47, 0x0e4e], [0x0eb1, 0x0eb1],
+    [0x0eb4, 0x0ebc], [0x0ec8, 0x0ecd], [0x0f18, 0x0f19],
+    [0x0f35, 0x0f35], [0x0f37, 0x0f37], [0x0f39, 0x0f39],
+    [0x0f71, 0x0f7e], [0x0f80, 0x0f84], [0x0f86, 0x0f87],
+    [0x0f8d, 0x0f97], [0x0f99, 0x0fbc], [0x0fc6, 0x0fc6],
+    [0x102d, 0x1030], [0x1032, 0x1037], [0x1039, 0x103a],
+    [0x103d, 0x103e], [0x1058, 0x1059], [0x105e, 0x1060],
+    [0x1071, 0x1074], [0x1082, 0x1082], [0x1085, 0x1086],
+    [0x108d, 0x108d], [0x109d, 0x109d], [0x1160, 0x11ff],
+    [0x135d, 0x135f], [0x1712, 0x1714], [0x1732, 0x1734],
+    [0x1752, 0x1753], [0x1772, 0x1773], [0x17b4, 0x17b5],
+    [0x17b7, 0x17bd], [0x17c6, 0x17c6], [0x17c9, 0x17d3],
+    [0x17dd, 0x17dd], [0x180b, 0x180e], [0x1885, 0x1886],
+    [0x18a9, 0x18a9], [0x1920, 0x1922], [0x1927, 0x1928],
+    [0x1932, 0x1932], [0x1939, 0x193b], [0x1a17, 0x1a18],
+    [0x1a1b, 0x1a1b], [0x1a56, 0x1a56], [0x1a58, 0x1a5e],
+    [0x1a60, 0x1a60], [0x1a62, 0x1a62], [0x1a65, 0x1a6c],
+    [0x1a73, 0x1a7c], [0x1a7f, 0x1a7f], [0x1ab0, 0x1abe],
+    [0x1b00, 0x1b03], [0x1b34, 0x1b34], [0x1b36, 0x1b3a],
+    [0x1b3c, 0x1b3c], [0x1b42, 0x1b42], [0x1b6b, 0x1b73],
+    [0x1b80, 0x1b81], [0x1ba2, 0x1ba5], [0x1ba8, 0x1ba9],
+    [0x1bab, 0x1bad], [0x1be6, 0x1be6], [0x1be8, 0x1be9],
+    [0x1bed, 0x1bed], [0x1bef, 0x1bf1], [0x1c2c, 0x1c33],
+    [0x1c36, 0x1c37], [0x1cd0, 0x1cd2], [0x1cd4, 0x1ce0],
+    [0x1ce2, 0x1ce8], [0x1ced, 0x1ced], [0x1cf4, 0x1cf4],
+    [0x1cf8, 0x1cf9], [0x1dc0, 0x1df9], [0x1dfb, 0x1dff],
+    [0x200b, 0x200f], [0x202a, 0x202e], [0x2060, 0x2064],
+    [0x2066, 0x206f], [0x20d0, 0x20f0], [0x2cef, 0x2cf1],
+    [0x2d7f, 0x2d7f], [0x2de0, 0x2dff], [0x302a, 0x302d],
+    [0x3099, 0x309a], [0xa66f, 0xa672], [0xa674, 0xa67d],
+    [0xa69e, 0xa69f], [0xa6f0, 0xa6f1], [0xa802, 0xa802],
+    [0xa806, 0xa806], [0xa80b, 0xa80b], [0xa825, 0xa826],
+    [0xa8c4, 0xa8c5], [0xa8e0, 0xa8f1], [0xa8ff, 0xa8ff],
+    [0xa926, 0xa92d], [0xa947, 0xa951], [0xa980, 0xa982],
+    [0xa9b3, 0xa9b3], [0xa9b6, 0xa9b9], [0xa9bc, 0xa9bd],
+    [0xa9e5, 0xa9e5], [0xaa29, 0xaa2e], [0xaa31, 0xaa32],
+    [0xaa35, 0xaa36], [0xaa43, 0xaa43], [0xaa4c, 0xaa4c],
+    [0xaa7c, 0xaa7c], [0xaab0, 0xaab0], [0xaab2, 0xaab4],
+    [0xaab7, 0xaab8], [0xaabe, 0xaabf], [0xaac1, 0xaac1],
+    [0xaaec, 0xaaed], [0xaaf6, 0xaaf6], [0xabe5, 0xabe5],
+    [0xabe8, 0xabe8], [0xabed, 0xabed], [0xfb1e, 0xfb1e],
+    [0xfe00, 0xfe0f], [0xfe20, 0xfe2f], [0xfeff, 0xfeff],
+    [0xfff9, 0xfffb], [0x101fd, 0x101fd], [0x102e0, 0x102e0],
+    [0x10376, 0x1037a], [0x10a01, 0x10a03], [0x10a05, 0x10a06],
+    [0x10a0c, 0x10a0f], [0x10a38, 0x10a3a], [0x10a3f, 0x10a3f],
+    [0x10ae5, 0x10ae6], [0x10d24, 0x10d27], [0x10f46, 0x10f50],
+    [0x11001, 0x11001], [0x11038, 0x11046], [0x1107f, 0x11081],
+    [0x110b3, 0x110b6], [0x110b9, 0x110ba], [0x11100, 0x11102],
+    [0x11127, 0x1112b], [0x1112d, 0x11134], [0x11173, 0x11173],
+    [0x11180, 0x11181], [0x111b6, 0x111be], [0x111c9, 0x111cc],
+    [0x1122f, 0x11231], [0x11234, 0x11234], [0x11236, 0x11237],
+    [0x1123e, 0x1123e], [0x112df, 0x112df], [0x112e3, 0x112ea],
+    [0x11300, 0x11301], [0x1133b, 0x1133c], [0x11340, 0x11340],
+    [0x11366, 0x1136c], [0x11370, 0x11374], [0x11438, 0x1143f],
+    [0x11442, 0x11444], [0x11446, 0x11446], [0x1145e, 0x1145e],
+    [0x114b3, 0x114b8], [0x114ba, 0x114ba], [0x114bf, 0x114c0],
+    [0x114c2, 0x114c3], [0x115b2, 0x115b5], [0x115bc, 0x115bd],
+    [0x115bf, 0x115c0], [0x115dc, 0x115dd], [0x11633, 0x1163a],
+    [0x1163d, 0x1163d], [0x1163f, 0x11640], [0x116ab, 0x116ab],
+    [0x116ad, 0x116ad], [0x116b0, 0x116b5], [0x116b7, 0x116b7],
+    [0x1171d, 0x1171f], [0x11722, 0x11725], [0x11727, 0x1172b],
+    [0x1182f, 0x11837], [0x11839, 0x1183a], [0x119d4, 0x119d7],
+    [0x119da, 0x119db], [0x119e0, 0x119e0], [0x11a01, 0x11a0a],
+    [0x11a33, 0x11a38], [0x11a3b, 0x11a3e], [0x11a47, 0x11a47],
+    [0x11a51, 0x11a56], [0x11a59, 0x11a5b], [0x11a8a, 0x11a96],
+    [0x11a98, 0x11a99], [0x11c30, 0x11c36], [0x11c38, 0x11c3d],
+    [0x11c3f, 0x11c3f], [0x11c92, 0x11ca7], [0x11caa, 0x11cb0],
+    [0x11cb2, 0x11cb3], [0x11cb5, 0x11cb6], [0x11d31, 0x11d36],
+    [0x11d3a, 0x11d3a], [0x11d3c, 0x11d3d], [0x11d3f, 0x11d45],
+    [0x11d47, 0x11d47], [0x11d90, 0x11d91], [0x11d95, 0x11d95],
+    [0x11d97, 0x11d97], [0x11ef3, 0x11ef4], [0x13430, 0x13438],
+    [0x16af0, 0x16af4], [0x16b30, 0x16b36], [0x16f4f, 0x16f4f],
+    [0x16f8f, 0x16f92], [0x1bc9d, 0x1bc9e], [0x1bca0, 0x1bca3],
+    [0x1d167, 0x1d169], [0x1d173, 0x1d182], [0x1d185, 0x1d18b],
+    [0x1d1aa, 0x1d1ad], [0x1d242, 0x1d244], [0x1da00, 0x1da36],
+    [0x1da3b, 0x1da6c], [0x1da75, 0x1da75], [0x1da84, 0x1da84],
+    [0x1da9b, 0x1da9f], [0x1daa1, 0x1daaf], [0x1e000, 0x1e006],
+    [0x1e008, 0x1e018], [0x1e01b, 0x1e021], [0x1e023, 0x1e024],
+    [0x1e026, 0x1e02a], [0x1e130, 0x1e136], [0x1e2ec, 0x1e2ef],
+    [0x1e8d0, 0x1e8d6], [0x1e944, 0x1e94a], [0xe0001, 0xe0001],
+    [0xe0020, 0xe007f], [0xe0100, 0xe01ef],
+];
+
+// Sorted list of non-overlapping intervals of East Asian Ambiguous characters
+// generated by the `./ranges.py` helper.
+lib.wc.ambiguous = [
+    [0x00a1, 0x00a1], [0x00a4, 0x00a4], [0x00a7, 0x00a8],
+    [0x00aa, 0x00aa], [0x00ad, 0x00ae], [0x00b0, 0x00b4],
+    [0x00b6, 0x00ba], [0x00bc, 0x00bf], [0x00c6, 0x00c6],
+    [0x00d0, 0x00d0], [0x00d7, 0x00d8], [0x00de, 0x00e1],
+    [0x00e6, 0x00e6], [0x00e8, 0x00ea], [0x00ec, 0x00ed],
+    [0x00f0, 0x00f0], [0x00f2, 0x00f3], [0x00f7, 0x00fa],
+    [0x00fc, 0x00fc], [0x00fe, 0x00fe], [0x0101, 0x0101],
+    [0x0111, 0x0111], [0x0113, 0x0113], [0x011b, 0x011b],
+    [0x0126, 0x0127], [0x012b, 0x012b], [0x0131, 0x0133],
+    [0x0138, 0x0138], [0x013f, 0x0142], [0x0144, 0x0144],
+    [0x0148, 0x014b], [0x014d, 0x014d], [0x0152, 0x0153],
+    [0x0166, 0x0167], [0x016b, 0x016b], [0x01ce, 0x01ce],
+    [0x01d0, 0x01d0], [0x01d2, 0x01d2], [0x01d4, 0x01d4],
+    [0x01d6, 0x01d6], [0x01d8, 0x01d8], [0x01da, 0x01da],
+    [0x01dc, 0x01dc], [0x0251, 0x0251], [0x0261, 0x0261],
+    [0x02c4, 0x02c4], [0x02c7, 0x02c7], [0x02c9, 0x02cb],
+    [0x02cd, 0x02cd], [0x02d0, 0x02d0], [0x02d8, 0x02db],
+    [0x02dd, 0x02dd], [0x02df, 0x02df], [0x0300, 0x036f],
+    [0x0391, 0x03a1], [0x03a3, 0x03a9], [0x03b1, 0x03c1],
+    [0x03c3, 0x03c9], [0x0401, 0x0401], [0x0410, 0x044f],
+    [0x0451, 0x0451], [0x1100, 0x115f], [0x2010, 0x2010],
+    [0x2013, 0x2016], [0x2018, 0x2019], [0x201c, 0x201d],
+    [0x2020, 0x2022], [0x2024, 0x2027], [0x2030, 0x2030],
+    [0x2032, 0x2033], [0x2035, 0x2035], [0x203b, 0x203b],
+    [0x203e, 0x203e], [0x2074, 0x2074], [0x207f, 0x207f],
+    [0x2081, 0x2084], [0x20ac, 0x20ac], [0x2103, 0x2103],
+    [0x2105, 0x2105], [0x2109, 0x2109], [0x2113, 0x2113],
+    [0x2116, 0x2116], [0x2121, 0x2122], [0x2126, 0x2126],
+    [0x212b, 0x212b], [0x2153, 0x2154], [0x215b, 0x215e],
+    [0x2160, 0x216b], [0x2170, 0x2179], [0x2189, 0x2189],
+    [0x2190, 0x2199], [0x21b8, 0x21b9], [0x21d2, 0x21d2],
+    [0x21d4, 0x21d4], [0x21e7, 0x21e7], [0x2200, 0x2200],
+    [0x2202, 0x2203], [0x2207, 0x2208], [0x220b, 0x220b],
+    [0x220f, 0x220f], [0x2211, 0x2211], [0x2215, 0x2215],
+    [0x221a, 0x221a], [0x221d, 0x2220], [0x2223, 0x2223],
+    [0x2225, 0x2225], [0x2227, 0x222c], [0x222e, 0x222e],
+    [0x2234, 0x2237], [0x223c, 0x223d], [0x2248, 0x2248],
+    [0x224c, 0x224c], [0x2252, 0x2252], [0x2260, 0x2261],
+    [0x2264, 0x2267], [0x226a, 0x226b], [0x226e, 0x226f],
+    [0x2282, 0x2283], [0x2286, 0x2287], [0x2295, 0x2295],
+    [0x2299, 0x2299], [0x22a5, 0x22a5], [0x22bf, 0x22bf],
+    [0x2312, 0x2312], [0x231a, 0x231b], [0x2329, 0x232a],
+    [0x23e9, 0x23ec], [0x23f0, 0x23f0], [0x23f3, 0x23f3],
+    [0x2460, 0x24e9], [0x24eb, 0x254b], [0x2550, 0x2573],
+    [0x2580, 0x258f], [0x2592, 0x2595], [0x25a0, 0x25a1],
+    [0x25a3, 0x25a9], [0x25b2, 0x25b3], [0x25b6, 0x25b7],
+    [0x25bc, 0x25bd], [0x25c0, 0x25c1], [0x25c6, 0x25c8],
+    [0x25cb, 0x25cb], [0x25ce, 0x25d1], [0x25e2, 0x25e5],
+    [0x25ef, 0x25ef], [0x25fd, 0x25fe], [0x2605, 0x2606],
+    [0x2609, 0x2609], [0x260e, 0x260f], [0x2614, 0x2615],
+    [0x261c, 0x261c], [0x261e, 0x261e], [0x2640, 0x2640],
+    [0x2642, 0x2642], [0x2648, 0x2653], [0x2660, 0x2661],
+    [0x2663, 0x2665], [0x2667, 0x266a], [0x266c, 0x266d],
+    [0x266f, 0x266f], [0x267f, 0x267f], [0x2693, 0x2693],
+    [0x269e, 0x269f], [0x26a1, 0x26a1], [0x26aa, 0x26ab],
+    [0x26bd, 0x26bf], [0x26c4, 0x26e1], [0x26e3, 0x26e3],
+    [0x26e8, 0x26ff], [0x2705, 0x2705], [0x270a, 0x270b],
+    [0x2728, 0x2728], [0x273d, 0x273d], [0x274c, 0x274c],
+    [0x274e, 0x274e], [0x2753, 0x2755], [0x2757, 0x2757],
+    [0x2776, 0x277f], [0x2795, 0x2797], [0x27b0, 0x27b0],
+    [0x27bf, 0x27bf], [0x2b1b, 0x2b1c], [0x2b50, 0x2b50],
+    [0x2b55, 0x2b59], [0x2e80, 0x2fdf], [0x2ff0, 0x303e],
+    [0x3040, 0x4dbf], [0x4e00, 0xa4cf], [0xa960, 0xa97f],
+    [0xac00, 0xd7a3], [0xe000, 0xfaff], [0xfe00, 0xfe19],
+    [0xfe30, 0xfe6f], [0xff01, 0xff60], [0xffe0, 0xffe6],
+    [0xfffd, 0xfffd], [0x16fe0, 0x16fe3], [0x17000, 0x18aff],
+    [0x1b000, 0x1b12f], [0x1b150, 0x1b152], [0x1b164, 0x1b167],
+    [0x1b170, 0x1b2ff], [0x1f004, 0x1f004], [0x1f0cf, 0x1f0cf],
+    [0x1f100, 0x1f10a], [0x1f110, 0x1f12d], [0x1f130, 0x1f169],
+    [0x1f170, 0x1f1ac], [0x1f200, 0x1f202], [0x1f210, 0x1f23b],
+    [0x1f240, 0x1f248], [0x1f250, 0x1f251], [0x1f260, 0x1f265],
+    [0x1f300, 0x1f320], [0x1f32d, 0x1f335], [0x1f337, 0x1f37c],
+    [0x1f37e, 0x1f393], [0x1f3a0, 0x1f3ca], [0x1f3cf, 0x1f3d3],
+    [0x1f3e0, 0x1f3f0], [0x1f3f4, 0x1f3f4], [0x1f3f8, 0x1f43e],
+    [0x1f440, 0x1f440], [0x1f442, 0x1f4fc], [0x1f4ff, 0x1f53d],
+    [0x1f54b, 0x1f54e], [0x1f550, 0x1f567], [0x1f57a, 0x1f57a],
+    [0x1f595, 0x1f596], [0x1f5a4, 0x1f5a4], [0x1f5fb, 0x1f64f],
+    [0x1f680, 0x1f6c5], [0x1f6cc, 0x1f6cc], [0x1f6d0, 0x1f6d2],
+    [0x1f6d5, 0x1f6d5], [0x1f6eb, 0x1f6ec], [0x1f6f4, 0x1f6fa],
+    [0x1f7e0, 0x1f7eb], [0x1f90d, 0x1f971], [0x1f973, 0x1f976],
+    [0x1f97a, 0x1f9a2], [0x1f9a5, 0x1f9aa], [0x1f9ae, 0x1f9ca],
+    [0x1f9cd, 0x1f9ff], [0x1fa70, 0x1fa73], [0x1fa78, 0x1fa7a],
+    [0x1fa80, 0x1fa82], [0x1fa90, 0x1fa95], [0x20000, 0x2fffd],
+    [0x30000, 0x3fffd], [0xe0100, 0xe01ef], [0xf0000, 0xffffd],
+    [0x100000, 0x10fffd],
+];
+
+// Sorted list of non-overlapping intervals of East Asian Unambiguous characters
+// generated by the `./ranges.py` helper.
+lib.wc.unambiguous = [
+    [0x1100, 0x115f], [0x231a, 0x231b], [0x2329, 0x232a],
+    [0x23e9, 0x23ec], [0x23f0, 0x23f0], [0x23f3, 0x23f3],
+    [0x25fd, 0x25fe], [0x2614, 0x2615], [0x2648, 0x2653],
+    [0x267f, 0x267f], [0x2693, 0x2693], [0x26a1, 0x26a1],
+    [0x26aa, 0x26ab], [0x26bd, 0x26be], [0x26c4, 0x26c5],
+    [0x26ce, 0x26ce], [0x26d4, 0x26d4], [0x26ea, 0x26ea],
+    [0x26f2, 0x26f3], [0x26f5, 0x26f5], [0x26fa, 0x26fa],
+    [0x26fd, 0x26fd], [0x2705, 0x2705], [0x270a, 0x270b],
+    [0x2728, 0x2728], [0x274c, 0x274c], [0x274e, 0x274e],
+    [0x2753, 0x2755], [0x2757, 0x2757], [0x2795, 0x2797],
+    [0x27b0, 0x27b0], [0x27bf, 0x27bf], [0x2b1b, 0x2b1c],
+    [0x2b50, 0x2b50], [0x2b55, 0x2b55], [0x2e80, 0x2fdf],
+    [0x2ff0, 0x303e], [0x3040, 0x3247], [0x3250, 0x4dbf],
+    [0x4e00, 0xa4cf], [0xa960, 0xa97f], [0xac00, 0xd7a3],
+    [0xf900, 0xfaff], [0xfe10, 0xfe19], [0xfe30, 0xfe6f],
+    [0xff01, 0xff60], [0xffe0, 0xffe6], [0x16fe0, 0x16fe3],
+    [0x17000, 0x18aff], [0x1b000, 0x1b12f], [0x1b150, 0x1b152],
+    [0x1b164, 0x1b167], [0x1b170, 0x1b2ff], [0x1f004, 0x1f004],
+    [0x1f0cf, 0x1f0cf], [0x1f18e, 0x1f18e], [0x1f191, 0x1f19a],
+    [0x1f200, 0x1f202], [0x1f210, 0x1f23b], [0x1f240, 0x1f248],
+    [0x1f250, 0x1f251], [0x1f260, 0x1f265], [0x1f300, 0x1f320],
+    [0x1f32d, 0x1f335], [0x1f337, 0x1f37c], [0x1f37e, 0x1f393],
+    [0x1f3a0, 0x1f3ca], [0x1f3cf, 0x1f3d3], [0x1f3e0, 0x1f3f0],
+    [0x1f3f4, 0x1f3f4], [0x1f3f8, 0x1f43e], [0x1f440, 0x1f440],
+    [0x1f442, 0x1f4fc], [0x1f4ff, 0x1f53d], [0x1f54b, 0x1f54e],
+    [0x1f550, 0x1f567], [0x1f57a, 0x1f57a], [0x1f595, 0x1f596],
+    [0x1f5a4, 0x1f5a4], [0x1f5fb, 0x1f64f], [0x1f680, 0x1f6c5],
+    [0x1f6cc, 0x1f6cc], [0x1f6d0, 0x1f6d2], [0x1f6d5, 0x1f6d5],
+    [0x1f6eb, 0x1f6ec], [0x1f6f4, 0x1f6fa], [0x1f7e0, 0x1f7eb],
+    [0x1f90d, 0x1f971], [0x1f973, 0x1f976], [0x1f97a, 0x1f9a2],
+    [0x1f9a5, 0x1f9aa], [0x1f9ae, 0x1f9ca], [0x1f9cd, 0x1f9ff],
+    [0x1fa70, 0x1fa73], [0x1fa78, 0x1fa7a], [0x1fa80, 0x1fa82],
+    [0x1fa90, 0x1fa95], [0x20000, 0x2fffd], [0x30000, 0x3fffd],
+];
+
+/**
+ * Binary search to check if the given unicode character is in the table.
+ *
+ * @param {number} ucs A unicode character code.
+ * @param {!Object} table A sorted list of internals to match against.
+ * @return {boolean} True if the given character is in the table.
+ */
+lib.wc.binaryTableSearch_ = function(ucs, table) {
+  var min = 0, max = table.length - 1;
+  var mid;
+
+  if (ucs < table[min][0] || ucs > table[max][1])
+    return false;
+  while (max >= min) {
+    mid = Math.floor((min + max) / 2);
+    if (ucs > table[mid][1]) {
+      min = mid + 1;
+    } else if (ucs < table[mid][0]) {
+      max = mid - 1;
+    } else {
+      return true;
+    }
+  }
+
+  return false;
+};
+
+/**
+ * Binary search to check if the given unicode character is a space character.
+ *
+ * @param {number} ucs A unicode character code.
+ * @return {boolean} True if the given character is a space character; false
+ *     otherwise.
+ */
+lib.wc.isSpace = function(ucs) {
+  return lib.wc.binaryTableSearch_(ucs, lib.wc.combining);
+};
+
+/**
+ * Auxiliary function for checking if the given unicode character is a East
+ * Asian Ambiguous character.
+ *
+ * @param {number} ucs A unicode character code.
+ * @return {boolean} True if the given character is a East Asian Ambiguous
+ *     character.
+ */
+lib.wc.isCjkAmbiguous = function(ucs) {
+  return lib.wc.binaryTableSearch_(ucs, lib.wc.ambiguous);
+};
+
+/**
+ * Determine the column width of the given character.
+ *
+ * @param {number} ucs A unicode character code.
+ * @return {number} The column width of the given character.
+ */
+lib.wc.charWidth = function(ucs) {
+  if (lib.wc.regardCjkAmbiguous) {
+    return lib.wc.charWidthRegardAmbiguous(ucs);
+  } else {
+    return lib.wc.charWidthDisregardAmbiguous(ucs);
+  }
+};
+
+/**
+ * Determine the column width of the given character without considering East
+ * Asian Ambiguous characters.
+ *
+ * @param {number} ucs A unicode character code.
+ * @return {number} The column width of the given character.
+ */
+lib.wc.charWidthDisregardAmbiguous = function(ucs) {
+  // Optimize for ASCII characters.
+  if (ucs < 0x7f) {
+    if (ucs >= 0x20)
+      return 1;
+    else if (ucs == 0)
+      return lib.wc.nulWidth;
+    else /* if (ucs < 0x20) */
+      return lib.wc.controlWidth;
+  }
+
+  // Test for 8-bit control characters.
+  if (ucs < 0xa0)
+    return lib.wc.controlWidth;
+
+  // Binary search in table of non-spacing characters.
+  if (lib.wc.isSpace(ucs))
+    return 0;
+
+  // Binary search in table of wide characters.
+  return lib.wc.binaryTableSearch_(ucs, lib.wc.unambiguous) ? 2 : 1;
+};
+
+/**
+ * Determine the column width of the given character considering East Asian
+ * Ambiguous characters.
+ *
+ * @param {number} ucs A unicode character code.
+ * @return {number} The column width of the given character.
+ */
+lib.wc.charWidthRegardAmbiguous = function(ucs) {
+  if (lib.wc.isCjkAmbiguous(ucs))
+    return lib.wc.cjkAmbiguousWidth;
+
+  return lib.wc.charWidthDisregardAmbiguous(ucs);
+};
+
+/**
+ * Determine the column width of the given string.
+ *
+ * @param {string} str A string.
+ * @return {number} The column width of the given string.
+ */
+lib.wc.strWidth = function(str) {
+  var width, rv = 0;
+
+  for (var i = 0; i < str.length;) {
+    var codePoint = str.codePointAt(i);
+    width = lib.wc.charWidth(codePoint);
+    if (width < 0)
+      return -1;
+    rv += width;
+    i += (codePoint <= 0xffff) ? 1 : 2;
+  }
+
+  return rv;
+};
+
+/**
+ * Get the substring at the given column offset of the given column width.
+ *
+ * @param {string} str The string to get substring from.
+ * @param {number} start The starting column offset to get substring.
+ * @param {number=} opt_width The column width of the substring.
+ * @return {string} The substring.
+ */
+lib.wc.substr = function(str, start, opt_width) {
+  var startIndex = 0;
+  var endIndex, width;
+
+  // Fun edge case: Normally we associate zero width codepoints (like combining
+  // characters) with the previous codepoint, so we skip any leading ones while
+  // including trailing ones.  However, if there are zero width codepoints at
+  // the start of the string, and the substring starts at 0, lets include them
+  // in the result.  This also makes for a simple optimization for a common
+  // request.
+  if (start) {
+    for (width = 0; startIndex < str.length;) {
+      const codePoint = str.codePointAt(startIndex);
+      width += lib.wc.charWidth(codePoint);
+      if (width > start)
+        break;
+      startIndex += (codePoint <= 0xffff) ? 1 : 2;
+    }
+  }
+
+  if (opt_width != undefined) {
+    for (endIndex = startIndex, width = 0; endIndex < str.length;) {
+      const codePoint = str.codePointAt(endIndex);
+      width += lib.wc.charWidth(codePoint);
+      if (width > opt_width)
+        break;
+      endIndex += (codePoint <= 0xffff) ? 1 : 2;
+    }
+    return str.substring(startIndex, endIndex);
+  }
+
+  return str.substr(startIndex);
+};
+
+/**
+ * Get substring at the given start and end column offset.
+ *
+ * @param {string} str The string to get substring from.
+ * @param {number} start The starting column offset.
+ * @param {number} end The ending column offset.
+ * @return {string} The substring.
+ */
+lib.wc.substring = function(str, start, end) {
+  return lib.wc.substr(str, start, end - start);
+};
+lib.resource.add('libdot/changelog/version', 'text/plain',
+'4.0.0'
+);
+
+lib.resource.add('libdot/changelog/date', 'text/plain',
+'2019-11-28'
+);
+
+// SOURCE FILE: hterm/js/hterm.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Declares the hterm.* namespace and some basic shared utilities
+ * that are too small to deserve dedicated files.
+ */
+var hterm = {};
+
+/**
+ * The type of window hosting hterm.
+ *
+ * This is set as part of hterm.init().  The value is invalid until
+ * initialization completes.
+ */
+hterm.windowType = null;
+
+/**
+ * The OS we're running under.
+ *
+ * Used when setting up OS-specific behaviors.
+ *
+ * This is set as part of hterm.init().  The value is invalid until
+ * initialization completes.
+ */
+hterm.os = null;
+
+/**
+ * Warning message to display in the terminal when browser zoom is enabled.
+ *
+ * You can replace it with your own localized message.
+ */
+hterm.zoomWarningMessage = 'ZOOM != 100%';
+
+/**
+ * Brief overlay message displayed when text is copied to the clipboard.
+ *
+ * By default it is the unicode BLACK SCISSORS character, but you can
+ * replace it with your own localized message.
+ *
+ * This is only displayed when the 'enable-clipboard-notice' preference
+ * is enabled.
+ */
+hterm.notifyCopyMessage = '\u2702';
+
+
+/**
+ * Text shown in a desktop notification for the terminal
+ * bell.  \u226a is a unicode EIGHTH NOTE, %(title) will
+ * be replaced by the terminal title.
+ */
+hterm.desktopNotificationTitle = '\u266A %(title) \u266A';
+
+/** @type {?lib.MessageManager} */
+hterm.messageManager = null;
+
+lib.registerInit(
+    'hterm',
+    /**
+     * The hterm init function, registered with lib.registerInit().
+     *
+     * This is called during lib.init().
+     *
+     * @param {function()} onInit The function lib.init() wants us to invoke
+     *     when initialization is complete.
+     */
+    function(onInit) {
+      function initOs(os) {
+        hterm.os = os;
+
+        onInit();
+      }
+
+      function initMessageManager() {
+        lib.i18n.getAcceptLanguages((languages) => {
+          if (!hterm.messageManager)
+            hterm.messageManager = new lib.MessageManager(languages);
+
+          // If OS detection fails, then we'll still set the value to something.
+          // The OS logic in hterm tends to be best effort anyways.
+          lib.f.getOs().then(initOs).catch(initOs);
+        });
+      }
+
+      function onWindow(window) {
+        hterm.windowType = window.type;
+        initMessageManager();
+      }
+
+      function onTab(tab) {
+        if (tab && window.chrome) {
+          chrome.windows.get(tab.windowId, null, onWindow);
+        } else {
+          // TODO(rginda): This is where we end up for a v1 app's background
+          // page. Maybe windowType = 'none' would be more appropriate, or
+          // something.
+          hterm.windowType = 'normal';
+          initMessageManager();
+        }
+      }
+
+      if (!hterm.defaultStorage) {
+        if (window.chrome && chrome.storage && chrome.storage.sync) {
+          hterm.defaultStorage = new lib.Storage.Chrome(chrome.storage.sync);
+        } else {
+          hterm.defaultStorage = new lib.Storage.Local();
+        }
+      }
+
+      // The chrome.tabs API is not supported in packaged apps, and detecting if
+      // you're a packaged app is a little awkward.
+      var isPackagedApp = false;
+      if (window.chrome && chrome.runtime && chrome.runtime.getManifest) {
+        var manifest = chrome.runtime.getManifest();
+        isPackagedApp = manifest.app && manifest.app.background;
+      }
+
+      if (isPackagedApp) {
+        // Packaged apps are never displayed in browser tabs.
+        setTimeout(onWindow.bind(null, {type: 'popup'}), 0);
+      } else {
+        if (window.chrome && chrome.tabs) {
+          // The getCurrent method gets the tab that is "currently running", not
+          // the topmost or focused tab.
+          chrome.tabs.getCurrent(onTab);
+        } else {
+          setTimeout(onWindow.bind(null, {type: 'normal'}), 0);
+        }
+      }
+    });
+
+/**
+ * Return decimal { width, height } for a given DOM element.
+ *
+ * @param {!Element} element The element whose size to lookup.
+ * @return {!DOMRect} The size of the element.
+ */
+hterm.getClientSize = function(element) {
+  return element.getBoundingClientRect();
+};
+
+/**
+ * Return decimal width for a given DOM element.
+ *
+ * @param {!Element} element The element whose width to lookup.
+ * @return {number} The width of the element.
+ */
+hterm.getClientWidth = function(element) {
+  return element.getBoundingClientRect().width;
+};
+
+/**
+ * Return decimal height for a given DOM element.
+ *
+ * @param {!Element} element The element whose height to lookup.
+ * @return {number} The height of the element.
+ */
+hterm.getClientHeight = function(element) {
+  return element.getBoundingClientRect().height;
+};
+
+/**
+ * Copy the specified text to the system clipboard.
+ *
+ * We'll create selections on demand based on the content to copy.
+ *
+ * @param {!Document} document The document with the selection to copy.
+ * @param {string} str The string data to copy out.
+ * @return {!Promise<void>}
+ */
+hterm.copySelectionToClipboard = function(document, str) {
+  // Request permission if need be.
+  const requestPermission = () => {
+    // Use the Permissions API if available.
+    if (navigator.permissions && navigator.permissions.query) {
+      return navigator.permissions.query({name: 'clipboard-write'})
+        .then((status) => {
+          const checkState = (resolve, reject) => {
+            switch (status.state) {
+              case 'granted':
+                return resolve();
+              case 'denied':
+                return reject();
+              default:
+                // Wait for the user to approve/disprove.
+                return new Promise((resolve, reject) => {
+                  status.onchange = () => checkState(resolve, reject);
+                });
+            }
+          };
+
+          return new Promise(checkState);
+        })
+        // If the platform doesn't support "clipboard-write", or is denied,
+        // we move on to the copying step anyways.
+        .catch(() => Promise.resolve());
+    } else {
+      // No permissions API, so resolve right away.
+      return Promise.resolve();
+    }
+  };
+
+  // Write to the clipboard.
+  const writeClipboard = () => {
+    // Use the Clipboard API if available.
+    if (navigator.clipboard && navigator.clipboard.writeText) {
+      // If this fails (perhaps due to focus changing windows), fallback to the
+      // legacy copy method.
+      return navigator.clipboard.writeText(str)
+        .catch(execCommand);
+    } else {
+      // No Clipboard API, so use the old execCommand style.
+      return execCommand();
+    }
+  };
+
+  // Write to the clipboard using the legacy execCommand method.
+  // TODO: Once we can rely on the Clipboard API everywhere, we can simplify
+  // this a lot by deleting the custom selection logic.
+  const execCommand = () => {
+    const copySource = document.createElement('pre');
+    copySource.id = 'hterm:copy-to-clipboard-source';
+    copySource.textContent = str;
+    copySource.style.cssText = (
+        '-webkit-user-select: text;' +
+        '-moz-user-select: text;' +
+        'position: absolute;' +
+        'top: -99px');
+
+    document.body.appendChild(copySource);
+
+    const selection = document.getSelection();
+    const anchorNode = selection.anchorNode;
+    const anchorOffset = selection.anchorOffset;
+    const focusNode = selection.focusNode;
+    const focusOffset = selection.focusOffset;
+
+    // FF sometimes throws NS_ERROR_FAILURE exceptions when we make this call.
+    // Catch it because a failure here leaks the copySource node.
+    // https://bugzilla.mozilla.org/show_bug.cgi?id=1178676
+    try {
+      selection.selectAllChildren(copySource);
+    } catch (ex) {}
+
+    try {
+      document.execCommand('copy');
+    } catch (firefoxException) {
+      // Ignore this. FF throws an exception if there was an error, even
+      // though the spec says just return false.
+    }
+
+    // IE doesn't support selection.extend.  This means that the selection won't
+    // return on IE.
+    if (selection.extend) {
+      // When running in the test harness, we won't have any related nodes.
+      if (anchorNode) {
+        selection.collapse(anchorNode, anchorOffset);
+      }
+      if (focusNode) {
+        selection.extend(focusNode, focusOffset);
+      }
+    }
+
+    copySource.parentNode.removeChild(copySource);
+
+    // Since execCommand is synchronous, resolve right away.
+    return Promise.resolve();
+  };
+
+  // Kick it all off!
+  return requestPermission().then(writeClipboard);
+};
+
+/**
+ * Paste the system clipboard into the element with focus.
+ *
+ * Note: In Chrome/Firefox app/extension environments, you'll need the
+ * "clipboardRead" permission.  In other environments, this might always
+ * fail as the browser frequently blocks access for security reasons.
+ *
+ * @param {!Document} document The document to paste into.
+ * @return {boolean} True if the paste succeeded.
+ */
+hterm.pasteFromClipboard = function(document) {
+  try {
+    return document.execCommand('paste');
+  } catch (firefoxException) {
+    // Ignore this.  FF 40 and older would incorrectly throw an exception if
+    // there was an error instead of returning false.
+    return false;
+  }
+};
+
+/**
+ * Return a formatted message in the current locale.
+ *
+ * @param {string} name The name of the message to return.
+ * @param {!Array<string>=} args The message arguments, if required.
+ * @param {string=} string The default message text.
+ * @return {string} The localized message.
+ */
+hterm.msg = function(name, args = [], string) {
+  return hterm.messageManager.get('HTERM_' + name, args, string);
+};
+
+/**
+ * Create a new notification.
+ *
+ * @param {{title:(string|undefined), body:(string|undefined)}=} params Various
+ *     parameters for the notification.
+ *     title The title (defaults to the window's title).
+ *     body The message body (main text).
+ * @return {!Notification}
+ */
+hterm.notify = function(params) {
+  var def = (curr, fallback) => curr !== undefined ? curr : fallback;
+  if (params === undefined || params === null)
+    params = {};
+
+  // Merge the user's choices with the default settings.  We don't take it
+  // directly in case it was stuffed with excess junk.
+  var options = {
+      'body': params.body,
+      'icon': def(params.icon, lib.resource.getDataUrl('hterm/images/icon-96')),
+  };
+
+  var title = def(params.title, window.document.title);
+  if (!title)
+    title = 'hterm';
+  title = lib.f.replaceVars(hterm.desktopNotificationTitle, {'title': title});
+
+  var n = new Notification(title, options);
+  n.onclick = function() {
+    window.focus();
+    n.close();
+  };
+  return n;
+};
+
+/**
+ * Launches url in a new tab.
+ *
+ * @param {string} url URL to launch in a new tab.
+ */
+hterm.openUrl = function(url) {
+  if (window.chrome && chrome.browser && chrome.browser.openTab) {
+    // For Chrome v2 apps, we need to use this API to properly open windows.
+    chrome.browser.openTab({'url': url});
+  } else {
+    const win = lib.f.openWindow(url, '_blank');
+    win.focus();
+  }
+};
+
+/**
+ * Constructor for a hterm.Size record.
+ *
+ * Instances of this class have public read/write members for width and height.
+ *
+ * @param {number} width The width of this record.
+ * @param {number} height The height of this record.
+ * @constructor
+ */
+hterm.Size = function(width, height) {
+  this.width = width;
+  this.height = height;
+};
+
+/**
+ * Adjust the width and height of this record.
+ *
+ * @param {number} width The new width of this record.
+ * @param {number} height The new height of this record.
+ */
+hterm.Size.prototype.resize = function(width, height) {
+  this.width = width;
+  this.height = height;
+};
+
+/**
+ * Return a copy of this record.
+ *
+ * @return {!hterm.Size} A new hterm.Size instance with the same width and
+ *     height.
+ */
+hterm.Size.prototype.clone = function() {
+  return new hterm.Size(this.width, this.height);
+};
+
+/**
+ * Set the height and width of this instance based on another hterm.Size.
+ *
+ * @param {!hterm.Size} that The object to copy from.
+ */
+hterm.Size.prototype.setTo = function(that) {
+  this.width = that.width;
+  this.height = that.height;
+};
+
+/**
+ * Test if another hterm.Size instance is equal to this one.
+ *
+ * @param {!hterm.Size} that The other hterm.Size instance.
+ * @return {boolean} True if both instances have the same width/height, false
+ *     otherwise.
+ */
+hterm.Size.prototype.equals = function(that) {
+  return this.width == that.width && this.height == that.height;
+};
+
+/**
+ * Return a string representation of this instance.
+ *
+ * @return {string} A string that identifies the width and height of this
+ *     instance.
+ * @override
+ */
+hterm.Size.prototype.toString = function() {
+  return '[hterm.Size: ' + this.width + ', ' + this.height + ']';
+};
+
+/**
+ * Constructor for a hterm.RowCol record.
+ *
+ * Instances of this class have public read/write members for row and column.
+ *
+ * This class includes an 'overflow' bit which is use to indicate that an
+ * attempt has been made to move the cursor column passed the end of the
+ * screen.  When this happens we leave the cursor column set to the last column
+ * of the screen but set the overflow bit.  In this state cursor movement
+ * happens normally, but any attempt to print new characters causes a cr/lf
+ * first.
+ *
+ * @param {number} row The row of this record.
+ * @param {number} column The column of this record.
+ * @param {boolean=} opt_overflow Optional boolean indicating that the RowCol
+ *     has overflowed.
+ * @constructor
+ */
+hterm.RowCol = function(row, column, opt_overflow) {
+  this.row = row;
+  this.column = column;
+  this.overflow = !!opt_overflow;
+};
+
+/**
+ * Adjust the row and column of this record.
+ *
+ * @param {number} row The new row of this record.
+ * @param {number} column The new column of this record.
+ * @param {boolean=} opt_overflow Optional boolean indicating that the RowCol
+ *     has overflowed.
+ */
+hterm.RowCol.prototype.move = function(row, column, opt_overflow) {
+  this.row = row;
+  this.column = column;
+  this.overflow = !!opt_overflow;
+};
+
+/**
+ * Return a copy of this record.
+ *
+ * @return {!hterm.RowCol} A new hterm.RowCol instance with the same row and
+ *     column.
+ */
+hterm.RowCol.prototype.clone = function() {
+  return new hterm.RowCol(this.row, this.column, this.overflow);
+};
+
+/**
+ * Set the row and column of this instance based on another hterm.RowCol.
+ *
+ * @param {!hterm.RowCol} that The object to copy from.
+ */
+hterm.RowCol.prototype.setTo = function(that) {
+  this.row = that.row;
+  this.column = that.column;
+  this.overflow = that.overflow;
+};
+
+/**
+ * Test if another hterm.RowCol instance is equal to this one.
+ *
+ * @param {!hterm.RowCol} that The other hterm.RowCol instance.
+ * @return {boolean} True if both instances have the same row/column, false
+ *     otherwise.
+ */
+hterm.RowCol.prototype.equals = function(that) {
+  return (this.row == that.row && this.column == that.column &&
+          this.overflow == that.overflow);
+};
+
+/**
+ * Return a string representation of this instance.
+ *
+ * @return {string} A string that identifies the row and column of this
+ *     instance.
+ * @override
+ */
+hterm.RowCol.prototype.toString = function() {
+  return ('[hterm.RowCol: ' + this.row + ', ' + this.column + ', ' +
+          this.overflow + ']');
+};
+// SOURCE FILE: hterm/js/hterm_accessibility_reader.js
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * AccessibilityReader responsible for rendering command output for AT.
+ *
+ * Renders command output for Assistive Technology using a live region. We don't
+ * use the visible rows of the terminal for rendering command output to the
+ * screen reader because the rendered content may be different from what we want
+ * read out by a screen reader. For example, we may not actually render every
+ * row of a large piece of output to the screen as it wouldn't be performant.
+ * But we want the screen reader to read it all out in order.
+ *
+ * @param {!Element} div The div element where the live region should be
+ *     added.
+ * @constructor
+ */
+hterm.AccessibilityReader = function(div) {
+  this.document_ = div.ownerDocument;
+
+  // The live region element to add text to.
+  const liveRegion = this.document_.createElement('div');
+  liveRegion.id = 'hterm:accessibility-live-region';
+  liveRegion.style.cssText = `position: absolute;
+                              width: 0; height: 0;
+                              overflow: hidden;
+                              left: 0; top: 0;`;
+  div.appendChild(liveRegion);
+
+  // Whether command output should be rendered for Assistive Technology.
+  // This isn't always enabled because it has an impact on performance.
+  this.accessibilityEnabled = false;
+
+  // This live element is used for command output.
+  this.liveElement_ = this.document_.createElement('p');
+  this.liveElement_.setAttribute('aria-live', 'polite');
+  this.liveElement_.setAttribute('aria-label', '');
+  liveRegion.appendChild(this.liveElement_);
+
+  // This live element is used for speaking out the current screen when
+  // navigating through the scrollback buffer. It will interrupt existing
+  // announcements.
+  this.assertiveLiveElement_ = this.document_.createElement('p');
+  this.assertiveLiveElement_.setAttribute('aria-live', 'assertive');
+  this.assertiveLiveElement_.setAttribute('aria-label', '');
+  liveRegion.appendChild(this.assertiveLiveElement_);
+
+  // A queue of updates to announce.
+  this.queue_ = [];
+
+  // A timer which tracks when next to add items to the live region. null when
+  // not running. This is used to combine updates that occur in a small window,
+  // as well as to avoid too much output being added to the live region in one
+  // go which can cause the renderer to hang.
+  this.nextReadTimer_ = null;
+
+  // This is set to true if the cursor is about to update position on the
+  // screen. i.e. beforeCursorChange has been called but not afterCursorChange.
+  this.cursorIsChanging_ = false;
+
+  // This tracks changes that would be added to queue_ while the cursor is
+  // changing. This is done so that we can decide to discard these changes if
+  // we announce something as a result of the cursor change.
+  this.cursorChangeQueue_ = [];
+
+  // The string of text on the row that the cursor was last on. Only valid while
+  // cursorIsChanging_ is true.
+  this.lastCursorRowString_ = null;
+
+  // The row that the cursor was last on. Only valid while cursorIsChanging_ is
+  // true.
+  this.lastCursorRow_ = null;
+
+  // The column that the cursor was last on. Only valid while cursorIsChanging_
+  // is true.
+  this.lastCursorColumn_ = null;
+
+  // True if a keypress has been performed since the last cursor change.
+  this.hasUserGesture = false;
+};
+
+/**
+ * Delay in ms to use for merging strings to output.
+ *
+ * We merge strings together to avoid hanging the terminal and to ensure that
+ * aria updates make it to the screen reader. We want this to be short so
+ * there's not a big delay between typing/executing commands and hearing output.
+ *
+ * @const
+ * @type {number}
+ */
+hterm.AccessibilityReader.DELAY = 50;
+
+/**
+ * Enable accessibility-friendly features that have a performance impact.
+ *
+ * @param {boolean} enabled Whether to enable accessibility-friendly features.
+ */
+hterm.AccessibilityReader.prototype.setAccessibilityEnabled =
+    function(enabled) {
+  if (!enabled) {
+    this.clear();
+  }
+
+  this.accessibilityEnabled = enabled;
+};
+
+/**
+ * Decorate the document where the terminal <x-screen> resides. This is needed
+ * for listening to keystrokes on the screen.
+ *
+ * @param {!Document} doc The document where the <x-screen> resides.
+ */
+hterm.AccessibilityReader.prototype.decorate = function(doc) {
+  const handlers = ['keydown', 'keypress', 'keyup', 'textInput'];
+  handlers.forEach((handler) => {
+    doc.addEventListener(handler, () => { this.hasUserGesture = true; });
+  });
+};
+
+/**
+ * This should be called before the cursor on the screen is about to get
+ * updated. This allows cursor changes to be tracked and related notifications
+ * to be announced.
+ *
+ * @param {string} cursorRowString The text in the row that the cursor is
+ *     currently on.
+ * @param {number} cursorRow The index of the row that the cursor is currently
+ *     on, including rows in the scrollback buffer.
+ * @param {number} cursorColumn The index of the column that the cursor is
+ *     currently on.
+ */
+hterm.AccessibilityReader.prototype.beforeCursorChange =
+    function(cursorRowString, cursorRow, cursorColumn) {
+  // If accessibility is enabled we don't announce selection changes as these
+  // can have a performance impact.
+  if (!this.accessibilityEnabled) {
+    return;
+  }
+
+  // If there is no user gesture that can be tied to the cursor change, we
+  // don't want to announce anything.
+  if (!this.hasUserGesture || this.cursorIsChanging_) {
+    return;
+  }
+
+  this.cursorIsChanging_ = true;
+  this.lastCursorRowString_ = cursorRowString;
+  this.lastCursorRow_ = cursorRow;
+  this.lastCursorColumn_ = cursorColumn;
+};
+
+/**
+ * This should be called after the cursor on the screen has been updated. Note
+ * that several updates to the cursor may have happened between
+ * beforeCursorChange and afterCursorChange.
+ *
+ * This allows cursor changes to be tracked and related notifications to be
+ * announced.
+ *
+ * @param {string} cursorRowString The text in the row that the cursor is
+ *     currently on.
+ * @param {number} cursorRow The index of the row that the cursor is currently
+ *     on, including rows in the scrollback buffer.
+ * @param {number} cursorColumn The index of the column that the cursor is
+ *     currently on.
+ */
+hterm.AccessibilityReader.prototype.afterCursorChange =
+    function(cursorRowString, cursorRow, cursorColumn) {
+  // This can happen if clear() is called midway through a cursor change.
+  if (!this.cursorIsChanging_) {
+    return;
+  }
+  this.cursorIsChanging_ = false;
+
+  if (!this.announceAction_(cursorRowString, cursorRow, cursorColumn)) {
+    // If we don't announce a special action, we re-queue all the output that
+    // was queued during the selection change.
+    for (let i = 0; i < this.cursorChangeQueue_.length; ++i) {
+      this.announce(this.cursorChangeQueue_[i]);
+    }
+  }
+
+  this.cursorChangeQueue_ = [];
+  this.lastCursorRowString_ = null;
+  this.lastCursorRow_ = null;
+  this.lastCursorColumn_ = null;
+  this.hasUserGesture = false;
+};
+
+/**
+ * Announce the command output.
+ *
+ * @param {string} str The string to announce using a live region.
+ */
+hterm.AccessibilityReader.prototype.announce = function(str) {
+  if (!this.accessibilityEnabled) {
+    return;
+  }
+
+  // If the cursor is in the middle of changing, we queue up the output
+  // separately as we may not want it to be announced if it's part of a cursor
+  // change announcement.
+  if (this.cursorIsChanging_) {
+    this.cursorChangeQueue_.push(str);
+    return;
+  }
+
+  // Don't append newlines to the queue if the queue is empty. It won't have any
+  // impact.
+  if (str == '\n' && this.queue_.length > 0) {
+    this.queue_.push('');
+    // We don't need to trigger an announcement on newlines because they won't
+    // change the existing content that's output.
+    return;
+  }
+
+  if (this.queue_.length == 0) {
+    this.queue_.push(str);
+  } else {
+    // We put a space between strings that appear on the same line.
+    // TODO(raymes): We should check the location on the row and not add a space
+    // if the strings are joined together.
+    let padding = '';
+    if (this.queue_[this.queue_.length - 1].length != 0) {
+      padding = ' ';
+    }
+    this.queue_[this.queue_.length - 1] += padding + str;
+  }
+
+  // If we've already scheduled text being added to the live region, wait for it
+  // to happen.
+  if (this.nextReadTimer_) {
+    return;
+  }
+
+  // If there's only one item in the queue, we may get other text being added
+  // very soon after. In that case, wait a small delay so we can merge the
+  // related strings.
+  if (this.queue_.length == 1) {
+    this.nextReadTimer_ = setTimeout(this.addToLiveRegion_.bind(this),
+                                     hterm.AccessibilityReader.DELAY);
+  } else {
+    throw new Error(
+        'Expected only one item in queue_ or nextReadTimer_ to be running.');
+  }
+};
+
+/**
+ * Voice an announcement that will interrupt other announcements.
+ *
+ * @param {string} str The string to announce using a live region.
+ */
+hterm.AccessibilityReader.prototype.assertiveAnnounce = function(str) {
+  if (this.hasUserGesture && str == ' ') {
+    str = hterm.msg('SPACE_CHARACTER', [], 'Space');
+  }
+
+  // If the same string is announced twice, an attribute change won't be
+  // registered and the screen reader won't know that the string has changed.
+  // So we slightly change the string to ensure that the attribute change gets
+  // registered.
+  str = str.trim();
+  if (str == this.assertiveLiveElement_.getAttribute('aria-label')) {
+    str = '\n' + str;
+  }
+
+  this.clear();
+  this.assertiveLiveElement_.setAttribute('aria-label', str);
+};
+
+/**
+ * Add a newline to the text that will be announced to the live region.
+ */
+hterm.AccessibilityReader.prototype.newLine = function() {
+  this.announce('\n');
+};
+
+/**
+ * Clear the live region and any in-flight announcements.
+ */
+hterm.AccessibilityReader.prototype.clear = function() {
+  this.liveElement_.setAttribute('aria-label', '');
+  this.assertiveLiveElement_.setAttribute('aria-label', '');
+  clearTimeout(this.nextReadTimer_);
+  this.nextReadTimer_ = null;
+  this.queue_ = [];
+
+  this.cursorIsChanging_ = false;
+  this.cursorChangeQueue_ = [];
+  this.lastCursorRowString_ = null;
+  this.lastCursorRow_ = null;
+  this.lastCursorColumn_ = null;
+  this.hasUserGesture = false;
+};
+
+/**
+ * This will announce an action that is related to a cursor change, for example
+ * when the user deletes a character we want the character deleted to be
+ * announced. Similarly, when the user moves the cursor along the line, we want
+ * the characters selected to be announced.
+ *
+ * Note that this function is a heuristic. Because of the nature of terminal
+ * emulators, we can't distinguish input and output, which means we don't really
+ * know what output is the result of a keypress and what isn't. Also in some
+ * terminal applications certain announcements may make sense whereas others may
+ * not. This function should try to account for the most common cases.
+ *
+ * @param {string} cursorRowString The text in the row that the cursor is
+ *     currently on.
+ * @param {number} cursorRow The index of the row that the cursor is currently
+ *     on, including rows in the scrollback buffer.
+ * @param {number} cursorColumn The index of the column that the cursor is
+ *     currently on.
+ * @return {boolean} Whether anything was announced.
+ */
+hterm.AccessibilityReader.prototype.announceAction_ =
+    function(cursorRowString, cursorRow, cursorColumn) {
+  // If the cursor changes rows, we don't announce anything at present.
+  if (this.lastCursorRow_ != cursorRow) {
+    return false;
+  }
+
+  lib.assert(this.lastCursorRowString_ !== null);
+
+  // The case when the row of text hasn't changed at all.
+  if (this.lastCursorRowString_ == cursorRowString) {
+    // Moving the cursor along the line. We check that no significant changes
+    // have been queued. If they have, it may not just be a cursor movement and
+    // it may be better to read those out.
+    if (this.lastCursorColumn_ != cursorColumn &&
+        this.cursorChangeQueue_.join('').trim() == '') {
+      // Announce the text between the old cursor position and the new one.
+      const start = Math.min(this.lastCursorColumn_, cursorColumn);
+      const len = Math.abs(cursorColumn - this.lastCursorColumn_);
+      this.assertiveAnnounce(
+          lib.wc.substr(this.lastCursorRowString_, start, len));
+      return true;
+    }
+    return false;
+  }
+
+  // The case when the row of text has changed.
+  if (this.lastCursorRowString_ != cursorRowString) {
+    // Spacebar. We manually announce this character since the screen reader may
+    // not announce the whitespace in a live region.
+    if (this.lastCursorColumn_ + 1 == cursorColumn) {
+      if (lib.wc.substr(cursorRowString, cursorColumn - 1, 1) == ' ' &&
+          this.cursorChangeQueue_.length > 0 &&
+          this.cursorChangeQueue_[0] == ' ') {
+        this.assertiveAnnounce(' ');
+        return true;
+      }
+    }
+
+    // Backspace and deletion.
+    // The position of the characters deleted is right after the current
+    // position of the cursor in the case of backspace and delete.
+    const cursorDeleted = cursorColumn;
+    // Check that the current row string is shorter than the previous. Also
+    // check that the start of the strings (up to the cursor) match.
+    if (lib.wc.strWidth(cursorRowString) <=
+        lib.wc.strWidth(this.lastCursorRowString_) &&
+        lib.wc.substr(this.lastCursorRowString_, 0, cursorDeleted) ==
+        lib.wc.substr(cursorRowString, 0, cursorDeleted)) {
+      // Find the length of the current row string ignoring space characters.
+      // These may be inserted at the end of the string when deleting characters
+      // so they should be ignored.
+      let lengthOfCurrentRow = lib.wc.strWidth(cursorRowString);
+      for (; lengthOfCurrentRow > 0; --lengthOfCurrentRow) {
+        if (lengthOfCurrentRow == cursorDeleted ||
+            lib.wc.substr(cursorRowString, lengthOfCurrentRow - 1, 1) != ' ') {
+          break;
+        }
+      }
+
+      const numCharsDeleted =
+          lib.wc.strWidth(this.lastCursorRowString_) - lengthOfCurrentRow;
+
+      // Check that the end of the strings match.
+      const lengthOfEndOfString = lengthOfCurrentRow - cursorDeleted;
+      const endOfLastRowString = lib.wc.substr(
+          this.lastCursorRowString_, cursorDeleted + numCharsDeleted,
+          lengthOfEndOfString);
+      const endOfCurrentRowString =
+          lib.wc.substr(cursorRowString, cursorDeleted, lengthOfEndOfString);
+      if (endOfLastRowString == endOfCurrentRowString) {
+        const deleted = lib.wc.substr(
+            this.lastCursorRowString_, cursorDeleted, numCharsDeleted);
+        if (deleted != '') {
+          this.assertiveAnnounce(deleted);
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  return false;
+};
+
+/**
+ * Add text from queue_ to the live region.
+ *
+ */
+hterm.AccessibilityReader.prototype.addToLiveRegion_ = function() {
+  this.nextReadTimer_ = null;
+
+  let str = this.queue_.join('\n').trim();
+
+  // If the same string is announced twice, an attribute change won't be
+  // registered and the screen reader won't know that the string has changed.
+  // So we slightly change the string to ensure that the attribute change gets
+  // registered.
+  if (str == this.liveElement_.getAttribute('aria-label')) {
+    str = '\n' + str;
+  }
+
+  this.liveElement_.setAttribute('aria-label', str);
+  this.queue_ = [];
+};
+// SOURCE FILE: hterm/js/hterm_contextmenu.js
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Context menu handling.
+ */
+
+/**
+ * Manage the context menu usually shown when right clicking.
+ *
+ * @constructor
+ */
+hterm.ContextMenu = function() {
+  // The document that contains this context menu.
+  this.document_ = null;
+  // The generated context menu (i.e. HTML elements).
+  this.element_ = null;
+  // The structured menu (i.e. JS objects).
+  /** @type {!Array<!hterm.ContextMenu.Item>} */
+  this.menu_ = [];
+};
+
+/** @typedef {{name:(string|symbol), action:function(!Event)}} */
+hterm.ContextMenu.Item;
+
+/**
+ * Constant to add a separator to the context menu.
+ */
+hterm.ContextMenu.SEPARATOR = Symbol('-');
+
+/**
+ * Bind context menu to a specific document element.
+ *
+ * @param {!Document} document The document to use when creating elements.
+ */
+hterm.ContextMenu.prototype.setDocument = function(document) {
+  if (this.element_) {
+    this.element_.remove();
+    this.element_ = null;
+  }
+  this.document_ = document;
+  this.regenerate_();
+  this.document_.body.appendChild(this.element_);
+};
+
+/**
+ * Regenerate the HTML elements based on internal menu state.
+ */
+hterm.ContextMenu.prototype.regenerate_ = function() {
+  if (!this.element_) {
+    this.element_ = this.document_.createElement('menu');
+    this.element_.id = 'hterm:context-menu';
+    this.element_.style.cssText = `
+        display: none;
+        border: solid 1px;
+        position: absolute;
+    `;
+  } else {
+    this.hide();
+  }
+
+  // Clear out existing menu entries.
+  while (this.element_.firstChild) {
+    this.element_.removeChild(this.element_.firstChild);
+  }
+
+  this.menu_.forEach(({name, action}) => {
+    const menuitem = this.document_.createElement('menuitem');
+    if (name === hterm.ContextMenu.SEPARATOR) {
+      menuitem.innerHTML = '<hr>';
+      menuitem.className = 'separator';
+    } else {
+      menuitem.innerText = name;
+      menuitem.addEventListener('mousedown', function(e) {
+        e.preventDefault();
+        action(e);
+      });
+    }
+    this.element_.appendChild(menuitem);
+  });
+};
+
+/**
+ * Set all the entries in the context menu.
+ *
+ * This is an array of arrays.  The first element in the array is the string to
+ * display while the second element is the function to call.
+ *
+ * The first element may also be the SEPARATOR constant to add a separator.
+ *
+ * This resets all existing menu entries.
+ *
+ * @param {!Array<!hterm.ContextMenu.Item>} items The menu entries.
+ */
+hterm.ContextMenu.prototype.setItems = function(items) {
+  this.menu_ = items;
+  this.regenerate_();
+};
+
+/**
+ * Show the context menu.
+ *
+ * The event is used to determine where to show the menu.
+ *
+ * If no menu entries are defined, then nothing will be shown.
+ *
+ * @param {!Event} e The event triggering this display.
+ * @param {!hterm.Terminal=} terminal The terminal object to get style info
+ *     from.
+ */
+hterm.ContextMenu.prototype.show = function(e, terminal) {
+  // If there are no menu entries, then don't try to show anything.
+  if (this.menu_.length == 0) {
+    return;
+  }
+
+  // If we have the terminal, sync the style preferences over.
+  if (terminal) {
+    this.element_.style.backgroundColor = terminal.getBackgroundColor();
+    this.element_.style.color = terminal.getForegroundColor();
+    this.element_.style.fontSize = terminal.getFontSize();
+    this.element_.style.fontFamily = terminal.getFontFamily();
+  }
+
+  this.element_.style.top = `${e.clientY}px`;
+  this.element_.style.left = `${e.clientX}px`;
+  const docSize = hterm.getClientSize(lib.notNull(this.document_.body));
+
+  this.element_.style.display = 'block';
+
+  // We can't calculate sizes until after it's displayed.
+  const eleSize = hterm.getClientSize(this.element_);
+  // Make sure the menu isn't clipped outside of the current element.
+  const minY = Math.max(0, docSize.height - eleSize.height);
+  const minX = Math.max(0, docSize.width - eleSize.width);
+  if (minY < e.clientY) {
+    this.element_.style.top = `${minY}px`;
+  }
+  if (minX < e.clientX) {
+    this.element_.style.left = `${minX}px`;
+  }
+};
+
+/**
+ * Hide the context menu.
+ */
+hterm.ContextMenu.prototype.hide = function() {
+  if (!this.element_) {
+    return;
+  }
+
+  this.element_.style.display = 'none';
+};
+// SOURCE FILE: hterm/js/hterm_frame.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * First draft of the interface between the terminal and a third party dialog.
+ *
+ * This is rough.  It's just the terminal->dialog layer.  To complete things
+ * we'll also need a command->terminal layer.  That will have to facilitate
+ * command->terminal->dialog or direct command->dialog communication.
+ *
+ * I imagine this class will change significantly when that happens.
+ */
+
+/**
+ * Construct a new frame for the given terminal.
+ *
+ * @param {!hterm.Terminal} terminal The parent terminal object.
+ * @param {string} url The url to load in the frame.
+ * @param {!Object=} opt_options Optional options for the frame.  Not
+ *     implemented.
+ * @constructor
+ */
+hterm.Frame = function(terminal, url, opt_options) {
+  this.terminal_ = terminal;
+  this.div_ = terminal.div_;
+  this.url = url;
+  this.options = opt_options || {};
+  this.iframe_ = null;
+  this.container_ = null;
+  this.messageChannel_ = null;
+};
+
+/**
+ * Handle messages from the iframe.
+ *
+ * @param {!MessageEvent} e The message to process.
+ */
+hterm.Frame.prototype.onMessage_ = function(e) {
+  switch (e.data.name) {
+    case 'ipc-init-ok':
+      // We get this response after we send them ipc-init and they finish.
+      this.sendTerminalInfo_();
+      return;
+    case 'terminal-info-ok':
+      // We get this response after we send them terminal-info and they finish.
+      // Show the finished frame, and then rebind our message handler to the
+      // callback below.
+      this.container_.style.display = 'flex';
+      this.postMessage('visible');
+      this.messageChannel_.port1.onmessage = this.onMessage.bind(this);
+      this.onLoad();
+      return;
+    default:
+      console.log('Unknown message from frame:', e.data);
+      return;
+  }
+};
+
+/**
+ * Clients could override this, I guess.
+ *
+ * It doesn't support multiple listeners, but I'm not sure that would make sense
+ * here.  It's probably better to speak directly to our parents.
+ */
+hterm.Frame.prototype.onMessage = function() {};
+
+/**
+ * Handle iframe onLoad event.
+ */
+hterm.Frame.prototype.onLoad_ = function() {
+  this.messageChannel_ = new MessageChannel();
+  this.messageChannel_.port1.onmessage = this.onMessage_.bind(this);
+  this.messageChannel_.port1.start();
+  this.iframe_.contentWindow.postMessage(
+      {name: 'ipc-init', argv: [{messagePort: this.messageChannel_.port2}]},
+      this.url, [this.messageChannel_.port2]);
+};
+
+/**
+ * Clients may override this.
+ */
+hterm.Frame.prototype.onLoad = function() {};
+
+/**
+ * Sends the terminal-info message to the iframe.
+ */
+hterm.Frame.prototype.sendTerminalInfo_ = function() {
+  lib.i18n.getAcceptLanguages(function(languages) {
+      this.postMessage('terminal-info', [{
+         acceptLanguages: languages,
+         foregroundColor: this.terminal_.getForegroundColor(),
+         backgroundColor: this.terminal_.getBackgroundColor(),
+         cursorColor: this.terminal_.getCursorColor(),
+         fontSize: this.terminal_.getFontSize(),
+         fontFamily: this.terminal_.getFontFamily(),
+         baseURL: lib.f.getURL('/')
+          }]
+        );
+    }.bind(this));
+};
+
+/**
+ * User clicked the close button on the frame decoration.
+ */
+hterm.Frame.prototype.onCloseClicked_ = function() {
+  this.close();
+};
+
+/**
+ * Close this frame.
+ */
+hterm.Frame.prototype.close = function() {
+  if (!this.container_ || !this.container_.parentNode)
+      return;
+
+  this.container_.parentNode.removeChild(this.container_);
+  this.onClose();
+};
+
+
+/**
+ * Clients may override this.
+ */
+hterm.Frame.prototype.onClose = function() {};
+
+/**
+ * Send a message to the iframe.
+ *
+ * @param {string} name The message name.
+ * @param {!Array=} argv The message arguments.
+ */
+hterm.Frame.prototype.postMessage = function(name, argv) {
+  if (!this.messageChannel_)
+    throw new Error('Message channel is not set up.');
+
+  this.messageChannel_.port1.postMessage({name: name, argv: argv});
+};
+
+/**
+ * Show the UI for this frame.
+ *
+ * The iframe src is not loaded until this method is called.
+ */
+hterm.Frame.prototype.show = function() {
+  var self = this;
+
+  function opt(name, defaultValue) {
+    if (name in self.options)
+      return self.options[name];
+
+    return defaultValue;
+  }
+
+  if (this.container_ && this.container_.parentNode) {
+    console.error('Frame already visible');
+    return;
+  }
+
+  var document = this.terminal_.document_;
+
+  var container = this.container_ = document.createElement('div');
+  container.style.cssText = (
+      'position: absolute;' +
+      'display: none;' +
+      'flex-direction: column;' +
+      'top: 10%;' +
+      'left: 4%;' +
+      'width: 90%;' +
+      'height: 80%;' +
+      'min-height: 20%;' +
+      'max-height: 80%;' +
+      'box-shadow: 0 0 2px ' + this.terminal_.getForegroundColor() + ';' +
+      'border: 2px ' + this.terminal_.getForegroundColor() + ' solid;');
+
+  var iframe = this.iframe_ = document.createElement('iframe');
+  iframe.onload = this.onLoad_.bind(this);
+  iframe.style.cssText = (
+      'display: flex;' +
+      'flex: 1;' +
+      'width: 100%');
+  iframe.setAttribute('src', this.url);
+  iframe.setAttribute('seamless', true);
+  container.appendChild(iframe);
+
+  this.div_.appendChild(container);
+};
+// SOURCE FILE: hterm/js/hterm_keyboard.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Keyboard handler.
+ *
+ * Consumes onKey* events and invokes onVTKeystroke on the associated
+ * hterm.Terminal object.
+ *
+ * See also: [XTERM] as referenced in vt.js.
+ *
+ * @param {!hterm.Terminal} terminal The Terminal object associated with this
+ *     keyboard.
+ * @constructor
+ */
+hterm.Keyboard = function(terminal) {
+  // The parent vt interpreter.
+  this.terminal = terminal;
+
+  // The element we're currently capturing keyboard events for.
+  this.keyboardElement_ = null;
+
+  // The event handlers we are interested in, and their bound callbacks, saved
+  // so they can be uninstalled with removeEventListener, when required.
+  this.handlers_ = [
+      ['focusout', this.onFocusOut_.bind(this)],
+      ['keydown', this.onKeyDown_.bind(this)],
+      ['keypress', this.onKeyPress_.bind(this)],
+      ['keyup', this.onKeyUp_.bind(this)],
+      ['textInput', this.onTextInput_.bind(this)]
+  ];
+
+  /**
+   * The current key map.
+   */
+  this.keyMap = new hterm.Keyboard.KeyMap(this);
+
+  this.bindings = new hterm.Keyboard.Bindings();
+
+  /**
+   * none: Disable any AltGr related munging.
+   * ctrl-alt: Assume Ctrl+Alt means AltGr.
+   * left-alt: Assume left Alt means AltGr.
+   * right-alt: Assume right Alt means AltGr.
+   */
+  this.altGrMode = 'none';
+
+  /**
+   * If true, Shift-Insert will fall through to the browser as a paste.
+   * If false, the keystroke will be sent to the host.
+   */
+  this.shiftInsertPaste = true;
+
+  /**
+   * If true, home/end will control the terminal scrollbar and shift home/end
+   * will send the VT keycodes.  If false then home/end sends VT codes and
+   * shift home/end scrolls.
+   */
+  this.homeKeysScroll = false;
+
+  /**
+   * Same as above, except for page up/page down.
+   */
+  this.pageKeysScroll = false;
+
+  /**
+   * If true, Ctrl-Plus/Minus/Zero controls zoom.
+   * If false, Ctrl-Shift-Plus/Minus/Zero controls zoom, Ctrl-Minus sends ^_,
+   * Ctrl-Plus/Zero do nothing.
+   */
+  this.ctrlPlusMinusZeroZoom = true;
+
+  /**
+   * Ctrl+C copies if true, sends ^C to host if false.
+   * Ctrl+Shift+C sends ^C to host if true, copies if false.
+   */
+  this.ctrlCCopy = false;
+
+  /**
+   * Ctrl+V pastes if true, sends ^V to host if false.
+   * Ctrl+Shift+V sends ^V to host if true, pastes if false.
+   */
+  this.ctrlVPaste = false;
+
+  /**
+   * Enable/disable application keypad.
+   *
+   * This changes the way numeric keys are sent from the keyboard.
+   */
+  this.applicationKeypad = false;
+
+  /**
+   * Enable/disable the application cursor mode.
+   *
+   * This changes the way cursor keys are sent from the keyboard.
+   */
+  this.applicationCursor = false;
+
+  /**
+   * If true, the backspace should send BS ('\x08', aka ^H).  Otherwise
+   * the backspace key should send '\x7f'.
+   */
+  this.backspaceSendsBackspace = false;
+
+  /**
+   * Set whether the meta key sends a leading escape or not.
+   */
+  this.metaSendsEscape = true;
+
+  /**
+   * Set whether meta-V gets passed to host.
+   */
+  this.passMetaV = true;
+
+  /**
+   * Controls how the alt key is handled.
+   *
+   *  escape....... Send an ESC prefix.
+   *  8-bit........ Add 128 to the unshifted character as in xterm.
+   *  browser-key.. Wait for the keypress event and see what the browser says.
+   *                (This won't work well on platforms where the browser
+   *                 performs a default action for some alt sequences.)
+   *
+   * This setting only matters when alt is distinct from meta (altIsMeta is
+   * false.)
+   */
+  this.altSendsWhat = 'escape';
+
+  /**
+   * Set whether the alt key acts as a meta key, instead of producing 8-bit
+   * characters.
+   *
+   * True to enable, false to disable, null to autodetect based on platform.
+   */
+  this.altIsMeta = false;
+
+  /**
+   * If true, tries to detect DEL key events that are from alt-backspace on
+   * Chrome OS vs from a true DEL key press.
+   *
+   * Background: At the time of writing, on Chrome OS, alt-backspace is mapped
+   * to DEL. Some users may be happy with this, but others may be frustrated
+   * that it's impossible to do meta-backspace. If the user enables this pref,
+   * we use a trick to tell a true DEL keypress from alt-backspace: on
+   * alt-backspace, we will see the alt key go down, then get a DEL keystroke
+   * that indicates that alt is not pressed. See https://crbug.com/174410 .
+   */
+  this.altBackspaceIsMetaBackspace = false;
+
+  /**
+   * Used to keep track of the current alt-key state, which is necessary for
+   * the altBackspaceIsMetaBackspace preference above and for the altGrMode
+   * preference.  This is a bitmap with where bit positions correspond to the
+   * "location" property of the key event.
+   */
+  this.altKeyPressed = 0;
+
+  /**
+   * If true, Chrome OS media keys will be mapped to their F-key equivalent.
+   * E.g. "Back" will be mapped to F1. If false, Chrome will handle the keys.
+   */
+  this.mediaKeysAreFKeys = false;
+
+  /**
+   * Holds the previous setting of altSendsWhat when DECSET 1039 is used. When
+   * DECRST 1039 is used, altSendsWhat is changed back to this and this is
+   * nulled out.
+   */
+  this.previousAltSendsWhat_ = null;
+};
+
+/**
+ * Special handling for keyCodes in a keyboard layout.
+ *
+ * @enum {symbol}
+ * @const
+ */
+hterm.Keyboard.KeyActions = {
+  /**
+   * Call preventDefault and stopPropagation for this key event and nothing
+   * else.
+   */
+  CANCEL: Symbol('CANCEL'),
+
+  /**
+   * This performs the default terminal action for the key.  If used in the
+   * 'normal' action and the the keystroke represents a printable key, the
+   * character will be sent to the host.  If used in one of the modifier
+   * actions, the terminal will perform the normal action after (possibly)
+   * altering it.
+   *
+   *  - If the normal sequence starts with CSI, the sequence will be adjusted
+   *    to include the modifier parameter as described in [XTERM] in the final
+   *    table of the "PC-Style Function Keys" section.
+   *
+   *  - If the control key is down and the key represents a printable character,
+   *    and the uppercase version of the unshifted keycap is between
+   *    64 (ASCII '@') and 95 (ASCII '_'), then the uppercase version of the
+   *    unshifted keycap minus 64 is sent.  This makes '^@' send '\x00' and
+   *    '^_' send '\x1f'.  (Note that one higher that 0x1f is 0x20, which is
+   *    the first printable ASCII value.)
+   *
+   *  - If the alt key is down and the key represents a printable character then
+   *    the value of the character is shifted up by 128.
+   *
+   *  - If meta is down and configured to send an escape, '\x1b' will be sent
+   *    before the normal action is performed.
+   */
+  DEFAULT: Symbol('DEFAULT'),
+
+  /**
+   * Causes the terminal to opt out of handling the key event, instead letting
+   * the browser deal with it.
+   */
+  PASS: Symbol('PASS'),
+
+  /**
+   * Insert the first or second character of the keyCap, based on e.shiftKey.
+   * The key will be handled in onKeyDown, and e.preventDefault() will be
+   * called.
+   *
+   * It is useful for a modified key action, where it essentially strips the
+   * modifier while preventing the browser from reacting to the key.
+   */
+  STRIP: Symbol('STRIP')
+};
+
+/** @typedef {string|!hterm.Keyboard.KeyActions} */
+hterm.Keyboard.KeyAction;
+
+/**
+ * Capture keyboard events sent to the associated element.
+ *
+ * This enables the keyboard.  Captured events are consumed by this class
+ * and will not perform their default action or bubble to other elements.
+ *
+ * Passing a null element will uninstall the keyboard handlers.
+ *
+ * @param {?Element} element The element whose events should be captured, or
+ *     null to disable the keyboard.
+ */
+hterm.Keyboard.prototype.installKeyboard = function(element) {
+  if (element == this.keyboardElement_)
+    return;
+
+  if (element && this.keyboardElement_)
+    this.installKeyboard(null);
+
+  for (var i = 0; i < this.handlers_.length; i++) {
+    var handler = this.handlers_[i];
+    if (element) {
+      element.addEventListener(handler[0], handler[1]);
+    } else {
+      this.keyboardElement_.removeEventListener(handler[0], handler[1]);
+    }
+  }
+
+  this.keyboardElement_ = element;
+};
+
+/**
+ * Disable keyboard event capture.
+ *
+ * This will allow the browser to process key events normally.
+ */
+hterm.Keyboard.prototype.uninstallKeyboard = function() {
+  this.installKeyboard(null);
+};
+
+/**
+ * Handle textInput events.
+ *
+ * These are generated when using IMEs, Virtual Keyboards (VKs), compose keys,
+ * Unicode input, etc...
+ *
+ * @param {!InputEvent} e The event to process.
+ */
+hterm.Keyboard.prototype.onTextInput_ = function(e) {
+  if (!e.data)
+    return;
+
+  // Just pass the generated buffer straight down.  No need for us to split it
+  // up or otherwise parse it ahead of times.
+  this.terminal.onVTKeystroke(e.data);
+};
+
+/**
+ * Handle keypress events.
+ *
+ * TODO(vapier): Drop this event entirely and only use keydown.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ */
+hterm.Keyboard.prototype.onKeyPress_ = function(e) {
+  // FF doesn't set keyCode reliably in keypress events.  Stick to the which
+  // field here until we can move to keydown entirely.
+  const key = String.fromCharCode(e.which).toLowerCase();
+  if ((e.ctrlKey || e.metaKey) && (key == 'c' || key == 'v')) {
+    // On FF the key press (not key down) event gets fired for copy/paste.
+    // Let it fall through for the default browser behavior.
+    return;
+  }
+
+  if (e.keyCode == 9 /* Tab */) {
+    // On FF, a key press event will be fired in addition of key down for the
+    // Tab key if key down isn't handled. This would only happen if a custom
+    // PASS binding has been created and therefore this should be handled by the
+    // browser.
+    return;
+  }
+
+  /** @type {string} */
+  var ch;
+  if (e.altKey && this.altSendsWhat == 'browser-key' && e.charCode == 0) {
+    // If we got here because we were expecting the browser to handle an
+    // alt sequence but it didn't do it, then we might be on an OS without
+    // an enabled IME system.  In that case we fall back to xterm-like
+    // behavior.
+    //
+    // This happens here only as a fallback.  Typically these platforms should
+    // set altSendsWhat to either 'escape' or '8-bit'.
+    ch = String.fromCharCode(e.keyCode);
+    if (!e.shiftKey)
+      ch = ch.toLowerCase();
+
+  } else if (e.charCode >= 32) {
+    ch = String.fromCharCode(e.charCode);
+  }
+
+  if (ch)
+    this.terminal.onVTKeystroke(ch);
+
+  e.preventDefault();
+  e.stopPropagation();
+};
+
+/**
+ * Prevent default handling for non-ctrl-shifted event.
+ *
+ * When combined with Chrome permission 'app.window.fullscreen.overrideEsc',
+ * and called for both key down and key up events,
+ * the ESC key remains usable within fullscreen Chrome app windows.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ */
+hterm.Keyboard.prototype.preventChromeAppNonCtrlShiftDefault_ = function(e) {
+  if (!window.chrome || !window.chrome.app || !window.chrome.app.window)
+    return;
+  if (!e.ctrlKey || !e.shiftKey)
+    e.preventDefault();
+};
+
+/**
+ * Handle focusout events.
+ *
+ * @param {!FocusEvent} e The event to process.
+ */
+hterm.Keyboard.prototype.onFocusOut_ = function(e) {
+  this.altKeyPressed = 0;
+};
+
+/**
+ * Handle keyup events.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ */
+hterm.Keyboard.prototype.onKeyUp_ = function(e) {
+  if (e.keyCode == 18)
+    this.altKeyPressed = this.altKeyPressed & ~(1 << (e.location - 1));
+
+  if (e.keyCode == 27)
+    this.preventChromeAppNonCtrlShiftDefault_(e);
+};
+
+/**
+ * Handle keydown events.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ */
+hterm.Keyboard.prototype.onKeyDown_ = function(e) {
+  if (e.keyCode == 18)
+    this.altKeyPressed = this.altKeyPressed | (1 << (e.location - 1));
+
+  if (e.keyCode == 27)
+    this.preventChromeAppNonCtrlShiftDefault_(e);
+
+  var keyDef = this.keyMap.keyDefs[e.keyCode];
+  if (!keyDef) {
+    // If this key hasn't been explicitly registered, fall back to the unknown
+    // key mapping (keyCode == 0), and then automatically register it to avoid
+    // any further warnings here.
+    console.warn(`No definition for key ${e.key} (keyCode ${e.keyCode})`);
+    keyDef = this.keyMap.keyDefs[0];
+    this.keyMap.addKeyDef(e.keyCode, keyDef);
+  }
+
+  // The type of action we're going to use.
+  var resolvedActionType = null;
+
+  var self = this;
+  /**
+   * @param {string} name
+   * @return {!hterm.Keyboard.KeyDefAction}
+   */
+  function getAction(name) {
+    // Get the key action for the given action name.  If the action is a
+    // function, dispatch it.  If the action defers to the normal action,
+    // resolve that instead.
+
+    resolvedActionType = name;
+
+    var action = keyDef[name];
+    if (typeof action == 'function')
+      action = action.call(self.keyMap, e, keyDef);
+
+    if (action === DEFAULT && name != 'normal')
+      action = getAction('normal');
+
+    return action;
+  }
+
+  // Note that we use the triple-equals ('===') operator to test equality for
+  // these constants, in order to distinguish usage of the constant from usage
+  // of a literal string that happens to contain the same bytes.
+  var CANCEL = hterm.Keyboard.KeyActions.CANCEL;
+  var DEFAULT = hterm.Keyboard.KeyActions.DEFAULT;
+  var PASS = hterm.Keyboard.KeyActions.PASS;
+  var STRIP = hterm.Keyboard.KeyActions.STRIP;
+
+  var control = e.ctrlKey;
+  var alt = this.altIsMeta ? false : e.altKey;
+  var meta = this.altIsMeta ? (e.altKey || e.metaKey) : e.metaKey;
+
+  // In the key-map, we surround the keyCap for non-printables in "[...]"
+  var isPrintable = !(/^\[\w+\]$/.test(keyDef.keyCap));
+
+  switch (this.altGrMode) {
+    case 'ctrl-alt':
+    if (isPrintable && control && alt) {
+      // ctrl-alt-printable means altGr.  We clear out the control and
+      // alt modifiers and wait to see the charCode in the keydown event.
+      control = false;
+      alt = false;
+    }
+    break;
+
+    case 'right-alt':
+    if (isPrintable && (this.terminal.keyboard.altKeyPressed & 2)) {
+      control = false;
+      alt = false;
+    }
+    break;
+
+    case 'left-alt':
+    if (isPrintable && (this.terminal.keyboard.altKeyPressed & 1)) {
+      control = false;
+      alt = false;
+    }
+    break;
+  }
+
+  /** @type {?hterm.Keyboard.KeyDefAction} */
+  var action;
+
+  if (control) {
+    action = getAction('control');
+  } else if (alt) {
+    action = getAction('alt');
+  } else if (meta) {
+    action = getAction('meta');
+  } else {
+    action = getAction('normal');
+  }
+
+  // If e.maskShiftKey was set (during getAction) it means the shift key is
+  // already accounted for in the action, and we should not act on it any
+  // further. This is currently only used for Ctrl-Shift-Tab, which should send
+  // "CSI Z", not "CSI 1 ; 2 Z".
+  var shift = !e.maskShiftKey && e.shiftKey;
+
+  /** @type {!hterm.Keyboard.KeyDown} */
+  var keyDown = {
+    keyCode: e.keyCode,
+    shift: e.shiftKey, // not `var shift` from above.
+    ctrl: control,
+    alt: alt,
+    meta: meta
+  };
+
+  var binding = this.bindings.getBinding(keyDown);
+
+  if (binding) {
+    // Clear out the modifier bits so we don't try to munge the sequence
+    // further.
+    shift = control = alt = meta = false;
+    resolvedActionType = 'normal';
+
+    if (typeof binding.action == 'function') {
+      const bindingFn =
+          /** @type {!hterm.Keyboard.KeyBindingFunction} */ (binding.action);
+      action = bindingFn.call(this, this.terminal, keyDown);
+    } else {
+      action = /** @type {!hterm.Keyboard.KeyAction} */ (binding.action);
+    }
+  }
+
+  if (alt && this.altSendsWhat == 'browser-key' && action == DEFAULT) {
+    // When altSendsWhat is 'browser-key', we wait for the keypress event.
+    // In keypress, the browser should have set the event.charCode to the
+    // appropriate character.
+    // TODO(rginda): Character compositions will need some black magic.
+    action = PASS;
+  }
+
+  if (action === PASS || (action === DEFAULT && !(control || alt || meta))) {
+    // If this key is supposed to be handled by the browser, or it is an
+    // unmodified key with the default action, then exit this event handler.
+    // If it's an unmodified key, it'll be handled in onKeyPress where we
+    // can tell for sure which ASCII code to insert.
+    //
+    // This block needs to come before the STRIP test, otherwise we'll strip
+    // the modifier and think it's ok to let the browser handle the keypress.
+    // The browser won't know we're trying to ignore the modifiers and might
+    // perform some default action.
+    return;
+  }
+
+  if (action === STRIP) {
+    alt = control = false;
+    action = keyDef.normal;
+    if (typeof action == 'function')
+      action = action.call(this.keyMap, e, keyDef);
+
+    if (action == DEFAULT && keyDef.keyCap.length == 2)
+      action = keyDef.keyCap.substr((shift ? 1 : 0), 1);
+  }
+
+  e.preventDefault();
+  e.stopPropagation();
+
+  if (action === CANCEL)
+    return;
+
+  if (action !== DEFAULT && typeof action != 'string') {
+    console.warn('Invalid action: ' + JSON.stringify(action));
+    return;
+  }
+
+  // Strip the modifier that is associated with the action, since we assume that
+  // modifier has already been accounted for in the action.
+  if (resolvedActionType == 'control') {
+    control = false;
+  } else if (resolvedActionType == 'alt') {
+    alt = false;
+  } else if (resolvedActionType == 'meta') {
+    meta = false;
+  }
+
+  if (typeof action == 'string' && action.substr(0, 2) == '\x1b[' &&
+      (alt || control || shift || meta)) {
+    // The action is an escape sequence that and it was triggered in the
+    // presence of a keyboard modifier, we may need to alter the action to
+    // include the modifier before sending it.
+
+    // The math is funky but aligns w/xterm.
+    let imod = 1;
+    if (shift)
+      imod += 1;
+    if (alt)
+      imod += 2;
+    if (control)
+      imod += 4;
+    if (meta)
+      imod += 8;
+    let mod = ';' + imod;
+
+    if (action.length == 3) {
+      // Some of the CSI sequences have zero parameters unless modified.
+      action = '\x1b[1' + mod + action.substr(2, 1);
+    } else {
+      // Others always have at least one parameter.
+      action = action.substr(0, action.length - 1) + mod +
+          action.substr(action.length - 1);
+    }
+
+  } else {
+    if (action === DEFAULT) {
+      action = keyDef.keyCap.substr((shift ? 1 : 0), 1);
+
+      if (control) {
+        var unshifted = keyDef.keyCap.substr(0, 1);
+        var code = unshifted.charCodeAt(0);
+        if (code >= 64 && code <= 95) {
+          action = String.fromCharCode(code - 64);
+        }
+      }
+    }
+
+    if (alt && this.altSendsWhat == '8-bit' && action.length == 1) {
+      var code = action.charCodeAt(0) + 128;
+      action = String.fromCharCode(code);
+    }
+
+    // We respect alt/metaSendsEscape even if the keymap action was a literal
+    // string.  Otherwise, every overridden alt/meta action would have to
+    // check alt/metaSendsEscape.
+    if ((alt && this.altSendsWhat == 'escape') ||
+        (meta && this.metaSendsEscape)) {
+      action = '\x1b' + action;
+    }
+  }
+
+  this.terminal.onVTKeystroke(/** @type {string} */ (action));
+};
+// SOURCE FILE: hterm/js/hterm_keyboard_bindings.js
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @typedef {{
+ *     keyCode: number,
+ *     shift: (boolean|undefined),
+ *     ctrl: (boolean|undefined),
+ *     alt: (boolean|undefined),
+ *     meta: (boolean|undefined),
+ * }}
+ */
+hterm.Keyboard.KeyDown;
+
+/**
+ * @typedef {function(!hterm.Terminal, !hterm.Keyboard.KeyDown):
+ *               !hterm.Keyboard.KeyAction}
+ */
+hterm.Keyboard.KeyBindingFunction;
+
+/** @typedef {!hterm.Keyboard.KeyAction|!hterm.Keyboard.KeyBindingFunction} */
+hterm.Keyboard.KeyBindingAction;
+
+/**
+ * @typedef {{
+ *     keyPattern: !hterm.Keyboard.KeyPattern,
+ *     action: !hterm.Keyboard.KeyBindingAction,
+ * }}
+ */
+hterm.Keyboard.KeyBinding;
+
+/**
+ * A mapping from hterm.Keyboard.KeyPattern to an action.
+ *
+ * TODO(rginda): For now this bindings code is only used for user overrides.
+ * hterm.Keyboard.KeyMap still handles all of the built-in key mappings.
+ * It'd be nice if we migrated that over to be hterm.Keyboard.Bindings based.
+ *
+ * @constructor
+ */
+hterm.Keyboard.Bindings = function() {
+  this.bindings_ = {};
+};
+
+/**
+ * Remove all bindings.
+ */
+hterm.Keyboard.Bindings.prototype.clear = function () {
+  this.bindings_ = {};
+};
+
+/**
+ * Add a new binding.
+ *
+ * Internal API that assumes parsed objects as inputs.
+ * See the public addBinding for more details.
+ *
+ * @param {!hterm.Keyboard.KeyPattern} keyPattern
+ * @param {!hterm.Keyboard.KeyBindingAction} action
+ */
+hterm.Keyboard.Bindings.prototype.addBinding_ = function(keyPattern, action) {
+  var binding = null;
+  var list = this.bindings_[keyPattern.keyCode];
+  if (list) {
+    for (var i = 0; i < list.length; i++) {
+      if (list[i].keyPattern.matchKeyPattern(keyPattern)) {
+        binding = list[i];
+        break;
+      }
+    }
+  }
+
+  if (binding) {
+    binding.action = action;
+  } else {
+    binding = {keyPattern: keyPattern, action: action};
+
+    if (!list) {
+      this.bindings_[keyPattern.keyCode] = [binding];
+    } else {
+      this.bindings_[keyPattern.keyCode].push(binding);
+
+      list.sort(function(a, b) {
+        return hterm.Keyboard.KeyPattern.sortCompare(
+            a.keyPattern, b.keyPattern);
+      });
+    }
+  }
+};
+
+/**
+ * Add a new binding.
+ *
+ * If a binding for the keyPattern already exists it will be overridden.
+ *
+ * More specific keyPatterns take precedence over those with wildcards.  Given
+ * bindings for "Ctrl-A" and "Ctrl-*-A", and a "Ctrl-A" keydown, the "Ctrl-A"
+ * binding will match even if "Ctrl-*-A" was created last.
+ *
+ * If action is a string, it will be passed through hterm.Parser.parseKeyAction.
+ *
+ * For example:
+ *   // Will replace Ctrl-P keystrokes with the string "hiya!".
+ *   addBinding('Ctrl-P', "'hiya!'");
+ *   // Will cancel the keystroke entirely (make it do nothing).
+ *   addBinding('Alt-D', hterm.Keyboard.KeyActions.CANCEL);
+ *   // Will execute the code and return the action.
+ *   addBinding('Ctrl-T', function() {
+ *     console.log('Got a T!');
+ *     return hterm.Keyboard.KeyActions.PASS;
+ *   });
+ *
+ * @param {string|!hterm.Keyboard.KeyPattern} key
+ * @param {!hterm.Keyboard.KeyBindingAction} action
+ */
+hterm.Keyboard.Bindings.prototype.addBinding = function(key, action) {
+  // If we're given a hterm.Keyboard.KeyPattern object, pass it down.
+  if (typeof key != 'string') {
+    this.addBinding_(key, action);
+    return;
+  }
+
+  // Here we treat key as a string.
+  var p = new hterm.Parser();
+
+  p.reset(key);
+  var sequence;
+
+  try {
+    sequence = p.parseKeySequence();
+  } catch (ex) {
+    console.error(ex);
+    return;
+  }
+
+  if (!p.isComplete()) {
+    console.error(p.error('Expected end of sequence: ' + sequence));
+    return;
+  }
+
+  // If action is a string, parse it.  Otherwise assume it's callable.
+  if (typeof action == 'string') {
+    p.reset(action);
+    try {
+      action = p.parseKeyAction();
+    } catch (ex) {
+      console.error(ex);
+      return;
+    }
+  }
+
+  if (!p.isComplete()) {
+    console.error(p.error('Expected end of sequence: ' + sequence));
+    return;
+  }
+
+  this.addBinding_(new hterm.Keyboard.KeyPattern(sequence), action);
+};
+
+/**
+ * Add multiple bindings at a time using a map of {string: string, ...}
+ *
+ * This uses hterm.Parser to parse the maps key into KeyPatterns, and the
+ * map values into {!hterm.Keyboard.KeyBindingAction}.
+ *
+ * For example:
+ *  {
+ *    // Will replace Ctrl-P keystrokes with the string "hiya!".
+ *    'Ctrl-P': "'hiya!'",
+ *    // Will cancel the keystroke entirely (make it do nothing).
+ *    'Alt-D': hterm.Keyboard.KeyActions.CANCEL,
+ *  }
+ *
+ * @param {!Object<string, !hterm.Keyboard.KeyBindingAction>} map
+ */
+hterm.Keyboard.Bindings.prototype.addBindings = function(map) {
+  for (var key in map) {
+    this.addBinding(key, map[key]);
+  }
+};
+
+/**
+ * Return the binding that is the best match for the given keyDown record,
+ * or null if there is no match.
+ *
+ * @param {!hterm.Keyboard.KeyDown} keyDown An object with a keyCode property
+ *     and zero or more boolean properties representing key modifiers.  These
+ *     property names must match those defined in
+ *     hterm.Keyboard.KeyPattern.modifiers.
+ * @return {?hterm.Keyboard.KeyBinding} The keyboard binding for this key.
+ */
+hterm.Keyboard.Bindings.prototype.getBinding = function(keyDown) {
+  var list = this.bindings_[keyDown.keyCode];
+  if (!list)
+    return null;
+
+  for (var i = 0; i < list.length; i++) {
+    var binding = list[i];
+    if (binding.keyPattern.matchKeyDown(keyDown))
+      return binding;
+  }
+
+  return null;
+};
+// SOURCE FILE: hterm/js/hterm_keyboard_keymap.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @typedef {{
+ *     keyCap: string,
+ *     normal: !hterm.Keyboard.KeyDefAction,
+ *     control: !hterm.Keyboard.KeyDefAction,
+ *     alt: !hterm.Keyboard.KeyDefAction,
+ *     meta: !hterm.Keyboard.KeyDefAction,
+ * }}
+ */
+hterm.Keyboard.KeyDef;
+
+/**
+ * @typedef {function(!KeyboardEvent, !hterm.Keyboard.KeyDef):
+ *               !hterm.Keyboard.KeyAction}
+ */
+hterm.Keyboard.KeyDefFunction;
+
+/** @typedef {!hterm.Keyboard.KeyAction|!hterm.Keyboard.KeyDefFunction} */
+hterm.Keyboard.KeyDefAction;
+
+/**
+ * The default key map for hterm.
+ *
+ * Contains a mapping of keyCodes to keyDefs (aka key definitions).  The key
+ * definition tells the hterm.Keyboard class how to handle keycodes.
+ *
+ * This should work for most cases, as the printable characters get handled
+ * in the keypress event.  In that case, even if the keycap is wrong in the
+ * key map, the correct character should be sent.
+ *
+ * Different layouts, such as Dvorak should work with this keymap, as those
+ * layouts typically move keycodes around on the keyboard without disturbing
+ * the actual keycaps.
+ *
+ * There may be issues with control keys on non-US keyboards or with keyboards
+ * that very significantly from the expectations here, in which case we may
+ * have to invent new key maps.
+ *
+ * The sequences defined in this key map come from [XTERM] as referenced in
+ * vt.js, starting with the section titled "Alt and Meta Keys".
+ *
+ * @param {!hterm.Keyboard} keyboard
+ * @constructor
+ */
+hterm.Keyboard.KeyMap = function(keyboard) {
+  this.keyboard = keyboard;
+  /** @type {!Object<number, !hterm.Keyboard.KeyDef>} */
+  this.keyDefs = {};
+  this.reset();
+};
+
+/**
+ * Add a single key definition.
+ *
+ * The definition is an object containing the following fields: 'keyCap',
+ * 'normal', 'control', 'alt', and 'meta'.
+ *
+ *  - keyCap is a string identifying the key on the keyboard.  For printable
+ *    keys, the key cap should be exactly two characters, starting with the
+ *    unshifted version.  For example, 'aA', 'bB', '1!' and '=+'.  For
+ *    non-printable the key cap should be surrounded in square braces, as in
+ *    '[INS]', '[LEFT]'.  By convention, non-printable keycaps are in uppercase
+ *    but this is not a strict requirement.
+ *
+ *  - Normal is the action that should be performed when the key is pressed
+ *    in the absence of any modifier.  See below for the supported actions.
+ *
+ *  - Control is the action that should be performed when the key is pressed
+ *    along with the control modifier.  See below for the supported actions.
+ *
+ *  - Alt is the action that should be performed when the key is pressed
+ *    along with the alt modifier.  See below for the supported actions.
+ *
+ *  - Meta is the action that should be performed when the key is pressed
+ *    along with the meta modifier.  See below for the supported actions.
+ *
+ * Actions can be one of the hterm.Keyboard.KeyActions as documented below,
+ * a literal string, or an array.  If the action is a literal string then
+ * the string is sent directly to the host.  If the action is an array it
+ * is taken to be an escape sequence that may be altered by modifier keys.
+ * The second-to-last element of the array will be overwritten with the
+ * state of the modifier keys, as specified in the final table of "PC-Style
+ * Function Keys" from [XTERM].
+ *
+ * @param {number} keyCode The KeyboardEvent.keyCode to match against.
+ * @param {!hterm.Keyboard.KeyDef} def The actions this key triggers.
+ */
+hterm.Keyboard.KeyMap.prototype.addKeyDef = function(keyCode, def) {
+  if (keyCode in this.keyDefs)
+    console.warn('Duplicate keyCode: ' + keyCode);
+
+  this.keyDefs[keyCode] = def;
+};
+
+/**
+ * Set up the default state for this keymap.
+ */
+hterm.Keyboard.KeyMap.prototype.reset = function() {
+  this.keyDefs = {};
+
+  const self = this;
+  const CANCEL = hterm.Keyboard.KeyActions.CANCEL;
+  const DEFAULT = hterm.Keyboard.KeyActions.DEFAULT;
+  const PASS = hterm.Keyboard.KeyActions.PASS;
+  const STRIP = hterm.Keyboard.KeyActions.STRIP;
+
+  /**
+   * This function is used by the "macro" functions below.  It makes it
+   * possible to use the call() macro as an argument to any other macro.
+   *
+   * @param {!hterm.Keyboard.KeyDefAction} action
+   * @param {!KeyboardEvent} e
+   * @param {!hterm.Keyboard.KeyDef} k
+   * @return {!hterm.Keyboard.KeyAction}
+   */
+  function resolve(action, e, k) {
+    if (typeof action == 'function') {
+      const keyDefFn = /** @type {!hterm.Keyboard.KeyDefFunction} */ (action);
+      return keyDefFn.call(self, e, k);
+    }
+    return action;
+  }
+
+  /**
+   * If not application keypad a, else b.  The keys that care about
+   * application keypad ignore it when the key is modified.
+   *
+   * @param {!hterm.Keyboard.KeyDefAction} a
+   * @param {!hterm.Keyboard.KeyDefAction} b
+   * @return {!hterm.Keyboard.KeyDefFunction}
+   */
+  function ak(a, b) {
+    return function(e, k) {
+      var action = (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey ||
+                    !self.keyboard.applicationKeypad) ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  /**
+   * If mod or not application cursor a, else b.  The keys that care about
+   * application cursor ignore it when the key is modified.
+   *
+   * @param {!hterm.Keyboard.KeyDefAction} a
+   * @param {!hterm.Keyboard.KeyDefAction} b
+   * @return {!hterm.Keyboard.KeyDefFunction}
+   */
+  function ac(a, b) {
+    return function(e, k) {
+      var action = (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey ||
+                    !self.keyboard.applicationCursor) ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  /**
+   * If not backspace-sends-backspace keypad a, else b.
+   *
+   * @param {!hterm.Keyboard.KeyDefAction} a
+   * @param {!hterm.Keyboard.KeyDefAction} b
+   * @return {!hterm.Keyboard.KeyDefFunction}
+   */
+  function bs(a, b) {
+    return function(e, k) {
+      var action = !self.keyboard.backspaceSendsBackspace ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  /**
+   * If not e.shiftKey a, else b.
+   *
+   * @param {!hterm.Keyboard.KeyDefAction} a
+   * @param {!hterm.Keyboard.KeyDefAction} b
+   * @return {!hterm.Keyboard.KeyDefFunction}
+   */
+  function sh(a, b) {
+    return function(e, k) {
+      var action = !e.shiftKey ? a : b;
+      e.maskShiftKey = true;
+      return resolve(action, e, k);
+    };
+  }
+
+  /**
+   * If not e.altKey a, else b.
+   *
+   * @param {!hterm.Keyboard.KeyDefAction} a
+   * @param {!hterm.Keyboard.KeyDefAction} b
+   * @return {!hterm.Keyboard.KeyDefFunction}
+   */
+  function alt(a, b) {
+    return function(e, k) {
+      var action = !e.altKey ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  /**
+   * If no modifiers a, else b.
+   *
+   * @param {!hterm.Keyboard.KeyDefAction} a
+   * @param {!hterm.Keyboard.KeyDefAction} b
+   * @return {!hterm.Keyboard.KeyDefFunction}
+   */
+  function mod(a, b) {
+    return function(e, k) {
+      var action = !(e.shiftKey || e.ctrlKey || e.altKey || e.metaKey) ? a : b;
+      return resolve(action, e, k);
+    };
+  }
+
+  /**
+   * Compute a control character for a given character.
+   *
+   * @param {string} ch
+   * @return {string}
+   */
+  function ctl(ch) { return String.fromCharCode(ch.charCodeAt(0) - 64); }
+
+  // Call a method on the keymap instance.
+  function c(m) { return function(e, k) { return this[m](e, k); }; }
+
+  // Ignore if not trapping media keys.
+  function med(fn) {
+    return function(e, k) {
+      if (!self.keyboard.mediaKeysAreFKeys) {
+        // Block Back, Forward, and Reload keys to avoid navigating away from
+        // the current page.
+        return (e.keyCode == 166 || e.keyCode == 167 || e.keyCode == 168) ?
+            CANCEL : PASS;
+      }
+      return resolve(fn, e, k);
+    };
+  }
+
+  /**
+   * @param {number} keyCode
+   * @param {string} keyCap
+   * @param {!hterm.Keyboard.KeyDefAction} normal
+   * @param {!hterm.Keyboard.KeyDefAction} control
+   * @param {!hterm.Keyboard.KeyDefAction} alt
+   * @param {!hterm.Keyboard.KeyDefAction} meta
+   */
+  const add = (keyCode, keyCap, normal, control, alt, meta) => {
+    this.addKeyDef(keyCode, {
+      keyCap: keyCap,
+      normal: normal,
+      control: control,
+      alt: alt,
+      meta: meta,
+    });
+  };
+
+  // Browser-specific differences.
+  if (window.navigator && navigator.userAgent &&
+      navigator.userAgent.includes('Firefox')) {
+    // Firefox defines some keys uniquely.  No other browser defines these in
+    // this way.  Some even conflict.  The keyCode field isn't well documented
+    // as it isn't standardized.  At some point we should switch to "key".
+    // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
+    // http://unixpapa.com/js/key.html
+    // var keycapMute = 181;   // Mute
+    // var keycapVolDn = 182;  // Volume Down
+    // var keycapVolUp = 183;  // Volume Up
+    var keycapSC = 59;      // ;:
+    var keycapEP = 61;      // =+
+    var keycapMU = 173;     // -_
+
+    // Firefox Italian +*.
+    add(171, '+*', DEFAULT, c('onZoom_'), DEFAULT, c('onZoom_'));
+  } else {
+    // All other browsers use these mappings.
+    // var keycapMute = 173;   // Mute
+    // var keycapVolDn = 174;  // Volume Down
+    // var keycapVolUp = 175;  // Volume Up
+    var keycapSC = 186;     // ;:
+    var keycapEP = 187;     // =+
+    var keycapMU = 189;     // -_
+  }
+
+  var ESC = '\x1b';
+  var CSI = '\x1b[';
+  var SS3 = '\x1bO';
+
+  // These fields are: [keycode, keycap, normal, control, alt, meta]
+
+  // The browser sends the keycode 0 for some keys.  We'll just assume it's
+  // going to do the right thing by default for those keys.
+  add(0,   '[UNKNOWN]', PASS, PASS, PASS, PASS);
+
+  // First row.
+  // These bindings match xterm for lack of a better standard.  The emitted
+  // values might look like they're skipping values, but it's what xterm does.
+  // https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-PC-Style-Function-Keys
+  add(27,  '[ESC]', ESC,                       DEFAULT, DEFAULT,     DEFAULT);
+  add(112, '[F1]',  mod(SS3 + 'P', CSI + 'P'), DEFAULT, CSI + '23~', DEFAULT);
+  add(113, '[F2]',  mod(SS3 + 'Q', CSI + 'Q'), DEFAULT, CSI + '24~', DEFAULT);
+  add(114, '[F3]',  mod(SS3 + 'R', CSI + 'R'), DEFAULT, CSI + '25~', DEFAULT);
+  add(115, '[F4]',  mod(SS3 + 'S', CSI + 'S'), DEFAULT, CSI + '26~', DEFAULT);
+  add(116, '[F5]',  CSI + '15~',               DEFAULT, CSI + '28~', DEFAULT);
+  add(117, '[F6]',  CSI + '17~',               DEFAULT, CSI + '29~', DEFAULT);
+  add(118, '[F7]',  CSI + '18~',               DEFAULT, CSI + '31~', DEFAULT);
+  add(119, '[F8]',  CSI + '19~',               DEFAULT, CSI + '32~', DEFAULT);
+  add(120, '[F9]',  CSI + '20~',               DEFAULT, CSI + '33~', DEFAULT);
+  add(121, '[F10]', CSI + '21~',               DEFAULT, CSI + '34~', DEFAULT);
+  add(122, '[F11]', c('onF11_'),               DEFAULT, CSI + '42~', DEFAULT);
+  add(123, '[F12]', CSI + '24~',               DEFAULT, CSI + '43~', DEFAULT);
+
+  // Second row.
+  add(192, '`~', DEFAULT, sh(ctl('@'), ctl('^')),     DEFAULT,           PASS);
+  add(49,  '1!', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_'));
+  add(50,  '2@', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_'));
+  add(51,  '3#', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_'));
+  add(52,  '4$', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_'));
+  add(53,  '5%', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_'));
+  add(54,  '6^', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_'));
+  add(55,  '7&', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_'));
+  add(56,  '8*', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_'));
+  add(57,  '9(', DEFAULT, c('onCtrlNum_'),    c('onAltNum_'), c('onMetaNum_'));
+  add(48,  '0)', DEFAULT, c('onZoom_'),       c('onAltNum_'), c('onZoom_'));
+  add(keycapMU, '-_', DEFAULT, c('onZoom_'),  DEFAULT,        c('onZoom_'));
+  add(keycapEP, '=+', DEFAULT, c('onZoom_'),  DEFAULT,        c('onZoom_'));
+
+  add(8,   '[BKSP]', bs('\x7f', '\b'), bs('\b', '\x7f'), DEFAULT,     DEFAULT);
+
+  // Third row.
+  add(9,   '[TAB]', sh('\t', CSI + 'Z'), STRIP,     PASS,    DEFAULT);
+  add(81,  'qQ',    DEFAULT,             ctl('Q'),  DEFAULT, DEFAULT);
+  add(87,  'wW',    DEFAULT,             ctl('W'),  DEFAULT, DEFAULT);
+  add(69,  'eE',    DEFAULT,             ctl('E'),  DEFAULT, DEFAULT);
+  add(82,  'rR',    DEFAULT,             ctl('R'),  DEFAULT, DEFAULT);
+  add(84,  'tT',    DEFAULT,             ctl('T'),  DEFAULT, DEFAULT);
+  add(89,  'yY',    DEFAULT,             ctl('Y'),  DEFAULT, DEFAULT);
+  add(85,  'uU',    DEFAULT,             ctl('U'),  DEFAULT, DEFAULT);
+  add(73,  'iI',    DEFAULT,             ctl('I'),  DEFAULT, DEFAULT);
+  add(79,  'oO',    DEFAULT,             ctl('O'),  DEFAULT, DEFAULT);
+  add(80,  'pP',    DEFAULT,             ctl('P'),  DEFAULT, DEFAULT);
+  add(219, '[{',    DEFAULT,             ctl('['),  DEFAULT, DEFAULT);
+  add(221, ']}',    DEFAULT,             ctl(']'),  DEFAULT, DEFAULT);
+  add(220, '\\|',   DEFAULT,             ctl('\\'), DEFAULT, DEFAULT);
+
+  // Fourth row. We let Ctrl-Shift-J pass for Chrome DevTools.
+  // To be compliant with xterm's behavior for modifiers on Enter
+  // would mean maximizing the window with Alt-Enter... so we don't
+  // want to do that. Our behavior on Enter is what most other
+  // modern emulators do.
+  add(20,  '[CAPS]',  PASS,    PASS,                        PASS,    DEFAULT);
+  add(65,  'aA',      DEFAULT, ctl('A'),                    DEFAULT, DEFAULT);
+  add(83,  'sS',      DEFAULT, ctl('S'),                    DEFAULT, DEFAULT);
+  add(68,  'dD',      DEFAULT, ctl('D'),                    DEFAULT, DEFAULT);
+  add(70,  'fF',      DEFAULT, ctl('F'),                    DEFAULT, DEFAULT);
+  add(71,  'gG',      DEFAULT, ctl('G'),                    DEFAULT, DEFAULT);
+  add(72,  'hH',      DEFAULT, ctl('H'),                    DEFAULT, DEFAULT);
+  add(74,  'jJ',      DEFAULT, sh(ctl('J'), PASS),          DEFAULT, DEFAULT);
+  add(75,  'kK',      DEFAULT, sh(ctl('K'), c('onClear_')), DEFAULT, DEFAULT);
+  add(76,  'lL',      DEFAULT, sh(ctl('L'), PASS),          DEFAULT, DEFAULT);
+  add(keycapSC, ';:', DEFAULT, STRIP,                       DEFAULT, DEFAULT);
+  add(222, '\'"',     DEFAULT, STRIP,                       DEFAULT, DEFAULT);
+  add(13,  '[ENTER]', '\r',    DEFAULT,                     DEFAULT, DEFAULT);
+
+  // Fifth row.  This includes the copy/paste shortcuts.  On some
+  // platforms it's Ctrl-C/V, on others it's Meta-C/V.  We assume either
+  // Ctrl-C/Meta-C should pass to the browser when there is a selection,
+  // and Ctrl-Shift-V/Meta-*-V should always pass to the browser (since
+  // these seem to be recognized as paste too).
+  add(16,  '[SHIFT]', PASS, PASS,                  PASS,    DEFAULT);
+  add(90,  'zZ',   DEFAULT, ctl('Z'),              DEFAULT, DEFAULT);
+  add(88,  'xX',   DEFAULT, ctl('X'),              DEFAULT, DEFAULT);
+  add(67,  'cC',   DEFAULT, c('onCtrlC_'),         DEFAULT, c('onMetaC_'));
+  add(86,  'vV',   DEFAULT, c('onCtrlV_'),         DEFAULT, c('onMetaV_'));
+  add(66,  'bB',   DEFAULT, sh(ctl('B'), PASS),    DEFAULT, sh(DEFAULT, PASS));
+  add(78,  'nN',   DEFAULT, c('onCtrlN_'),         DEFAULT, c('onMetaN_'));
+  add(77,  'mM',   DEFAULT, ctl('M'),              DEFAULT, DEFAULT);
+  add(188, ',<',   DEFAULT, alt(STRIP, PASS),      DEFAULT, DEFAULT);
+  add(190, '.>',   DEFAULT, alt(STRIP, PASS),      DEFAULT, DEFAULT);
+  add(191, '/?',   DEFAULT, sh(ctl('_'), ctl('?')), DEFAULT, DEFAULT);
+
+  // Sixth and final row.
+  add(17,  '[CTRL]',  PASS,    PASS,     PASS,    PASS);
+  add(18,  '[ALT]',   PASS,    PASS,     PASS,    PASS);
+  add(91,  '[LAPL]',  PASS,    PASS,     PASS,    PASS);
+  add(32,  ' ',       DEFAULT, ctl('@'), DEFAULT, DEFAULT);
+  add(92,  '[RAPL]',  PASS,    PASS,     PASS,    PASS);
+  add(93,  '[RMENU]', PASS,    PASS,     PASS,    PASS);
+
+  // These things.
+  add(42,  '[PRTSCR]', PASS, PASS, PASS, PASS);
+  add(145, '[SCRLK]',  PASS, PASS, PASS, PASS);
+  add(19,  '[BREAK]',  PASS, PASS, PASS, PASS);
+
+  // The block of six keys above the arrows.
+  add(45,  '[INSERT]', c('onKeyInsert_'),   DEFAULT, DEFAULT, DEFAULT);
+  add(36,  '[HOME]',   c('onKeyHome_'),     DEFAULT, DEFAULT, DEFAULT);
+  add(33,  '[PGUP]',   c('onKeyPageUp_'),   DEFAULT, DEFAULT, DEFAULT);
+  add(46,  '[DEL]',    c('onKeyDel_'),      DEFAULT, DEFAULT, DEFAULT);
+  add(35,  '[END]',    c('onKeyEnd_'),      DEFAULT, DEFAULT, DEFAULT);
+  add(34,  '[PGDOWN]', c('onKeyPageDown_'), DEFAULT, DEFAULT, DEFAULT);
+
+  // Arrow keys.  When unmodified they respect the application cursor state,
+  // otherwise they always send the CSI codes.
+  add(38, '[UP]',    c('onKeyArrowUp_'), DEFAULT, DEFAULT, DEFAULT);
+  add(40, '[DOWN]',  c('onKeyArrowDown_'), DEFAULT, DEFAULT, DEFAULT);
+  add(39, '[RIGHT]', ac(CSI + 'C', SS3 + 'C'), DEFAULT, DEFAULT, DEFAULT);
+  add(37, '[LEFT]',  ac(CSI + 'D', SS3 + 'D'), DEFAULT, DEFAULT, DEFAULT);
+
+  add(144, '[NUMLOCK]', PASS, PASS, PASS, PASS);
+
+  // On Apple keyboards, the NumLock key is a Clear key.  It also tends to be
+  // what KP5 sends when numlock is off.  Not clear if we could do anything
+  // useful with it, so just pass it along.
+  add(12, '[CLEAR]', PASS, PASS, PASS, PASS);
+
+  // With numlock off, the keypad generates the same key codes as the arrows
+  // and 'block of six' for some keys, and null key codes for the rest.
+
+  // Keypad with numlock on generates unique key codes...
+  add(96,  '[KP0]', DEFAULT, DEFAULT,      DEFAULT, DEFAULT);
+  add(97,  '[KP1]', DEFAULT, DEFAULT,      DEFAULT, DEFAULT);
+  add(98,  '[KP2]', DEFAULT, DEFAULT,      DEFAULT, DEFAULT);
+  add(99,  '[KP3]', DEFAULT, DEFAULT,      DEFAULT, DEFAULT);
+  add(100, '[KP4]', DEFAULT, DEFAULT,      DEFAULT, DEFAULT);
+  add(101, '[KP5]', DEFAULT, DEFAULT,      DEFAULT, DEFAULT);
+  add(102, '[KP6]', DEFAULT, DEFAULT,      DEFAULT, DEFAULT);
+  add(103, '[KP7]', DEFAULT, DEFAULT,      DEFAULT, DEFAULT);
+  add(104, '[KP8]', DEFAULT, DEFAULT,      DEFAULT, DEFAULT);
+  add(105, '[KP9]', DEFAULT, DEFAULT,      DEFAULT, DEFAULT);
+  add(107, '[KP+]', DEFAULT, c('onZoom_'), DEFAULT, c('onZoom_'));
+  add(109, '[KP-]', DEFAULT, c('onZoom_'), DEFAULT, c('onZoom_'));
+  add(106, '[KP*]', DEFAULT, DEFAULT,      DEFAULT, DEFAULT);
+  add(111, '[KP/]', DEFAULT, DEFAULT,      DEFAULT, DEFAULT);
+  add(110, '[KP.]', DEFAULT, DEFAULT,      DEFAULT, DEFAULT);
+
+  // OS-specific differences.
+  if (hterm.os == 'cros') {
+    // Chrome OS keyboard top row.  The media-keys-are-fkeys preference allows
+    // users to make these always behave as function keys (see those bindings
+    // above for more details).
+    /* eslint-disable max-len */
+    add(166, '[BACK]',   med(mod(SS3+'P', CSI+'P')), DEFAULT, CSI+'23~', DEFAULT);  // F1
+    add(167, '[FWD]',    med(mod(SS3+'Q', CSI+'Q')), DEFAULT, CSI+'24~', DEFAULT);  // F2
+    add(168, '[RELOAD]', med(mod(SS3+'R', CSI+'R')), DEFAULT, CSI+'25~', DEFAULT);  // F3
+    add(183, '[FSCR]',   med(mod(SS3+'S', CSI+'S')), DEFAULT, CSI+'26~', DEFAULT);  // F4
+    add(182, '[WINS]',   med(CSI + '15~'),           DEFAULT, CSI+'28~', DEFAULT);  // F5
+    add(216, '[BRIT-]',  med(CSI + '17~'),           DEFAULT, CSI+'29~', DEFAULT);  // F6
+    add(217, '[BRIT+]',  med(CSI + '18~'),           DEFAULT, CSI+'31~', DEFAULT);  // F7
+    add(173, '[MUTE]',   med(CSI + '19~'),           DEFAULT, CSI+'32~', DEFAULT);  // F8
+    add(174, '[VOL-]',   med(CSI + '20~'),           DEFAULT, CSI+'33~', DEFAULT);  // F9
+    add(175, '[VOL+]',   med(CSI + '21~'),           DEFAULT, CSI+'34~', DEFAULT);  // F10
+    /* eslint-enable max-len */
+
+    // We could make this into F11, but it'd be a bit weird.  Chrome allows us
+    // to see this and react, but it doesn't actually allow us to block or
+    // cancel it, so it makes the screen flash/lock still.
+    add(152, '[POWER]', DEFAULT, DEFAULT, DEFAULT, DEFAULT);
+
+    // The Pixelbook has a slightly different layout.  This means half the keys
+    // above are off by one.  https://crbug.com/807513
+    add(179, '[PLAY]', med(CSI + '18~'), DEFAULT, CSI + '31~', DEFAULT); // F7
+    // The settings / hamburgers / three hot dogs / menu / whatever-it's-called.
+    add(154, '[DOGS]', med(CSI + '23~'), DEFAULT, CSI + '42~', DEFAULT); // F11
+
+    // We don't use this for anything, but keep it from popping up by default.
+    add(153, '[ASSIST]', DEFAULT, DEFAULT, DEFAULT, DEFAULT);
+  }
+};
+
+/**
+ * Either allow the paste or send a key sequence.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyInsert_ = function(e) {
+  if (this.keyboard.shiftInsertPaste && e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  return '\x1b[2~';
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyHome_ = function(e) {
+  if (!this.keyboard.homeKeysScroll ^ e.shiftKey) {
+    if ((e.altey || e.ctrlKey || e.shiftKey) ||
+        !this.keyboard.applicationCursor) {
+      return '\x1b[H';
+    }
+
+    return '\x1bOH';
+  }
+
+  this.keyboard.terminal.scrollHome();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyEnd_ = function(e) {
+  if (!this.keyboard.homeKeysScroll ^ e.shiftKey) {
+    if ((e.altKey || e.ctrlKey || e.shiftKey) ||
+        !this.keyboard.applicationCursor) {
+      return '\x1b[F';
+    }
+
+    return '\x1bOF';
+  }
+
+  this.keyboard.terminal.scrollEnd();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyPageUp_ = function(e) {
+  if (!this.keyboard.pageKeysScroll ^ e.shiftKey)
+    return '\x1b[5~';
+
+  this.keyboard.terminal.scrollPageUp();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Either send a true DEL, or sub in meta-backspace.
+ *
+ * On Chrome OS, if we know the alt key is down, but we get a DEL event that
+ * claims that the alt key is not pressed, we know the DEL was a synthetic
+ * one from a user that hit alt-backspace. Based on a user pref, we can sub
+ * in meta-backspace in this case.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyDel_ = function(e) {
+  if (this.keyboard.altBackspaceIsMetaBackspace &&
+      this.keyboard.altKeyPressed && !e.altKey)
+    return '\x1b\x7f';
+  return '\x1b[3~';
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyPageDown_ = function(e) {
+  if (!this.keyboard.pageKeysScroll ^ e.shiftKey)
+    return '\x1b[6~';
+
+  this.keyboard.terminal.scrollPageDown();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyArrowUp_ = function(e) {
+  if (!this.keyboard.applicationCursor && e.shiftKey) {
+    this.keyboard.terminal.scrollLineUp();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  return (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey ||
+          !this.keyboard.applicationCursor) ? '\x1b[A' : '\x1bOA';
+};
+
+/**
+ * Either scroll the scrollback buffer or send a key sequence.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onKeyArrowDown_ = function(e) {
+  if (!this.keyboard.applicationCursor && e.shiftKey) {
+    this.keyboard.terminal.scrollLineDown();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  return (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey ||
+          !this.keyboard.applicationCursor) ? '\x1b[B' : '\x1bOB';
+};
+
+/**
+ * Clear the primary/alternate screens and the scrollback buffer.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onClear_ = function(e) {
+  this.keyboard.terminal.wipeContents();
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+
+/**
+ * Handle F11 behavior (fullscreen) when not in a window.
+ *
+ * It would be nice to use the Fullscreen API, but the UX is slightly different
+ * a bad way: the Escape key is automatically registered for exiting.  If we let
+ * the browser handle F11 directly though, we still get to capture Escape.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onF11_ = function(e) {
+  if (hterm.windowType != 'popup')
+    return hterm.Keyboard.KeyActions.PASS;
+  else
+    return '\x1b[23~';
+};
+
+/**
+ * Either pass Ctrl-1..9 to the browser or send them to the host.
+ *
+ * Note that Ctrl-1 and Ctrl-9 don't actually have special sequences mapped
+ * to them in xterm or gnome-terminal.  The range is really Ctrl-2..8, but
+ * we handle 1..9 since Chrome treats the whole range special.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @param {!hterm.Keyboard.KeyDef} keyDef Key definition.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onCtrlNum_ = function(e, keyDef) {
+  // Compute a control character for a given character.
+  function ctl(ch) { return String.fromCharCode(ch.charCodeAt(0) - 64); }
+
+  if (this.keyboard.terminal.passCtrlNumber && !e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  switch (keyDef.keyCap.substr(0, 1)) {
+    case '1': return '1';
+    case '2': return ctl('@');
+    case '3': return ctl('[');
+    case '4': return ctl('\\');
+    case '5': return ctl(']');
+    case '6': return ctl('^');
+    case '7': return ctl('_');
+    case '8': return '\x7f';
+    case '9': return '9';
+  }
+  return hterm.Keyboard.KeyActions.PASS;
+};
+
+/**
+ * Either pass Alt-1..9 to the browser or send them to the host.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onAltNum_ = function(e) {
+  if (this.keyboard.terminal.passAltNumber && !e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  return hterm.Keyboard.KeyActions.DEFAULT;
+};
+
+/**
+ * Either pass Meta-1..9 to the browser or send them to the host.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onMetaNum_ = function(e) {
+  if (this.keyboard.terminal.passMetaNumber && !e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  return hterm.Keyboard.KeyActions.DEFAULT;
+};
+
+/**
+ * Either send a ^C or interpret the keystroke as a copy command.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onCtrlC_ = function(e) {
+  var selection = this.keyboard.terminal.getDocument().getSelection();
+
+  if (!selection.isCollapsed) {
+    if (this.keyboard.ctrlCCopy && !e.shiftKey) {
+      // Ctrl-C should copy if there is a selection, send ^C otherwise.
+      // Perform the copy by letting the browser handle Ctrl-C.  On most
+      // browsers, this is the *only* way to place text on the clipboard from
+      // the 'drive-by' web.
+      if (this.keyboard.terminal.clearSelectionAfterCopy) {
+        setTimeout(selection.collapseToEnd.bind(selection), 50);
+      }
+      return hterm.Keyboard.KeyActions.PASS;
+    }
+
+    if (!this.keyboard.ctrlCCopy && e.shiftKey) {
+      // Ctrl-Shift-C should copy if there is a selection, send ^C otherwise.
+      // Perform the copy manually.  This only works in situations where
+      // document.execCommand('copy') is allowed.
+      if (this.keyboard.terminal.clearSelectionAfterCopy) {
+        setTimeout(selection.collapseToEnd.bind(selection), 50);
+      }
+      this.keyboard.terminal.copySelectionToClipboard();
+      return hterm.Keyboard.KeyActions.CANCEL;
+    }
+  }
+
+  return '\x03';
+};
+
+/**
+ * Either send a ^N or open a new window to the same location.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onCtrlN_ = function(e) {
+  if (e.shiftKey) {
+    lib.f.openWindow(document.location.href, '',
+                     'chrome=no,close=yes,resize=yes,scrollbars=yes,' +
+                     'minimizable=yes,width=' + window.innerWidth +
+                     ',height=' + window.innerHeight);
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  return '\x0e';
+};
+
+/**
+ * Either send a ^V or issue a paste command.
+ *
+ * The default behavior is to paste if the user presses Ctrl-Shift-V, and send
+ * a ^V if the user presses Ctrl-V. This can be flipped with the
+ * 'ctrl-v-paste' preference.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onCtrlV_ = function(e) {
+  if ((!e.shiftKey && this.keyboard.ctrlVPaste) ||
+      (e.shiftKey && !this.keyboard.ctrlVPaste)) {
+    // We try to do the pasting ourselves as not all browsers/OSs bind Ctrl-V to
+    // pasting.  Notably, on macOS, Ctrl-V/Ctrl-Shift-V do nothing.
+    // However, this might run into web restrictions, so if it fails, we still
+    // fallback to the letting the native behavior (hopefully) save us.
+    if (this.keyboard.terminal.paste())
+      return hterm.Keyboard.KeyActions.CANCEL;
+    else
+      return hterm.Keyboard.KeyActions.PASS;
+  }
+
+  return '\x16';
+};
+
+/**
+ * Either the default action or open a new window to the same location.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onMetaN_ = function(e) {
+  if (e.shiftKey) {
+    lib.f.openWindow(document.location.href, '',
+                     'chrome=no,close=yes,resize=yes,scrollbars=yes,' +
+                     'minimizable=yes,width=' + window.outerWidth +
+                     ',height=' + window.outerHeight);
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  return hterm.Keyboard.KeyActions.DEFAULT;
+};
+
+/**
+ * Either send a Meta-C or allow the browser to interpret the keystroke as a
+ * copy command.
+ *
+ * If there is no selection, or if the user presses Meta-Shift-C, then we'll
+ * transmit an '\x1b' (if metaSendsEscape is on) followed by 'c' or 'C'.
+ *
+ * If there is a selection, we defer to the browser.  In this case we clear out
+ * the selection so the user knows we heard them, and also to give them a
+ * chance to send a Meta-C by just hitting the key again.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @param {!hterm.Keyboard.KeyDef} keyDef Key definition.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onMetaC_ = function(e, keyDef) {
+  var document = this.keyboard.terminal.getDocument();
+  if (e.shiftKey || document.getSelection().isCollapsed) {
+    // If the shift key is being held, or there is no document selection, send
+    // a Meta-C.  The keyboard code will add the ESC if metaSendsEscape is true,
+    // we just have to decide between 'c' and 'C'.
+    return keyDef.keyCap.substr(e.shiftKey ? 1 : 0, 1);
+  }
+
+  // Otherwise let the browser handle it as a copy command.
+  if (this.keyboard.terminal.clearSelectionAfterCopy) {
+    setTimeout(function() { document.getSelection().collapseToEnd(); }, 50);
+  }
+  return hterm.Keyboard.KeyActions.PASS;
+};
+
+/**
+ * Either PASS or DEFAULT Meta-V, depending on preference.
+ *
+ * Always PASS Meta-Shift-V to allow browser to interpret the keystroke as
+ * a paste command.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onMetaV_ = function(e) {
+  if (e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
+
+  return this.keyboard.passMetaV ?
+      hterm.Keyboard.KeyActions.PASS :
+      hterm.Keyboard.KeyActions.DEFAULT;
+};
+
+/**
+ * Handle font zooming.
+ *
+ * The browser's built-in zoom has a bit of an issue at certain zoom levels.
+ * At some magnifications, the measured height of a row of text differs from
+ * the height that was explicitly set.
+ *
+ * We override the browser zoom keys to change the ScrollPort's font size to
+ * avoid the issue.
+ *
+ * @param {!KeyboardEvent} e The event to process.
+ * @param {!hterm.Keyboard.KeyDef} keyDef Key definition.
+ * @return {symbol|string} Key action or sequence.
+ */
+hterm.Keyboard.KeyMap.prototype.onZoom_ = function(e, keyDef) {
+  if (!(this.keyboard.ctrlPlusMinusZeroZoom ^ e.shiftKey)) {
+    // If ctrl-PMZ controls zoom and the shift key is pressed, or
+    // ctrl-shift-PMZ controls zoom and this shift key is not pressed,
+    // then we want to send the control code instead of affecting zoom.
+    if (keyDef.keyCap == '-_')
+      return '\x1f';  // ^_
+
+    // Only ^_ is valid, the other sequences have no meaning.
+    return hterm.Keyboard.KeyActions.CANCEL;
+  }
+
+  if (this.keyboard.terminal.getZoomFactor() != 1) {
+    // If we're not at 1:1 zoom factor, let the Ctrl +/-/0 keys control the
+    // browser zoom, so it's easier to for the user to get back to 100%.
+    return hterm.Keyboard.KeyActions.PASS;
+  }
+
+  var cap = keyDef.keyCap.substr(0, 1);
+  if (cap == '0') {
+      this.keyboard.terminal.setFontSize(0);
+  } else {
+    var size = this.keyboard.terminal.getFontSize();
+
+    if (cap == '-' || keyDef.keyCap == '[KP-]') {
+      size -= 1;
+    } else {
+      size += 1;
+    }
+
+    this.keyboard.terminal.setFontSize(size);
+  }
+
+  return hterm.Keyboard.KeyActions.CANCEL;
+};
+// SOURCE FILE: hterm/js/hterm_keyboard_keypattern.js
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * A record of modifier bits and keycode used to define a key binding.
+ *
+ * The modifier names are enumerated in the static KeyPattern.modifiers
+ * property below.  Each modifier can be true, false, or "*".  True means
+ * the modifier key must be present, false means it must not, and "*" means
+ * it doesn't matter.
+ *
+ * @param {!hterm.Keyboard.KeyDown} spec
+ * @constructor
+ */
+hterm.Keyboard.KeyPattern = function(spec) {
+  this.wildcardCount = 0;
+  this.keyCode = spec.keyCode;
+
+  hterm.Keyboard.KeyPattern.modifiers.forEach(function(mod) {
+    this[mod] = spec[mod] || false;
+    if (this[mod] == '*')
+      this.wildcardCount++;
+  }.bind(this));
+};
+
+/**
+ * Valid modifier names.
+ */
+hterm.Keyboard.KeyPattern.modifiers = [
+  'shift', 'ctrl', 'alt', 'meta'
+];
+
+/**
+ * A compare callback for Array.prototype.sort().
+ *
+ * The bindings code wants to be sure to search through the strictest key
+ * patterns first, so that loosely defined patterns have a lower priority than
+ * exact patterns.
+ *
+ * @param {!hterm.Keyboard.KeyPattern} a
+ * @param {!hterm.Keyboard.KeyPattern} b
+ * @return {number}
+ */
+hterm.Keyboard.KeyPattern.sortCompare = function(a, b) {
+  if (a.wildcardCount < b.wildcardCount)
+    return -1;
+
+  if (a.wildcardCount > b.wildcardCount)
+    return 1;
+
+  return 0;
+};
+
+/**
+ * Private method used to match this key pattern against other key patterns
+ * or key down events.
+ *
+ * @param {!hterm.Keyboard.KeyDown} obj The object to match.
+ * @param {boolean} exactMatch True if we should ignore wildcards.  Useful when
+ *     you want
+ *   to perform and exact match against another key pattern.
+ * @return {boolean}
+ */
+hterm.Keyboard.KeyPattern.prototype.match_ = function(obj, exactMatch) {
+  if (this.keyCode != obj.keyCode)
+    return false;
+
+  var rv = true;
+
+  hterm.Keyboard.KeyPattern.modifiers.forEach(function(mod) {
+    var modValue = (mod in obj) ? obj[mod] : false;
+    if (!rv || (!exactMatch && this[mod] == '*') || this[mod] == modValue)
+      return;
+
+    rv = false;
+  }.bind(this));
+
+  return rv;
+};
+
+/**
+ * Return true if the given keyDown object is a match for this key pattern.
+ *
+ * @param {!hterm.Keyboard.KeyDown} keyDown An object with a keyCode property
+ *     and zero or more boolean properties representing key modifiers.  These
+ *     property names must match those defined in
+ *     hterm.Keyboard.KeyPattern.modifiers.
+ * @return {boolean}
+ */
+hterm.Keyboard.KeyPattern.prototype.matchKeyDown = function(keyDown) {
+  return this.match_(keyDown, false);
+};
+
+/**
+ * Return true if the given hterm.Keyboard.KeyPattern is exactly the same as
+ * this one.
+ *
+ * @param {!hterm.Keyboard.KeyPattern} keyPattern
+ * @return {boolean}
+ */
+hterm.Keyboard.KeyPattern.prototype.matchKeyPattern = function(keyPattern) {
+  return this.match_(keyPattern, true);
+};
+// SOURCE FILE: hterm/js/hterm_options.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview This file implements the hterm.Options class,
+ * which stores current operating conditions for the terminal.  This object is
+ * used instead of a series of parameters to allow saving/restoring of cursor
+ * conditions easily, and to provide an easy place for common configuration
+ * options.
+ *
+ * Original code by Cory Maccarrone.
+ */
+
+/**
+ * Constructor for the hterm.Options class, optionally acting as a copy
+ * constructor.
+ *
+ * The defaults are as defined in http://www.vt100.net/docs/vt510-rm/DECSTR
+ * except that we enable autowrap (wraparound) by default since that seems to
+ * be what xterm does.
+ *
+ * @param {!hterm.Options=} opt_copy Optional instance to copy.
+ * @constructor
+ */
+hterm.Options = function(opt_copy) {
+  // All attributes in this class are public to allow easy access by the
+  // terminal.
+
+  this.wraparound = opt_copy ? opt_copy.wraparound : true;
+  this.reverseWraparound = opt_copy ? opt_copy.reverseWraparound : false;
+  this.originMode = opt_copy ? opt_copy.originMode : false;
+  this.autoCarriageReturn = opt_copy ? opt_copy.autoCarriageReturn : false;
+  this.cursorVisible = opt_copy ? opt_copy.cursorVisible : false;
+  this.cursorBlink = opt_copy ? opt_copy.cursorBlink : false;
+  this.insertMode = opt_copy ? opt_copy.insertMode : false;
+  this.reverseVideo = opt_copy ? opt_copy.reverseVideo : false;
+  this.bracketedPaste = opt_copy ? opt_copy.bracketedPaste : false;
+};
+// SOURCE FILE: hterm/js/hterm_parser.js
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Parses the key definition syntax used for user keyboard customizations.
+ *
+ * @constructor
+ */
+hterm.Parser = function() {
+  /**
+   * @type {string} The source string.
+   */
+  this.source = '';
+
+  /**
+   * @type {number} The current position.
+   */
+  this.pos = 0;
+
+  /**
+   * @type {?string} The character at the current position.
+   */
+  this.ch = null;
+};
+
+/**
+ * @param {string} message
+ * @return {!Error}
+ */
+hterm.Parser.prototype.error = function(message) {
+  return new Error('Parse error at ' + this.pos + ': ' + message);
+};
+
+/** @return {boolean} */
+hterm.Parser.prototype.isComplete = function() {
+  return this.pos == this.source.length;
+};
+
+/**
+ * @param {string} source
+ * @param {number=} opt_pos
+ */
+hterm.Parser.prototype.reset = function(source, opt_pos) {
+  this.source = source;
+  this.pos = opt_pos || 0;
+  this.ch = source.substr(0, 1);
+};
+
+/**
+ * Parse a key sequence.
+ *
+ * A key sequence is zero or more of the key modifiers defined in
+ * hterm.Parser.identifiers.modifierKeys followed by a key code.  Key
+ * codes can be an integer or an identifier from
+ * hterm.Parser.identifiers.keyCodes.  Modifiers and keyCodes should be joined
+ * by the dash character.
+ *
+ * An asterisk "*" can be used to indicate that the unspecified modifiers
+ * are optional.
+ *
+ * For example:
+ *   A: Matches only an unmodified "A" character.
+ *   65: Same as above.
+ *   0x41: Same as above.
+ *   Ctrl-A: Matches only Ctrl-A.
+ *   Ctrl-65: Same as above.
+ *   Ctrl-0x41: Same as above.
+ *   Ctrl-Shift-A: Matches only Ctrl-Shift-A.
+ *   Ctrl-*-A: Matches Ctrl-A, as well as any other key sequence that includes
+ *     at least the Ctrl and A keys.
+ *
+ * @return {!hterm.Keyboard.KeyDown} An object with shift, ctrl, alt, meta,
+ *     keyCode properties.
+ */
+hterm.Parser.prototype.parseKeySequence = function() {
+  var rv = {
+    keyCode: null
+  };
+
+  for (var k in hterm.Parser.identifiers.modifierKeys) {
+    rv[hterm.Parser.identifiers.modifierKeys[k]] = false;
+  }
+
+  while (this.pos < this.source.length) {
+    this.skipSpace();
+
+    var token = this.parseToken();
+    if (token.type == 'integer') {
+      rv.keyCode = token.value;
+
+    } else if (token.type == 'identifier') {
+      var ucValue = token.value.toUpperCase();
+      if (ucValue in hterm.Parser.identifiers.modifierKeys &&
+          hterm.Parser.identifiers.modifierKeys.hasOwnProperty(ucValue)) {
+        var mod = hterm.Parser.identifiers.modifierKeys[ucValue];
+        if (rv[mod] && rv[mod] != '*')
+          throw this.error('Duplicate modifier: ' + token.value);
+        rv[mod] = true;
+
+      } else if (ucValue in hterm.Parser.identifiers.keyCodes &&
+                 hterm.Parser.identifiers.keyCodes.hasOwnProperty(ucValue)) {
+        rv.keyCode = hterm.Parser.identifiers.keyCodes[ucValue];
+
+      } else {
+        throw this.error('Unknown key: ' + token.value);
+      }
+
+    } else if (token.type == 'symbol') {
+      if (token.value == '*') {
+        for (var id in hterm.Parser.identifiers.modifierKeys) {
+          var p = hterm.Parser.identifiers.modifierKeys[id];
+          if (!rv[p])
+            rv[p] =  '*';
+        }
+      } else {
+        throw this.error('Unexpected symbol: ' + token.value);
+      }
+    } else {
+      throw this.error('Expected integer or identifier');
+    }
+
+    this.skipSpace();
+
+    if (this.ch != '-')
+      break;
+
+    if (rv.keyCode != null)
+      throw this.error('Extra definition after target key');
+
+    this.advance(1);
+  }
+
+  if (rv.keyCode == null)
+    throw this.error('Missing target key');
+
+  return rv;
+};
+
+/** @return {string} */
+hterm.Parser.prototype.parseKeyAction = function() {
+  this.skipSpace();
+
+  var token = this.parseToken();
+
+  if (token.type == 'string')
+    return token.value;
+
+  if (token.type == 'identifier') {
+    if (token.value in hterm.Parser.identifiers.actions &&
+        hterm.Parser.identifiers.actions.hasOwnProperty(token.value))
+      return hterm.Parser.identifiers.actions[token.value];
+
+    throw this.error('Unknown key action: ' + token.value);
+  }
+
+  throw this.error('Expected string or identifier');
+
+};
+
+/** @return {boolean} */
+hterm.Parser.prototype.peekString = function() {
+  return this.ch == '\'' || this.ch == '"';
+};
+
+/** @return {boolean} */
+hterm.Parser.prototype.peekIdentifier = function() {
+  return !!this.ch.match(/[a-z_]/i);
+};
+
+/** @return {boolean} */
+hterm.Parser.prototype.peekInteger = function() {
+  return !!this.ch.match(/[0-9]/);
+};
+
+/** @return {!Object} */
+hterm.Parser.prototype.parseToken = function() {
+  if (this.ch == '*') {
+    var rv = {type: 'symbol', value: this.ch};
+    this.advance(1);
+    return rv;
+  }
+
+  if (this.peekIdentifier())
+    return {type: 'identifier', value: this.parseIdentifier()};
+
+  if (this.peekString())
+    return {type: 'string', value: this.parseString()};
+
+  if (this.peekInteger())
+    return {type: 'integer', value: this.parseInteger()};
+
+
+  throw this.error('Unexpected token');
+};
+
+/** @return {string} */
+hterm.Parser.prototype.parseIdentifier = function() {
+  if (!this.peekIdentifier())
+    throw this.error('Expected identifier');
+
+  return this.parsePattern(/[a-z0-9_]+/ig);
+};
+
+/** @return {number} */
+hterm.Parser.prototype.parseInteger = function() {
+  if (this.ch == '0' && this.pos < this.source.length - 1 &&
+      this.source.substr(this.pos + 1, 1) == 'x') {
+    return parseInt(this.parsePattern(/0x[0-9a-f]+/gi), undefined);
+  }
+
+  return parseInt(this.parsePattern(/\d+/g), 10);
+};
+
+/**
+ * Parse a single or double quoted string.
+ *
+ * The current position should point at the initial quote character.  Single
+ * quoted strings will be treated literally, double quoted will process escapes.
+ *
+ * TODO(rginda): Variable interpolation.
+ *
+ * @return {string}
+ */
+hterm.Parser.prototype.parseString = function() {
+  var result = '';
+
+  var quote = this.ch;
+  if (quote != '"' && quote != '\'')
+    throw this.error('String expected');
+
+  this.advance(1);
+
+  var re = new RegExp('[\\\\' + quote + ']', 'g');
+
+  while (this.pos < this.source.length) {
+    re.lastIndex = this.pos;
+    if (!re.exec(this.source))
+      throw this.error('Unterminated string literal');
+
+    result += this.source.substring(this.pos, re.lastIndex - 1);
+
+    this.advance(re.lastIndex - this.pos - 1);
+
+    if (quote == '"' && this.ch == '\\') {
+      this.advance(1);
+      result += this.parseEscape();
+      continue;
+    }
+
+    if (quote == '\'' && this.ch == '\\') {
+      result += this.ch;
+      this.advance(1);
+      continue;
+    }
+
+    if (this.ch == quote) {
+      this.advance(1);
+      return result;
+    }
+  }
+
+  throw this.error('Unterminated string literal');
+};
+
+
+/**
+ * Parse an escape code from the current position (which should point to
+ * the first character AFTER the leading backslash.)
+ *
+ * @return {string}
+ */
+hterm.Parser.prototype.parseEscape = function() {
+  var map = {
+    '"': '"',
+    '\'': '\'',
+    '\\': '\\',
+    'a': '\x07',
+    'b': '\x08',
+    'e': '\x1b',
+    'f': '\x0c',
+    'n': '\x0a',
+    'r': '\x0d',
+    't': '\x09',
+    'v': '\x0b',
+    'x': function() {
+      var value = this.parsePattern(/[a-z0-9]{2}/ig);
+      return String.fromCharCode(parseInt(value, 16));
+    },
+    'u': function() {
+      var value = this.parsePattern(/[a-z0-9]{4}/ig);
+      return String.fromCharCode(parseInt(value, 16));
+    }
+  };
+
+  if (!(this.ch in map && map.hasOwnProperty(this.ch)))
+    throw this.error('Unknown escape: ' + this.ch);
+
+  var value = map[this.ch];
+  this.advance(1);
+
+  if (typeof value == 'function')
+    value = value.call(this);
+
+  return value;
+};
+
+/**
+ * Parse the given pattern starting from the current position.
+ *
+ * @param {!RegExp} pattern A pattern representing the characters to span.  MUST
+ *   include the "global" RegExp flag.
+ * @return {string}
+ */
+hterm.Parser.prototype.parsePattern = function(pattern) {
+  if (!pattern.global)
+    throw this.error('Internal error: Span patterns must be global');
+
+  pattern.lastIndex = this.pos;
+  var ary = pattern.exec(this.source);
+
+  if (!ary || pattern.lastIndex - ary[0].length != this.pos)
+    throw this.error('Expected match for: ' + pattern);
+
+  this.pos = pattern.lastIndex - 1;
+  this.advance(1);
+
+  return ary[0];
+};
+
+
+/**
+ * Advance the current position.
+ *
+ * @param {number} count
+ */
+hterm.Parser.prototype.advance = function(count) {
+  this.pos += count;
+  this.ch = this.source.substr(this.pos, 1);
+};
+
+/**
+ * @param {string=} opt_expect A list of valid non-whitespace characters to
+ *   terminate on.
+ * @return {void}
+ */
+hterm.Parser.prototype.skipSpace = function(opt_expect) {
+  if (!/\s/.test(this.ch))
+    return;
+
+  var re = /\s+/gm;
+  re.lastIndex = this.pos;
+
+  var source = this.source;
+  if (re.exec(source))
+    this.pos = re.lastIndex;
+
+  this.ch = this.source.substr(this.pos, 1);
+
+  if (opt_expect) {
+    if (this.ch.indexOf(opt_expect) == -1) {
+      throw this.error('Expected one of ' + opt_expect + ', found: ' +
+          this.ch);
+    }
+  }
+};
+// SOURCE FILE: hterm/js/hterm_parser_identifiers.js
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Collections of identifier for hterm.Parser.
+ */
+hterm.Parser.identifiers = {};
+
+/**
+ * Modifier key names used when defining key sequences.
+ *
+ * These are upper case so we can normalize the user input and be forgiving.
+ * "CTRL-A" and "Ctrl-A" and "ctrl-a" are all accepted.
+ *
+ * Note: Names here cannot overlap with hterm.Parser.identifiers.keyCodes.
+ */
+hterm.Parser.identifiers.modifierKeys = {
+  SHIFT: 'shift',
+  CTRL: 'ctrl',
+  // Common alias.
+  CONTROL: 'ctrl',
+  ALT: 'alt',
+  META: 'meta'
+};
+
+/**
+ * Key codes useful when defining key sequences.
+ *
+ * Punctuation is mostly left out of this list because they can move around
+ * based on keyboard locale and browser.
+ *
+ * In a key sequence like "Ctrl-ESC", the ESC comes from this list of
+ * identifiers.  It is equivalent to "Ctrl-27" and "Ctrl-0x1b".
+ *
+ * These are upper case so we can normalize the user input and be forgiving.
+ * "Ctrl-ESC" and "Ctrl-Esc" an "Ctrl-esc" are all accepted.
+ *
+ * We also include common aliases for the same key.  "Esc" and "Escape" are the
+ * same key.
+ *
+ * Note: Names here cannot overlap with hterm.Parser.identifiers.modifierKeys.
+ */
+hterm.Parser.identifiers.keyCodes = {
+  // Top row.
+  ESCAPE: 27,
+  ESC: 27,
+  F1: 112,
+  F2: 113,
+  F3: 114,
+  F4: 115,
+  F5: 116,
+  F6: 117,
+  F7: 118,
+  F8: 119,
+  F9: 120,
+  F10: 121,
+  F11: 122,
+  F12: 123,
+
+  // Row two.
+  ONE: 49,
+  TWO: 50,
+  THREE: 51,
+  FOUR: 52,
+  FIVE: 53,
+  SIX: 54,
+  SEVEN: 55,
+  EIGHT: 56,
+  NINE: 57,
+  ZERO: 48,
+  BACKSPACE: 8,
+  BKSP: 8,
+  BS: 8,
+
+  // Row three.
+  TAB: 9,
+  Q: 81,
+  W: 87,
+  E: 69,
+  R: 82,
+  T: 84,
+  Y: 89,
+  U: 85,
+  I: 73,
+  O: 79,
+  P: 80,
+
+  // Row four.
+  CAPS_LOCK: 20,
+  CAPSLOCK: 20,
+  CAPS: 20,
+  A: 65,
+  S: 83,
+  D: 68,
+  F: 70,
+  G: 71,
+  H: 72,
+  J: 74,
+  K: 75,
+  L: 76,
+  // We map enter and return together even though enter should really be 10
+  // because most people don't know or care about the history here.  Plus,
+  // most keyboards/programs map them together already.  If they really want
+  // to bind them differently, they can also use the numeric value.
+  ENTER: 13,
+  ENT: 13,
+  RETURN: 13,
+  RET: 13,
+
+  // Row five.
+  Z: 90,
+  X: 88,
+  C: 67,
+  V: 86,
+  B: 66,
+  N: 78,
+  M: 77,
+
+  // Etc.
+  SPACE: 32,
+  SP: 32,
+  PRINT_SCREEN: 42,
+  PRTSC: 42,
+  SCROLL_LOCK: 145,
+  SCRLK: 145,
+  BREAK: 19,
+  BRK: 19,
+  INSERT: 45,
+  INS: 45,
+  HOME: 36,
+  PAGE_UP: 33,
+  PGUP: 33,
+  DELETE: 46,
+  DEL: 46,
+  END: 35,
+  PAGE_DOWN: 34,
+  PGDOWN: 34,
+  PGDN: 34,
+  UP: 38,
+  DOWN: 40,
+  RIGHT: 39,
+  LEFT: 37,
+  NUMLOCK: 144,
+
+  // Keypad
+  KP0: 96,
+  KP1: 97,
+  KP2: 98,
+  KP3: 99,
+  KP4: 100,
+  KP5: 101,
+  KP6: 102,
+  KP7: 103,
+  KP8: 104,
+  KP9: 105,
+  KP_PLUS: 107,
+  KP_ADD: 107,
+  KP_MINUS: 109,
+  KP_SUBTRACT: 109,
+  KP_STAR: 106,
+  KP_MULTIPLY: 106,
+  KP_DIVIDE: 111,
+  KP_DECIMAL: 110,
+  KP_PERIOD: 110,
+
+  // Chrome OS media keys
+  NAVIGATE_BACK: 166,
+  NAVIGATE_FORWARD: 167,
+  RELOAD: 168,
+  FULL_SCREEN: 183,
+  WINDOW_OVERVIEW: 182,
+  BRIGHTNESS_UP: 216,
+  BRIGHTNESS_DOWN: 217
+};
+
+/**
+ * Identifiers for use in key actions.
+ */
+hterm.Parser.identifiers.actions = {
+  /**
+   * Prevent the browser and operating system from handling the event.
+   */
+  CANCEL: hterm.Keyboard.KeyActions.CANCEL,
+
+  /**
+   * Wait for a "keypress" event, send the keypress charCode to the host.
+   */
+  DEFAULT: hterm.Keyboard.KeyActions.DEFAULT,
+
+  /**
+   * Let the browser or operating system handle the key.
+   */
+  PASS: hterm.Keyboard.KeyActions.PASS,
+
+  /**
+   * Scroll the terminal one line up.
+   *
+   * @param {!hterm.Terminal} terminal
+   * @return {!hterm.Keyboard.KeyActions}
+   */
+  scrollLineUp: function(terminal) {
+    terminal.scrollLineUp();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal one line down.
+   *
+   * @param {!hterm.Terminal} terminal
+   * @return {!hterm.Keyboard.KeyActions}
+   */
+  scrollLineDown: function(terminal) {
+    terminal.scrollLineDown();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal one page up.
+   *
+   * @param {!hterm.Terminal} terminal
+   * @return {!hterm.Keyboard.KeyActions}
+   */
+  scrollPageUp: function(terminal) {
+    terminal.scrollPageUp();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal one page down.
+   *
+   * @param {!hterm.Terminal} terminal
+   * @return {!hterm.Keyboard.KeyActions}
+   */
+  scrollPageDown: function(terminal) {
+    terminal.scrollPageDown();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal to the top.
+   *
+   * @param {!hterm.Terminal} terminal
+   * @return {!hterm.Keyboard.KeyActions}
+   */
+  scrollToTop: function(terminal) {
+    terminal.scrollHome();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Scroll the terminal to the bottom.
+   *
+   * @param {!hterm.Terminal} terminal
+   * @return {!hterm.Keyboard.KeyActions}
+   */
+  scrollToBottom: function(terminal) {
+    terminal.scrollEnd();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Clear the active screen and move the cursor to (0,0).
+   *
+   * @param {!hterm.Terminal} terminal
+   * @return {!hterm.Keyboard.KeyActions}
+   */
+  clearScreen: function(terminal) {
+    terminal.clearHome();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Clear the scrollback buffer.
+   *
+   * @param {!hterm.Terminal} terminal
+   * @return {!hterm.Keyboard.KeyActions}
+   */
+  clearScrollback: function(terminal) {
+    terminal.clearScrollback();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Clear the terminal and scrollback buffer and move the cursor to (0,0).
+   *
+   * @param {!hterm.Terminal} terminal
+   * @return {!hterm.Keyboard.KeyActions}
+   */
+  clearTerminal: function(terminal) {
+    terminal.wipeContents();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Perform a full terminal reset.
+   *
+   * @param {!hterm.Terminal} terminal
+   * @return {!hterm.Keyboard.KeyActions}
+   */
+  fullReset: function(terminal) {
+    terminal.reset();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+
+  /**
+   * Perform a soft terminal reset.
+   *
+   * @param {!hterm.Terminal} terminal
+   * @return {!hterm.Keyboard.KeyActions}
+   */
+  softReset: function(terminal) {
+    terminal.softReset();
+    return hterm.Keyboard.KeyActions.CANCEL;
+  },
+};
+// SOURCE FILE: hterm/js/hterm_preference_manager.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * PreferenceManager subclass managing global NaSSH preferences.
+ *
+ * This is currently just an ordered list of known connection profiles.
+ *
+ * @param {string} profileId
+ * @extends {lib.PreferenceManager}
+ * @constructor
+ */
+hterm.PreferenceManager = function(profileId) {
+  lib.PreferenceManager.call(this, hterm.defaultStorage,
+                             hterm.PreferenceManager.prefix_ + profileId);
+  Object.entries(hterm.PreferenceManager.defaultPreferences).forEach(
+      ([key, entry]) => {
+        this.definePreference(key, entry['default']);
+      });
+};
+
+/**
+ * The storage key prefix to namespace the preferences.
+ */
+hterm.PreferenceManager.prefix_ = '/hterm/profiles/';
+
+/**
+ * List all the defined profiles.
+ *
+ * @param {function(!Array<string>)} callback Called with the list of profiles.
+ */
+hterm.PreferenceManager.listProfiles = function(callback) {
+  hterm.defaultStorage.getItems(null, (items) => {
+    const profiles = {};
+    for (let key of Object.keys(items)) {
+      if (key.startsWith(hterm.PreferenceManager.prefix_)) {
+        // Turn "/hterm/profiles/foo/bar/cow" to "foo/bar/cow".
+        const subKey = key.slice(hterm.PreferenceManager.prefix_.length);
+        // Turn "foo/bar/cow" into "foo".
+        profiles[subKey.split('/', 1)[0]] = true;
+      }
+    }
+    callback(Object.keys(profiles));
+  });
+};
+
+/** @enum {string} */
+hterm.PreferenceManager.Categories = {
+  Keyboard: 'Keyboard',
+  Appearance: 'Appearance',
+  CopyPaste: 'CopyPaste',
+  Sounds: 'Sounds',
+  Scrolling: 'Scrolling',
+  Encoding: 'Encoding',
+  Extensions: 'Extensions',
+  Miscellaneous: 'Miscellaneous',
+};
+
+/**
+ * List of categories, ordered by display order (top to bottom)
+ */
+hterm.PreferenceManager.categoryDefinitions = [
+  { id: hterm.PreferenceManager.Categories.Appearance,
+    text: 'Appearance (fonts, colors, images)'},
+  { id: hterm.PreferenceManager.Categories.CopyPaste,
+    text: 'Copy & Paste'},
+  { id: hterm.PreferenceManager.Categories.Encoding,
+    text: 'Encoding'},
+  { id: hterm.PreferenceManager.Categories.Keyboard,
+    text: 'Keyboard'},
+  { id: hterm.PreferenceManager.Categories.Scrolling,
+    text: 'Scrolling'},
+  { id: hterm.PreferenceManager.Categories.Sounds,
+    text: 'Sounds'},
+  { id: hterm.PreferenceManager.Categories.Extensions,
+    text: 'Extensions'},
+  { id: hterm.PreferenceManager.Categories.Miscellaneous,
+    text: 'Miscellaneous'}
+];
+
+/**
+ * Internal helper to create a default preference object.
+ *
+ * @param {string} name The user readable name/title.
+ * @param {!hterm.PreferenceManager.Categories} category The pref category.
+ * @param {boolean|number|string|?Object} defaultValue The default pref value.
+ * @param {string|!Array<string|null>} type The type for this pref (or an array
+ *     for enums).
+ * @param {string} help The user readable help text.
+ * @return {!Object} The default pref object.
+ */
+hterm.PreferenceManager.definePref_ = function(
+    name, category, defaultValue, type, help) {
+  return {
+    'name': name,
+    'category': category,
+    'default': defaultValue,
+    'type': type,
+    'help': help,
+  };
+};
+
+hterm.PreferenceManager.defaultPreferences = {
+  'alt-gr-mode': hterm.PreferenceManager.definePref_(
+      'AltGr key mode',
+      hterm.PreferenceManager.Categories.Keyboard,
+      null, [null, 'none', 'ctrl-alt', 'left-alt', 'right-alt'],
+      `Select an AltGr detection heuristic.\n` +
+      `\n` +
+      `'null': Autodetect based on navigator.language:\n` +
+      `      'en-us' => 'none', else => 'right-alt'\n` +
+      `'none': Disable any AltGr related munging.\n` +
+      `'ctrl-alt': Assume Ctrl+Alt means AltGr.\n` +
+      `'left-alt': Assume left Alt means AltGr.\n` +
+      `'right-alt': Assume right Alt means AltGr.`
+  ),
+
+  'alt-backspace-is-meta-backspace': hterm.PreferenceManager.definePref_(
+      'Alt-Backspace is Meta-Backspace',
+      hterm.PreferenceManager.Categories.Keyboard,
+      false, 'bool',
+      `If set, undoes the Chrome OS Alt-Backspace->DEL remap, so that ` +
+      `Alt-Backspace indeed is Alt-Backspace.`
+  ),
+
+  'alt-is-meta': hterm.PreferenceManager.definePref_(
+      'Treat Alt key as Meta key',
+      hterm.PreferenceManager.Categories.Keyboard,
+      false, 'bool',
+      `Whether the Alt key acts as a Meta key or as a distinct Alt key.`
+  ),
+
+  'alt-sends-what': hterm.PreferenceManager.definePref_(
+      'Alt key modifier handling',
+      hterm.PreferenceManager.Categories.Keyboard,
+      'escape', ['escape', '8-bit', 'browser-key'],
+      `Controls how the Alt key is handled.\n` +
+      `\n` +
+      `  escape: Send an ESC prefix.\n` +
+      `  8-bit: Add 128 to the typed character as in xterm.\n` +
+      `  browser-key: Wait for the keypress event and see what the browser\n` +
+      `    says. (This won't work well on platforms where the browser\n` +
+      `    performs a default action for some Alt sequences.)`
+  ),
+
+  'audible-bell-sound': hterm.PreferenceManager.definePref_(
+      'Alert bell sound (URI)',
+      hterm.PreferenceManager.Categories.Sounds,
+      'lib-resource:hterm/audio/bell', 'url',
+      `URL of the terminal bell sound. Empty string for no audible bell.`
+  ),
+
+  'desktop-notification-bell': hterm.PreferenceManager.definePref_(
+      'Create desktop notifications for alert bells',
+      hterm.PreferenceManager.Categories.Sounds,
+      false, 'bool',
+      `If true, terminal bells in the background will create a Web ` +
+      `Notification. https://www.w3.org/TR/notifications/\n` +
+      `\n` +
+      `Displaying notifications requires permission from the user. When this ` +
+      `option is set to true, hterm will attempt to ask the user for ` +
+      `permission if necessary. Browsers may not show this permission ` +
+      `request if it was not triggered by a user action.\n` +
+      `\n` +
+      `Chrome extensions with the "notifications" permission have permission ` +
+      `to display notifications.`
+  ),
+
+  'background-color': hterm.PreferenceManager.definePref_(
+      'Background color',
+      hterm.PreferenceManager.Categories.Appearance,
+      'rgb(16, 16, 16)', 'color',
+      `The background color for text with no other color attributes.`
+  ),
+
+  'background-image': hterm.PreferenceManager.definePref_(
+      'Background image',
+      hterm.PreferenceManager.Categories.Appearance,
+      '', 'string',
+      `CSS value of the background image. Empty string for no image.\n` +
+      `\n` +
+      `For example:\n` +
+      `  url(https://goo.gl/anedTK)\n` +
+      `  linear-gradient(top bottom, blue, red)`
+  ),
+
+  'background-size': hterm.PreferenceManager.definePref_(
+      'Background image size',
+      hterm.PreferenceManager.Categories.Appearance,
+      '', 'string',
+      `CSS value of the background image size.`
+  ),
+
+  'background-position': hterm.PreferenceManager.definePref_(
+      'Background image position',
+      hterm.PreferenceManager.Categories.Appearance,
+      '', 'string',
+      `CSS value of the background image position.\n` +
+      `\n` +
+      `For example:\n` +
+      `  10% 10%\n` +
+      `  center`
+  ),
+
+  'backspace-sends-backspace': hterm.PreferenceManager.definePref_(
+      'Backspace key behavior',
+      hterm.PreferenceManager.Categories.Keyboard,
+      false, 'bool',
+      `If true, the backspace should send BS ('\\x08', aka ^H). Otherwise ` +
+      `the backspace key should send '\\x7f'.`
+  ),
+
+  'character-map-overrides': hterm.PreferenceManager.definePref_(
+      'Character map overrides',
+      hterm.PreferenceManager.Categories.Appearance,
+      null, 'value',
+      `This is specified as an object. It is a sparse array, where each ` +
+      `property is the character set code and the value is an object that is ` +
+      `a sparse array itself. In that sparse array, each property is the ` +
+      `received character and the value is the displayed character.\n` +
+      `\n` +
+      `For example:\n` +
+      `  {"0":{"+":"\\u2192",",":"\\u2190","-":"\\u2191",".":"\\u2193", ` +
+      `"0":"\\u2588"}}`
+  ),
+
+  'close-on-exit': hterm.PreferenceManager.definePref_(
+      'Close window on exit',
+      hterm.PreferenceManager.Categories.Miscellaneous,
+      true, 'bool',
+      `Whether to close the window when the command finishes executing.`
+  ),
+
+  'cursor-blink': hterm.PreferenceManager.definePref_(
+      'Cursor blink',
+      hterm.PreferenceManager.Categories.Appearance,
+      false, 'bool',
+      `Whether the text cursor blinks by default. This can be toggled at ` +
+      `runtime via terminal escape sequences.`
+  ),
+
+  'cursor-blink-cycle': hterm.PreferenceManager.definePref_(
+      'Cursor blink rate',
+      hterm.PreferenceManager.Categories.Appearance,
+      [1000, 500], 'value',
+      `The text cursor blink rate in milliseconds.\n` +
+      `\n` +
+      `A two element array, the first of which is how long the text cursor ` +
+      `should be on, second is how long it should be off.`
+  ),
+
+  'cursor-shape': hterm.PreferenceManager.definePref_(
+      'Text cursor shape',
+      hterm.PreferenceManager.Categories.Appearance,
+      'BLOCK', ['BLOCK', 'BEAM', 'UNDERLINE'],
+      `The shape of the visible text cursor. This can be toggled at ` +
+      `runtime via terminal escape sequences.`
+  ),
+
+  'cursor-color': hterm.PreferenceManager.definePref_(
+      'Text cursor color',
+      hterm.PreferenceManager.Categories.Appearance,
+      'rgba(255, 0, 0, 0.5)', 'color',
+      `The color of the visible text cursor.`
+  ),
+
+  'color-palette-overrides': hterm.PreferenceManager.definePref_(
+      'Initial color palette',
+      hterm.PreferenceManager.Categories.Appearance,
+      null, 'value',
+      `Override colors in the default palette.\n` +
+      `\n` +
+      `This can be specified as an array or an object. If specified as an ` +
+      `object it is assumed to be a sparse array, where each property ` +
+      `is a numeric index into the color palette.\n` +
+      `\n` +
+      `Values can be specified as almost any CSS color value. This ` +
+      `includes #RGB, #RRGGBB, rgb(...), rgba(...), and any color names ` +
+      `that are also part of the standard X11 rgb.txt file.\n` +
+      `\n` +
+      `You can use 'null' to specify that the default value should be not ` +
+      `be changed. This is useful for skipping a small number of indices ` +
+      `when the value is specified as an array.\n` +
+      `\n` +
+      `For example, these both set color index 1 to blue:\n` +
+      `  {1: "#0000ff"}\n` +
+      `  [null, "#0000ff"]`
+  ),
+
+  'copy-on-select': hterm.PreferenceManager.definePref_(
+      'Automatically copy selected content',
+      hterm.PreferenceManager.Categories.CopyPaste,
+      true, 'bool',
+      `Automatically copy mouse selection to the clipboard.`
+  ),
+
+  'use-default-window-copy': hterm.PreferenceManager.definePref_(
+      'Let the browser handle text copying',
+      hterm.PreferenceManager.Categories.CopyPaste,
+      false, 'bool',
+      `Whether to use the default browser/OS's copy behavior.\n` +
+      `\n` +
+      `Allow the browser/OS to handle the copy event directly which might ` +
+      `improve compatibility with some systems (where copying doesn't work ` +
+      `at all), but makes the text selection less robust.\n` +
+      `\n` +
+      `For example, long lines that were automatically line wrapped will ` +
+      `be copied with the newlines still in them.`
+  ),
+
+  'clear-selection-after-copy': hterm.PreferenceManager.definePref_(
+      'Automatically clear text selection',
+      hterm.PreferenceManager.Categories.CopyPaste,
+      true, 'bool',
+      `Whether to clear the selection after copying.`
+  ),
+
+  'ctrl-plus-minus-zero-zoom': hterm.PreferenceManager.definePref_(
+      'Ctrl-+/-/0 zoom behavior',
+      hterm.PreferenceManager.Categories.Keyboard,
+      true, 'bool',
+      `If true, Ctrl-Plus/Minus/Zero controls zoom.\n` +
+      `If false, Ctrl-Shift-Plus/Minus/Zero controls zoom, Ctrl-Minus sends ` +
+      `^_, Ctrl-Plus/Zero do nothing.`
+  ),
+
+  'ctrl-c-copy': hterm.PreferenceManager.definePref_(
+      'Ctrl-C copy behavior',
+      hterm.PreferenceManager.Categories.Keyboard,
+      false, 'bool',
+      `Ctrl-C copies if true, send ^C to host if false.\n` +
+      `Ctrl-Shift-C sends ^C to host if true, copies if false.`
+  ),
+
+  'ctrl-v-paste': hterm.PreferenceManager.definePref_(
+      'Ctrl-V paste behavior',
+      hterm.PreferenceManager.Categories.Keyboard,
+      false, 'bool',
+      `Ctrl-V pastes if true, send ^V to host if false.\n` +
+      `Ctrl-Shift-V sends ^V to host if true, pastes if false.`
+  ),
+
+  'east-asian-ambiguous-as-two-column': hterm.PreferenceManager.definePref_(
+      'East Asian Ambiguous use two columns',
+      hterm.PreferenceManager.Categories.Keyboard,
+      false, 'bool',
+      `Whether East Asian Ambiguous characters have two column width.`
+  ),
+
+  'enable-8-bit-control': hterm.PreferenceManager.definePref_(
+      'Support non-UTF-8 C1 control characters',
+      hterm.PreferenceManager.Categories.Keyboard,
+      false, 'bool',
+      `True to enable 8-bit control characters, false to ignore them.\n` +
+      `\n` +
+      `We'll respect the two-byte versions of these control characters ` +
+      `regardless of this setting.`
+  ),
+
+  'enable-bold': hterm.PreferenceManager.definePref_(
+      'Bold text behavior',
+      hterm.PreferenceManager.Categories.Appearance,
+      null, 'tristate',
+      `If true, use bold weight font for text with the bold/bright ` +
+      `attribute. False to use the normal weight font. Null to autodetect.`
+  ),
+
+  'enable-bold-as-bright': hterm.PreferenceManager.definePref_(
+      'Use bright colors with bold text',
+      hterm.PreferenceManager.Categories.Appearance,
+      true, 'bool',
+      `If true, use bright colors (8-15 on a 16 color palette) for any text ` +
+      `with the bold attribute. False otherwise.`
+  ),
+
+  'enable-blink': hterm.PreferenceManager.definePref_(
+      'Enable blinking text',
+      hterm.PreferenceManager.Categories.Appearance,
+      true, 'bool',
+      `If true, respect the blink attribute. False to ignore it.`
+  ),
+
+  'enable-clipboard-notice': hterm.PreferenceManager.definePref_(
+      'Show notification when copying content',
+      hterm.PreferenceManager.Categories.CopyPaste,
+      true, 'bool',
+      `Whether to show a message in the terminal when the host writes to the ` +
+      `clipboard.`
+  ),
+
+  'enable-clipboard-write': hterm.PreferenceManager.definePref_(
+      'Allow remote clipboard writes',
+      hterm.PreferenceManager.Categories.CopyPaste,
+      true, 'bool',
+      `Allow the remote host to write directly to the local system ` +
+      `clipboard.\n` +
+      `Read access is never granted regardless of this setting.\n` +
+      `\n` +
+      `This is used to control access to features like OSC-52.`
+  ),
+
+  'enable-dec12': hterm.PreferenceManager.definePref_(
+      'Allow changing of text cursor blinking',
+      hterm.PreferenceManager.Categories.Miscellaneous,
+      false, 'bool',
+      `Respect the host's attempt to change the text cursor blink status ` +
+      `using DEC Private Mode 12.`
+  ),
+
+  'enable-csi-j-3': hterm.PreferenceManager.definePref_(
+      'Allow clearing of scrollback buffer (CSI-J-3)',
+      hterm.PreferenceManager.Categories.Miscellaneous,
+      true, 'bool',
+      `Whether CSI-J (Erase Display) mode 3 may clear the terminal ` +
+      `scrollback buffer.\n` +
+      `\n` +
+      `Enabling this by default is safe.`
+  ),
+
+  'environment': hterm.PreferenceManager.definePref_(
+      'Environment variables',
+      hterm.PreferenceManager.Categories.Miscellaneous,
+      {
+        // Signal ncurses based apps to use UTF-8 output instead of legacy
+        // drawing modes (which only work in ISO-2022 mode).  Since hterm is
+        // always UTF-8, this shouldn't cause problems.
+        'NCURSES_NO_UTF8_ACS': '1',
+        'TERM': 'xterm-256color',
+        // Set this env var that a bunch of mainstream terminal emulators set
+        // to indicate we support true colors.
+        // https://gist.github.com/XVilka/8346728
+        'COLORTERM': 'truecolor',
+      },
+      'value',
+      `The initial set of environment variables, as an object.`
+  ),
+
+  'font-family': hterm.PreferenceManager.definePref_(
+      'Text font family',
+      hterm.PreferenceManager.Categories.Appearance,
+      '"DejaVu Sans Mono", "Noto Sans Mono", "Everson Mono", FreeMono, ' +
+      'Menlo, Terminal, monospace',
+      'string',
+      `Default font family for the terminal text.`
+  ),
+
+  'font-size': hterm.PreferenceManager.definePref_(
+      'Text font size',
+      hterm.PreferenceManager.Categories.Appearance,
+      15, 'int',
+      `The default font size in pixels.`
+  ),
+
+  'font-smoothing': hterm.PreferenceManager.definePref_(
+      'Text font smoothing',
+      hterm.PreferenceManager.Categories.Appearance,
+      'antialiased', 'string',
+      `CSS font-smoothing property.`
+  ),
+
+  'foreground-color': hterm.PreferenceManager.definePref_(
+      'Text color',
+      hterm.PreferenceManager.Categories.Appearance,
+      'rgb(240, 240, 240)', 'color',
+      `The foreground color for text with no other color attributes.`
+  ),
+
+  'enable-resize-status': hterm.PreferenceManager.definePref_(
+      'Show terminal dimensions when resized',
+      hterm.PreferenceManager.Categories.Appearance,
+      false, 'bool',
+      `Whether to show terminal dimensions when the terminal changes size.`
+  ),
+
+  'hide-mouse-while-typing': hterm.PreferenceManager.definePref_(
+      'Hide mouse cursor while typing',
+      hterm.PreferenceManager.Categories.Keyboard,
+      null, 'tristate',
+      `Whether to automatically hide the mouse cursor when typing. ` +
+      `By default, autodetect whether the platform/OS handles this.\n` +
+      `\n` +
+      `Note: Some operating systems may override this setting and thus you ` +
+      `might not be able to always disable it.`
+  ),
+
+  'home-keys-scroll': hterm.PreferenceManager.definePref_(
+      'Home/End key scroll behavior',
+      hterm.PreferenceManager.Categories.Keyboard,
+      false, 'bool',
+      `If true, Home/End controls the terminal scrollbar and Shift-Home/` +
+      `Shift-End are sent to the remote host. If false, then Home/End are ` +
+      `sent to the remote host and Shift-Home/Shift-End scrolls.`
+  ),
+
+  'keybindings': hterm.PreferenceManager.definePref_(
+      'Keyboard bindings/shortcuts',
+      hterm.PreferenceManager.Categories.Keyboard,
+      null, 'value',
+      `A map of key sequence to key actions. Key sequences include zero or ` +
+      `more modifier keys followed by a key code. Key codes can be decimal ` +
+      `or hexadecimal numbers, or a key identifier. Key actions can be ` +
+      `specified as a string to send to the host, or an action identifier. ` +
+      `For a full explanation of the format, see https://goo.gl/LWRndr.\n` +
+      `\n` +
+      `Sample keybindings:\n` +
+      `{\n` +
+      `  "Ctrl-Alt-K": "clearTerminal",\n` +
+      `  "Ctrl-Shift-L": "PASS",\n` +
+      `  "Ctrl-H": "'Hello World'"\n` +
+      `}`
+  ),
+
+  'media-keys-are-fkeys': hterm.PreferenceManager.definePref_(
+      'Media keys are Fkeys',
+      hterm.PreferenceManager.Categories.Keyboard,
+      false, 'bool',
+      `If true, convert media keys to their Fkey equivalent. If false, let ` +
+      `the browser handle the keys.`
+  ),
+
+  'meta-sends-escape': hterm.PreferenceManager.definePref_(
+      'Meta key modifier handling',
+      hterm.PreferenceManager.Categories.Keyboard,
+      true, 'bool',
+      `Send an ESC prefix when pressing a key while holding the Meta key.\n` +
+      `\n` +
+      `For example, when enabled, pressing Meta-K will send ^[k as if you ` +
+      `typed Escape then k. When disabled, only k will be sent.`
+  ),
+
+  'mouse-right-click-paste': hterm.PreferenceManager.definePref_(
+      'Mouse right clicks paste content',
+      hterm.PreferenceManager.Categories.CopyPaste,
+      true, 'bool',
+      `Paste on right mouse button clicks.\n` +
+      `\n` +
+      `This option is independent of the "mouse-paste-button" setting.\n` +
+      `\n` +
+      `Note: This will handle left & right handed mice correctly.`
+  ),
+
+  'mouse-paste-button': hterm.PreferenceManager.definePref_(
+      'Mouse button paste',
+      hterm.PreferenceManager.Categories.CopyPaste,
+      null, [null, 0, 1, 2, 3, 4, 5, 6],
+      `Mouse paste button, or null to autodetect.\n` +
+      `\n` +
+      `For autodetect, we'll use the middle mouse button for non-X11 ` +
+      `platforms (including Chrome OS). On X11, we'll use the right mouse ` +
+      `button (since the native window manager should paste via the middle ` +
+      `mouse button).\n` +
+      `\n` +
+      `0 == left (primary) button.\n` +
+      `1 == middle (auxiliary) button.\n` +
+      `2 == right (secondary) button.\n` +
+      `\n` +
+      `This option is independent of the setting for right-click paste.\n` +
+      `\n` +
+      `Note: This will handle left & right handed mice correctly.`
+  ),
+
+  'word-break-match-left': hterm.PreferenceManager.definePref_(
+      'Automatic selection halting (to the left)',
+      hterm.PreferenceManager.Categories.CopyPaste,
+      '[^\\s\\[\\](){}<>"\'\\^!@#$%&*,;:`]', 'string',
+      `Regular expression to halt matching to the left (start) of a ` +
+      `selection.\n` +
+      `\n` +
+      `Normally this is a character class to reject specific characters.\n` +
+      `We allow "~" and "." by default as paths frequently start with those.`
+  ),
+
+  'word-break-match-right': hterm.PreferenceManager.definePref_(
+      'Automatic selection halting (to the right)',
+      hterm.PreferenceManager.Categories.CopyPaste,
+      '[^\\s\\[\\](){}<>"\'\\^!@#$%&*,;:~.`]', 'string',
+      `Regular expression to halt matching to the right (end) of a ` +
+      `selection.\n` +
+      `\n` +
+      `Normally this is a character class to reject specific characters.`
+  ),
+
+  'word-break-match-middle': hterm.PreferenceManager.definePref_(
+      'Word break characters',
+      hterm.PreferenceManager.Categories.CopyPaste,
+      '[^\\s\\[\\](){}<>"\'\\^]*', 'string',
+      `Regular expression to match all the characters in the middle.\n` +
+      `\n` +
+      `Normally this is a character class to reject specific characters.\n` +
+      `\n` +
+      `Used to expand the selection surrounding the starting point.`
+  ),
+
+  'page-keys-scroll': hterm.PreferenceManager.definePref_(
+      'Page Up/Down key scroll behavior',
+      hterm.PreferenceManager.Categories.Keyboard,
+      false, 'bool',
+      `If true, Page Up/Page Down controls the terminal scrollbar and ` +
+      `Shift-Page Up/Shift-Page Down are sent to the remote host. If false, ` +
+      `then Page Up/Page Down are sent to the remote host and Shift-Page Up/` +
+      `Shift-Page Down scrolls.`
+  ),
+
+  'pass-alt-number': hterm.PreferenceManager.definePref_(
+      'Pass Alt-1..9 key behavior',
+      hterm.PreferenceManager.Categories.Keyboard,
+      null, 'tristate',
+      `Whether Alt-1..9 is passed to the browser.\n` +
+      `\n` +
+      `This is handy when running hterm in a browser tab, so that you don't ` +
+      `lose Chrome's "switch to tab" keyboard accelerators. When not running ` +
+      `in a tab it's better to send these keys to the host so they can be ` +
+      `used in vim or emacs.\n` +
+      `\n` +
+      `If true, Alt-1..9 will be handled by the browser. If false, Alt-1..9 ` +
+      `will be sent to the host. If null, autodetect based on browser ` +
+      `platform and window type.`
+  ),
+
+  'pass-ctrl-number': hterm.PreferenceManager.definePref_(
+      'Pass Ctrl-1..9 key behavior',
+      hterm.PreferenceManager.Categories.Keyboard,
+      null, 'tristate',
+      `Whether Ctrl-1..9 is passed to the browser.\n` +
+      `\n` +
+      `This is handy when running hterm in a browser tab, so that you don't ` +
+      `lose Chrome's "switch to tab" keyboard accelerators. When not running ` +
+      `in a tab it's better to send these keys to the host so they can be ` +
+      `used in vim or emacs.\n` +
+      `\n` +
+      `If true, Ctrl-1..9 will be handled by the browser. If false, ` +
+      `Ctrl-1..9 will be sent to the host. If null, autodetect based on ` +
+      `browser platform and window type.`
+  ),
+
+  'pass-meta-number': hterm.PreferenceManager.definePref_(
+      'Pass Meta-1..9 key behavior',
+      hterm.PreferenceManager.Categories.Keyboard,
+      null, 'tristate',
+      `Whether Meta-1..9 is passed to the browser.\n` +
+      `\n` +
+      `This is handy when running hterm in a browser tab, so that you don't ` +
+      `lose Chrome's "switch to tab" keyboard accelerators. When not running ` +
+      `in a tab it's better to send these keys to the host so they can be ` +
+      `used in vim or emacs.\n` +
+      `\n` +
+      `If true, Meta-1..9 will be handled by the browser. If false, ` +
+      `Meta-1..9 will be sent to the host. If null, autodetect based on ` +
+      `browser platform and window type.`
+  ),
+
+  'pass-meta-v': hterm.PreferenceManager.definePref_(
+      'Pass Meta-V key behavior',
+      hterm.PreferenceManager.Categories.Keyboard,
+      true, 'bool',
+      `Whether Meta-V gets passed to host.`
+  ),
+
+  'paste-on-drop': hterm.PreferenceManager.definePref_(
+      'Allow drag & drop to paste',
+      hterm.PreferenceManager.Categories.CopyPaste,
+      true, 'bool',
+      `If true, Drag and dropped text will paste into terminal.\n` +
+      `If false, dropped text will be ignored.`
+  ),
+
+  'receive-encoding': hterm.PreferenceManager.definePref_(
+      'Receive encoding',
+      hterm.PreferenceManager.Categories.Encoding,
+      'utf-8', ['utf-8', 'raw'],
+      `Set the expected encoding for data received from the host.\n` +
+      `If the encodings do not match, visual bugs are likely to be ` +
+      `observed.\n` +
+      `\n` +
+      `Valid values are 'utf-8' and 'raw'.`
+  ),
+
+  'scroll-on-keystroke': hterm.PreferenceManager.definePref_(
+      'Scroll to bottom after keystroke',
+      hterm.PreferenceManager.Categories.Scrolling,
+      true, 'bool',
+      `Whether to scroll to the bottom on any keystroke.`
+  ),
+
+  'scroll-on-output': hterm.PreferenceManager.definePref_(
+      'Scroll to bottom after new output',
+      hterm.PreferenceManager.Categories.Scrolling,
+      false, 'bool',
+      `Whether to scroll to the bottom on terminal output.`
+  ),
+
+  'scrollbar-visible': hterm.PreferenceManager.definePref_(
+      'Scrollbar visibility',
+      hterm.PreferenceManager.Categories.Scrolling,
+      true, 'bool',
+      `The vertical scrollbar mode.`
+  ),
+
+  'scroll-wheel-may-send-arrow-keys': hterm.PreferenceManager.definePref_(
+      'Emulate arrow keys with scroll wheel',
+      hterm.PreferenceManager.Categories.Scrolling,
+      false, 'bool',
+      `When using the alternative screen buffer, and DECCKM (Application ` +
+      `Cursor Keys) is active, mouse wheel scroll events will emulate arrow ` +
+      `keys.\n` +
+      `\n` +
+      `It can be temporarily disabled by holding the Shift key.\n` +
+      `\n` +
+      `This frequently comes up when using pagers (less) or reading man ` +
+      `pages or text editors (vi/nano) or using screen/tmux.`
+  ),
+
+  'scroll-wheel-move-multiplier': hterm.PreferenceManager.definePref_(
+      'Mouse scroll wheel multiplier',
+      hterm.PreferenceManager.Categories.Scrolling,
+      1, 'int',
+      `The multiplier for scroll wheel events when measured in pixels.\n` +
+      `\n` +
+      `Alters how fast the page scrolls.`
+  ),
+
+  'terminal-encoding': hterm.PreferenceManager.definePref_(
+      'Terminal encoding',
+      hterm.PreferenceManager.Categories.Encoding,
+      'utf-8', ['iso-2022', 'utf-8', 'utf-8-locked'],
+      `The default terminal encoding (DOCS).\n` +
+      `\n` +
+      `ISO-2022 enables character map translations (like graphics maps).\n` +
+      `UTF-8 disables support for those.\n` +
+      `\n` +
+      `The locked variant means the encoding cannot be changed at runtime ` +
+      `via terminal escape sequences.\n` +
+      `\n` +
+      `You should stick with UTF-8 unless you notice broken rendering with ` +
+      `legacy applications.`
+  ),
+
+  'shift-insert-paste': hterm.PreferenceManager.definePref_(
+      'Shift-Insert paste',
+      hterm.PreferenceManager.Categories.Keyboard,
+      true, 'bool',
+      `Whether Shift-Insert is used for pasting or is sent to the remote host.`
+  ),
+
+  'user-css': hterm.PreferenceManager.definePref_(
+      'Custom CSS (URI)',
+      hterm.PreferenceManager.Categories.Appearance,
+      '', 'url',
+      `URL of user stylesheet to include in the terminal document.`
+  ),
+
+  'user-css-text': hterm.PreferenceManager.definePref_(
+      'Custom CSS (inline text)',
+      hterm.PreferenceManager.Categories.Appearance,
+      '', 'multiline-string',
+      `Custom CSS text for styling the terminal.`
+  ),
+
+  'allow-images-inline': hterm.PreferenceManager.definePref_(
+      'Allow inline image display',
+      hterm.PreferenceManager.Categories.Extensions,
+      null, 'tristate',
+      `Whether to allow the remote host to display images in the terminal.\n` +
+      `\n` +
+      `By default, we prompt until a choice is made.`
+  ),
+};
+
+hterm.PreferenceManager.prototype =
+    Object.create(lib.PreferenceManager.prototype);
+/** @override */
+hterm.PreferenceManager.constructor = hterm.PreferenceManager;
+// SOURCE FILE: hterm/js/hterm_pubsub.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Utility class used to add publish/subscribe/unsubscribe functionality to
+ * an existing object.
+ *
+ * @constructor
+ */
+hterm.PubSub = function() {
+  this.observers_ = {};
+};
+
+/**
+ * Add publish, subscribe, and unsubscribe methods to an existing object.
+ *
+ * No other properties of the object are touched, so there is no need to
+ * worry about clashing private properties.
+ *
+ * @param {!Object} obj The object to add this behavior to.
+ */
+hterm.PubSub.addBehavior = function(obj) {
+  var pubsub = new hterm.PubSub();
+  for (var m in hterm.PubSub.prototype) {
+    obj[m] = hterm.PubSub.prototype[m].bind(pubsub);
+  }
+};
+
+/**
+ * Subscribe to be notified of messages about a subject.
+ *
+ * @param {string} subject The subject to subscribe to.
+ * @param {function(...)} callback The function to invoke for notifications.
+ */
+hterm.PubSub.prototype.subscribe = function(subject, callback) {
+  if (!(subject in this.observers_))
+    this.observers_[subject] = [];
+
+  this.observers_[subject].push(callback);
+};
+
+/**
+ * Unsubscribe from a subject.
+ *
+ * @param {string} subject The subject to unsubscribe from.
+ * @param {function(...)} callback A callback previously registered via
+ *     subscribe().
+ */
+hterm.PubSub.prototype.unsubscribe = function(subject, callback) {
+  var list = this.observers_[subject];
+  if (!list)
+    throw 'Invalid subject: ' + subject;
+
+  var i = list.indexOf(callback);
+  if (i < 0)
+    throw 'Not subscribed: ' + subject;
+
+  list.splice(i, 1);
+};
+
+/**
+ * Publish a message about a subject.
+ *
+ * Subscribers (and the optional final callback) are invoked asynchronously.
+ * This method will return before anyone is actually notified.
+ *
+ * @param {string} subject The subject to publish about.
+ * @param {?Object=} e An arbitrary object associated with this notification.
+ * @param {function(!Object)=} opt_lastCallback An optional function to call
+ *     after all subscribers have been notified.
+ */
+hterm.PubSub.prototype.publish = function(subject, e, opt_lastCallback) {
+  function notifyList(i) {
+    // Set this timeout before invoking the callback, so we don't have to
+    // concern ourselves with exceptions.
+    if (i < list.length - 1)
+      setTimeout(notifyList, 0, i + 1);
+
+    list[i](e);
+  }
+
+  var list = this.observers_[subject];
+  if (list) {
+    // Copy the list, in case it changes while we're notifying.
+    list = [].concat(list);
+  }
+
+  if (opt_lastCallback) {
+    if (list) {
+      list.push(opt_lastCallback);
+    } else {
+      list = [opt_lastCallback];
+    }
+  }
+
+  if (list)
+    setTimeout(notifyList, 0, 0);
+};
+// SOURCE FILE: hterm/js/hterm_screen.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview This class represents a single terminal screen full of text.
+ *
+ * It maintains the current cursor position and has basic methods for text
+ * insert and overwrite, and adding or removing rows from the screen.
+ *
+ * This class has no knowledge of the scrollback buffer.
+ *
+ * The number of rows on the screen is determined only by the number of rows
+ * that the caller inserts into the screen.  If a caller wants to ensure a
+ * constant number of rows on the screen, it's their responsibility to remove a
+ * row for each row inserted.
+ *
+ * The screen width, in contrast, is enforced locally.
+ *
+ *
+ * In practice...
+ * - The hterm.Terminal class holds two hterm.Screen instances.  One for the
+ * primary screen and one for the alternate screen.
+ *
+ * - The html.Screen class only cares that rows are HTML Elements.  In the
+ * larger context of hterm, however, the rows happen to be displayed by an
+ * hterm.ScrollPort and have to follow a few rules as a result.  Each
+ * row must be rooted by the custom HTML tag 'x-row', and each must have a
+ * rowIndex property that corresponds to the index of the row in the context
+ * of the scrollback buffer.  These invariants are enforced by hterm.Terminal
+ * because that is the class using the hterm.Screen in the context of an
+ * hterm.ScrollPort.
+ */
+
+/**
+ * Create a new screen instance.
+ *
+ * The screen initially has no rows and a maximum column count of 0.
+ *
+ * @param {number=} columnCount The maximum number of columns for this
+ *    screen.  See insertString() and overwriteString() for information about
+ *    what happens when too many characters are added too a row.  Defaults to
+ *    0 if not provided.
+ * @constructor
+ */
+hterm.Screen = function(columnCount=0) {
+  /**
+   * Public, read-only access to the rows in this screen.
+   *
+   * @type {!Array<!Element>}
+   */
+  this.rowsArray = [];
+
+  // The max column width for this screen.
+  this.columnCount_ = columnCount;
+
+  // The current color, bold, underline and blink attributes.
+  this.textAttributes = new hterm.TextAttributes(window.document);
+
+  // Current zero-based cursor coordinates.
+  this.cursorPosition = new hterm.RowCol(0, 0);
+
+  // Saved state used by DECSC and related settings.  This is only for saving
+  // and restoring specific state, not for the current/active state.
+  this.cursorState_ = new hterm.Screen.CursorState(this);
+
+  // The node containing the row that the cursor is positioned on.
+  this.cursorRowNode_ = null;
+
+  // The node containing the span of text that the cursor is positioned on.
+  this.cursorNode_ = null;
+
+  // The offset in column width into cursorNode_ where the cursor is positioned.
+  this.cursorOffset_ = 0;
+
+  // Regexes for expanding word selections.
+  /** @type {?string} */
+  this.wordBreakMatchLeft = null;
+  /** @type {?string} */
+  this.wordBreakMatchRight = null;
+  /** @type {?string} */
+  this.wordBreakMatchMiddle = null;
+};
+
+/**
+ * Return the screen size as an hterm.Size object.
+ *
+ * @return {!hterm.Size} hterm.Size object representing the current number
+ *     of rows and columns in this screen.
+ */
+hterm.Screen.prototype.getSize = function() {
+  return new hterm.Size(this.columnCount_, this.rowsArray.length);
+};
+
+/**
+ * Return the current number of rows in this screen.
+ *
+ * @return {number} The number of rows in this screen.
+ */
+hterm.Screen.prototype.getHeight = function() {
+  return this.rowsArray.length;
+};
+
+/**
+ * Return the current number of columns in this screen.
+ *
+ * @return {number} The number of columns in this screen.
+ */
+hterm.Screen.prototype.getWidth = function() {
+  return this.columnCount_;
+};
+
+/**
+ * Set the maximum number of columns per row.
+ *
+ * @param {number} count The maximum number of columns per row.
+ */
+hterm.Screen.prototype.setColumnCount = function(count) {
+  this.columnCount_ = count;
+
+  if (this.cursorPosition.column >= count)
+    this.setCursorPosition(this.cursorPosition.row, count - 1);
+};
+
+/**
+ * Remove the first row from the screen and return it.
+ *
+ * @return {!Element} The first row in this screen.
+ */
+hterm.Screen.prototype.shiftRow = function() {
+  return this.shiftRows(1)[0];
+};
+
+/**
+ * Remove rows from the top of the screen and return them as an array.
+ *
+ * @param {number} count The number of rows to remove.
+ * @return {!Array<!Element>} The selected rows.
+ */
+hterm.Screen.prototype.shiftRows = function(count) {
+  return this.rowsArray.splice(0, count);
+};
+
+/**
+ * Insert a row at the top of the screen.
+ *
+ * @param {!Element} row The row to insert.
+ */
+hterm.Screen.prototype.unshiftRow = function(row) {
+  this.rowsArray.splice(0, 0, row);
+};
+
+/**
+ * Insert rows at the top of the screen.
+ *
+ * @param {!Array<!Element>} rows The rows to insert.
+ */
+hterm.Screen.prototype.unshiftRows = function(rows) {
+  this.rowsArray.unshift.apply(this.rowsArray, rows);
+};
+
+/**
+ * Remove the last row from the screen and return it.
+ *
+ * @return {!Element} The last row in this screen.
+ */
+hterm.Screen.prototype.popRow = function() {
+  return this.popRows(1)[0];
+};
+
+/**
+ * Remove rows from the bottom of the screen and return them as an array.
+ *
+ * @param {number} count The number of rows to remove.
+ * @return {!Array<!Element>} The selected rows.
+ */
+hterm.Screen.prototype.popRows = function(count) {
+  return this.rowsArray.splice(this.rowsArray.length - count, count);
+};
+
+/**
+ * Insert a row at the bottom of the screen.
+ *
+ * @param {!Element} row The row to insert.
+ */
+hterm.Screen.prototype.pushRow = function(row) {
+  this.rowsArray.push(row);
+};
+
+/**
+ * Insert rows at the bottom of the screen.
+ *
+ * @param {!Array<!Element>} rows The rows to insert.
+ */
+hterm.Screen.prototype.pushRows = function(rows) {
+  rows.push.apply(this.rowsArray, rows);
+};
+
+/**
+ * Insert a row at the specified row of the screen.
+ *
+ * @param {number} index The index to insert the row.
+ * @param {!Element} row The row to insert.
+ */
+hterm.Screen.prototype.insertRow = function(index, row) {
+  this.rowsArray.splice(index, 0, row);
+};
+
+/**
+ * Insert rows at the specified row of the screen.
+ *
+ * @param {number} index The index to insert the rows.
+ * @param {!Array<!Element>} rows The rows to insert.
+ */
+hterm.Screen.prototype.insertRows = function(index, rows) {
+  for (var i = 0; i < rows.length; i++) {
+    this.rowsArray.splice(index + i, 0, rows[i]);
+  }
+};
+
+/**
+ * Remove a row from the screen and return it.
+ *
+ * @param {number} index The index of the row to remove.
+ * @return {!Element} The selected row.
+ */
+hterm.Screen.prototype.removeRow = function(index) {
+  return this.rowsArray.splice(index, 1)[0];
+};
+
+/**
+ * Remove rows from the bottom of the screen and return them as an array.
+ *
+ * @param {number} index The index to start removing rows.
+ * @param {number} count The number of rows to remove.
+ * @return {!Array<!Element>} The selected rows.
+ */
+hterm.Screen.prototype.removeRows = function(index, count) {
+  return this.rowsArray.splice(index, count);
+};
+
+/**
+ * Invalidate the current cursor position.
+ *
+ * This sets this.cursorPosition to (0, 0) and clears out some internal
+ * data.
+ *
+ * Attempting to insert or overwrite text while the cursor position is invalid
+ * will raise an obscure exception.
+ */
+hterm.Screen.prototype.invalidateCursorPosition = function() {
+  this.cursorPosition.move(0, 0);
+  this.cursorRowNode_ = null;
+  this.cursorNode_ = null;
+  this.cursorOffset_ = 0;
+};
+
+/**
+ * Clear the contents of the cursor row.
+ */
+hterm.Screen.prototype.clearCursorRow = function() {
+  this.cursorRowNode_.innerHTML = '';
+  this.cursorRowNode_.removeAttribute('line-overflow');
+  this.cursorOffset_ = 0;
+  this.cursorPosition.column = 0;
+  this.cursorPosition.overflow = false;
+
+  var text;
+  if (this.textAttributes.isDefault()) {
+    text = '';
+  } else {
+    text = ' '.repeat(this.columnCount_);
+  }
+
+  // We shouldn't honor inverse colors when clearing an area, to match
+  // xterm's back color erase behavior.
+  var inverse = this.textAttributes.inverse;
+  this.textAttributes.inverse = false;
+  this.textAttributes.syncColors();
+
+  var node = this.textAttributes.createContainer(text);
+  this.cursorRowNode_.appendChild(node);
+  this.cursorNode_ = node;
+
+  this.textAttributes.inverse = inverse;
+  this.textAttributes.syncColors();
+};
+
+/**
+ * Mark the current row as having overflowed to the next line.
+ *
+ * The line overflow state is used when converting a range of rows into text.
+ * It makes it possible to recombine two or more overflow terminal rows into
+ * a single line.
+ *
+ * This is distinct from the cursor being in the overflow state.  Cursor
+ * overflow indicates that printing at the cursor position will commit a
+ * line overflow, unless it is preceded by a repositioning of the cursor
+ * to a non-overflow state.
+ */
+hterm.Screen.prototype.commitLineOverflow = function() {
+  this.cursorRowNode_.setAttribute('line-overflow', true);
+};
+
+/**
+ * Relocate the cursor to a give row and column.
+ *
+ * @param {number} row The zero based row.
+ * @param {number} column The zero based column.
+ */
+hterm.Screen.prototype.setCursorPosition = function(row, column) {
+  if (!this.rowsArray.length) {
+    console.warn('Attempt to set cursor position on empty screen.');
+    return;
+  }
+
+  if (row >= this.rowsArray.length) {
+    console.error('Row out of bounds: ' + row);
+    row = this.rowsArray.length - 1;
+  } else if (row < 0) {
+    console.error('Row out of bounds: ' + row);
+    row = 0;
+  }
+
+  if (column >= this.columnCount_) {
+    console.error('Column out of bounds: ' + column);
+    column = this.columnCount_ - 1;
+  } else if (column < 0) {
+    console.error('Column out of bounds: ' + column);
+    column = 0;
+  }
+
+  this.cursorPosition.overflow = false;
+
+  var rowNode = this.rowsArray[row];
+  var node = rowNode.firstChild;
+
+  if (!node) {
+    node = rowNode.ownerDocument.createTextNode('');
+    rowNode.appendChild(node);
+  }
+
+  var currentColumn = 0;
+
+  if (rowNode == this.cursorRowNode_) {
+    if (column >= this.cursorPosition.column - this.cursorOffset_) {
+      node = this.cursorNode_;
+      currentColumn = this.cursorPosition.column - this.cursorOffset_;
+    }
+  } else {
+    this.cursorRowNode_ = rowNode;
+  }
+
+  this.cursorPosition.move(row, column);
+
+  while (node) {
+    var offset = column - currentColumn;
+    var width = hterm.TextAttributes.nodeWidth(node);
+    if (!node.nextSibling || width > offset) {
+      this.cursorNode_ = node;
+      this.cursorOffset_ = offset;
+      return;
+    }
+
+    currentColumn += width;
+    node = node.nextSibling;
+  }
+};
+
+/**
+ * Set the provided selection object to be a caret selection at the current
+ * cursor position.
+ *
+ * @param {!Selection} selection
+ */
+hterm.Screen.prototype.syncSelectionCaret = function(selection) {
+  try {
+    selection.collapse(this.cursorNode_, this.cursorOffset_);
+  } catch (firefoxIgnoredException) {
+    // FF can throw an exception if the range is off, rather than just not
+    // performing the collapse.
+  }
+};
+
+/**
+ * Split a single node into two nodes at the given offset.
+ *
+ * For example:
+ * Given the DOM fragment '<div><span>Hello World</span></div>', call splitNode_
+ * passing the span and an offset of 6.  This would modify the fragment to
+ * become: '<div><span>Hello </span><span>World</span></div>'.  If the span
+ * had any attributes they would have been copied to the new span as well.
+ *
+ * The to-be-split node must have a container, so that the new node can be
+ * placed next to it.
+ *
+ * @param {!Node} node The node to split.
+ * @param {number} offset The offset into the node where the split should
+ *     occur.
+ */
+hterm.Screen.prototype.splitNode_ = function(node, offset) {
+  var afterNode = node.cloneNode(false);
+
+  var textContent = node.textContent;
+  node.textContent = hterm.TextAttributes.nodeSubstr(node, 0, offset);
+  afterNode.textContent = lib.wc.substr(textContent, offset);
+
+  if (afterNode.textContent)
+    node.parentNode.insertBefore(afterNode, node.nextSibling);
+  if (!node.textContent)
+    node.parentNode.removeChild(node);
+};
+
+/**
+ * Ensure that text is clipped and the cursor is clamped to the column count.
+ */
+hterm.Screen.prototype.maybeClipCurrentRow = function() {
+  var width = hterm.TextAttributes.nodeWidth(lib.notNull(this.cursorRowNode_));
+
+  if (width <= this.columnCount_) {
+    // Current row does not need clipping, but may need clamping.
+    if (this.cursorPosition.column >= this.columnCount_) {
+      this.setCursorPosition(this.cursorPosition.row, this.columnCount_ - 1);
+      this.cursorPosition.overflow = true;
+    }
+
+    return;
+  }
+
+  // Save off the current column so we can maybe restore it later.
+  var currentColumn = this.cursorPosition.column;
+
+  // Move the cursor to the final column.
+  this.setCursorPosition(this.cursorPosition.row, this.columnCount_ - 1);
+
+  // Remove any text that partially overflows.
+  width = hterm.TextAttributes.nodeWidth(lib.notNull(this.cursorNode_));
+
+  if (this.cursorOffset_ < width - 1) {
+    this.cursorNode_.textContent = hterm.TextAttributes.nodeSubstr(
+        this.cursorNode_, 0, this.cursorOffset_ + 1);
+  }
+
+  // Remove all nodes after the cursor.
+  var rowNode = this.cursorRowNode_;
+  var node = this.cursorNode_.nextSibling;
+
+  while (node) {
+    rowNode.removeChild(node);
+    node = this.cursorNode_.nextSibling;
+  }
+
+  if (currentColumn < this.columnCount_) {
+    // If the cursor was within the screen before we started then restore its
+    // position.
+    this.setCursorPosition(this.cursorPosition.row, currentColumn);
+  } else {
+    // Otherwise leave it at the the last column in the overflow state.
+    this.cursorPosition.overflow = true;
+  }
+};
+
+/**
+ * Insert a string at the current character position using the current
+ * text attributes.
+ *
+ * You must call maybeClipCurrentRow() after in order to clip overflowed
+ * text and clamp the cursor.
+ *
+ * It is also up to the caller to properly maintain the line overflow state
+ * using hterm.Screen..commitLineOverflow().
+ *
+ * @param {string} str The string to insert.
+ * @param {number=} wcwidth The cached lib.wc.strWidth value for |str|.  Will be
+ *     calculated on demand if need be.  Passing in a cached value helps speed
+ *     up processing as this is a hot codepath.
+ */
+hterm.Screen.prototype.insertString = function(str, wcwidth=undefined) {
+  var cursorNode = this.cursorNode_;
+  var cursorNodeText = cursorNode.textContent;
+
+  this.cursorRowNode_.removeAttribute('line-overflow');
+
+  // We may alter the width of the string by prepending some missing
+  // whitespaces, so we need to record the string width ahead of time.
+  if (wcwidth === undefined)
+    wcwidth = lib.wc.strWidth(str);
+
+  // No matter what, before this function exits the cursor column will have
+  // moved this much.
+  this.cursorPosition.column += wcwidth;
+
+  // Local cache of the cursor offset.
+  var offset = this.cursorOffset_;
+
+  // Reverse offset is the offset measured from the end of the string.
+  // Zero implies that the cursor is at the end of the cursor node.
+  var reverseOffset = hterm.TextAttributes.nodeWidth(cursorNode) - offset;
+
+  if (reverseOffset < 0) {
+    // A negative reverse offset means the cursor is positioned past the end
+    // of the characters on this line.  We'll need to insert the missing
+    // whitespace.
+    const ws = ' '.repeat(-reverseOffset);
+
+    // This whitespace should be completely unstyled.  Underline, background
+    // color, and strikethrough would be visible on whitespace, so we can't use
+    // one of those spans to hold the text.
+    if (!(this.textAttributes.underline ||
+          this.textAttributes.strikethrough ||
+          this.textAttributes.background ||
+          this.textAttributes.wcNode ||
+          !this.textAttributes.asciiNode ||
+          this.textAttributes.tileData != null)) {
+      // Best case scenario, we can just pretend the spaces were part of the
+      // original string.
+      str = ws + str;
+    } else if (cursorNode.nodeType == Node.TEXT_NODE ||
+               !(cursorNode.wcNode ||
+                 !cursorNode.asciiNode ||
+                 cursorNode.tileNode ||
+                 cursorNode.style.textDecoration ||
+                 cursorNode.style.textDecorationStyle ||
+                 cursorNode.style.textDecorationLine ||
+                 cursorNode.style.backgroundColor)) {
+      // Second best case, the current node is able to hold the whitespace.
+      cursorNode.textContent = (cursorNodeText += ws);
+    } else {
+      // Worst case, we have to create a new node to hold the whitespace.
+      var wsNode = cursorNode.ownerDocument.createTextNode(ws);
+      this.cursorRowNode_.insertBefore(wsNode, cursorNode.nextSibling);
+      this.cursorNode_ = cursorNode = wsNode;
+      this.cursorOffset_ = offset = -reverseOffset;
+      cursorNodeText = ws;
+    }
+
+    // We now know for sure that we're at the last character of the cursor node.
+    reverseOffset = 0;
+  }
+
+  if (this.textAttributes.matchesContainer(cursorNode)) {
+    // The new text can be placed directly in the cursor node.
+    if (reverseOffset == 0) {
+      cursorNode.textContent = cursorNodeText + str;
+    } else if (offset == 0) {
+      cursorNode.textContent = str + cursorNodeText;
+    } else {
+      cursorNode.textContent =
+          hterm.TextAttributes.nodeSubstr(cursorNode, 0, offset) +
+          str + hterm.TextAttributes.nodeSubstr(cursorNode, offset);
+    }
+
+    this.cursorOffset_ += wcwidth;
+    return;
+  }
+
+  // The cursor node is the wrong style for the new text.  If we're at the
+  // beginning or end of the cursor node, then the adjacent node is also a
+  // potential candidate.
+
+  if (offset == 0) {
+    // At the beginning of the cursor node, the check the previous sibling.
+    var previousSibling = cursorNode.previousSibling;
+    if (previousSibling &&
+        this.textAttributes.matchesContainer(previousSibling)) {
+      previousSibling.textContent += str;
+      this.cursorNode_ = previousSibling;
+      this.cursorOffset_ = lib.wc.strWidth(previousSibling.textContent);
+      return;
+    }
+
+    var newNode = this.textAttributes.createContainer(str);
+    this.cursorRowNode_.insertBefore(newNode, cursorNode);
+    this.cursorNode_ = newNode;
+    this.cursorOffset_ = wcwidth;
+    return;
+  }
+
+  if (reverseOffset == 0) {
+    // At the end of the cursor node, the check the next sibling.
+    var nextSibling = cursorNode.nextSibling;
+    if (nextSibling &&
+        this.textAttributes.matchesContainer(nextSibling)) {
+      nextSibling.textContent = str + nextSibling.textContent;
+      this.cursorNode_ = nextSibling;
+      this.cursorOffset_ = lib.wc.strWidth(str);
+      return;
+    }
+
+    var newNode = this.textAttributes.createContainer(str);
+    this.cursorRowNode_.insertBefore(newNode, nextSibling);
+    this.cursorNode_ = newNode;
+    // We specifically need to include any missing whitespace here, since it's
+    // going in a new node.
+    this.cursorOffset_ = hterm.TextAttributes.nodeWidth(newNode);
+    return;
+  }
+
+  // Worst case, we're somewhere in the middle of the cursor node.  We'll
+  // have to split it into two nodes and insert our new container in between.
+  this.splitNode_(cursorNode, offset);
+  var newNode = this.textAttributes.createContainer(str);
+  this.cursorRowNode_.insertBefore(newNode, cursorNode.nextSibling);
+  this.cursorNode_ = newNode;
+  this.cursorOffset_ = wcwidth;
+};
+
+/**
+ * Overwrite the text at the current cursor position.
+ *
+ * You must call maybeClipCurrentRow() after in order to clip overflowed
+ * text and clamp the cursor.
+ *
+ * It is also up to the caller to properly maintain the line overflow state
+ * using hterm.Screen..commitLineOverflow().
+ *
+ * @param {string} str The source string for overwriting existing content.
+ * @param {number=} wcwidth The cached lib.wc.strWidth value for |str|.  Will be
+ *     calculated on demand if need be.  Passing in a cached value helps speed
+ *     up processing as this is a hot codepath.
+ */
+hterm.Screen.prototype.overwriteString = function(str, wcwidth=undefined) {
+  var maxLength = this.columnCount_ - this.cursorPosition.column;
+  if (!maxLength)
+    return;
+
+  if (wcwidth === undefined)
+    wcwidth = lib.wc.strWidth(str);
+
+  if (this.textAttributes.matchesContainer(lib.notNull(this.cursorNode_)) &&
+      this.cursorNode_.textContent.substr(this.cursorOffset_) ==
+          str) {
+    // This overwrite would be a no-op, just move the cursor and return.
+    this.cursorOffset_ += wcwidth;
+    this.cursorPosition.column += wcwidth;
+    return;
+  }
+
+  this.deleteChars(Math.min(wcwidth, maxLength));
+  this.insertString(str, wcwidth);
+};
+
+/**
+ * Forward-delete one or more characters at the current cursor position.
+ *
+ * Text to the right of the deleted characters is shifted left.  Only affects
+ * characters on the same row as the cursor.
+ *
+ * @param {number} count The column width of characters to delete.  This is
+ *     clamped to the column width minus the cursor column.
+ * @return {number} The column width of the characters actually deleted.
+ */
+hterm.Screen.prototype.deleteChars = function(count) {
+  var node = this.cursorNode_;
+  var offset = this.cursorOffset_;
+
+  var currentCursorColumn = this.cursorPosition.column;
+  count = Math.min(count, this.columnCount_ - currentCursorColumn);
+  if (!count)
+    return 0;
+
+  var rv = count;
+  var startLength, endLength;
+
+  while (node && count) {
+    // Sanity check so we don't loop forever, but we don't also go quietly.
+    if (count < 0) {
+      console.error(`Deleting ${rv} chars went negative: ${count}`);
+      break;
+    }
+
+    startLength = hterm.TextAttributes.nodeWidth(node);
+    node.textContent = hterm.TextAttributes.nodeSubstr(node, 0, offset) +
+        hterm.TextAttributes.nodeSubstr(node, offset + count);
+    endLength = hterm.TextAttributes.nodeWidth(node);
+
+    // Deal with splitting wide characters.  There are two ways: we could delete
+    // the first column or the second column.  In both cases, we delete the wide
+    // character and replace one of the columns with a space (since the other
+    // was deleted).  If there are more chars to delete, the next loop will pick
+    // up the slack.
+    if (node.wcNode && offset < startLength &&
+        ((endLength && startLength == endLength) ||
+         (!endLength && offset == 1))) {
+      // No characters were deleted when there should be.  We're probably trying
+      // to delete one column width from a wide character node.  We remove the
+      // wide character node here and replace it with a single space.
+      var spaceNode = this.textAttributes.createContainer(' ');
+      node.parentNode.insertBefore(spaceNode, offset ? node : node.nextSibling);
+      node.textContent = '';
+      endLength = 0;
+      count -= 1;
+    } else
+      count -= startLength - endLength;
+
+    var nextNode = node.nextSibling;
+    if (endLength == 0 && node != this.cursorNode_) {
+      node.parentNode.removeChild(node);
+    }
+    node = nextNode;
+    offset = 0;
+  }
+
+  // Remove this.cursorNode_ if it is an empty non-text node.
+  if (this.cursorNode_.nodeType != Node.TEXT_NODE &&
+      !this.cursorNode_.textContent) {
+    var cursorNode = this.cursorNode_;
+    if (cursorNode.previousSibling) {
+      this.cursorNode_ = cursorNode.previousSibling;
+      this.cursorOffset_ = hterm.TextAttributes.nodeWidth(
+          cursorNode.previousSibling);
+    } else if (cursorNode.nextSibling) {
+      this.cursorNode_ = cursorNode.nextSibling;
+      this.cursorOffset_ = 0;
+    } else {
+      var emptyNode = this.cursorRowNode_.ownerDocument.createTextNode('');
+      this.cursorRowNode_.appendChild(emptyNode);
+      this.cursorNode_ = emptyNode;
+      this.cursorOffset_ = 0;
+    }
+    this.cursorRowNode_.removeChild(cursorNode);
+  }
+
+  return rv;
+};
+
+/**
+ * Finds first X-ROW of a line containing specified X-ROW.
+ * Used to support line overflow.
+ *
+ * @param {!Node} row X-ROW to begin search for first row of line.
+ * @return {!Node} The X-ROW that is at the beginning of the line.
+ **/
+hterm.Screen.prototype.getLineStartRow_ = function(row) {
+  while (row.previousSibling &&
+         row.previousSibling.hasAttribute('line-overflow')) {
+    row = row.previousSibling;
+  }
+  return row;
+};
+
+/**
+ * Gets text of a line beginning with row.
+ * Supports line overflow.
+ *
+ * @param {!Node} row First X-ROW of line.
+ * @return {string} Text content of line.
+ **/
+hterm.Screen.prototype.getLineText_ = function(row) {
+  let rowText = '';
+  let rowOrNull = row;
+  while (rowOrNull) {
+    rowText += rowOrNull.textContent;
+    if (rowOrNull.hasAttribute('line-overflow')) {
+      rowOrNull = rowOrNull.nextSibling;
+    } else {
+      break;
+    }
+  }
+  return rowText;
+};
+
+/**
+ * Returns X-ROW that is ancestor of the node.
+ *
+ * @param {!Node} node Node to get X-ROW ancestor for.
+ * @return {?Node} X-ROW ancestor of node, or null if not found.
+ **/
+hterm.Screen.prototype.getXRowAncestor_ = function(node) {
+  let nodeOrNull = node;
+  while (nodeOrNull) {
+    if (nodeOrNull.nodeName === 'X-ROW')
+      break;
+    nodeOrNull = nodeOrNull.parentNode;
+  }
+  return nodeOrNull;
+};
+
+/**
+ * Returns position within line of character at offset within node.
+ * Supports line overflow.
+ *
+ * @param {!Node} row X-ROW at beginning of line.
+ * @param {!Node} node Node to get position of.
+ * @param {number} offset Offset into node.
+ * @return {number} Position within line of character at offset within node.
+ **/
+hterm.Screen.prototype.getPositionWithOverflow_ = function(row, node, offset) {
+  if (!node)
+    return -1;
+  var ancestorRow = this.getXRowAncestor_(node);
+  if (!ancestorRow)
+    return -1;
+  var position = 0;
+  while (ancestorRow != row) {
+    position += hterm.TextAttributes.nodeWidth(row);
+    if (row.hasAttribute('line-overflow') && row.nextSibling) {
+      row = row.nextSibling;
+    } else {
+      return -1;
+    }
+  }
+  return position + this.getPositionWithinRow_(row, node, offset);
+};
+
+/**
+ * Returns position within row of character at offset within node.
+ * Does not support line overflow.
+ *
+ * @param {!Node} row X-ROW to get position within.
+ * @param {!Node} node Node to get position for.
+ * @param {number} offset Offset within node to get position for.
+ * @return {number} Position within row of character at offset within node.
+ **/
+hterm.Screen.prototype.getPositionWithinRow_ = function(row, node, offset) {
+  if (node.parentNode != row) {
+    // If we traversed to the top node, then there's nothing to find here.
+    if (node.parentNode == null)
+      return -1;
+
+    return this.getPositionWithinRow_(node.parentNode, node, offset) +
+           this.getPositionWithinRow_(row, node.parentNode, 0);
+  }
+  var position = 0;
+  for (var i = 0; i < row.childNodes.length; i++) {
+    var currentNode = row.childNodes[i];
+    if (currentNode == node)
+      return position + offset;
+    position += hterm.TextAttributes.nodeWidth(currentNode);
+  }
+  return -1;
+};
+
+/**
+ * Returns the node and offset corresponding to position within line.
+ * Supports line overflow.
+ *
+ * @param {!Node} row X-ROW at beginning of line.
+ * @param {number} position Position within line to retrieve node and offset.
+ * @return {?Array} Two element array containing node and offset respectively.
+ **/
+hterm.Screen.prototype.getNodeAndOffsetWithOverflow_ = function(row, position) {
+  while (row && position > hterm.TextAttributes.nodeWidth(row)) {
+    if (row.hasAttribute('line-overflow') && row.nextSibling) {
+      position -= hterm.TextAttributes.nodeWidth(row);
+      row = row.nextSibling;
+    } else {
+      return [null, -1];
+    }
+  }
+  return this.getNodeAndOffsetWithinRow_(row, position);
+};
+
+/**
+ * Returns the node and offset corresponding to position within row.
+ * Does not support line overflow.
+ *
+ * @param {!Node} row X-ROW to get position within.
+ * @param {number} position Position within row to retrieve node and offset.
+ * @return {?Array} Two element array containing node and offset respectively.
+ **/
+hterm.Screen.prototype.getNodeAndOffsetWithinRow_ = function(row, position) {
+  for (var i = 0; i < row.childNodes.length; i++) {
+    var node = row.childNodes[i];
+    var nodeTextWidth = hterm.TextAttributes.nodeWidth(node);
+    if (position <= nodeTextWidth) {
+      if (node.nodeName === 'SPAN') {
+        /** Drill down to node contained by SPAN. **/
+        return this.getNodeAndOffsetWithinRow_(node, position);
+      } else {
+        return [node, position];
+      }
+    }
+    position -= nodeTextWidth;
+  }
+  return null;
+};
+
+/**
+ * Returns the node and offset corresponding to position within line.
+ * Supports line overflow.
+ *
+ * @param {!Node} row X-ROW at beginning of line.
+ * @param {number} start Start position of range within line.
+ * @param {number} end End position of range within line.
+ * @param {!Range} range Range to modify.
+ **/
+hterm.Screen.prototype.setRange_ = function(row, start, end, range) {
+  var startNodeAndOffset = this.getNodeAndOffsetWithOverflow_(row, start);
+  if (startNodeAndOffset == null)
+    return;
+  var endNodeAndOffset = this.getNodeAndOffsetWithOverflow_(row, end);
+  if (endNodeAndOffset == null)
+    return;
+  range.setStart(startNodeAndOffset[0], startNodeAndOffset[1]);
+  range.setEnd(endNodeAndOffset[0], endNodeAndOffset[1]);
+};
+
+/**
+ * Expands selection to surrounding string with word break matches.
+ *
+ * @param {?Selection} selection Selection to expand.
+ * @param {string} leftMatch left word break match.
+ * @param {string} rightMatch right word break match.
+ * @param {string} insideMatch inside word break match.
+ */
+hterm.Screen.prototype.expandSelectionWithWordBreakMatches_ =
+    function(selection, leftMatch, rightMatch, insideMatch) {
+  if (!selection)
+    return;
+
+  var range = selection.getRangeAt(0);
+  if (!range || range.toString().match(/\s/))
+    return;
+
+  const rowElement = this.getXRowAncestor_(lib.notNull(range.startContainer));
+  if (!rowElement)
+    return;
+  const row = this.getLineStartRow_(rowElement);
+  if (!row)
+    return;
+
+  var startPosition = this.getPositionWithOverflow_(
+      row, lib.notNull(range.startContainer), range.startOffset);
+  if (startPosition == -1)
+    return;
+  var endPosition = this.getPositionWithOverflow_(
+      row, lib.notNull(range.endContainer), range.endOffset);
+  if (endPosition == -1)
+    return;
+
+  //Move start to the left.
+  var rowText = this.getLineText_(row);
+  var lineUpToRange = lib.wc.substring(rowText, 0, endPosition);
+  var leftRegularExpression = new RegExp(leftMatch + insideMatch + "$");
+  var expandedStart = lineUpToRange.search(leftRegularExpression);
+  if (expandedStart == -1 || expandedStart > startPosition)
+    return;
+
+  //Move end to the right.
+  var lineFromRange = lib.wc.substring(rowText, startPosition,
+                                       lib.wc.strWidth(rowText));
+  var rightRegularExpression = new RegExp("^" + insideMatch + rightMatch);
+  var found = lineFromRange.match(rightRegularExpression);
+  if (!found)
+    return;
+  var expandedEnd = startPosition + lib.wc.strWidth(found[0]);
+  if (expandedEnd == -1 || expandedEnd < endPosition)
+    return;
+
+  this.setRange_(row, expandedStart, expandedEnd, range);
+  selection.addRange(range);
+};
+
+/**
+ * Expands selection to surrounding string using the user's settings.
+ *
+ * @param {?Selection} selection Selection to expand.
+ */
+hterm.Screen.prototype.expandSelection = function(selection) {
+  this.expandSelectionWithWordBreakMatches_(
+      selection,
+      lib.notNull(this.wordBreakMatchLeft),
+      lib.notNull(this.wordBreakMatchRight),
+      lib.notNull(this.wordBreakMatchMiddle));
+};
+
+/**
+ * Expands selection to surrounding URL using a set of fixed match settings.
+ *
+ * @param {?Selection} selection Selection to expand.
+ */
+hterm.Screen.prototype.expandSelectionForUrl = function(selection) {
+  this.expandSelectionWithWordBreakMatches_(
+      selection,
+      "[^\\s\\[\\](){}<>\"'\\^!@#$%&*,;:`]",
+      "[^\\s\\[\\](){}<>\"'\\^!@#$%&*,;:~.`]",
+      "[^\\s\\[\\](){}<>\"'\\^]*");
+};
+
+/**
+ * Save the current cursor state to the corresponding screens.
+ *
+ * @param {!hterm.VT} vt The VT object to read graphic codeset details from.
+ */
+hterm.Screen.prototype.saveCursorAndState = function(vt) {
+  this.cursorState_.save(vt);
+};
+
+/**
+ * Restore the saved cursor state in the corresponding screens.
+ *
+ * @param {!hterm.VT} vt The VT object to write graphic codeset details to.
+ */
+hterm.Screen.prototype.restoreCursorAndState = function(vt) {
+  this.cursorState_.restore(vt);
+};
+
+/**
+ * Track all the things related to the current "cursor".
+ *
+ * The set of things saved & restored here is defined by DEC:
+ * https://vt100.net/docs/vt510-rm/DECSC.html
+ * - Cursor position
+ * - Character attributes set by the SGR command
+ * - Character sets (G0, G1, G2, or G3) currently in GL and GR
+ * - Wrap flag (autowrap or no autowrap)
+ * - State of origin mode (DECOM)
+ * - Selective erase attribute
+ * - Any single shift 2 (SS2) or single shift 3 (SS3) functions sent
+ *
+ * These are done on a per-screen basis.
+ *
+ * @param {!hterm.Screen} screen The screen this cursor is tied to.
+ * @constructor
+ */
+hterm.Screen.CursorState = function(screen) {
+  this.screen_ = screen;
+  this.cursor = null;
+  this.textAttributes = null;
+  this.GL = this.GR = this.G0 = this.G1 = this.G2 = this.G3 = null;
+};
+
+/**
+ * Save all the cursor state.
+ *
+ * @param {!hterm.VT} vt The VT object to read graphic codeset details from.
+ */
+hterm.Screen.CursorState.prototype.save = function(vt) {
+  this.cursor = vt.terminal.saveCursor();
+
+  this.textAttributes = this.screen_.textAttributes.clone();
+
+  this.GL = vt.GL;
+  this.GR = vt.GR;
+
+  this.G0 = vt.G0;
+  this.G1 = vt.G1;
+  this.G2 = vt.G2;
+  this.G3 = vt.G3;
+};
+
+/**
+ * Restore the previously saved cursor state.
+ *
+ * @param {!hterm.VT} vt The VT object to write graphic codeset details to.
+ */
+hterm.Screen.CursorState.prototype.restore = function(vt) {
+  vt.terminal.restoreCursor(this.cursor);
+
+  // Cursor restore includes char attributes (bold/etc...), but does not change
+  // the color palette (which are a terminal setting).
+  const tattrs = this.textAttributes.clone();
+  tattrs.colorPalette = this.screen_.textAttributes.colorPalette;
+  tattrs.syncColors();
+
+  this.screen_.textAttributes = tattrs;
+
+  vt.GL = this.GL;
+  vt.GR = this.GR;
+
+  vt.G0 = this.G0;
+  vt.G1 = this.G1;
+  vt.G2 = this.G2;
+  vt.G3 = this.G3;
+};
+// SOURCE FILE: hterm/js/hterm_scrollport.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * The RowProvider should return rows rooted by the custom tag name 'x-row'.
+ * This ensures that we can quickly assign the correct display height
+ * to the rows with css.
+ *
+ * @interface
+ */
+hterm.RowProvider = function() {};
+
+/**
+ * @abstract
+ * @return {number} The current number of rows.
+ */
+hterm.RowProvider.prototype.getRowCount = function() {};
+
+/**
+ * Get specified row.
+ *
+ * @abstract
+ * @param {number} index The index of the row.
+ * @return {!Element}
+ */
+hterm.RowProvider.prototype.getRowNode = function(index) {};
+
+/**
+ * A 'viewport' view of fixed-height rows with support for selection and
+ * copy-to-clipboard.
+ *
+ * 'Viewport' in this case means that only the visible rows are in the DOM.
+ * If the rowProvider has 100,000 rows, but the ScrollPort is only 25 rows
+ * tall, then only 25 dom nodes are created.  The ScrollPort will ask the
+ * RowProvider to create new visible rows on demand as they are scrolled in
+ * to the visible area.
+ *
+ * This viewport is designed so that select and copy-to-clipboard still works,
+ * even when all or part of the selection is scrolled off screen.
+ *
+ * Note that the X11 mouse clipboard does not work properly when all or part
+ * of the selection is off screen.  It would be difficult to fix this without
+ * adding significant overhead to pathologically large selection cases.
+ *
+ * @param {!hterm.RowProvider} rowProvider An object capable of providing rows
+ *     as raw text or row nodes.
+ * @constructor
+ * @extends {hterm.PubSub}
+ */
+hterm.ScrollPort = function(rowProvider) {
+  hterm.PubSub.addBehavior(this);
+
+  this.rowProvider_ = rowProvider;
+
+  // SWAG the character size until we can measure it.
+  this.characterSize = new hterm.Size(10, 10);
+
+  // DOM node used for character measurement.
+  this.ruler_ = null;
+
+  this.selection = new hterm.ScrollPort.Selection(this);
+
+  // A map of rowIndex => rowNode for each row that is drawn as part of a
+  // pending redraw_() call.  Null if there is no pending redraw_ call.
+  this.currentRowNodeCache_ = null;
+
+  // A map of rowIndex => rowNode for each row that was drawn as part of the
+  // previous redraw_() call.
+  this.previousRowNodeCache_ = {};
+
+  // Used during scroll events to detect when the underlying cause is a resize.
+  this.lastScreenWidth_ = null;
+  this.lastScreenHeight_ = null;
+
+  // True if the user should be allowed to select text in the terminal.
+  // This is disabled when the host requests mouse drag events so that we don't
+  // end up with two notions of selection.
+  this.selectionEnabled_ = true;
+
+  // The last row count returned by the row provider, re-populated during
+  // syncScrollHeight().
+  this.lastRowCount_ = 0;
+
+  // The scroll wheel pixel delta multiplier to increase/decrease
+  // the scroll speed of mouse wheel events. See: https://goo.gl/sXelnq
+  this.scrollWheelMultiplier_ = 1;
+
+  // The last touch events we saw to support touch based scrolling.  Indexed
+  // by touch identifier since we can have more than one touch active.
+  this.lastTouch_ = {};
+
+  /**
+   * True if the last scroll caused the scrollport to show the final row.
+   */
+  this.isScrolledEnd = true;
+
+  /**
+   * A guess at the current scrollbar width, fixed in resize().
+   */
+  this.currentScrollbarWidthPx = 16;
+
+  /**
+   * Whether the ctrl-v key on the screen should paste.
+   */
+  this.ctrlVPaste = false;
+
+  /**
+   * Whether to paste on dropped text.
+   */
+  this.pasteOnDrop = true;
+
+  this.div_ = null;
+  this.document_ = null;
+  /** @type {?Element} */
+  this.screen_ = null;
+
+  // Collection of active timeout handles.
+  this.timeouts_ = {};
+
+  this.observers_ = {};
+
+  // Offscreen selection rows that are set with 'aria-hidden'.
+  // They must be unset when selection changes or the rows are visible.
+  this.ariaHiddenSelectionRows_ = [];
+
+  this.DEBUG_ = false;
+};
+
+/**
+ * Proxy for the native selection object which understands how to walk up the
+ * DOM to find the containing row node and sort out which comes first.
+ *
+ * @param {!hterm.ScrollPort} scrollPort The parent hterm.ScrollPort instance.
+ * @constructor
+ */
+hterm.ScrollPort.Selection = function(scrollPort) {
+  this.scrollPort_ = scrollPort;
+
+  /**
+   * The row containing the start of the selection.
+   *
+   * This may be partially or fully selected.  It may be the selection anchor
+   * or the focus, but its rowIndex is guaranteed to be less-than-or-equal-to
+   * that of the endRow.
+   *
+   * If only one row is selected then startRow == endRow.  If there is no
+   * selection or the selection is collapsed then startRow == null.
+   */
+  this.startRow = null;
+
+  /**
+   * The row containing the end of the selection.
+   *
+   * This may be partially or fully selected.  It may be the selection anchor
+   * or the focus, but its rowIndex is guaranteed to be greater-than-or-equal-to
+   * that of the startRow.
+   *
+   * If only one row is selected then startRow == endRow.  If there is no
+   * selection or the selection is collapsed then startRow == null.
+   */
+  this.endRow = null;
+
+  /**
+   * True if startRow != endRow.
+   */
+  this.isMultiline = null;
+
+  /**
+   * True if the selection is just a point rather than a range.
+   */
+  this.isCollapsed = null;
+};
+
+/**
+ * Given a list of DOM nodes and a container, return the DOM node that
+ * is first according to a depth-first search.
+ *
+ * @param {!Node} parent
+ * @param {!Array<!Node>} childAry
+ * @return {?Node} Returns null if none of the children are found.
+ */
+hterm.ScrollPort.Selection.prototype.findFirstChild = function(
+    parent, childAry) {
+  var node = parent.firstChild;
+
+  while (node) {
+    if (childAry.indexOf(node) != -1)
+      return node;
+
+    if (node.childNodes.length) {
+      var rv = this.findFirstChild(node, childAry);
+      if (rv)
+        return rv;
+    }
+
+    node = node.nextSibling;
+  }
+
+  return null;
+};
+
+/**
+ * Synchronize this object with the current DOM selection.
+ *
+ * This is a one-way synchronization, the DOM selection is copied to this
+ * object, not the other way around.
+ */
+hterm.ScrollPort.Selection.prototype.sync = function() {
+  var self = this;
+
+  // The dom selection object has no way to tell which nodes come first in
+  // the document, so we have to figure that out.
+  //
+  // This function is used when we detect that the "anchor" node is first.
+  function anchorFirst() {
+    self.startRow = anchorRow;
+    self.startNode = selection.anchorNode;
+    self.startOffset = selection.anchorOffset;
+    self.endRow = focusRow;
+    self.endNode = selection.focusNode;
+    self.endOffset = selection.focusOffset;
+  }
+
+  // This function is used when we detect that the "focus" node is first.
+  function focusFirst() {
+    self.startRow = focusRow;
+    self.startNode = selection.focusNode;
+    self.startOffset = selection.focusOffset;
+    self.endRow = anchorRow;
+    self.endNode = selection.anchorNode;
+    self.endOffset = selection.anchorOffset;
+  }
+
+  var selection = this.scrollPort_.getDocument().getSelection();
+
+  this.startRow = null;
+  this.endRow = null;
+  this.isMultiline = null;
+  this.isCollapsed = !selection || selection.isCollapsed;
+
+  if (!selection) {
+    return;
+  }
+
+  // Usually collapsed selections wouldn't be interesting, however screen
+  // readers will set a collapsed selection as they navigate through the DOM.
+  // It is important to preserve these nodes in the DOM as scrolling happens
+  // so that screen reader navigation isn't cleared.
+  const accessibilityEnabled = this.scrollPort_.accessibilityReader_ &&
+      this.scrollPort_.accessibilityReader_.accessibilityEnabled;
+  if (this.isCollapsed && !accessibilityEnabled) {
+    return;
+  }
+
+  var anchorRow = selection.anchorNode;
+  while (anchorRow && anchorRow.nodeName != 'X-ROW') {
+    anchorRow = anchorRow.parentNode;
+  }
+
+  if (!anchorRow) {
+    // Don't set a selection if it's not a row node that's selected.
+    return;
+  }
+
+  var focusRow = selection.focusNode;
+  while (focusRow && focusRow.nodeName != 'X-ROW') {
+    focusRow = focusRow.parentNode;
+  }
+
+  if (!focusRow) {
+    // Don't set a selection if it's not a row node that's selected.
+    return;
+  }
+
+  if (anchorRow.rowIndex < focusRow.rowIndex) {
+    anchorFirst();
+
+  } else if (anchorRow.rowIndex > focusRow.rowIndex) {
+    focusFirst();
+
+  } else if (selection.focusNode == selection.anchorNode) {
+    if (selection.anchorOffset < selection.focusOffset) {
+      anchorFirst();
+    } else {
+      focusFirst();
+    }
+
+  } else {
+    // The selection starts and ends in the same row, but isn't contained all
+    // in a single node.
+    var firstNode = this.findFirstChild(
+        anchorRow, [selection.anchorNode, selection.focusNode]);
+
+    if (!firstNode)
+      throw new Error('Unexpected error syncing selection.');
+
+    if (firstNode == selection.anchorNode) {
+      anchorFirst();
+    } else {
+      focusFirst();
+    }
+  }
+
+  this.isMultiline = anchorRow.rowIndex != focusRow.rowIndex;
+};
+
+/**
+ * Turn a div into this hterm.ScrollPort.
+ *
+ * @param {!Element} div
+ * @param {function()=} callback
+ */
+hterm.ScrollPort.prototype.decorate = function(div, callback) {
+  this.div_ = div;
+
+  this.iframe_ = div.ownerDocument.createElement('iframe');
+  this.iframe_.style.cssText = (
+      'border: 0;' +
+      'height: 100%;' +
+      'position: absolute;' +
+      'width: 100%');
+
+  div.appendChild(this.iframe_);
+
+  const onLoad = () => {
+    this.paintIframeContents_();
+    if (callback) {
+      callback();
+    }
+  };
+
+  // Insert Iframe content asynchronously in FF.  Otherwise when the frame's
+  // load event fires in FF it clears out the content of the iframe.
+  if ('mozInnerScreenX' in window) { // detect a FF only property
+    this.iframe_.addEventListener('load', () => onLoad());
+  } else {
+    onLoad();
+  }
+};
+
+
+/**
+ * Initialises the content of this.iframe_. This needs to be done asynchronously
+ * in FF after the Iframe's load event has fired.
+ *
+ * @private
+ */
+hterm.ScrollPort.prototype.paintIframeContents_ = function() {
+  this.iframe_.contentWindow.addEventListener('resize',
+                                              this.onResize_.bind(this));
+
+  var doc = this.document_ = this.iframe_.contentDocument;
+  doc.body.style.cssText = (
+      'margin: 0px;' +
+      'padding: 0px;' +
+      'height: 100%;' +
+      'width: 100%;' +
+      'overflow: hidden;' +
+      'cursor: var(--hterm-mouse-cursor-style);' +
+      '-webkit-user-select: none;' +
+      '-moz-user-select: none;');
+
+  const metaCharset = doc.createElement('meta');
+  metaCharset.setAttribute('charset', 'utf-8');
+  doc.head.appendChild(metaCharset);
+
+  if (this.DEBUG_) {
+    // When we're debugging we add padding to the body so that the offscreen
+    // elements are visible.
+    this.document_.body.style.paddingTop =
+        this.document_.body.style.paddingBottom =
+        'calc(var(--hterm-charsize-height) * 3)';
+  }
+
+  var style = doc.createElement('style');
+  style.textContent = (
+      'x-row {' +
+      '  display: block;' +
+      '  height: var(--hterm-charsize-height);' +
+      '  line-height: var(--hterm-charsize-height);' +
+      '}');
+  doc.head.appendChild(style);
+
+  this.userCssLink_ = doc.createElement('link');
+  this.userCssLink_.setAttribute('rel', 'stylesheet');
+
+  this.userCssText_ = doc.createElement('style');
+  doc.head.appendChild(this.userCssText_);
+
+  // TODO(rginda): Sorry, this 'screen_' isn't the same thing as hterm.Screen
+  // from screen.js.  I need to pick a better name for one of them to avoid
+  // the collision.
+  // We make this field editable even though we don't actually allow anything
+  // to be edited here so that Chrome will do the right thing with virtual
+  // keyboards and IMEs.  But make sure we turn off all the input helper logic
+  // that doesn't make sense here, and might inadvertently mung or save input.
+  // Some of these attributes are standard while others are browser specific,
+  // but should be safely ignored by other browsers.
+  this.screen_ = doc.createElement('x-screen');
+  this.screen_.setAttribute('contenteditable', 'true');
+  this.screen_.setAttribute('spellcheck', 'false');
+  this.screen_.setAttribute('autocomplete', 'off');
+  this.screen_.setAttribute('autocorrect', 'off');
+  this.screen_.setAttribute('autocapitalize', 'none');
+
+  // In some ways the terminal behaves like a text box but not in all ways. It
+  // is not editable in the same ways a text box is editable and the content we
+  // want to be read out by a screen reader does not always align with the edits
+  // (selection changes) that happen in the terminal window. Use the log role so
+  // that the screen reader doesn't treat it like a text box and announce all
+  // selection changes. The announcements that we want spoken are generated
+  // by a separate live region, which gives more control over what will be
+  // spoken.
+  this.screen_.setAttribute('role', 'log');
+  this.screen_.setAttribute('aria-live', 'off');
+  this.screen_.setAttribute('aria-roledescription', 'Terminal');
+
+  // Set aria-readonly to indicate to the screen reader that the text on the
+  // screen is not modifiable by the html cursor. It may be modifiable by
+  // sending input to the application running in the terminal, but this is
+  // orthogonal to the DOM's notion of modifiable.
+  this.screen_.setAttribute('aria-readonly', 'true');
+  this.screen_.setAttribute('tabindex', '-1');
+  this.screen_.style.cssText = (
+      'caret-color: transparent;' +
+      'display: block;' +
+      'font-family: monospace;' +
+      'font-size: 15px;' +
+      'font-variant-ligatures: none;' +
+      'height: 100%;' +
+      'overflow-y: scroll; overflow-x: hidden;' +
+      'white-space: pre;' +
+      'width: 100%;' +
+      'outline: none !important');
+
+  doc.body.appendChild(this.screen_);
+
+  /**
+   * @param {function(...)} f
+   * @return {!EventListener}
+   */
+  const el = (f) => /** @type {!EventListener} */ (f);
+  this.screen_.addEventListener('scroll', el(this.onScroll_.bind(this)));
+  this.screen_.addEventListener('wheel', el(this.onScrollWheel_.bind(this)));
+  this.screen_.addEventListener('touchstart', el(this.onTouch_.bind(this)));
+  this.screen_.addEventListener('touchmove', el(this.onTouch_.bind(this)));
+  this.screen_.addEventListener('touchend', el(this.onTouch_.bind(this)));
+  this.screen_.addEventListener('touchcancel', el(this.onTouch_.bind(this)));
+  this.screen_.addEventListener('copy', el(this.onCopy_.bind(this)));
+  this.screen_.addEventListener('paste', el(this.onPaste_.bind(this)));
+  this.screen_.addEventListener('drop', el(this.onDragAndDrop_.bind(this)));
+
+  doc.body.addEventListener('keydown', this.onBodyKeyDown_.bind(this));
+
+  // Add buttons to make accessible scrolling through terminal history work
+  // well. These are positioned off-screen until they are selected, at which
+  // point they are moved on-screen.
+  const scrollButtonHeight = 30;
+  const scrollButtonBorder = 1;
+  const scrollButtonTotalHeight = scrollButtonHeight + 2 * scrollButtonBorder;
+  const scrollButtonStyle = `right: 0px;
+                             position:fixed;
+                             z-index: 1;
+                             text-align: center;
+                             cursor: pointer;
+                             height: ${scrollButtonHeight}px;
+                             width: 110px;
+                             line-height: ${scrollButtonHeight}px;
+                             border-width: ${scrollButtonBorder}px;
+                             border-style: solid;
+                             font-weight: bold;`;
+  // Note: we use a <div> rather than a <button> because we don't want it to be
+  // focusable. If it's focusable this interferes with the contenteditable
+  // focus.
+  this.scrollUpButton_ = this.document_.createElement('div');
+  this.scrollUpButton_.id = 'hterm:a11y:page-up';
+  this.scrollUpButton_.innerText = hterm.msg('BUTTON_PAGE_UP', [], 'Page up');
+  this.scrollUpButton_.setAttribute('role', 'button');
+  this.scrollUpButton_.style.cssText = scrollButtonStyle;
+  this.scrollUpButton_.style.top = -scrollButtonTotalHeight + 'px';
+  this.scrollUpButton_.addEventListener('click', this.scrollPageUp.bind(this));
+
+  this.scrollDownButton_ = this.document_.createElement('div');
+  this.scrollDownButton_.id = 'hterm:a11y:page-down';
+  this.scrollDownButton_.innerText =
+      hterm.msg('BUTTON_PAGE_DOWN', [], 'Page down');
+  this.scrollDownButton_.setAttribute('role', 'button');
+  this.scrollDownButton_.style.cssText = scrollButtonStyle;
+  this.scrollDownButton_.style.bottom = -scrollButtonTotalHeight + 'px';
+  this.scrollDownButton_.addEventListener(
+      'click', this.scrollPageDown.bind(this));
+
+  // We only allow the scroll buttons to display after a delay, otherwise the
+  // page up button can flash onto the screen during the intial change in focus.
+  // This seems to be because it is the first element inside the <x-screen>
+  // element, which will get focussed on page load.
+  this.allowScrollButtonsToDisplay_ = false;
+  setTimeout(() => { this.allowScrollButtonsToDisplay_ = true; }, 500);
+  this.document_.addEventListener('selectionchange', () => {
+    this.selection.sync();
+
+    if (!this.allowScrollButtonsToDisplay_)
+      return;
+
+    const accessibilityEnabled = this.accessibilityReader_ &&
+        this.accessibilityReader_.accessibilityEnabled;
+
+    const selectedElement = this.document_.getSelection().anchorNode;
+    if (accessibilityEnabled && selectedElement == this.scrollUpButton_) {
+      this.scrollUpButton_.style.top = '0px';
+    } else {
+      this.scrollUpButton_.style.top = -scrollButtonTotalHeight + 'px';
+    }
+    if (accessibilityEnabled && selectedElement == this.scrollDownButton_) {
+      this.scrollDownButton_.style.bottom = '0px';
+    } else {
+      this.scrollDownButton_.style.bottom = -scrollButtonTotalHeight + 'px';
+    }
+  });
+
+  this.screen_.appendChild(this.scrollUpButton_);
+
+  // This is the main container for the fixed rows.
+  this.rowNodes_ = doc.createElement('div');
+  this.rowNodes_.id = 'hterm:row-nodes';
+  this.rowNodes_.style.cssText = (
+      'display: block;' +
+      'position: fixed;' +
+      'overflow: hidden;' +
+      '-webkit-user-select: text;' +
+      '-moz-user-select: text;');
+  this.screen_.appendChild(this.rowNodes_);
+
+  this.screen_.appendChild(this.scrollDownButton_);
+
+  // Two nodes to hold offscreen text during the copy event.
+  this.topSelectBag_ = doc.createElement('x-select-bag');
+  this.topSelectBag_.style.cssText = (
+      'display: block;' +
+      'overflow: hidden;' +
+      'height: var(--hterm-charsize-height);' +
+      'white-space: pre;');
+
+  this.bottomSelectBag_ = this.topSelectBag_.cloneNode();
+
+  // Nodes above the top fold and below the bottom fold are hidden.  They are
+  // only used to hold rows that are part of the selection but are currently
+  // scrolled off the top or bottom of the visible range.
+  this.topFold_ = doc.createElement('x-fold');
+  this.topFold_.id = 'hterm:top-fold-for-row-selection';
+  this.topFold_.style.cssText = 'display: block;';
+  this.rowNodes_.appendChild(this.topFold_);
+
+  this.bottomFold_ = this.topFold_.cloneNode();
+  this.bottomFold_.id = 'hterm:bottom-fold-for-row-selection';
+  this.rowNodes_.appendChild(this.bottomFold_);
+
+  // This hidden div accounts for the vertical space that would be consumed by
+  // all the rows in the buffer if they were visible.  It's what causes the
+  // scrollbar to appear on the 'x-screen', and it moves within the screen when
+  // the scrollbar is moved.
+  //
+  // It is set 'visibility: hidden' to keep the browser from trying to include
+  // it in the selection when a user 'drag selects' upwards (drag the mouse to
+  // select and scroll at the same time).  Without this, the selection gets
+  // out of whack.
+  this.scrollArea_ = doc.createElement('div');
+  this.scrollArea_.id = 'hterm:scrollarea';
+  this.scrollArea_.style.cssText = 'visibility: hidden';
+  this.screen_.appendChild(this.scrollArea_);
+
+  // This svg element is used to detect when the browser is zoomed.  It must be
+  // placed in the outermost document for currentScale to be correct.
+  // TODO(rginda): This means that hterm nested in an iframe will not correctly
+  // detect browser zoom level.  We should come up with a better solution.
+  // Note: This must be http:// else Chrome cannot create the element correctly.
+  var xmlns = 'http://www.w3.org/2000/svg';
+  this.svg_ =
+      /** @type {?SVGSVGElement} */
+      (this.div_.ownerDocument.createElementNS(xmlns, 'svg'));
+  this.svg_.id = 'hterm:zoom-detector';
+  this.svg_.setAttribute('xmlns', xmlns);
+  this.svg_.setAttribute('version', '1.1');
+  this.svg_.style.cssText = (
+      'position: absolute;' +
+      'top: 0;' +
+      'left: 0;' +
+      'visibility: hidden');
+
+
+  // We send focus to this element just before a paste happens, so we can
+  // capture the pasted text and forward it on to someone who cares.
+  this.pasteTarget_ = doc.createElement('textarea');
+  this.pasteTarget_.id = 'hterm:ctrl-v-paste-target';
+  this.pasteTarget_.setAttribute('tabindex', '-1');
+  this.pasteTarget_.setAttribute('aria-hidden', 'true');
+  this.pasteTarget_.style.cssText = (
+    'position: absolute;' +
+    'height: 1px;' +
+    'width: 1px;' +
+    'left: 0px; ' +
+    'bottom: 0px;' +
+    'opacity: 0');
+  this.pasteTarget_.contentEditable = true;
+
+  this.screen_.appendChild(this.pasteTarget_);
+  this.pasteTarget_.addEventListener(
+      'textInput', this.handlePasteTargetTextInput_.bind(this));
+
+  this.resize();
+};
+
+/**
+ * Set the AccessibilityReader object to use to announce page scroll updates.
+ *
+ * @param {!hterm.AccessibilityReader} accessibilityReader for announcing page
+ *     scroll updates.
+ */
+hterm.ScrollPort.prototype.setAccessibilityReader =
+    function(accessibilityReader) {
+  this.accessibilityReader_ = accessibilityReader;
+};
+
+/**
+ * Scroll the terminal one page up (minus one line) relative to the current
+ * position.
+ */
+hterm.ScrollPort.prototype.scrollPageUp = function() {
+  if (this.getTopRowIndex() == 0) {
+    return;
+  }
+
+  const i = this.getTopRowIndex();
+  this.scrollRowToTop(i - this.visibleRowCount + 1);
+
+  this.assertiveAnnounce_();
+};
+
+/**
+ * Scroll the terminal one page down (minus one line) relative to the current
+ * position.
+ */
+hterm.ScrollPort.prototype.scrollPageDown = function() {
+  if (this.isScrolledEnd) {
+    return;
+  }
+
+  const i = this.getTopRowIndex();
+  this.scrollRowToTop(i + this.visibleRowCount - 1);
+
+  this.assertiveAnnounce_();
+};
+
+/**
+ * Select the font-family and font-smoothing for this scrollport.
+ *
+ * @param {string} fontFamily Value of the CSS 'font-family' to use for this
+ *     scrollport.  Should be a monospace font.
+ * @param {string=} opt_smoothing Optional value for '-webkit-font-smoothing'.
+ *     Defaults to an empty string if not specified.
+ */
+hterm.ScrollPort.prototype.setFontFamily = function(fontFamily, opt_smoothing) {
+  this.screen_.style.fontFamily = fontFamily;
+  if (opt_smoothing) {
+    this.screen_.style.webkitFontSmoothing = opt_smoothing;
+  } else {
+    this.screen_.style.webkitFontSmoothing = '';
+  }
+
+  this.syncCharacterSize();
+};
+
+/** @return {string} */
+hterm.ScrollPort.prototype.getFontFamily = function() {
+  return this.screen_.style.fontFamily;
+};
+
+/**
+ * Set a custom stylesheet to include in the scrollport.
+ *
+ * Defaults to null, meaning no custom css is loaded.  Set it back to null or
+ * the empty string to remove a previously applied custom css.
+ *
+ * @param {?string} url
+ */
+hterm.ScrollPort.prototype.setUserCssUrl = function(url) {
+  if (url) {
+    this.userCssLink_.setAttribute('href', url);
+
+    if (!this.userCssLink_.parentNode)
+      this.document_.head.appendChild(this.userCssLink_);
+  } else if (this.userCssLink_.parentNode) {
+    this.document_.head.removeChild(this.userCssLink_);
+  }
+};
+
+/** @param {string} text */
+hterm.ScrollPort.prototype.setUserCssText = function(text) {
+  this.userCssText_.textContent = text;
+};
+
+/** Focus. */
+hterm.ScrollPort.prototype.focus = function() {
+  this.iframe_.focus();
+  this.screen_.focus();
+  this.publish('focus');
+};
+
+/**
+ * Unfocus the scrollport.
+ */
+hterm.ScrollPort.prototype.blur = function() {
+  this.screen_.blur();
+};
+
+/** @return {string} */
+hterm.ScrollPort.prototype.getForegroundColor = function() {
+  return this.screen_.style.color;
+};
+
+/** @param {string} color */
+hterm.ScrollPort.prototype.setForegroundColor = function(color) {
+  this.screen_.style.color = color;
+  this.scrollUpButton_.style.backgroundColor = color;
+  this.scrollDownButton_.style.backgroundColor = color;
+};
+
+/** @return {string} */
+hterm.ScrollPort.prototype.getBackgroundColor = function() {
+  return this.screen_.style.backgroundColor;
+};
+
+/** @param {string} color */
+hterm.ScrollPort.prototype.setBackgroundColor = function(color) {
+  this.screen_.style.backgroundColor = color;
+  this.scrollUpButton_.style.color = color;
+  this.scrollDownButton_.style.color = color;
+};
+
+/** @param {string} image */
+hterm.ScrollPort.prototype.setBackgroundImage = function(image) {
+  this.screen_.style.backgroundImage = image;
+};
+
+/** @param {string} size */
+hterm.ScrollPort.prototype.setBackgroundSize = function(size) {
+  this.screen_.style.backgroundSize = size;
+};
+
+/** @param {string} position */
+hterm.ScrollPort.prototype.setBackgroundPosition = function(position) {
+  this.screen_.style.backgroundPosition = position;
+};
+
+/** @param {boolean} ctrlVPaste */
+hterm.ScrollPort.prototype.setCtrlVPaste = function(ctrlVPaste) {
+  this.ctrlVPaste = ctrlVPaste;
+};
+
+/** @param {boolean} pasteOnDrop */
+hterm.ScrollPort.prototype.setPasteOnDrop = function(pasteOnDrop) {
+  this.pasteOnDrop = pasteOnDrop;
+};
+
+/**
+ * Get the usable size of the scrollport screen.
+ *
+ * The width will not include the scrollbar width.
+ *
+ * @return {{height: number, width: number}}
+ */
+hterm.ScrollPort.prototype.getScreenSize = function() {
+  var size = hterm.getClientSize(lib.notNull(this.screen_));
+  return {
+    height: size.height,
+    width: size.width - this.currentScrollbarWidthPx
+  };
+};
+
+/**
+ * Get the usable width of the scrollport screen.
+ *
+ * This the widget width minus scrollbar width.
+ *
+ * @return {number}
+ */
+hterm.ScrollPort.prototype.getScreenWidth = function() {
+  return this.getScreenSize().width ;
+};
+
+/**
+ * Get the usable height of the scrollport screen.
+ *
+ * @return {number}
+ */
+hterm.ScrollPort.prototype.getScreenHeight = function() {
+  return this.getScreenSize().height;
+};
+
+/**
+ * Return the document that holds the visible rows of this hterm.ScrollPort.
+ *
+ * @return {!Document}
+ */
+hterm.ScrollPort.prototype.getDocument = function() {
+  return this.document_;
+};
+
+/**
+ * Returns the x-screen element that holds the rows of this hterm.ScrollPort.
+ *
+ * @return {?Element}
+ */
+hterm.ScrollPort.prototype.getScreenNode = function() {
+  return this.screen_;
+};
+
+/**
+ * Clear out any cached rowNodes.
+ */
+hterm.ScrollPort.prototype.resetCache = function() {
+  this.currentRowNodeCache_ = null;
+  this.previousRowNodeCache_ = {};
+};
+
+/**
+ * Change the current rowProvider.
+ *
+ * This will clear the row cache and cause a redraw.
+ *
+ * @param {!hterm.RowProvider} rowProvider An object capable of providing the
+ *     rows in this hterm.ScrollPort.
+ */
+hterm.ScrollPort.prototype.setRowProvider = function(rowProvider) {
+  this.resetCache();
+  this.rowProvider_ = rowProvider;
+  this.scheduleRedraw();
+};
+
+/**
+ * Inform the ScrollPort that the root DOM nodes for some or all of the visible
+ * rows are no longer valid.
+ *
+ * Specifically, this should be called if this.rowProvider_.getRowNode() now
+ * returns an entirely different node than it did before.  It does not
+ * need to be called if the content of a row node is the only thing that
+ * changed.
+ *
+ * This skips some of the overhead of a full redraw, but should not be used
+ * in cases where the scrollport has been scrolled, or when the row count has
+ * changed.
+ */
+hterm.ScrollPort.prototype.invalidate = function() {
+  var node = this.topFold_.nextSibling;
+  while (node != this.bottomFold_) {
+    var nextSibling = node.nextSibling;
+    node.parentElement.removeChild(node);
+    node = nextSibling;
+  }
+
+  this.previousRowNodeCache_ = null;
+  var topRowIndex = this.getTopRowIndex();
+  var bottomRowIndex = this.getBottomRowIndex(topRowIndex);
+
+  this.drawVisibleRows_(topRowIndex, bottomRowIndex);
+};
+
+/**
+ * Schedule invalidate.
+ */
+hterm.ScrollPort.prototype.scheduleInvalidate = function() {
+  if (this.timeouts_.invalidate)
+    return;
+
+  var self = this;
+  this.timeouts_.invalidate = setTimeout(function () {
+      delete self.timeouts_.invalidate;
+      self.invalidate();
+    }, 0);
+};
+
+/**
+ * Set the font size of the ScrollPort.
+ *
+ * @param {number} px
+ */
+hterm.ScrollPort.prototype.setFontSize = function(px) {
+  this.screen_.style.fontSize = px + 'px';
+  this.syncCharacterSize();
+};
+
+/**
+ * Return the current font size of the ScrollPort.
+ *
+ * @return {number}
+ */
+hterm.ScrollPort.prototype.getFontSize = function() {
+  return parseInt(this.screen_.style.fontSize, 10);
+};
+
+/**
+ * Measure the size of a single character in pixels.
+ *
+ * @param {string=} opt_weight The font weight to measure, or 'normal' if
+ *     omitted.
+ * @return {!hterm.Size} A new hterm.Size object.
+ */
+hterm.ScrollPort.prototype.measureCharacterSize = function(opt_weight) {
+  // Number of lines used to average the height of a single character.
+  var numberOfLines = 100;
+  // Number of chars per line used to average the width of a single character.
+  var lineLength = 100;
+
+  if (!this.ruler_) {
+    this.ruler_ = this.document_.createElement('div');
+    this.ruler_.id = 'hterm:ruler-character-size';
+    this.ruler_.style.cssText = (
+        'position: absolute;' +
+        'top: 0;' +
+        'left: 0;' +
+        'visibility: hidden;' +
+        'height: auto !important;' +
+        'width: auto !important;');
+
+    // We need to put the text in a span to make the size calculation
+    // work properly in Firefox
+    this.rulerSpan_ = this.document_.createElement('span');
+    this.rulerSpan_.id = 'hterm:ruler-span-workaround';
+    this.rulerSpan_.innerHTML =
+        ('X'.repeat(lineLength) + '\r').repeat(numberOfLines);
+    this.ruler_.appendChild(this.rulerSpan_);
+
+    this.rulerBaseline_ = this.document_.createElement('span');
+    this.rulerSpan_.id = 'hterm:ruler-baseline';
+    // We want to collapse it on the baseline
+    this.rulerBaseline_.style.fontSize = '0px';
+    this.rulerBaseline_.textContent = 'X';
+  }
+
+  this.rulerSpan_.style.fontWeight = opt_weight || '';
+
+  this.rowNodes_.appendChild(this.ruler_);
+  var rulerSize = hterm.getClientSize(this.rulerSpan_);
+
+  var size = new hterm.Size(rulerSize.width / lineLength,
+                            rulerSize.height / numberOfLines);
+
+  this.ruler_.appendChild(this.rulerBaseline_);
+  this.ruler_.removeChild(this.rulerBaseline_);
+
+  this.rowNodes_.removeChild(this.ruler_);
+
+  this.div_.ownerDocument.body.appendChild(this.svg_);
+  size.zoomFactor = this.svg_.currentScale;
+  this.div_.ownerDocument.body.removeChild(this.svg_);
+
+  return size;
+};
+
+/**
+ * Synchronize the character size.
+ *
+ * This will re-measure the current character size and adjust the height
+ * of an x-row to match.
+ */
+hterm.ScrollPort.prototype.syncCharacterSize = function() {
+  this.characterSize = this.measureCharacterSize();
+
+  this.resize();
+};
+
+/**
+ * Reset dimensions and visible row count to account for a change in the
+ * dimensions of the 'x-screen'.
+ */
+hterm.ScrollPort.prototype.resize = function() {
+  this.currentScrollbarWidthPx =
+    hterm.getClientWidth(lib.notNull(this.screen_)) - this.screen_.clientWidth;
+
+  this.syncScrollHeight();
+  this.syncRowNodesDimensions_();
+
+  var self = this;
+  this.publish(
+      'resize', { scrollPort: this },
+      function() {
+        self.scheduleRedraw();
+      });
+};
+
+/**
+ * Announce text content on the current screen for the screen reader.
+ */
+hterm.ScrollPort.prototype.assertiveAnnounce_ = function() {
+  if (!this.accessibilityReader_) {
+    return;
+  }
+
+  const topRow = this.getTopRowIndex();
+  const bottomRow = this.getBottomRowIndex(topRow);
+
+  let percentScrolled = 100 * topRow /
+      Math.max(1, this.rowProvider_.getRowCount() - this.visibleRowCount);
+  percentScrolled = Math.min(100, Math.round(percentScrolled));
+  let currentScreenContent = hterm.msg('ANNOUNCE_CURRENT_SCREEN_HEADER',
+                                       [percentScrolled],
+                                       '$1% scrolled,');
+  currentScreenContent += '\n';
+
+  for (let i = topRow; i <= bottomRow; ++i) {
+    const node = this.fetchRowNode_(i);
+    currentScreenContent += node.textContent + '\n';
+  }
+
+  this.accessibilityReader_.assertiveAnnounce(currentScreenContent);
+};
+
+/**
+ * Set the position and size of the row nodes element.
+ */
+hterm.ScrollPort.prototype.syncRowNodesDimensions_ = function() {
+  var screenSize = this.getScreenSize();
+
+  this.lastScreenWidth_ = screenSize.width;
+  this.lastScreenHeight_ = screenSize.height;
+
+  // We don't want to show a partial row because it would be distracting
+  // in a terminal, so we floor any fractional row count.
+  this.visibleRowCount = lib.f.smartFloorDivide(
+      screenSize.height, this.characterSize.height);
+
+  // Then compute the height of our integral number of rows.
+  var visibleRowsHeight = this.visibleRowCount * this.characterSize.height;
+
+  // Then the difference between the screen height and total row height needs to
+  // be made up for as top margin.  We need to record this value so it
+  // can be used later to determine the topRowIndex.
+  this.visibleRowTopMargin = 0;
+  this.visibleRowBottomMargin = screenSize.height - visibleRowsHeight;
+
+  this.topFold_.style.marginBottom = this.visibleRowTopMargin + 'px';
+
+
+  var topFoldOffset = 0;
+  var node = this.topFold_.previousSibling;
+  while (node) {
+    topFoldOffset += hterm.getClientHeight(node);
+    node = node.previousSibling;
+  }
+
+  // Set the dimensions of the visible rows container.
+  this.rowNodes_.style.width = screenSize.width + 'px';
+  this.rowNodes_.style.height = visibleRowsHeight + topFoldOffset + 'px';
+  this.rowNodes_.style.left = this.screen_.offsetLeft + 'px';
+  this.rowNodes_.style.top = this.screen_.offsetTop - topFoldOffset + 'px';
+};
+
+/**
+ * Resize the scroll area to appear as though it contains every row.
+ */
+hterm.ScrollPort.prototype.syncScrollHeight = function() {
+  this.lastRowCount_ = this.rowProvider_.getRowCount();
+  this.scrollArea_.style.height = (this.characterSize.height *
+                                   this.lastRowCount_ +
+                                   this.visibleRowTopMargin +
+                                   this.visibleRowBottomMargin +
+                                   'px');
+};
+
+/**
+ * Schedule a redraw to happen asynchronously.
+ *
+ * If this method is called multiple times before the redraw has a chance to
+ * run only one redraw occurs.
+ */
+hterm.ScrollPort.prototype.scheduleRedraw = function() {
+  if (this.timeouts_.redraw)
+    return;
+
+  var self = this;
+  this.timeouts_.redraw = setTimeout(function () {
+      delete self.timeouts_.redraw;
+      self.redraw_();
+    }, 0);
+};
+
+/**
+ * Update the state of scroll up/down buttons.
+ *
+ * If the viewport is at the top or bottom row of output, these buttons will
+ * be made transparent and clicking them shouldn't scroll any further.
+ */
+hterm.ScrollPort.prototype.updateScrollButtonState_ = function() {
+  const setButton = (button, disabled) => {
+    button.setAttribute('aria-disabled', disabled ? 'true' : 'false');
+    button.style.opacity = disabled ? 0.5 : 1;
+  };
+  setButton(this.scrollUpButton_, this.getTopRowIndex() == 0);
+  setButton(this.scrollDownButton_, this.isScrolledEnd);
+};
+
+/**
+ * Redraw the current hterm.ScrollPort based on the current scrollbar position.
+ *
+ * When redrawing, we are careful to make sure that the rows that start or end
+ * the current selection are not touched in any way.  Doing so would disturb
+ * the selection, and cleaning up after that would cause flashes at best and
+ * incorrect selection at worst.  Instead, we modify the DOM around these nodes.
+ * We even stash the selection start/end outside of the visible area if
+ * they are not supposed to be visible in the hterm.ScrollPort.
+ */
+hterm.ScrollPort.prototype.redraw_ = function() {
+  this.resetSelectBags_();
+  this.selection.sync();
+
+  this.syncScrollHeight();
+
+  this.currentRowNodeCache_ = {};
+
+  var topRowIndex = this.getTopRowIndex();
+  var bottomRowIndex = this.getBottomRowIndex(topRowIndex);
+
+  this.drawTopFold_(topRowIndex);
+  this.drawBottomFold_(bottomRowIndex);
+  this.drawVisibleRows_(topRowIndex, bottomRowIndex);
+  this.ariaHideOffscreenSelectionRows_(topRowIndex, bottomRowIndex);
+
+  this.syncRowNodesDimensions_();
+
+  this.previousRowNodeCache_ = this.currentRowNodeCache_;
+  this.currentRowNodeCache_ = null;
+
+  this.isScrolledEnd = (
+    this.getTopRowIndex() + this.visibleRowCount >= this.lastRowCount_);
+
+  this.updateScrollButtonState_();
+};
+
+/**
+ * Ensure that the nodes above the top fold are as they should be.
+ *
+ * If the selection start and/or end nodes are above the visible range
+ * of this hterm.ScrollPort then the dom will be adjusted so that they appear
+ * before the top fold (the first x-fold element, aka this.topFold).
+ *
+ * If not, the top fold will be the first element.
+ *
+ * It is critical that this method does not move the selection nodes.  Doing
+ * so would clear the current selection.  Instead, the rest of the DOM is
+ * adjusted around them.
+ *
+ * @param {number} topRowIndex
+ */
+hterm.ScrollPort.prototype.drawTopFold_ = function(topRowIndex) {
+  if (!this.selection.startRow ||
+      this.selection.startRow.rowIndex >= topRowIndex) {
+    // Selection is entirely below the top fold, just make sure the fold is
+    // the first child.
+    if (this.rowNodes_.firstChild != this.topFold_)
+      this.rowNodes_.insertBefore(this.topFold_, this.rowNodes_.firstChild);
+
+    return;
+  }
+
+  if (!this.selection.isMultiline ||
+      this.selection.endRow.rowIndex >= topRowIndex) {
+    // Only the startRow is above the fold.
+    if (this.selection.startRow.nextSibling != this.topFold_)
+      this.rowNodes_.insertBefore(this.topFold_,
+                                  this.selection.startRow.nextSibling);
+  } else {
+    // Both rows are above the fold.
+    if (this.selection.endRow.nextSibling != this.topFold_) {
+      this.rowNodes_.insertBefore(this.topFold_,
+                                  this.selection.endRow.nextSibling);
+    }
+
+    // Trim any intermediate lines.
+    while (this.selection.startRow.nextSibling !=
+           this.selection.endRow) {
+      this.rowNodes_.removeChild(this.selection.startRow.nextSibling);
+    }
+  }
+
+  while(this.rowNodes_.firstChild != this.selection.startRow) {
+    this.rowNodes_.removeChild(this.rowNodes_.firstChild);
+  }
+};
+
+/**
+ * Ensure that the nodes below the bottom fold are as they should be.
+ *
+ * If the selection start and/or end nodes are below the visible range
+ * of this hterm.ScrollPort then the dom will be adjusted so that they appear
+ * after the bottom fold (the second x-fold element, aka this.bottomFold).
+ *
+ * If not, the bottom fold will be the last element.
+ *
+ * It is critical that this method does not move the selection nodes.  Doing
+ * so would clear the current selection.  Instead, the rest of the DOM is
+ * adjusted around them.
+ *
+ * @param {number} bottomRowIndex
+ */
+hterm.ScrollPort.prototype.drawBottomFold_ = function(bottomRowIndex) {
+  if (!this.selection.endRow ||
+      this.selection.endRow.rowIndex <= bottomRowIndex) {
+    // Selection is entirely above the bottom fold, just make sure the fold is
+    // the last child.
+    if (this.rowNodes_.lastChild != this.bottomFold_)
+      this.rowNodes_.appendChild(this.bottomFold_);
+
+    return;
+  }
+
+  if (!this.selection.isMultiline ||
+      this.selection.startRow.rowIndex <= bottomRowIndex) {
+    // Only the endRow is below the fold.
+    if (this.bottomFold_.nextSibling != this.selection.endRow)
+      this.rowNodes_.insertBefore(this.bottomFold_,
+                                  this.selection.endRow);
+  } else {
+    // Both rows are below the fold.
+    if (this.bottomFold_.nextSibling != this.selection.startRow) {
+      this.rowNodes_.insertBefore(this.bottomFold_,
+                                  this.selection.startRow);
+    }
+
+    // Trim any intermediate lines.
+    while (this.selection.startRow.nextSibling !=
+           this.selection.endRow) {
+      this.rowNodes_.removeChild(this.selection.startRow.nextSibling);
+    }
+  }
+
+  while(this.rowNodes_.lastChild != this.selection.endRow) {
+    this.rowNodes_.removeChild(this.rowNodes_.lastChild);
+  }
+};
+
+/**
+ * Ensure that the rows between the top and bottom folds are as they should be.
+ *
+ * This method assumes that drawTopFold_() and drawBottomFold_() have already
+ * run, and that they have left any visible selection row (selection start
+ * or selection end) between the folds.
+ *
+ * It recycles DOM nodes from the previous redraw where possible, but will ask
+ * the rowSource to make new nodes if necessary.
+ *
+ * It is critical that this method does not move the selection nodes.  Doing
+ * so would clear the current selection.  Instead, the rest of the DOM is
+ * adjusted around them.
+ *
+ * @param {number} topRowIndex
+ * @param {number} bottomRowIndex
+ */
+hterm.ScrollPort.prototype.drawVisibleRows_ = function(
+    topRowIndex, bottomRowIndex) {
+  var self = this;
+
+  // Keep removing nodes, starting with currentNode, until we encounter
+  // targetNode.  Throws on failure.
+  function removeUntilNode(currentNode, targetNode) {
+    while (currentNode != targetNode) {
+      if (!currentNode)
+        throw 'Did not encounter target node';
+
+      if (currentNode == self.bottomFold_)
+        throw 'Encountered bottom fold before target node';
+
+      var deadNode = currentNode;
+      currentNode = currentNode.nextSibling;
+      deadNode.parentNode.removeChild(deadNode);
+    }
+  }
+
+  // Shorthand for things we're going to use a lot.
+  var selectionStartRow = this.selection.startRow;
+  var selectionEndRow = this.selection.endRow;
+  var bottomFold = this.bottomFold_;
+
+  // The node we're examining during the current iteration.
+  var node = this.topFold_.nextSibling;
+
+  var targetDrawCount = Math.min(this.visibleRowCount,
+                                 this.rowProvider_.getRowCount());
+
+  for (var drawCount = 0; drawCount < targetDrawCount; drawCount++) {
+    var rowIndex = topRowIndex + drawCount;
+
+    if (node == bottomFold) {
+      // We've hit the bottom fold, we need to insert a new row.
+      var newNode = this.fetchRowNode_(rowIndex);
+      if (!newNode) {
+        console.log("Couldn't fetch row index: " + rowIndex);
+        break;
+      }
+
+      this.rowNodes_.insertBefore(newNode, node);
+      continue;
+    }
+
+    if (node.rowIndex == rowIndex) {
+      // This node is in the right place, move along.
+      node = node.nextSibling;
+      continue;
+    }
+
+    if (selectionStartRow && selectionStartRow.rowIndex == rowIndex) {
+      // The selection start row is supposed to be here, remove nodes until
+      // we find it.
+      removeUntilNode(node, selectionStartRow);
+      node = selectionStartRow.nextSibling;
+      continue;
+    }
+
+    if (selectionEndRow && selectionEndRow.rowIndex == rowIndex) {
+      // The selection end row is supposed to be here, remove nodes until
+      // we find it.
+      removeUntilNode(node, selectionEndRow);
+      node = selectionEndRow.nextSibling;
+      continue;
+    }
+
+    if (node == selectionStartRow || node == selectionEndRow) {
+      // We encountered the start/end of the selection, but we don't want it
+      // yet.  Insert a new row instead.
+      var newNode = this.fetchRowNode_(rowIndex);
+      if (!newNode) {
+        console.log("Couldn't fetch row index: " + rowIndex);
+        break;
+      }
+
+      this.rowNodes_.insertBefore(newNode, node);
+      continue;
+    }
+
+    // There is nothing special about this node, but it's in our way.  Replace
+    // it with the node that should be here.
+    var newNode = this.fetchRowNode_(rowIndex);
+    if (!newNode) {
+      console.log("Couldn't fetch row index: " + rowIndex);
+      break;
+    }
+
+    if (node == newNode) {
+      node = node.nextSibling;
+      continue;
+    }
+
+    this.rowNodes_.insertBefore(newNode, node);
+    this.rowNodes_.removeChild(node);
+    node = newNode.nextSibling;
+  }
+
+  if (node != this.bottomFold_)
+    removeUntilNode(node, bottomFold);
+};
+
+/**
+ * Ensure aria-hidden is set on any selection rows that are offscreen.
+ *
+ * The attribute aria-hidden is set to 'true' so that hidden rows are ignored
+ * by screen readers.  We keep a list of currently hidden rows so they can be
+ * reset each time this function is called as the selection and/or scrolling
+ * may have changed.
+ *
+ * @param {number} topRowIndex Index of top row on screen.
+ * @param {number} bottomRowIndex Index of bottom row on screen.
+ */
+hterm.ScrollPort.prototype.ariaHideOffscreenSelectionRows_ = function(
+    topRowIndex, bottomRowIndex) {
+  // Reset previously hidden selection rows.
+  const hiddenRows = this.ariaHiddenSelectionRows_;
+  let row;
+  while ((row = hiddenRows.pop())) {
+    row.removeAttribute('aria-hidden');
+  }
+
+  function checkRow(row) {
+    if (row && (row.rowIndex < topRowIndex || row.rowIndex > bottomRowIndex)) {
+      row.setAttribute('aria-hidden', 'true');
+      hiddenRows.push(row);
+    }
+  }
+  checkRow(this.selection.startRow);
+  checkRow(this.selection.endRow);
+};
+
+/**
+ * Empty out both select bags and remove them from the document.
+ *
+ * These nodes hold the text between the start and end of the selection
+ * when that text is otherwise off screen.  They are filled out in the
+ * onCopy_ event.
+ */
+hterm.ScrollPort.prototype.resetSelectBags_ = function() {
+  if (this.topSelectBag_.parentNode) {
+    this.topSelectBag_.textContent = '';
+    this.topSelectBag_.parentNode.removeChild(this.topSelectBag_);
+  }
+
+  if (this.bottomSelectBag_.parentNode) {
+    this.bottomSelectBag_.textContent = '';
+    this.bottomSelectBag_.parentNode.removeChild(this.bottomSelectBag_);
+  }
+};
+
+/**
+ * Place a row node in the cache of visible nodes.
+ *
+ * This method may only be used during a redraw_.
+ *
+ * @param {!Node} rowNode
+ */
+hterm.ScrollPort.prototype.cacheRowNode_ = function(rowNode) {
+  this.currentRowNodeCache_[rowNode.rowIndex] = rowNode;
+};
+
+/**
+ * Fetch the row node for the given index.
+ *
+ * This will return a node from the cache if possible, or will request one
+ * from the RowProvider if not.
+ *
+ * If a redraw_ is in progress the row will be added to the current cache.
+ *
+ * @param {number} rowIndex
+ * @return {!Node}
+ */
+hterm.ScrollPort.prototype.fetchRowNode_ = function(rowIndex) {
+  var node;
+
+  if (this.previousRowNodeCache_ && rowIndex in this.previousRowNodeCache_) {
+    node = this.previousRowNodeCache_[rowIndex];
+  } else {
+    node = this.rowProvider_.getRowNode(rowIndex);
+  }
+
+  if (this.currentRowNodeCache_)
+    this.cacheRowNode_(node);
+
+  return node;
+};
+
+/**
+ * Select all rows in the viewport.
+ */
+hterm.ScrollPort.prototype.selectAll = function() {
+  var firstRow;
+
+  if (this.topFold_.nextSibling.rowIndex != 0) {
+    while (this.topFold_.previousSibling) {
+      this.rowNodes_.removeChild(this.topFold_.previousSibling);
+    }
+
+    firstRow = this.fetchRowNode_(0);
+    this.rowNodes_.insertBefore(firstRow, this.topFold_);
+    this.syncRowNodesDimensions_();
+  } else {
+    firstRow = this.topFold_.nextSibling;
+  }
+
+  var lastRowIndex = this.rowProvider_.getRowCount() - 1;
+  var lastRow;
+
+  if (this.bottomFold_.previousSibling.rowIndex != lastRowIndex) {
+    while (this.bottomFold_.nextSibling) {
+      this.rowNodes_.removeChild(this.bottomFold_.nextSibling);
+    }
+
+    lastRow = this.fetchRowNode_(lastRowIndex);
+    this.rowNodes_.appendChild(lastRow);
+  } else {
+    lastRow = this.bottomFold_.previousSibling.rowIndex;
+  }
+
+  var selection = this.document_.getSelection();
+  selection.collapse(firstRow, 0);
+  selection.extend(lastRow, lastRow.childNodes.length);
+
+  this.selection.sync();
+};
+
+/**
+ * Return the maximum scroll position in pixels.
+ *
+ * @return {number}
+ */
+hterm.ScrollPort.prototype.getScrollMax_ = function() {
+  return (hterm.getClientHeight(this.scrollArea_) +
+          this.visibleRowTopMargin + this.visibleRowBottomMargin -
+          hterm.getClientHeight(lib.notNull(this.screen_)));
+};
+
+/**
+ * Scroll the given rowIndex to the top of the hterm.ScrollPort.
+ *
+ * @param {number} rowIndex Index of the target row.
+ */
+hterm.ScrollPort.prototype.scrollRowToTop = function(rowIndex) {
+  this.syncScrollHeight();
+
+  this.isScrolledEnd = (
+    rowIndex + this.visibleRowCount >= this.lastRowCount_);
+
+  var scrollTop = rowIndex * this.characterSize.height +
+      this.visibleRowTopMargin;
+
+  var scrollMax = this.getScrollMax_();
+  if (scrollTop > scrollMax)
+    scrollTop = scrollMax;
+
+  if (this.screen_.scrollTop == scrollTop)
+    return;
+
+  this.screen_.scrollTop = scrollTop;
+  this.scheduleRedraw();
+};
+
+/**
+ * Scroll the given rowIndex to the bottom of the hterm.ScrollPort.
+ *
+ * @param {number} rowIndex Index of the target row.
+ */
+hterm.ScrollPort.prototype.scrollRowToBottom = function(rowIndex) {
+  this.syncScrollHeight();
+
+  this.isScrolledEnd = (
+    rowIndex + this.visibleRowCount >= this.lastRowCount_);
+
+  var scrollTop = rowIndex * this.characterSize.height +
+      this.visibleRowTopMargin + this.visibleRowBottomMargin;
+  scrollTop -= this.visibleRowCount * this.characterSize.height;
+
+  if (scrollTop < 0)
+    scrollTop = 0;
+
+  if (this.screen_.scrollTop == scrollTop)
+    return;
+
+  this.screen_.scrollTop = scrollTop;
+};
+
+/**
+ * Return the row index of the first visible row.
+ *
+ * This is based on the scroll position.  If a redraw_ is in progress this
+ * returns the row that *should* be at the top.
+ *
+ * @return {number}
+ */
+hterm.ScrollPort.prototype.getTopRowIndex = function() {
+  return Math.round(this.screen_.scrollTop / this.characterSize.height);
+};
+
+/**
+ * Return the row index of the last visible row.
+ *
+ * This is based on the scroll position.  If a redraw_ is in progress this
+ * returns the row that *should* be at the bottom.
+ *
+ * @param {number} topRowIndex
+ * @return {number}
+ */
+hterm.ScrollPort.prototype.getBottomRowIndex = function(topRowIndex) {
+  return topRowIndex + this.visibleRowCount - 1;
+};
+
+/**
+ * Handler for scroll events.
+ *
+ * The onScroll event fires when scrollArea's scrollTop property changes.  This
+ * may be due to the user manually move the scrollbar, or a programmatic change.
+ *
+ * @param {!Event} e
+ */
+hterm.ScrollPort.prototype.onScroll_ = function(e) {
+  var screenSize = this.getScreenSize();
+  if (screenSize.width != this.lastScreenWidth_ ||
+      screenSize.height != this.lastScreenHeight_) {
+    // This event may also fire during a resize (but before the resize event!).
+    // This happens when the browser moves the scrollbar as part of the resize.
+    // In these cases, we want to ignore the scroll event and let onResize
+    // handle things.  If we don't, then we end up scrolling to the wrong
+    // position after a resize.
+    this.resize();
+    return;
+  }
+
+  this.redraw_();
+  this.publish('scroll', { scrollPort: this });
+};
+
+/**
+ * Clients can override this if they want to hear scrollwheel events.
+ *
+ * Clients may call event.preventDefault() if they want to keep the scrollport
+ * from also handling the events.
+ *
+ * @param {!WheelEvent} e
+ */
+hterm.ScrollPort.prototype.onScrollWheel = function(e) {};
+
+/**
+ * Handler for scroll-wheel events.
+ *
+ * The onScrollWheel event fires when the user moves their scrollwheel over this
+ * hterm.ScrollPort.  Because the frontmost element in the hterm.ScrollPort is
+ * a fixed position DIV, the scroll wheel does nothing by default.  Instead, we
+ * have to handle it manually.
+ *
+ * @param {!WheelEvent} e
+ */
+hterm.ScrollPort.prototype.onScrollWheel_ = function(e) {
+  this.onScrollWheel(e);
+
+  // Ignore the event if it was already handled (preventDefault was called),
+  // or if it is non-cancelable since preventDefault is ignored for these.
+  // See https://crbug.com/894223 where blink sends non-cancelable touchpad
+  // scrollWheel events.
+  if (e.defaultPrevented || !e.cancelable)
+    return;
+
+  // Figure out how far this event wants us to scroll.
+  const delta = this.scrollWheelDelta(e);
+
+  let top = this.screen_.scrollTop - delta.y;
+  if (top < 0)
+    top = 0;
+
+  var scrollMax = this.getScrollMax_();
+  if (top > scrollMax)
+    top = scrollMax;
+
+  if (top != this.screen_.scrollTop) {
+    // Moving scrollTop causes a scroll event, which triggers the redraw.
+    this.screen_.scrollTop = top;
+
+    // Only preventDefault when we've actually scrolled.  If there's nothing
+    // to scroll we want to pass the event through so Chrome can detect the
+    // overscroll.
+    e.preventDefault();
+  }
+};
+
+/**
+ * Calculate how far a wheel event should scroll.
+ *
+ * This normalizes the browser's concept of a scroll (pixels, lines, etc...)
+ * into a standard pixel distance.
+ *
+ * @param {!WheelEvent} e The mouse wheel event to process.
+ * @return {{x:number, y:number}} The x & y of how far (in pixels) to scroll.
+ */
+hterm.ScrollPort.prototype.scrollWheelDelta = function(e) {
+  const delta = {x: 0, y: 0};
+
+  switch (e.deltaMode) {
+    case WheelEvent.DOM_DELTA_PIXEL:
+      delta.x = e.deltaX * this.scrollWheelMultiplier_;
+      delta.y = e.deltaY * this.scrollWheelMultiplier_;
+      break;
+    case WheelEvent.DOM_DELTA_LINE:
+      delta.x = e.deltaX * this.characterSize.width;
+      delta.y = e.deltaY * this.characterSize.height;
+      break;
+    case WheelEvent.DOM_DELTA_PAGE:
+      delta.x = e.deltaX * this.characterSize.width *
+          hterm.getClientWidth(lib.notNull(this.screen_));
+      delta.y = e.deltaY * this.characterSize.height *
+          hterm.getClientHeight(lib.notNull(this.screen_));
+      break;
+  }
+
+  // The Y sign is inverted from what we would expect: up/down are
+  // negative/positive respectively.  The X sign is sane though: left/right
+  // are negative/positive respectively.
+  delta.y *= -1;
+
+  return delta;
+};
+
+/**
+ * Clients can override this if they want to hear touch events.
+ *
+ * Clients may call event.preventDefault() if they want to keep the scrollport
+ * from also handling the events.
+ *
+ * @param {!TouchEvent} e
+ */
+hterm.ScrollPort.prototype.onTouch = function(e) {};
+
+/**
+ * Handler for touch events.
+ *
+ * @param {!TouchEvent} e
+ */
+hterm.ScrollPort.prototype.onTouch_ = function(e) {
+  this.onTouch(e);
+
+  if (e.defaultPrevented)
+    return;
+
+  // Extract the fields from the Touch event that we need.  If we saved the
+  // event directly, it has references to other objects (like x-row) that
+  // might stick around for a long time.  This way we only have small objects
+  // in our lastTouch_ state.
+  var scrubTouch = function(t) {
+    return {
+      id: t.identifier,
+      y: t.clientY,
+      x: t.clientX,
+    };
+  };
+
+  var i, touch;
+  switch (e.type) {
+    case 'touchstart':
+      // Workaround focus bug on CrOS if possible.
+      // TODO(vapier): Drop this once https://crbug.com/919222 is fixed.
+      if (hterm.os == 'cros' && window.chrome && chrome.windows) {
+        chrome.windows.getCurrent((win) => {
+          if (!win.focused) {
+            chrome.windows.update(win.id, {focused: true});
+          }
+        });
+      }
+
+      // Save the current set of touches.
+      for (i = 0; i < e.changedTouches.length; ++i) {
+        touch = scrubTouch(e.changedTouches[i]);
+        this.lastTouch_[touch.id] = touch;
+      }
+      break;
+
+    case 'touchcancel':
+    case 'touchend':
+      // Throw away existing touches that we're finished with.
+      for (i = 0; i < e.changedTouches.length; ++i)
+        delete this.lastTouch_[e.changedTouches[i].identifier];
+      break;
+
+    case 'touchmove':
+      // Walk all of the touches in this one event and merge all of their
+      // changes into one delta.  This lets multiple fingers scroll faster.
+      var delta = 0;
+      for (i = 0; i < e.changedTouches.length; ++i) {
+        touch = scrubTouch(e.changedTouches[i]);
+        delta += (this.lastTouch_[touch.id].y - touch.y);
+        this.lastTouch_[touch.id] = touch;
+      }
+
+      // Invert to match the touchscreen scrolling direction of browser windows.
+      delta *= -1;
+
+      var top = this.screen_.scrollTop - delta;
+      if (top < 0)
+        top = 0;
+
+      var scrollMax = this.getScrollMax_();
+      if (top > scrollMax)
+        top = scrollMax;
+
+      if (top != this.screen_.scrollTop) {
+        // Moving scrollTop causes a scroll event, which triggers the redraw.
+        this.screen_.scrollTop = top;
+      }
+      break;
+  }
+
+  // To disable gestures or anything else interfering with our scrolling.
+  e.preventDefault();
+};
+
+/**
+ * Handler for resize events.
+ *
+ * The browser will resize us such that the top row stays at the top, but we
+ * prefer to the bottom row to stay at the bottom.
+ *
+ * @param {!FocusEvent} e
+ */
+hterm.ScrollPort.prototype.onResize_ = function(e) {
+  // Re-measure, since onResize also happens for browser zoom changes.
+  this.syncCharacterSize();
+};
+
+/**
+ * Clients can override this if they want to hear copy events.
+ *
+ * Clients may call event.preventDefault() if they want to keep the scrollport
+ * from also handling the events.
+ *
+ * @param {!ClipboardEvent} e
+ */
+hterm.ScrollPort.prototype.onCopy = function(e) { };
+
+/**
+ * Handler for copy-to-clipboard events.
+ *
+ * If some or all of the selected rows are off screen we may need to fill in
+ * the rows between selection start and selection end.  This handler determines
+ * if we're missing some of the selected text, and if so populates one or both
+ * of the "select bags" with the missing text.
+ *
+ * @param {!ClipboardEvent} e
+ */
+hterm.ScrollPort.prototype.onCopy_ = function(e) {
+  this.onCopy(e);
+
+  if (e.defaultPrevented)
+    return;
+
+  this.resetSelectBags_();
+  this.selection.sync();
+
+  if (this.selection.isCollapsed ||
+      this.selection.endRow.rowIndex - this.selection.startRow.rowIndex < 2) {
+    return;
+  }
+
+  var topRowIndex = this.getTopRowIndex();
+  var bottomRowIndex = this.getBottomRowIndex(topRowIndex);
+
+  if (this.selection.startRow.rowIndex < topRowIndex) {
+    // Start of selection is above the top fold.
+    var endBackfillIndex;
+
+    if (this.selection.endRow.rowIndex < topRowIndex) {
+      // Entire selection is above the top fold.
+      endBackfillIndex = this.selection.endRow.rowIndex;
+    } else {
+      // Selection extends below the top fold.
+      endBackfillIndex = this.topFold_.nextSibling.rowIndex;
+    }
+
+    this.topSelectBag_.textContent = this.rowProvider_.getRowsText(
+        this.selection.startRow.rowIndex + 1, endBackfillIndex);
+    this.rowNodes_.insertBefore(this.topSelectBag_,
+                                this.selection.startRow.nextSibling);
+    this.syncRowNodesDimensions_();
+  }
+
+  if (this.selection.endRow.rowIndex > bottomRowIndex) {
+    // Selection ends below the bottom fold.
+    var startBackfillIndex;
+
+    if (this.selection.startRow.rowIndex > bottomRowIndex) {
+      // Entire selection is below the bottom fold.
+      startBackfillIndex = this.selection.startRow.rowIndex + 1;
+    } else {
+      // Selection starts above the bottom fold.
+      startBackfillIndex = this.bottomFold_.previousSibling.rowIndex + 1;
+    }
+
+    this.bottomSelectBag_.textContent = this.rowProvider_.getRowsText(
+        startBackfillIndex, this.selection.endRow.rowIndex);
+    this.rowNodes_.insertBefore(this.bottomSelectBag_, this.selection.endRow);
+  }
+};
+
+/**
+ * Focuses on the paste target on a ctrl-v keydown event, as in
+ * FF a content editable element must be focused before the paste event.
+ *
+ * @param {!KeyboardEvent} e
+ */
+hterm.ScrollPort.prototype.onBodyKeyDown_ = function(e) {
+  if (!this.ctrlVPaste)
+    return;
+
+  if ((e.ctrlKey || e.metaKey) && e.keyCode == 86 /* 'V' */)
+    this.pasteTarget_.focus();
+};
+
+/**
+ * Handle a paste event on the the ScrollPort's screen element.
+ *
+ * TODO: Handle ClipboardData.files transfers.  https://crbug.com/433581.
+ *
+ * @param {!ClipboardEvent} e
+ */
+hterm.ScrollPort.prototype.onPaste_ = function(e) {
+  this.pasteTarget_.focus();
+
+  var self = this;
+  setTimeout(function() {
+      self.publish('paste', { text: self.pasteTarget_.value });
+      self.pasteTarget_.value = '';
+      self.focus();
+    }, 0);
+};
+
+/**
+ * Handles a textInput event on the paste target. Stops this from
+ * propagating as we want this to be handled in the onPaste_ method.
+ *
+ * @param {!Event} e
+ */
+hterm.ScrollPort.prototype.handlePasteTargetTextInput_ = function(e) {
+  e.stopPropagation();
+};
+
+/**
+ * Handle a drop event on the the ScrollPort's screen element.
+ *
+ * By default we try to copy in the structured format (HTML/whatever).
+ * The shift key can select plain text though.
+ *
+ * TODO: Handle DataTransfer.files transfers.  https://crbug.com/433581.
+ *
+ * @param {!DragEvent} e The drag event that fired us.
+ */
+hterm.ScrollPort.prototype.onDragAndDrop_ = function(e) {
+  if (!this.pasteOnDrop)
+    return;
+
+  e.preventDefault();
+
+  let data;
+  let format;
+
+  // If the shift key active, try to find a "rich" text source (but not plain
+  // text).  e.g. text/html is OK.
+  if (e.shiftKey) {
+    e.dataTransfer.types.forEach((t) => {
+      if (!format && t != 'text/plain' && t.startsWith('text/'))
+        format = t;
+    });
+
+    // If we found a non-plain text source, try it out first.
+    if (format)
+      data = e.dataTransfer.getData(format);
+  }
+
+  // If we haven't loaded anything useful, fall back to plain text.
+  if (!data)
+    data = e.dataTransfer.getData('text/plain');
+
+  if (data)
+    this.publish('paste', {text: data});
+};
+
+/**
+ * Set the vertical scrollbar mode of the ScrollPort.
+ *
+ * @param {boolean} state
+ */
+hterm.ScrollPort.prototype.setScrollbarVisible = function(state) {
+  this.screen_.style.overflowY = state ? 'scroll' : 'hidden';
+};
+
+/**
+ * Set scroll wheel multiplier. This alters how much the screen scrolls on
+ * mouse wheel events.
+ *
+ * @param {number} multiplier
+ */
+hterm.ScrollPort.prototype.setScrollWheelMoveMultipler = function(multiplier) {
+  this.scrollWheelMultiplier_ = multiplier;
+};
+// SOURCE FILE: hterm/js/hterm_terminal.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Constructor for the Terminal class.
+ *
+ * A Terminal pulls together the hterm.ScrollPort, hterm.Screen and hterm.VT100
+ * classes to provide the complete terminal functionality.
+ *
+ * There are a number of lower-level Terminal methods that can be called
+ * directly to manipulate the cursor, text, scroll region, and other terminal
+ * attributes.  However, the primary method is interpret(), which parses VT
+ * escape sequences and invokes the appropriate Terminal methods.
+ *
+ * This class was heavily influenced by Cory Maccarrone's Framebuffer class.
+ *
+ * TODO(rginda): Eventually we're going to need to support characters which are
+ * displayed twice as wide as standard latin characters.  This is to support
+ * CJK (and possibly other character sets).
+ *
+ * @param {?string=} profileId Optional preference profile name.  If not
+ *     provided or null, defaults to 'default'.
+ * @constructor
+ * @implements {hterm.RowProvider}
+ */
+hterm.Terminal = function(profileId) {
+  this.profileId_ = null;
+
+  /** @type {?hterm.PreferenceManager} */
+  this.prefs_ = null;
+
+  // Two screen instances.
+  this.primaryScreen_ = new hterm.Screen();
+  this.alternateScreen_ = new hterm.Screen();
+
+  // The "current" screen.
+  this.screen_ = this.primaryScreen_;
+
+  // The local notion of the screen size.  ScreenBuffers also have a size which
+  // indicates their present size.  During size changes, the two may disagree.
+  // Also, the inactive screen's size is not altered until it is made the active
+  // screen.
+  this.screenSize = new hterm.Size(0, 0);
+
+  // The scroll port we'll be using to display the visible rows.
+  this.scrollPort_ = new hterm.ScrollPort(this);
+  this.scrollPort_.subscribe('resize', this.onResize_.bind(this));
+  this.scrollPort_.subscribe('scroll', this.onScroll_.bind(this));
+  this.scrollPort_.subscribe('paste', this.onPaste_.bind(this));
+  this.scrollPort_.subscribe('focus', this.onScrollportFocus_.bind(this));
+  this.scrollPort_.onCopy = this.onCopy_.bind(this);
+
+  // The div that contains this terminal.
+  this.div_ = null;
+
+  // The document that contains the scrollPort.  Defaulted to the global
+  // document here so that the terminal is functional even if it hasn't been
+  // inserted into a document yet, but re-set in decorate().
+  this.document_ = window.document;
+
+  // The rows that have scrolled off screen and are no longer addressable.
+  this.scrollbackRows_ = [];
+
+  // Saved tab stops.
+  this.tabStops_ = [];
+
+  // Keep track of whether default tab stops have been erased; after a TBC
+  // clears all tab stops, defaults aren't restored on resize until a reset.
+  this.defaultTabStops = true;
+
+  // The VT's notion of the top and bottom rows.  Used during some VT
+  // cursor positioning and scrolling commands.
+  this.vtScrollTop_ = null;
+  this.vtScrollBottom_ = null;
+
+  // The DIV element for the visible cursor.
+  this.cursorNode_ = null;
+
+  // The current cursor shape of the terminal.
+  this.cursorShape_ = hterm.Terminal.cursorShape.BLOCK;
+
+  // Cursor blink on/off cycle in ms, overwritten by prefs once they're loaded.
+  this.cursorBlinkCycle_ = [100, 100];
+
+  // Whether to temporarily disable blinking.
+  this.cursorBlinkPause_ = false;
+
+  // Pre-bound onCursorBlink_ handler, so we don't have to do this for each
+  // cursor on/off servicing.
+  this.myOnCursorBlink_ = this.onCursorBlink_.bind(this);
+
+  // These prefs are cached so we don't have to read from local storage with
+  // each output and keystroke.  They are initialized by the preference manager.
+  /** @type {string} */
+  this.backgroundColor_ = '';
+  /** @type {string} */
+  this.foregroundColor_ = '';
+  this.scrollOnOutput_ = null;
+  this.scrollOnKeystroke_ = null;
+  this.scrollWheelArrowKeys_ = null;
+
+  // True if we should override mouse event reporting to allow local selection.
+  this.defeatMouseReports_ = false;
+
+  // Whether to auto hide the mouse cursor when typing.
+  this.setAutomaticMouseHiding();
+  // Timer to keep mouse visible while it's being used.
+  this.mouseHideDelay_ = null;
+
+  // Terminal bell sound.
+  this.bellAudio_ = this.document_.createElement('audio');
+  this.bellAudio_.id = 'hterm:bell-audio';
+  this.bellAudio_.setAttribute('preload', 'auto');
+
+  // The AccessibilityReader object for announcing command output.
+  this.accessibilityReader_ = null;
+
+  // The context menu object.
+  this.contextMenu = new hterm.ContextMenu();
+
+  // All terminal bell notifications that have been generated (not necessarily
+  // shown).
+  this.bellNotificationList_ = [];
+  this.bellSquelchTimeout_ = null;
+
+  // Whether we have permission to display notifications.
+  this.desktopNotificationBell_ = false;
+
+  // Cursor position and attributes saved with DECSC.
+  this.savedOptions_ = {};
+
+  // The current mode bits for the terminal.
+  this.options_ = new hterm.Options();
+
+  // Timeouts we might need to clear.
+  this.timeouts_ = {};
+
+  // The VT escape sequence interpreter.
+  this.vt = new hterm.VT(this);
+
+  this.saveCursorAndState(true);
+
+  // The keyboard handler.
+  this.keyboard = new hterm.Keyboard(this);
+
+  // General IO interface that can be given to third parties without exposing
+  // the entire terminal object.
+  this.io = new hterm.Terminal.IO(this);
+
+  // True if mouse-click-drag should scroll the terminal.
+  this.enableMouseDragScroll = true;
+
+  this.copyOnSelect = null;
+  this.mouseRightClickPaste = null;
+  this.mousePasteButton = null;
+
+  // Whether to use the default window copy behavior.
+  this.useDefaultWindowCopy = false;
+
+  this.clearSelectionAfterCopy = true;
+
+  this.realizeSize_(80, 24);
+  this.setDefaultTabStops();
+
+  // Whether we allow images to be shown.
+  this.allowImagesInline = null;
+
+  this.reportFocus = false;
+
+  this.setProfile(profileId || 'default',
+                  function() { this.onTerminalReady(); }.bind(this));
+};
+
+/**
+ * Possible cursor shapes.
+ */
+hterm.Terminal.cursorShape = {
+  BLOCK: 'BLOCK',
+  BEAM: 'BEAM',
+  UNDERLINE: 'UNDERLINE'
+};
+
+/**
+ * Clients should override this to be notified when the terminal is ready
+ * for use.
+ *
+ * The terminal initialization is asynchronous, and shouldn't be used before
+ * this method is called.
+ */
+hterm.Terminal.prototype.onTerminalReady = function() { };
+
+/**
+ * Default tab with of 8 to match xterm.
+ */
+hterm.Terminal.prototype.tabWidth = 8;
+
+/**
+ * Select a preference profile.
+ *
+ * This will load the terminal preferences for the given profile name and
+ * associate subsequent preference changes with the new preference profile.
+ *
+ * @param {string} profileId The name of the preference profile.  Forward slash
+ *     characters will be removed from the name.
+ * @param {function()=} opt_callback Optional callback to invoke when the
+ *     profile transition is complete.
+ */
+hterm.Terminal.prototype.setProfile = function(profileId, opt_callback) {
+  this.profileId_ = profileId.replace(/\//g, '');
+
+  var terminal = this;
+
+  if (this.prefs_)
+    this.prefs_.deactivate();
+
+  this.prefs_ = new hterm.PreferenceManager(this.profileId_);
+  this.prefs_.addObservers(null, {
+    'alt-gr-mode': function(v) {
+      if (v == null) {
+        if (navigator.language.toLowerCase() == 'en-us') {
+          v = 'none';
+        } else {
+          v = 'right-alt';
+        }
+      } else if (typeof v == 'string') {
+        v = v.toLowerCase();
+      } else {
+        v = 'none';
+      }
+
+      if (!/^(none|ctrl-alt|left-alt|right-alt)$/.test(v))
+        v = 'none';
+
+      terminal.keyboard.altGrMode = v;
+    },
+
+    'alt-backspace-is-meta-backspace': function(v) {
+      terminal.keyboard.altBackspaceIsMetaBackspace = v;
+    },
+
+    'alt-is-meta': function(v) {
+      terminal.keyboard.altIsMeta = v;
+    },
+
+    'alt-sends-what': function(v) {
+      if (!/^(escape|8-bit|browser-key)$/.test(v))
+        v = 'escape';
+
+      terminal.keyboard.altSendsWhat = v;
+    },
+
+    'audible-bell-sound': function(v) {
+      var ary = v.match(/^lib-resource:(\S+)/);
+      if (ary) {
+        terminal.bellAudio_.setAttribute('src',
+                                         lib.resource.getDataUrl(ary[1]));
+      } else {
+        terminal.bellAudio_.setAttribute('src', v);
+      }
+    },
+
+    'desktop-notification-bell': function(v) {
+      if (v && Notification) {
+        terminal.desktopNotificationBell_ =
+            Notification.permission === 'granted';
+        if (!terminal.desktopNotificationBell_) {
+          // Note: We don't call Notification.requestPermission here because
+          // Chrome requires the call be the result of a user action (such as an
+          // onclick handler), and pref listeners are run asynchronously.
+          //
+          // A way of working around this would be to display a dialog in the
+          // terminal with a "click-to-request-permission" button.
+          console.warn('desktop-notification-bell is true but we do not have ' +
+                       'permission to display notifications.');
+        }
+      } else {
+        terminal.desktopNotificationBell_ = false;
+      }
+    },
+
+    'background-color': function(v) {
+      terminal.setBackgroundColor(v);
+    },
+
+    'background-image': function(v) {
+      terminal.scrollPort_.setBackgroundImage(v);
+    },
+
+    'background-size': function(v) {
+      terminal.scrollPort_.setBackgroundSize(v);
+    },
+
+    'background-position': function(v) {
+      terminal.scrollPort_.setBackgroundPosition(v);
+    },
+
+    'backspace-sends-backspace': function(v) {
+      terminal.keyboard.backspaceSendsBackspace = v;
+    },
+
+    'character-map-overrides': function(v) {
+      if (!(v == null || v instanceof Object)) {
+        console.warn('Preference character-map-modifications is not an ' +
+                     'object: ' + v);
+        return;
+      }
+
+      terminal.vt.characterMaps.reset();
+      terminal.vt.characterMaps.setOverrides(v);
+    },
+
+    'cursor-blink': function(v) {
+      terminal.setCursorBlink(!!v);
+    },
+
+    'cursor-shape': function(v) {
+      terminal.setCursorShape(v);
+    },
+
+    'cursor-blink-cycle': function(v) {
+        if (v instanceof Array &&
+            typeof v[0] == 'number' &&
+            typeof v[1] == 'number') {
+          terminal.cursorBlinkCycle_ = v;
+        } else if (typeof v == 'number') {
+          terminal.cursorBlinkCycle_ = [v, v];
+        } else {
+          // Fast blink indicates an error.
+          terminal.cursorBlinkCycle_ = [100, 100];
+        }
+    },
+
+    'cursor-color': function(v) {
+      terminal.setCursorColor(v);
+    },
+
+    'color-palette-overrides': function(v) {
+      if (!(v == null || v instanceof Object || v instanceof Array)) {
+        console.warn('Preference color-palette-overrides is not an array or ' +
+                     'object: ' + v);
+        return;
+      }
+
+      lib.colors.colorPalette = lib.colors.stockColorPalette.concat();
+
+      if (v) {
+        for (var key in v) {
+          var i = parseInt(key, 10);
+          if (isNaN(i) || i < 0 || i > 255) {
+            console.log('Invalid value in palette: ' + key + ': ' + v[key]);
+            continue;
+          }
+
+          if (v[i]) {
+            var rgb = lib.colors.normalizeCSS(v[i]);
+            if (rgb)
+              lib.colors.colorPalette[i] = rgb;
+          }
+        }
+      }
+
+      terminal.primaryScreen_.textAttributes.resetColorPalette();
+      terminal.alternateScreen_.textAttributes.resetColorPalette();
+    },
+
+    'copy-on-select': function(v) {
+      terminal.copyOnSelect = !!v;
+    },
+
+    'use-default-window-copy': function(v) {
+      terminal.useDefaultWindowCopy = !!v;
+    },
+
+    'clear-selection-after-copy': function(v) {
+      terminal.clearSelectionAfterCopy = !!v;
+    },
+
+    'ctrl-plus-minus-zero-zoom': function(v) {
+      terminal.keyboard.ctrlPlusMinusZeroZoom = v;
+    },
+
+    'ctrl-c-copy': function(v) {
+      terminal.keyboard.ctrlCCopy = v;
+    },
+
+    'ctrl-v-paste': function(v) {
+      terminal.keyboard.ctrlVPaste = v;
+      terminal.scrollPort_.setCtrlVPaste(v);
+    },
+
+    'paste-on-drop': function(v) {
+      terminal.scrollPort_.setPasteOnDrop(v);
+    },
+
+    'east-asian-ambiguous-as-two-column': function(v) {
+      lib.wc.regardCjkAmbiguous = v;
+    },
+
+    'enable-8-bit-control': function(v) {
+      terminal.vt.enable8BitControl = !!v;
+    },
+
+    'enable-bold': function(v) {
+      terminal.syncBoldSafeState();
+    },
+
+    'enable-bold-as-bright': function(v) {
+      terminal.primaryScreen_.textAttributes.enableBoldAsBright = !!v;
+      terminal.alternateScreen_.textAttributes.enableBoldAsBright = !!v;
+    },
+
+    'enable-blink': function(v) {
+      terminal.setTextBlink(!!v);
+    },
+
+    'enable-clipboard-write': function(v) {
+      terminal.vt.enableClipboardWrite = !!v;
+    },
+
+    'enable-dec12': function(v) {
+      terminal.vt.enableDec12 = !!v;
+    },
+
+    'enable-csi-j-3': function(v) {
+      terminal.vt.enableCsiJ3 = !!v;
+    },
+
+    'font-family': function(v) {
+      terminal.syncFontFamily();
+    },
+
+    'font-size': function(v) {
+      v = parseInt(v, 10);
+      if (v <= 0) {
+        console.error(`Invalid font size: ${v}`);
+        return;
+      }
+
+      terminal.setFontSize(v);
+    },
+
+    'font-smoothing': function(v) {
+      terminal.syncFontFamily();
+    },
+
+    'foreground-color': function(v) {
+      terminal.setForegroundColor(v);
+    },
+
+    'hide-mouse-while-typing': function(v) {
+      terminal.setAutomaticMouseHiding(v);
+    },
+
+    'home-keys-scroll': function(v) {
+      terminal.keyboard.homeKeysScroll = v;
+    },
+
+    'keybindings': function(v) {
+      terminal.keyboard.bindings.clear();
+
+      if (!v)
+        return;
+
+      if (!(v instanceof Object)) {
+        console.error('Error in keybindings preference: Expected object');
+        return;
+      }
+
+      try {
+        terminal.keyboard.bindings.addBindings(v);
+      } catch (ex) {
+        console.error('Error in keybindings preference: ' + ex);
+      }
+    },
+
+    'media-keys-are-fkeys': function(v) {
+      terminal.keyboard.mediaKeysAreFKeys = v;
+    },
+
+    'meta-sends-escape': function(v) {
+      terminal.keyboard.metaSendsEscape = v;
+    },
+
+    'mouse-right-click-paste': function(v) {
+      terminal.mouseRightClickPaste = v;
+    },
+
+    'mouse-paste-button': function(v) {
+      terminal.syncMousePasteButton();
+    },
+
+    'page-keys-scroll': function(v) {
+      terminal.keyboard.pageKeysScroll = v;
+    },
+
+    'pass-alt-number': function(v) {
+      if (v == null) {
+        // Let Alt-1..9 pass to the browser (to control tab switching) on
+        // non-OS X systems, or if hterm is not opened in an app window.
+        v = (hterm.os != 'mac' && hterm.windowType != 'popup');
+      }
+
+      terminal.passAltNumber = v;
+    },
+
+    'pass-ctrl-number': function(v) {
+      if (v == null) {
+        // Let Ctrl-1..9 pass to the browser (to control tab switching) on
+        // non-OS X systems, or if hterm is not opened in an app window.
+        v = (hterm.os != 'mac' && hterm.windowType != 'popup');
+      }
+
+      terminal.passCtrlNumber = v;
+    },
+
+    'pass-meta-number': function(v) {
+      if (v == null) {
+        // Let Meta-1..9 pass to the browser (to control tab switching) on
+        // OS X systems, or if hterm is not opened in an app window.
+        v = (hterm.os == 'mac' && hterm.windowType != 'popup');
+      }
+
+      terminal.passMetaNumber = v;
+    },
+
+    'pass-meta-v': function(v) {
+      terminal.keyboard.passMetaV = v;
+    },
+
+    'receive-encoding': function(v) {
+       if (!(/^(utf-8|raw)$/).test(v)) {
+         console.warn('Invalid value for "receive-encoding": ' + v);
+         v = 'utf-8';
+       }
+
+       terminal.vt.characterEncoding = v;
+    },
+
+    'scroll-on-keystroke': function(v) {
+      terminal.scrollOnKeystroke_ = v;
+    },
+
+    'scroll-on-output': function(v) {
+      terminal.scrollOnOutput_ = v;
+    },
+
+    'scrollbar-visible': function(v) {
+      terminal.setScrollbarVisible(v);
+    },
+
+    'scroll-wheel-may-send-arrow-keys': function(v) {
+      terminal.scrollWheelArrowKeys_ = v;
+    },
+
+    'scroll-wheel-move-multiplier': function(v) {
+      terminal.setScrollWheelMoveMultipler(v);
+    },
+
+    'shift-insert-paste': function(v) {
+      terminal.keyboard.shiftInsertPaste = v;
+    },
+
+    'terminal-encoding': function(v) {
+      terminal.vt.setEncoding(v);
+    },
+
+    'user-css': function(v) {
+      terminal.scrollPort_.setUserCssUrl(v);
+    },
+
+    'user-css-text': function(v) {
+      terminal.scrollPort_.setUserCssText(v);
+    },
+
+    'word-break-match-left': function(v) {
+      terminal.primaryScreen_.wordBreakMatchLeft = v;
+      terminal.alternateScreen_.wordBreakMatchLeft = v;
+    },
+
+    'word-break-match-right': function(v) {
+      terminal.primaryScreen_.wordBreakMatchRight = v;
+      terminal.alternateScreen_.wordBreakMatchRight = v;
+    },
+
+    'word-break-match-middle': function(v) {
+      terminal.primaryScreen_.wordBreakMatchMiddle = v;
+      terminal.alternateScreen_.wordBreakMatchMiddle = v;
+    },
+
+    'allow-images-inline': function(v) {
+      terminal.allowImagesInline = v;
+    },
+  });
+
+  this.prefs_.readStorage(function() {
+    this.prefs_.notifyAll();
+
+    if (opt_callback)
+      opt_callback();
+  }.bind(this));
+};
+
+/**
+ * Returns the preferences manager used for configuring this terminal.
+ *
+ * @return {!hterm.PreferenceManager}
+ */
+hterm.Terminal.prototype.getPrefs = function() {
+  return lib.notNull(this.prefs_);
+};
+
+/**
+ * Enable or disable bracketed paste mode.
+ *
+ * @param {boolean} state The value to set.
+ */
+hterm.Terminal.prototype.setBracketedPaste = function(state) {
+  this.options_.bracketedPaste = state;
+};
+
+/**
+ * Set the color for the cursor.
+ *
+ * If you want this setting to persist, set it through prefs_, rather than
+ * with this method.
+ *
+ * @param {string=} color The color to set.  If not defined, we reset to the
+ *     saved user preference.
+ */
+hterm.Terminal.prototype.setCursorColor = function(color) {
+  if (color === undefined)
+    color = this.prefs_.getString('cursor-color');
+
+  this.setCssVar('cursor-color', color);
+};
+
+/**
+ * Return the current cursor color as a string.
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getCursorColor = function() {
+  return this.getCssVar('cursor-color');
+};
+
+/**
+ * Enable or disable mouse based text selection in the terminal.
+ *
+ * @param {boolean} state The value to set.
+ */
+hterm.Terminal.prototype.setSelectionEnabled = function(state) {
+  this.enableMouseDragScroll = state;
+};
+
+/**
+ * Set the background color.
+ *
+ * If you want this setting to persist, set it through prefs_, rather than
+ * with this method.
+ *
+ * @param {string=} color The color to set.  If not defined, we reset to the
+ *     saved user preference.
+ */
+hterm.Terminal.prototype.setBackgroundColor = function(color) {
+  if (color === undefined)
+    color = this.prefs_.getString('background-color');
+
+  this.backgroundColor_ = lib.colors.normalizeCSS(color) || '';
+  this.primaryScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_);
+  this.alternateScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_);
+  this.scrollPort_.setBackgroundColor(color);
+};
+
+/**
+ * Return the current terminal background color.
+ *
+ * Intended for use by other classes, so we don't have to expose the entire
+ * prefs_ object.
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getBackgroundColor = function() {
+  return lib.notNull(this.backgroundColor_);
+};
+
+/**
+ * Set the foreground color.
+ *
+ * If you want this setting to persist, set it through prefs_, rather than
+ * with this method.
+ *
+ * @param {string=} color The color to set.  If not defined, we reset to the
+ *     saved user preference.
+ */
+hterm.Terminal.prototype.setForegroundColor = function(color) {
+  if (color === undefined)
+    color = this.prefs_.getString('foreground-color');
+
+  this.foregroundColor_ = lib.colors.normalizeCSS(color) || '';
+  this.primaryScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_);
+  this.alternateScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_);
+  this.scrollPort_.setForegroundColor(color);
+};
+
+/**
+ * Return the current terminal foreground color.
+ *
+ * Intended for use by other classes, so we don't have to expose the entire
+ * prefs_ object.
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getForegroundColor = function() {
+  return lib.notNull(this.foregroundColor_);
+};
+
+/**
+ * Create a new instance of a terminal command and run it with a given
+ * argument string.
+ *
+ * @param {!Function} commandClass The constructor for a terminal command.
+ * @param {string} commandName The command to run for this terminal.
+ * @param {!Array<string>} args The arguments to pass to the command.
+ */
+hterm.Terminal.prototype.runCommandClass = function(
+    commandClass, commandName, args) {
+  var environment = this.prefs_.get('environment');
+  if (typeof environment != 'object' || environment == null)
+    environment = {};
+
+  var self = this;
+  this.command = new commandClass(
+      {
+        commandName: commandName,
+        args: args,
+        io: this.io.push(),
+        environment: environment,
+        onExit: function(code) {
+          self.io.pop();
+          self.uninstallKeyboard();
+          self.div_.dispatchEvent(new CustomEvent('terminal-closing'));
+          if (self.prefs_.get('close-on-exit'))
+              window.close();
+        }
+      });
+
+  this.installKeyboard();
+  this.command.run();
+};
+
+/**
+ * Returns true if the current screen is the primary screen, false otherwise.
+ *
+ * @return {boolean}
+ */
+hterm.Terminal.prototype.isPrimaryScreen = function() {
+  return this.screen_ == this.primaryScreen_;
+};
+
+/**
+ * Install the keyboard handler for this terminal.
+ *
+ * This will prevent the browser from seeing any keystrokes sent to the
+ * terminal.
+ */
+hterm.Terminal.prototype.installKeyboard = function() {
+  this.keyboard.installKeyboard(this.scrollPort_.getDocument().body);
+};
+
+/**
+ * Uninstall the keyboard handler for this terminal.
+ */
+hterm.Terminal.prototype.uninstallKeyboard = function() {
+  this.keyboard.installKeyboard(null);
+};
+
+/**
+ * Set a CSS variable.
+ *
+ * Normally this is used to set variables in the hterm namespace.
+ *
+ * @param {string} name The variable to set.
+ * @param {string|number} value The value to assign to the variable.
+ * @param {string=} opt_prefix The variable namespace/prefix to use.
+ */
+hterm.Terminal.prototype.setCssVar = function(name, value,
+                                              opt_prefix='--hterm-') {
+  this.document_.documentElement.style.setProperty(
+      `${opt_prefix}${name}`, value.toString());
+};
+
+/**
+ * Get a CSS variable.
+ *
+ * Normally this is used to get variables in the hterm namespace.
+ *
+ * @param {string} name The variable to read.
+ * @param {string=} opt_prefix The variable namespace/prefix to use.
+ * @return {string} The current setting for this variable.
+ */
+hterm.Terminal.prototype.getCssVar = function(name, opt_prefix='--hterm-') {
+  return this.document_.documentElement.style.getPropertyValue(
+      `${opt_prefix}${name}`);
+};
+
+/**
+ * Set the font size for this terminal.
+ *
+ * Call setFontSize(0) to reset to the default font size.
+ *
+ * This function does not modify the font-size preference.
+ *
+ * @param {number} px The desired font size, in pixels.
+ */
+hterm.Terminal.prototype.setFontSize = function(px) {
+  if (px <= 0)
+    px = this.prefs_.getNumber('font-size');
+
+  this.scrollPort_.setFontSize(px);
+  this.setCssVar('charsize-width', this.scrollPort_.characterSize.width + 'px');
+  this.setCssVar('charsize-height',
+                 this.scrollPort_.characterSize.height + 'px');
+};
+
+/**
+ * Get the current font size.
+ *
+ * @return {number}
+ */
+hterm.Terminal.prototype.getFontSize = function() {
+  return this.scrollPort_.getFontSize();
+};
+
+/**
+ * Get the current font family.
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getFontFamily = function() {
+  return this.scrollPort_.getFontFamily();
+};
+
+/**
+ * Set the CSS "font-family" for this terminal.
+ */
+hterm.Terminal.prototype.syncFontFamily = function() {
+  this.scrollPort_.setFontFamily(this.prefs_.getString('font-family'),
+                                 this.prefs_.getString('font-smoothing'));
+  this.syncBoldSafeState();
+};
+
+/**
+ * Set this.mousePasteButton based on the mouse-paste-button pref,
+ * autodetecting if necessary.
+ */
+hterm.Terminal.prototype.syncMousePasteButton = function() {
+  var button = this.prefs_.get('mouse-paste-button');
+  if (typeof button == 'number') {
+    this.mousePasteButton = button;
+    return;
+  }
+
+  if (hterm.os != 'linux') {
+    this.mousePasteButton = 1;  // Middle mouse button.
+  } else {
+    this.mousePasteButton = 2;  // Right mouse button.
+  }
+};
+
+/**
+ * Enable or disable bold based on the enable-bold pref, autodetecting if
+ * necessary.
+ */
+hterm.Terminal.prototype.syncBoldSafeState = function() {
+  var enableBold = this.prefs_.get('enable-bold');
+  if (enableBold !== null) {
+    this.primaryScreen_.textAttributes.enableBold = enableBold;
+    this.alternateScreen_.textAttributes.enableBold = enableBold;
+    return;
+  }
+
+  var normalSize = this.scrollPort_.measureCharacterSize();
+  var boldSize = this.scrollPort_.measureCharacterSize('bold');
+
+  var isBoldSafe = normalSize.equals(boldSize);
+  if (!isBoldSafe) {
+    console.warn('Bold characters disabled: Size of bold weight differs ' +
+                 'from normal.  Font family is: ' +
+                 this.scrollPort_.getFontFamily());
+  }
+
+  this.primaryScreen_.textAttributes.enableBold = isBoldSafe;
+  this.alternateScreen_.textAttributes.enableBold = isBoldSafe;
+};
+
+/**
+ * Control text blinking behavior.
+ *
+ * @param {boolean=} state Whether to enable support for blinking text.
+ */
+hterm.Terminal.prototype.setTextBlink = function(state) {
+  if (state === undefined)
+    state = this.prefs_.getBoolean('enable-blink');
+  this.setCssVar('blink-node-duration', state ? '0.7s' : '0');
+};
+
+/**
+ * Set the mouse cursor style based on the current terminal mode.
+ */
+hterm.Terminal.prototype.syncMouseStyle = function() {
+  this.setCssVar('mouse-cursor-style',
+                 this.vt.mouseReport == this.vt.MOUSE_REPORT_DISABLED ?
+                     'var(--hterm-mouse-cursor-text)' :
+                     'var(--hterm-mouse-cursor-default)');
+};
+
+/**
+ * Return a copy of the current cursor position.
+ *
+ * @return {!hterm.RowCol} The RowCol object representing the current position.
+ */
+hterm.Terminal.prototype.saveCursor = function() {
+  return this.screen_.cursorPosition.clone();
+};
+
+/**
+ * Return the current text attributes.
+ *
+ * @return {!hterm.TextAttributes}
+ */
+hterm.Terminal.prototype.getTextAttributes = function() {
+  return this.screen_.textAttributes;
+};
+
+/**
+ * Set the text attributes.
+ *
+ * @param {!hterm.TextAttributes} textAttributes The attributes to set.
+ */
+hterm.Terminal.prototype.setTextAttributes = function(textAttributes) {
+  this.screen_.textAttributes = textAttributes;
+};
+
+/**
+ * Return the current browser zoom factor applied to the terminal.
+ *
+ * @return {number} The current browser zoom factor.
+ */
+hterm.Terminal.prototype.getZoomFactor = function() {
+  return this.scrollPort_.characterSize.zoomFactor;
+};
+
+/**
+ * Change the title of this terminal's window.
+ *
+ * @param {string} title The title to set.
+ */
+hterm.Terminal.prototype.setWindowTitle = function(title) {
+  window.document.title = title;
+};
+
+/**
+ * Restore a previously saved cursor position.
+ *
+ * @param {!hterm.RowCol} cursor The position to restore.
+ */
+hterm.Terminal.prototype.restoreCursor = function(cursor) {
+  var row = lib.f.clamp(cursor.row, 0, this.screenSize.height - 1);
+  var column = lib.f.clamp(cursor.column, 0, this.screenSize.width - 1);
+  this.screen_.setCursorPosition(row, column);
+  if (cursor.column > column ||
+      cursor.column == column && cursor.overflow) {
+    this.screen_.cursorPosition.overflow = true;
+  }
+};
+
+/**
+ * Clear the cursor's overflow flag.
+ */
+hterm.Terminal.prototype.clearCursorOverflow = function() {
+  this.screen_.cursorPosition.overflow = false;
+};
+
+/**
+ * Save the current cursor state to the corresponding screens.
+ *
+ * See the hterm.Screen.CursorState class for more details.
+ *
+ * @param {boolean=} both If true, update both screens, else only update the
+ *     current screen.
+ */
+hterm.Terminal.prototype.saveCursorAndState = function(both) {
+  if (both) {
+    this.primaryScreen_.saveCursorAndState(this.vt);
+    this.alternateScreen_.saveCursorAndState(this.vt);
+  } else
+    this.screen_.saveCursorAndState(this.vt);
+};
+
+/**
+ * Restore the saved cursor state in the corresponding screens.
+ *
+ * See the hterm.Screen.CursorState class for more details.
+ *
+ * @param {boolean=} both If true, update both screens, else only update the
+ *     current screen.
+ */
+hterm.Terminal.prototype.restoreCursorAndState = function(both) {
+  if (both) {
+    this.primaryScreen_.restoreCursorAndState(this.vt);
+    this.alternateScreen_.restoreCursorAndState(this.vt);
+  } else
+    this.screen_.restoreCursorAndState(this.vt);
+};
+
+/**
+ * Sets the cursor shape
+ *
+ * @param {string} shape The shape to set.
+ */
+hterm.Terminal.prototype.setCursorShape = function(shape) {
+  this.cursorShape_ = shape;
+  this.restyleCursor_();
+};
+
+/**
+ * Get the cursor shape
+ *
+ * @return {string}
+ */
+hterm.Terminal.prototype.getCursorShape = function() {
+  return this.cursorShape_;
+};
+
+/**
+ * Set the width of the terminal, resizing the UI to match.
+ *
+ * @param {?number} columnCount
+ */
+hterm.Terminal.prototype.setWidth = function(columnCount) {
+  if (columnCount == null) {
+    this.div_.style.width = '100%';
+    return;
+  }
+
+  this.div_.style.width = Math.ceil(
+      this.scrollPort_.characterSize.width *
+      columnCount + this.scrollPort_.currentScrollbarWidthPx) + 'px';
+  this.realizeSize_(columnCount, this.screenSize.height);
+  this.scheduleSyncCursorPosition_();
+};
+
+/**
+ * Set the height of the terminal, resizing the UI to match.
+ *
+ * @param {?number} rowCount The height in rows.
+ */
+hterm.Terminal.prototype.setHeight = function(rowCount) {
+  if (rowCount == null) {
+    this.div_.style.height = '100%';
+    return;
+  }
+
+  this.div_.style.height =
+      this.scrollPort_.characterSize.height * rowCount + 'px';
+  this.realizeSize_(this.screenSize.width, rowCount);
+  this.scheduleSyncCursorPosition_();
+};
+
+/**
+ * Deal with terminal size changes.
+ *
+ * @param {number} columnCount The number of columns.
+ * @param {number} rowCount The number of rows.
+ */
+hterm.Terminal.prototype.realizeSize_ = function(columnCount, rowCount) {
+  let notify = false;
+
+  if (columnCount != this.screenSize.width) {
+    notify = true;
+    this.realizeWidth_(columnCount);
+  }
+
+  if (rowCount != this.screenSize.height) {
+    notify = true;
+    this.realizeHeight_(rowCount);
+  }
+
+  // Send new terminal size to plugin.
+  if (notify) {
+    this.io.onTerminalResize_(columnCount, rowCount);
+  }
+};
+
+/**
+ * Deal with terminal width changes.
+ *
+ * This function does what needs to be done when the terminal width changes
+ * out from under us.  It happens here rather than in onResize_() because this
+ * code may need to run synchronously to handle programmatic changes of
+ * terminal width.
+ *
+ * Relying on the browser to send us an async resize event means we may not be
+ * in the correct state yet when the next escape sequence hits.
+ *
+ * @param {number} columnCount The number of columns.
+ */
+hterm.Terminal.prototype.realizeWidth_ = function(columnCount) {
+  if (columnCount <= 0)
+    throw new Error('Attempt to realize bad width: ' + columnCount);
+
+  var deltaColumns = columnCount - this.screen_.getWidth();
+  if (deltaColumns == 0) {
+    // No change, so don't bother recalculating things.
+    return;
+  }
+
+  this.screenSize.width = columnCount;
+  this.screen_.setColumnCount(columnCount);
+
+  if (deltaColumns > 0) {
+    if (this.defaultTabStops)
+      this.setDefaultTabStops(this.screenSize.width - deltaColumns);
+  } else {
+    for (var i = this.tabStops_.length - 1; i >= 0; i--) {
+      if (this.tabStops_[i] < columnCount)
+        break;
+
+      this.tabStops_.pop();
+    }
+  }
+
+  this.screen_.setColumnCount(this.screenSize.width);
+};
+
+/**
+ * Deal with terminal height changes.
+ *
+ * This function does what needs to be done when the terminal height changes
+ * out from under us.  It happens here rather than in onResize_() because this
+ * code may need to run synchronously to handle programmatic changes of
+ * terminal height.
+ *
+ * Relying on the browser to send us an async resize event means we may not be
+ * in the correct state yet when the next escape sequence hits.
+ *
+ * @param {number} rowCount The number of rows.
+ */
+hterm.Terminal.prototype.realizeHeight_ = function(rowCount) {
+  if (rowCount <= 0)
+    throw new Error('Attempt to realize bad height: ' + rowCount);
+
+  var deltaRows = rowCount - this.screen_.getHeight();
+  if (deltaRows == 0) {
+    // No change, so don't bother recalculating things.
+    return;
+  }
+
+  this.screenSize.height = rowCount;
+
+  var cursor = this.saveCursor();
+
+  if (deltaRows < 0) {
+    // Screen got smaller.
+    deltaRows *= -1;
+    while (deltaRows) {
+      var lastRow = this.getRowCount() - 1;
+      if (lastRow - this.scrollbackRows_.length == cursor.row)
+        break;
+
+      if (this.getRowText(lastRow))
+        break;
+
+      this.screen_.popRow();
+      deltaRows--;
+    }
+
+    var ary = this.screen_.shiftRows(deltaRows);
+    this.scrollbackRows_.push.apply(this.scrollbackRows_, ary);
+
+    // We just removed rows from the top of the screen, we need to update
+    // the cursor to match.
+    cursor.row = Math.max(cursor.row - deltaRows, 0);
+  } else if (deltaRows > 0) {
+    // Screen got larger.
+
+    if (deltaRows <= this.scrollbackRows_.length) {
+      var scrollbackCount = Math.min(deltaRows, this.scrollbackRows_.length);
+      var rows = this.scrollbackRows_.splice(
+          this.scrollbackRows_.length - scrollbackCount, scrollbackCount);
+      this.screen_.unshiftRows(rows);
+      deltaRows -= scrollbackCount;
+      cursor.row += scrollbackCount;
+    }
+
+    if (deltaRows)
+      this.appendRows_(deltaRows);
+  }
+
+  this.setVTScrollRegion(null, null);
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Scroll the terminal to the top of the scrollback buffer.
+ */
+hterm.Terminal.prototype.scrollHome = function() {
+  this.scrollPort_.scrollRowToTop(0);
+};
+
+/**
+ * Scroll the terminal to the end.
+ */
+hterm.Terminal.prototype.scrollEnd = function() {
+  this.scrollPort_.scrollRowToBottom(this.getRowCount());
+};
+
+/**
+ * Scroll the terminal one page up (minus one line) relative to the current
+ * position.
+ */
+hterm.Terminal.prototype.scrollPageUp = function() {
+  this.scrollPort_.scrollPageUp();
+};
+
+/**
+ * Scroll the terminal one page down (minus one line) relative to the current
+ * position.
+ */
+hterm.Terminal.prototype.scrollPageDown = function() {
+  this.scrollPort_.scrollPageDown();
+};
+
+/**
+ * Scroll the terminal one line up relative to the current position.
+ */
+hterm.Terminal.prototype.scrollLineUp = function() {
+  var i = this.scrollPort_.getTopRowIndex();
+  this.scrollPort_.scrollRowToTop(i - 1);
+};
+
+/**
+ * Scroll the terminal one line down relative to the current position.
+ */
+hterm.Terminal.prototype.scrollLineDown = function() {
+  var i = this.scrollPort_.getTopRowIndex();
+  this.scrollPort_.scrollRowToTop(i + 1);
+};
+
+/**
+ * Clear primary screen, secondary screen, and the scrollback buffer.
+ */
+hterm.Terminal.prototype.wipeContents = function() {
+  this.clearHome(this.primaryScreen_);
+  this.clearHome(this.alternateScreen_);
+
+  this.clearScrollback();
+};
+
+/**
+ * Clear scrollback buffer.
+ */
+hterm.Terminal.prototype.clearScrollback = function() {
+  // Move to the end of the buffer in case the screen was scrolled back.
+  // We're going to throw it away which would leave the display invalid.
+  this.scrollEnd();
+
+  this.scrollbackRows_.length = 0;
+  this.scrollPort_.resetCache();
+
+  [this.primaryScreen_, this.alternateScreen_].forEach((screen) => {
+    const bottom = screen.getHeight();
+    this.renumberRows_(0, bottom, screen);
+  });
+
+  this.syncCursorPosition_();
+  this.scrollPort_.invalidate();
+};
+
+/**
+ * Full terminal reset.
+ *
+ * Perform a full reset to the default values listed in
+ * https://vt100.net/docs/vt510-rm/RIS.html
+ */
+hterm.Terminal.prototype.reset = function() {
+  this.vt.reset();
+
+  this.clearAllTabStops();
+  this.setDefaultTabStops();
+
+  const resetScreen = (screen) => {
+    // We want to make sure to reset the attributes before we clear the screen.
+    // The attributes might be used to initialize default/empty rows.
+    screen.textAttributes.reset();
+    screen.textAttributes.resetColorPalette();
+    this.clearHome(screen);
+    screen.saveCursorAndState(this.vt);
+  };
+  resetScreen(this.primaryScreen_);
+  resetScreen(this.alternateScreen_);
+
+  // Reset terminal options to their default values.
+  this.options_ = new hterm.Options();
+  this.setCursorBlink(!!this.prefs_.get('cursor-blink'));
+
+  this.setVTScrollRegion(null, null);
+
+  this.setCursorVisible(true);
+};
+
+/**
+ * Soft terminal reset.
+ *
+ * Perform a soft reset to the default values listed in
+ * http://www.vt100.net/docs/vt510-rm/DECSTR#T5-9
+ */
+hterm.Terminal.prototype.softReset = function() {
+  this.vt.reset();
+
+  // Reset terminal options to their default values.
+  this.options_ = new hterm.Options();
+
+  // We show the cursor on soft reset but do not alter the blink state.
+  this.options_.cursorBlink = !!this.timeouts_.cursorBlink;
+
+  const resetScreen = (screen) => {
+    // Xterm also resets the color palette on soft reset, even though it doesn't
+    // seem to be documented anywhere.
+    screen.textAttributes.reset();
+    screen.textAttributes.resetColorPalette();
+    screen.saveCursorAndState(this.vt);
+  };
+  resetScreen(this.primaryScreen_);
+  resetScreen(this.alternateScreen_);
+
+  // The xterm man page explicitly says this will happen on soft reset.
+  this.setVTScrollRegion(null, null);
+
+  // Xterm also shows the cursor on soft reset, but does not alter the blink
+  // state.
+  this.setCursorVisible(true);
+};
+
+/**
+ * Move the cursor forward to the next tab stop, or to the last column
+ * if no more tab stops are set.
+ */
+hterm.Terminal.prototype.forwardTabStop = function() {
+  var column = this.screen_.cursorPosition.column;
+
+  for (var i = 0; i < this.tabStops_.length; i++) {
+    if (this.tabStops_[i] > column) {
+      this.setCursorColumn(this.tabStops_[i]);
+      return;
+    }
+  }
+
+  // xterm does not clear the overflow flag on HT or CHT.
+  var overflow = this.screen_.cursorPosition.overflow;
+  this.setCursorColumn(this.screenSize.width - 1);
+  this.screen_.cursorPosition.overflow = overflow;
+};
+
+/**
+ * Move the cursor backward to the previous tab stop, or to the first column
+ * if no previous tab stops are set.
+ */
+hterm.Terminal.prototype.backwardTabStop = function() {
+  var column = this.screen_.cursorPosition.column;
+
+  for (var i = this.tabStops_.length - 1; i >= 0; i--) {
+    if (this.tabStops_[i] < column) {
+      this.setCursorColumn(this.tabStops_[i]);
+      return;
+    }
+  }
+
+  this.setCursorColumn(1);
+};
+
+/**
+ * Set a tab stop at the given column.
+ *
+ * @param {number} column Zero based column.
+ */
+hterm.Terminal.prototype.setTabStop = function(column) {
+  for (var i = this.tabStops_.length - 1; i >= 0; i--) {
+    if (this.tabStops_[i] == column)
+      return;
+
+    if (this.tabStops_[i] < column) {
+      this.tabStops_.splice(i + 1, 0, column);
+      return;
+    }
+  }
+
+  this.tabStops_.splice(0, 0, column);
+};
+
+/**
+ * Clear the tab stop at the current cursor position.
+ *
+ * No effect if there is no tab stop at the current cursor position.
+ */
+hterm.Terminal.prototype.clearTabStopAtCursor = function() {
+  var column = this.screen_.cursorPosition.column;
+
+  var i = this.tabStops_.indexOf(column);
+  if (i == -1)
+    return;
+
+  this.tabStops_.splice(i, 1);
+};
+
+/**
+ * Clear all tab stops.
+ */
+hterm.Terminal.prototype.clearAllTabStops = function() {
+  this.tabStops_.length = 0;
+  this.defaultTabStops = false;
+};
+
+/**
+ * Set up the default tab stops, starting from a given column.
+ *
+ * This sets a tabstop every (column % this.tabWidth) column, starting
+ * from the specified column, or 0 if no column is provided.  It also flags
+ * future resizes to set them up.
+ *
+ * This does not clear the existing tab stops first, use clearAllTabStops
+ * for that.
+ *
+ * @param {number=} opt_start Optional starting zero based starting column,
+ *     useful for filling out missing tab stops when the terminal is resized.
+ */
+hterm.Terminal.prototype.setDefaultTabStops = function(opt_start) {
+  var start = opt_start || 0;
+  var w = this.tabWidth;
+  // Round start up to a default tab stop.
+  start = start - 1 - ((start - 1) % w) + w;
+  for (var i = start; i < this.screenSize.width; i += w) {
+    this.setTabStop(i);
+  }
+
+  this.defaultTabStops = true;
+};
+
+/**
+ * Interpret a sequence of characters.
+ *
+ * Incomplete escape sequences are buffered until the next call.
+ *
+ * @param {string} str Sequence of characters to interpret or pass through.
+ */
+hterm.Terminal.prototype.interpret = function(str) {
+  this.scheduleSyncCursorPosition_();
+  this.vt.interpret(str);
+};
+
+/**
+ * Take over the given DIV for use as the terminal display.
+ *
+ * @param {!Element} div The div to use as the terminal display.
+ */
+hterm.Terminal.prototype.decorate = function(div) {
+  const charset = div.ownerDocument.characterSet.toLowerCase();
+  if (charset != 'utf-8') {
+    console.warn(`Document encoding should be set to utf-8, not "${charset}";` +
+                 ` Add <meta charset='utf-8'/> to your HTML <head> to fix.`);
+  }
+
+  this.div_ = div;
+
+  this.accessibilityReader_ = new hterm.AccessibilityReader(div);
+
+  this.scrollPort_.decorate(div, () => this.setupScrollPort_());
+};
+
+/**
+ * Initialisation of ScrollPort properties which need to be set after its DOM
+ * has been initialised.
+ *
+ * @private
+ */
+hterm.Terminal.prototype.setupScrollPort_ = function() {
+  this.scrollPort_.setBackgroundImage(
+      this.prefs_.getString('background-image'));
+  this.scrollPort_.setBackgroundSize(this.prefs_.getString('background-size'));
+  this.scrollPort_.setBackgroundPosition(
+      this.prefs_.getString('background-position'));
+  this.scrollPort_.setUserCssUrl(this.prefs_.getString('user-css'));
+  this.scrollPort_.setUserCssText(this.prefs_.getString('user-css-text'));
+  this.scrollPort_.setAccessibilityReader(
+      lib.notNull(this.accessibilityReader_));
+
+  this.div_.focus = this.focus.bind(this);
+
+  this.setFontSize(this.prefs_.getNumber('font-size'));
+  this.syncFontFamily();
+
+  this.setScrollbarVisible(this.prefs_.getBoolean('scrollbar-visible'));
+  this.setScrollWheelMoveMultipler(
+      this.prefs_.getNumber('scroll-wheel-move-multiplier'));
+
+  this.document_ = this.scrollPort_.getDocument();
+  this.accessibilityReader_.decorate(this.document_);
+
+  this.document_.body.oncontextmenu = function() { return false; };
+  this.contextMenu.setDocument(this.document_);
+
+  var onMouse = this.onMouse_.bind(this);
+  var screenNode = this.scrollPort_.getScreenNode();
+  screenNode.addEventListener(
+      'mousedown', /** @type {!EventListener} */ (onMouse));
+  screenNode.addEventListener(
+      'mouseup', /** @type {!EventListener} */ (onMouse));
+  screenNode.addEventListener(
+      'mousemove', /** @type {!EventListener} */ (onMouse));
+  this.scrollPort_.onScrollWheel = onMouse;
+
+  screenNode.addEventListener(
+      'keydown',
+      /** @type {!EventListener} */ (this.onKeyboardActivity_.bind(this)));
+
+  screenNode.addEventListener(
+      'focus', this.onFocusChange_.bind(this, true));
+  // Listen for mousedown events on the screenNode as in FF the focus
+  // events don't bubble.
+  screenNode.addEventListener('mousedown', function() {
+    setTimeout(this.onFocusChange_.bind(this, true));
+  }.bind(this));
+
+  screenNode.addEventListener(
+      'blur', this.onFocusChange_.bind(this, false));
+
+  var style = this.document_.createElement('style');
+  style.textContent = `
+.cursor-node[focus="false"] {
+  box-sizing: border-box;
+  background-color: transparent !important;
+  border-width: 2px;
+  border-style: solid;
+}
+menu {
+  margin: 0;
+  padding: 0;
+  cursor: var(--hterm-mouse-cursor-pointer);
+}
+menuitem {
+  white-space: nowrap;
+  border-bottom: 1px dashed;
+  display: block;
+  padding: 0.3em 0.3em 0 0.3em;
+}
+menuitem.separator {
+  border-bottom: none;
+  height: 0.5em;
+  padding: 0;
+}
+menuitem:hover {
+  color: var(--hterm-cursor-color);
+}
+.wc-node {
+  display: inline-block;
+  text-align: center;
+  width: calc(var(--hterm-charsize-width) * 2);
+  line-height: var(--hterm-charsize-height);
+}
+:root {
+  --hterm-charsize-width: ${this.scrollPort_.characterSize.width}px;
+  --hterm-charsize-height: ${this.scrollPort_.characterSize.height}px;
+  /* Default position hides the cursor for when the window is initializing. */
+  --hterm-cursor-offset-col: -1;
+  --hterm-cursor-offset-row: -1;
+  --hterm-blink-node-duration: 0.7s;
+  --hterm-mouse-cursor-default: default;
+  --hterm-mouse-cursor-text: text;
+  --hterm-mouse-cursor-pointer: pointer;
+  --hterm-mouse-cursor-style: var(--hterm-mouse-cursor-text);
+}
+.uri-node:hover {
+  text-decoration: underline;
+  cursor: var(--hterm-mouse-cursor-pointer);
+}
+@keyframes blink {
+  from { opacity: 1.0; }
+  to { opacity: 0.0; }
+}
+.blink-node {
+  animation-name: blink;
+  animation-duration: var(--hterm-blink-node-duration);
+  animation-iteration-count: infinite;
+  animation-timing-function: ease-in-out;
+  animation-direction: alternate;
+}`;
+  // Insert this stock style as the first node so that any user styles will
+  // override w/out having to use !important everywhere.  The rules above mix
+  // runtime variables with default ones designed to be overridden by the user,
+  // but we can wait for a concrete case from the users to determine the best
+  // way to split the sheet up to before & after the user-css settings.
+  this.document_.head.insertBefore(style, this.document_.head.firstChild);
+
+  this.cursorNode_ = this.document_.createElement('div');
+  this.cursorNode_.id = 'hterm:terminal-cursor';
+  this.cursorNode_.className = 'cursor-node';
+  this.cursorNode_.style.cssText = `
+position: absolute;
+left: calc(var(--hterm-charsize-width) * var(--hterm-cursor-offset-col));
+top: calc(var(--hterm-charsize-height) * var(--hterm-cursor-offset-row));
+display: ${this.options_.cursorVisible ? '' : 'none'};
+width: var(--hterm-charsize-width);
+height: var(--hterm-charsize-height);
+background-color: var(--hterm-cursor-color);
+border-color: var(--hterm-cursor-color);
+-webkit-transition: opacity, background-color 100ms linear;
+-moz-transition: opacity, background-color 100ms linear;`;
+
+  this.setCursorColor();
+  this.setCursorBlink(!!this.prefs_.get('cursor-blink'));
+  this.restyleCursor_();
+
+  this.document_.body.appendChild(this.cursorNode_);
+
+  // When 'enableMouseDragScroll' is off we reposition this element directly
+  // under the mouse cursor after a click.  This makes Chrome associate
+  // subsequent mousemove events with the scroll-blocker.  Since the
+  // scroll-blocker is a peer (not a child) of the scrollport, the mousemove
+  // events do not cause the scrollport to scroll.
+  //
+  // It's a hack, but it's the cleanest way I could find.
+  this.scrollBlockerNode_ = this.document_.createElement('div');
+  this.scrollBlockerNode_.id = 'hterm:mouse-drag-scroll-blocker';
+  this.scrollBlockerNode_.setAttribute('aria-hidden', 'true');
+  this.scrollBlockerNode_.style.cssText =
+      ('position: absolute;' +
+       'top: -99px;' +
+       'display: block;' +
+       'width: 10px;' +
+       'height: 10px;');
+  this.document_.body.appendChild(this.scrollBlockerNode_);
+
+  this.scrollPort_.onScrollWheel = onMouse;
+  ['mousedown', 'mouseup', 'mousemove', 'click', 'dblclick',
+   ].forEach(function(event) {
+       this.scrollBlockerNode_.addEventListener(event, onMouse);
+       this.cursorNode_.addEventListener(
+           event, /** @type {!EventListener} */ (onMouse));
+       this.document_.addEventListener(
+           event, /** @type {!EventListener} */ (onMouse));
+     }.bind(this));
+
+  this.cursorNode_.addEventListener('mousedown', function() {
+      setTimeout(this.focus.bind(this));
+    }.bind(this));
+
+  this.setReverseVideo(false);
+
+  this.scrollPort_.focus();
+  this.scrollPort_.scheduleRedraw();
+};
+
+/**
+ * Return the HTML document that contains the terminal DOM nodes.
+ *
+ * @return {!Document}
+ */
+hterm.Terminal.prototype.getDocument = function() {
+  return this.document_;
+};
+
+/**
+ * Focus the terminal.
+ */
+hterm.Terminal.prototype.focus = function() {
+  this.scrollPort_.focus();
+};
+
+/**
+ * Unfocus the terminal.
+ */
+hterm.Terminal.prototype.blur = function() {
+  this.scrollPort_.blur();
+};
+
+/**
+ * Return the HTML Element for a given row index.
+ *
+ * This is a method from the RowProvider interface.  The ScrollPort uses
+ * it to fetch rows on demand as they are scrolled into view.
+ *
+ * TODO(rginda): Consider saving scrollback rows as (HTML source, text content)
+ * pairs to conserve memory.
+ *
+ * @param {number} index The zero-based row index, measured relative to the
+ *     start of the scrollback buffer.  On-screen rows will always have the
+ *     largest indices.
+ * @return {!Element} The 'x-row' element containing for the requested row.
+ * @override
+ */
+hterm.Terminal.prototype.getRowNode = function(index) {
+  if (index < this.scrollbackRows_.length)
+    return this.scrollbackRows_[index];
+
+  var screenIndex = index - this.scrollbackRows_.length;
+  return this.screen_.rowsArray[screenIndex];
+};
+
+/**
+ * Return the text content for a given range of rows.
+ *
+ * This is a method from the RowProvider interface.  The ScrollPort uses
+ * it to fetch text content on demand when the user attempts to copy their
+ * selection to the clipboard.
+ *
+ * @param {number} start The zero-based row index to start from, measured
+ *     relative to the start of the scrollback buffer.  On-screen rows will
+ *     always have the largest indices.
+ * @param {number} end The zero-based row index to end on, measured
+ *     relative to the start of the scrollback buffer.
+ * @return {string} A single string containing the text value of the range of
+ *     rows.  Lines will be newline delimited, with no trailing newline.
+ */
+hterm.Terminal.prototype.getRowsText = function(start, end) {
+  var ary = [];
+  for (var i = start; i < end; i++) {
+    var node = this.getRowNode(i);
+    ary.push(node.textContent);
+    if (i < end - 1 && !node.getAttribute('line-overflow'))
+      ary.push('\n');
+  }
+
+  return ary.join('');
+};
+
+/**
+ * Return the text content for a given row.
+ *
+ * This is a method from the RowProvider interface.  The ScrollPort uses
+ * it to fetch text content on demand when the user attempts to copy their
+ * selection to the clipboard.
+ *
+ * @param {number} index The zero-based row index to return, measured
+ *     relative to the start of the scrollback buffer.  On-screen rows will
+ *     always have the largest indices.
+ * @return {string} A string containing the text value of the selected row.
+ */
+hterm.Terminal.prototype.getRowText = function(index) {
+  var node = this.getRowNode(index);
+  return node.textContent;
+};
+
+/**
+ * Return the total number of rows in the addressable screen and in the
+ * scrollback buffer of this terminal.
+ *
+ * This is a method from the RowProvider interface.  The ScrollPort uses
+ * it to compute the size of the scrollbar.
+ *
+ * @return {number} The number of rows in this terminal.
+ * @override
+ */
+hterm.Terminal.prototype.getRowCount = function() {
+  return this.scrollbackRows_.length + this.screen_.rowsArray.length;
+};
+
+/**
+ * Create DOM nodes for new rows and append them to the end of the terminal.
+ *
+ * This is the only correct way to add a new DOM node for a row.  Notice that
+ * the new row is appended to the bottom of the list of rows, and does not
+ * require renumbering (of the rowIndex property) of previous rows.
+ *
+ * If you think you want a new blank row somewhere in the middle of the
+ * terminal, look into moveRows_().
+ *
+ * This method does not pay attention to vtScrollTop/Bottom, since you should
+ * be using moveRows() in cases where they would matter.
+ *
+ * The cursor will be positioned at column 0 of the first inserted line.
+ *
+ * @param {number} count The number of rows to created.
+ */
+hterm.Terminal.prototype.appendRows_ = function(count) {
+  var cursorRow = this.screen_.rowsArray.length;
+  var offset = this.scrollbackRows_.length + cursorRow;
+  for (var i = 0; i < count; i++) {
+    var row = this.document_.createElement('x-row');
+    row.appendChild(this.document_.createTextNode(''));
+    row.rowIndex = offset + i;
+    this.screen_.pushRow(row);
+  }
+
+  var extraRows = this.screen_.rowsArray.length - this.screenSize.height;
+  if (extraRows > 0) {
+    var ary = this.screen_.shiftRows(extraRows);
+    Array.prototype.push.apply(this.scrollbackRows_, ary);
+    if (this.scrollPort_.isScrolledEnd)
+      this.scheduleScrollDown_();
+  }
+
+  if (cursorRow >= this.screen_.rowsArray.length)
+    cursorRow = this.screen_.rowsArray.length - 1;
+
+  this.setAbsoluteCursorPosition(cursorRow, 0);
+};
+
+/**
+ * Relocate rows from one part of the addressable screen to another.
+ *
+ * This is used to recycle rows during VT scrolls (those which are driven
+ * by VT commands, rather than by the user manipulating the scrollbar.)
+ *
+ * In this case, the blank lines scrolled into the scroll region are made of
+ * the nodes we scrolled off.  These have their rowIndex properties carefully
+ * renumbered so as not to confuse the ScrollPort.
+ *
+ * @param {number} fromIndex The start index.
+ * @param {number} count The number of rows to move.
+ * @param {number} toIndex The destination index.
+ */
+hterm.Terminal.prototype.moveRows_ = function(fromIndex, count, toIndex) {
+  var ary = this.screen_.removeRows(fromIndex, count);
+  this.screen_.insertRows(toIndex, ary);
+
+  var start, end;
+  if (fromIndex < toIndex) {
+    start = fromIndex;
+    end = toIndex + count;
+  } else {
+    start = toIndex;
+    end = fromIndex + count;
+  }
+
+  this.renumberRows_(start, end);
+  this.scrollPort_.scheduleInvalidate();
+};
+
+/**
+ * Renumber the rowIndex property of the given range of rows.
+ *
+ * The start and end indices are relative to the screen, not the scrollback.
+ * Rows in the scrollback buffer cannot be renumbered.  Since they are not
+ * addressable (you can't delete them, scroll them, etc), you should have
+ * no need to renumber scrollback rows.
+ *
+ * @param {number} start The start index.
+ * @param {number} end The end index.
+ * @param {!hterm.Screen=} opt_screen The screen to renumber.
+ */
+hterm.Terminal.prototype.renumberRows_ = function(start, end, opt_screen) {
+  var screen = opt_screen || this.screen_;
+
+  var offset = this.scrollbackRows_.length;
+  for (var i = start; i < end; i++) {
+    screen.rowsArray[i].rowIndex = offset + i;
+  }
+};
+
+/**
+ * Print a string to the terminal.
+ *
+ * This respects the current insert and wraparound modes.  It will add new lines
+ * to the end of the terminal, scrolling off the top into the scrollback buffer
+ * if necessary.
+ *
+ * The string is *not* parsed for escape codes.  Use the interpret() method if
+ * that's what you're after.
+ *
+ * @param {string} str The string to print.
+ */
+hterm.Terminal.prototype.print = function(str) {
+  this.scheduleSyncCursorPosition_();
+
+  // Basic accessibility output for the screen reader.
+  this.accessibilityReader_.announce(str);
+
+  var startOffset = 0;
+
+  var strWidth = lib.wc.strWidth(str);
+  // Fun edge case: If the string only contains zero width codepoints (like
+  // combining characters), we make sure to iterate at least once below.
+  if (strWidth == 0 && str)
+    strWidth = 1;
+
+  while (startOffset < strWidth) {
+    if (this.options_.wraparound && this.screen_.cursorPosition.overflow) {
+      this.screen_.commitLineOverflow();
+      this.newLine(true);
+    }
+
+    var count = strWidth - startOffset;
+    var didOverflow = false;
+    var substr;
+
+    if (this.screen_.cursorPosition.column + count >= this.screenSize.width) {
+      didOverflow = true;
+      count = this.screenSize.width - this.screen_.cursorPosition.column;
+    }
+
+    if (didOverflow && !this.options_.wraparound) {
+      // If the string overflowed the line but wraparound is off, then the
+      // last printed character should be the last of the string.
+      // TODO: This will add to our problems with multibyte UTF-16 characters.
+      substr = lib.wc.substr(str, startOffset, count - 1) +
+          lib.wc.substr(str, strWidth - 1);
+      count = strWidth;
+    } else {
+      substr = lib.wc.substr(str, startOffset, count);
+    }
+
+    var tokens = hterm.TextAttributes.splitWidecharString(substr);
+    for (var i = 0; i < tokens.length; i++) {
+      this.screen_.textAttributes.wcNode = tokens[i].wcNode;
+      this.screen_.textAttributes.asciiNode = tokens[i].asciiNode;
+
+      if (this.options_.insertMode) {
+        this.screen_.insertString(tokens[i].str, tokens[i].wcStrWidth);
+      } else {
+        this.screen_.overwriteString(tokens[i].str, tokens[i].wcStrWidth);
+      }
+      this.screen_.textAttributes.wcNode = false;
+      this.screen_.textAttributes.asciiNode = true;
+    }
+
+    this.screen_.maybeClipCurrentRow();
+    startOffset += count;
+  }
+
+  if (this.scrollOnOutput_)
+    this.scrollPort_.scrollRowToBottom(this.getRowCount());
+};
+
+/**
+ * Set the VT scroll region.
+ *
+ * This also resets the cursor position to the absolute (0, 0) position, since
+ * that's what xterm appears to do.
+ *
+ * Setting the scroll region to the full height of the terminal will clear
+ * the scroll region.  This is *NOT* what most terminals do.  We're explicitly
+ * going "off-spec" here because it makes `screen` and `tmux` overflow into the
+ * local scrollback buffer, which means the scrollbars and shift-pgup/pgdn
+ * continue to work as most users would expect.
+ *
+ * @param {?number} scrollTop The zero-based top of the scroll region.
+ * @param {?number} scrollBottom The zero-based bottom of the scroll region,
+ *     inclusive.
+ */
+hterm.Terminal.prototype.setVTScrollRegion = function(scrollTop, scrollBottom) {
+  if (scrollTop == 0 && scrollBottom == this.screenSize.height - 1) {
+    this.vtScrollTop_ = null;
+    this.vtScrollBottom_ = null;
+  } else {
+    this.vtScrollTop_ = scrollTop;
+    this.vtScrollBottom_ = scrollBottom;
+  }
+};
+
+/**
+ * Return the top row index according to the VT.
+ *
+ * This will return 0 unless the terminal has been told to restrict scrolling
+ * to some lower row.  It is used for some VT cursor positioning and scrolling
+ * commands.
+ *
+ * @return {number} The topmost row in the terminal's scroll region.
+ */
+hterm.Terminal.prototype.getVTScrollTop = function() {
+  if (this.vtScrollTop_ != null)
+    return this.vtScrollTop_;
+
+  return 0;
+};
+
+/**
+ * Return the bottom row index according to the VT.
+ *
+ * This will return the height of the terminal unless the it has been told to
+ * restrict scrolling to some higher row.  It is used for some VT cursor
+ * positioning and scrolling commands.
+ *
+ * @return {number} The bottom most row in the terminal's scroll region.
+ */
+hterm.Terminal.prototype.getVTScrollBottom = function() {
+  if (this.vtScrollBottom_ != null)
+    return this.vtScrollBottom_;
+
+  return this.screenSize.height - 1;
+};
+
+/**
+ * Process a '\n' character.
+ *
+ * If the cursor is on the final row of the terminal this will append a new
+ * blank row to the screen and scroll the topmost row into the scrollback
+ * buffer.
+ *
+ * Otherwise, this moves the cursor to column zero of the next row.
+ *
+ * @param {boolean=} dueToOverflow Whether the newline is due to wraparound of
+ *     the terminal.
+ */
+hterm.Terminal.prototype.newLine = function(dueToOverflow = false) {
+  if (!dueToOverflow)
+    this.accessibilityReader_.newLine();
+
+  var cursorAtEndOfScreen = (this.screen_.cursorPosition.row ==
+                             this.screen_.rowsArray.length - 1);
+
+  if (this.vtScrollBottom_ != null) {
+    // A VT Scroll region is active, we never append new rows.
+    if (this.screen_.cursorPosition.row == this.vtScrollBottom_) {
+      // We're at the end of the VT Scroll Region, perform a VT scroll.
+      this.vtScrollUp(1);
+      this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row, 0);
+    } else if (cursorAtEndOfScreen) {
+      // We're at the end of the screen, the only thing to do is put the
+      // cursor to column 0.
+      this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row, 0);
+    } else {
+      // Anywhere else, advance the cursor row, and reset the column.
+      this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row + 1, 0);
+    }
+  } else if (cursorAtEndOfScreen) {
+    // We're at the end of the screen.  Append a new row to the terminal,
+    // shifting the top row into the scrollback.
+    this.appendRows_(1);
+  } else {
+    // Anywhere else in the screen just moves the cursor.
+    this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row + 1, 0);
+  }
+};
+
+/**
+ * Like newLine(), except maintain the cursor column.
+ */
+hterm.Terminal.prototype.lineFeed = function() {
+  var column = this.screen_.cursorPosition.column;
+  this.newLine();
+  this.setCursorColumn(column);
+};
+
+/**
+ * If autoCarriageReturn is set then newLine(), else lineFeed().
+ */
+hterm.Terminal.prototype.formFeed = function() {
+  if (this.options_.autoCarriageReturn) {
+    this.newLine();
+  } else {
+    this.lineFeed();
+  }
+};
+
+/**
+ * Move the cursor up one row, possibly inserting a blank line.
+ *
+ * The cursor column is not changed.
+ */
+hterm.Terminal.prototype.reverseLineFeed = function() {
+  var scrollTop = this.getVTScrollTop();
+  var currentRow = this.screen_.cursorPosition.row;
+
+  if (currentRow == scrollTop) {
+    this.insertLines(1);
+  } else {
+    this.setAbsoluteCursorRow(currentRow - 1);
+  }
+};
+
+/**
+ * Replace all characters to the left of the current cursor with the space
+ * character.
+ *
+ * TODO(rginda): This should probably *remove* the characters (not just replace
+ * with a space) if there are no characters at or beyond the current cursor
+ * position.
+ */
+hterm.Terminal.prototype.eraseToLeft = function() {
+  var cursor = this.saveCursor();
+  this.setCursorColumn(0);
+  const count = cursor.column + 1;
+  this.screen_.overwriteString(' '.repeat(count), count);
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Erase a given number of characters to the right of the cursor.
+ *
+ * The cursor position is unchanged.
+ *
+ * If the current background color is not the default background color this
+ * will insert spaces rather than delete.  This is unfortunate because the
+ * trailing space will affect text selection, but it's difficult to come up
+ * with a way to style empty space that wouldn't trip up the hterm.Screen
+ * code.
+ *
+ * eraseToRight is ignored in the presence of a cursor overflow.  This deviates
+ * from xterm, but agrees with gnome-terminal and konsole, xfce4-terminal.  See
+ * crbug.com/232390 for details.
+ *
+ * @param {number=} opt_count The number of characters to erase.
+ */
+hterm.Terminal.prototype.eraseToRight = function(opt_count) {
+  if (this.screen_.cursorPosition.overflow)
+    return;
+
+  var maxCount = this.screenSize.width - this.screen_.cursorPosition.column;
+  var count = opt_count ? Math.min(opt_count, maxCount) : maxCount;
+
+  if (this.screen_.textAttributes.background ===
+      this.screen_.textAttributes.DEFAULT_COLOR) {
+    var cursorRow = this.screen_.rowsArray[this.screen_.cursorPosition.row];
+    if (hterm.TextAttributes.nodeWidth(cursorRow) <=
+        this.screen_.cursorPosition.column + count) {
+      this.screen_.deleteChars(count);
+      this.clearCursorOverflow();
+      return;
+    }
+  }
+
+  var cursor = this.saveCursor();
+  this.screen_.overwriteString(' '.repeat(count), count);
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Erase the current line.
+ *
+ * The cursor position is unchanged.
+ */
+hterm.Terminal.prototype.eraseLine = function() {
+  var cursor = this.saveCursor();
+  this.screen_.clearCursorRow();
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Erase all characters from the start of the screen to the current cursor
+ * position, regardless of scroll region.
+ *
+ * The cursor position is unchanged.
+ */
+hterm.Terminal.prototype.eraseAbove = function() {
+  var cursor = this.saveCursor();
+
+  this.eraseToLeft();
+
+  for (var i = 0; i < cursor.row; i++) {
+    this.setAbsoluteCursorPosition(i, 0);
+    this.screen_.clearCursorRow();
+  }
+
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Erase all characters from the current cursor position to the end of the
+ * screen, regardless of scroll region.
+ *
+ * The cursor position is unchanged.
+ */
+hterm.Terminal.prototype.eraseBelow = function() {
+  var cursor = this.saveCursor();
+
+  this.eraseToRight();
+
+  var bottom = this.screenSize.height - 1;
+  for (var i = cursor.row + 1; i <= bottom; i++) {
+    this.setAbsoluteCursorPosition(i, 0);
+    this.screen_.clearCursorRow();
+  }
+
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Fill the terminal with a given character.
+ *
+ * This methods does not respect the VT scroll region.
+ *
+ * @param {string} ch The character to use for the fill.
+ */
+hterm.Terminal.prototype.fill = function(ch) {
+  var cursor = this.saveCursor();
+
+  this.setAbsoluteCursorPosition(0, 0);
+  for (var row = 0; row < this.screenSize.height; row++) {
+    for (var col = 0; col < this.screenSize.width; col++) {
+      this.setAbsoluteCursorPosition(row, col);
+      this.screen_.overwriteString(ch, 1);
+    }
+  }
+
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Erase the entire display and leave the cursor at (0, 0).
+ *
+ * This does not respect the scroll region.
+ *
+ * @param {!hterm.Screen=} opt_screen Optional screen to operate on.  Defaults
+ *     to the current screen.
+ */
+hterm.Terminal.prototype.clearHome = function(opt_screen) {
+  var screen = opt_screen || this.screen_;
+  var bottom = screen.getHeight();
+
+  this.accessibilityReader_.clear();
+
+  if (bottom == 0) {
+    // Empty screen, nothing to do.
+    return;
+  }
+
+  for (var i = 0; i < bottom; i++) {
+    screen.setCursorPosition(i, 0);
+    screen.clearCursorRow();
+  }
+
+  screen.setCursorPosition(0, 0);
+};
+
+/**
+ * Erase the entire display without changing the cursor position.
+ *
+ * The cursor position is unchanged.  This does not respect the scroll
+ * region.
+ *
+ * @param {!hterm.Screen=} opt_screen Optional screen to operate on.  Defaults
+ *     to the current screen.
+ */
+hterm.Terminal.prototype.clear = function(opt_screen) {
+  var screen = opt_screen || this.screen_;
+  var cursor = screen.cursorPosition.clone();
+  this.clearHome(screen);
+  screen.setCursorPosition(cursor.row, cursor.column);
+};
+
+/**
+ * VT command to insert lines at the current cursor row.
+ *
+ * This respects the current scroll region.  Rows pushed off the bottom are
+ * lost (they won't show up in the scrollback buffer).
+ *
+ * @param {number} count The number of lines to insert.
+ */
+hterm.Terminal.prototype.insertLines = function(count) {
+  var cursorRow = this.screen_.cursorPosition.row;
+
+  var bottom = this.getVTScrollBottom();
+  count = Math.min(count, bottom - cursorRow);
+
+  // The moveCount is the number of rows we need to relocate to make room for
+  // the new row(s).  The count is the distance to move them.
+  var moveCount = bottom - cursorRow - count + 1;
+  if (moveCount)
+    this.moveRows_(cursorRow, moveCount, cursorRow + count);
+
+  for (var i = count - 1; i >= 0; i--) {
+    this.setAbsoluteCursorPosition(cursorRow + i, 0);
+    this.screen_.clearCursorRow();
+  }
+};
+
+/**
+ * VT command to delete lines at the current cursor row.
+ *
+ * New rows are added to the bottom of scroll region to take their place.  New
+ * rows are strictly there to take up space and have no content or style.
+ *
+ * @param {number} count The number of lines to delete.
+ */
+hterm.Terminal.prototype.deleteLines = function(count) {
+  var cursor = this.saveCursor();
+
+  var top = cursor.row;
+  var bottom = this.getVTScrollBottom();
+
+  var maxCount = bottom - top + 1;
+  count = Math.min(count, maxCount);
+
+  var moveStart = bottom - count + 1;
+  if (count != maxCount)
+    this.moveRows_(top, count, moveStart);
+
+  for (var i = 0; i < count; i++) {
+    this.setAbsoluteCursorPosition(moveStart + i, 0);
+    this.screen_.clearCursorRow();
+  }
+
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Inserts the given number of spaces at the current cursor position.
+ *
+ * The cursor position is not changed.
+ *
+ * @param {number} count The number of spaces to insert.
+ */
+hterm.Terminal.prototype.insertSpace = function(count) {
+  var cursor = this.saveCursor();
+
+  const ws = ' '.repeat(count || 1);
+  this.screen_.insertString(ws, ws.length);
+  this.screen_.maybeClipCurrentRow();
+
+  this.restoreCursor(cursor);
+  this.clearCursorOverflow();
+};
+
+/**
+ * Forward-delete the specified number of characters starting at the cursor
+ * position.
+ *
+ * @param {number} count The number of characters to delete.
+ */
+hterm.Terminal.prototype.deleteChars = function(count) {
+  var deleted = this.screen_.deleteChars(count);
+  if (deleted && !this.screen_.textAttributes.isDefault()) {
+    var cursor = this.saveCursor();
+    this.setCursorColumn(this.screenSize.width - deleted);
+    this.screen_.insertString(' '.repeat(deleted));
+    this.restoreCursor(cursor);
+  }
+
+  this.clearCursorOverflow();
+};
+
+/**
+ * Shift rows in the scroll region upwards by a given number of lines.
+ *
+ * New rows are inserted at the bottom of the scroll region to fill the
+ * vacated rows.  The new rows not filled out with the current text attributes.
+ *
+ * This function does not affect the scrollback rows at all.  Rows shifted
+ * off the top are lost.
+ *
+ * The cursor position is not altered.
+ *
+ * @param {number} count The number of rows to scroll.
+ */
+hterm.Terminal.prototype.vtScrollUp = function(count) {
+  var cursor = this.saveCursor();
+
+  this.setAbsoluteCursorRow(this.getVTScrollTop());
+  this.deleteLines(count);
+
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Shift rows below the cursor down by a given number of lines.
+ *
+ * This function respects the current scroll region.
+ *
+ * New rows are inserted at the top of the scroll region to fill the
+ * vacated rows.  The new rows not filled out with the current text attributes.
+ *
+ * This function does not affect the scrollback rows at all.  Rows shifted
+ * off the bottom are lost.
+ *
+ * @param {number} count The number of rows to scroll.
+ */
+hterm.Terminal.prototype.vtScrollDown = function(count) {
+  var cursor = this.saveCursor();
+
+  this.setAbsoluteCursorPosition(this.getVTScrollTop(), 0);
+  this.insertLines(count);
+
+  this.restoreCursor(cursor);
+};
+
+/**
+ * Enable accessibility-friendly features that have a performance impact.
+ *
+ * This will generate additional DOM nodes in an aria-live region that will
+ * cause Assitive Technology to announce the output of the terminal. It also
+ * enables other features that aid assistive technology. All the features gated
+ * behind this flag have a performance impact on the terminal which is why they
+ * are made optional.
+ *
+ * @param {boolean} enabled Whether to enable accessibility-friendly features.
+ */
+hterm.Terminal.prototype.setAccessibilityEnabled = function(enabled) {
+  this.accessibilityReader_.setAccessibilityEnabled(enabled);
+};
+
+/**
+ * Set the cursor position.
+ *
+ * The cursor row is relative to the scroll region if the terminal has
+ * 'origin mode' enabled, or relative to the addressable screen otherwise.
+ *
+ * @param {number} row The new zero-based cursor row.
+ * @param {number} column The new zero-based cursor column.
+ */
+hterm.Terminal.prototype.setCursorPosition = function(row, column) {
+  if (this.options_.originMode) {
+    this.setRelativeCursorPosition(row, column);
+  } else {
+    this.setAbsoluteCursorPosition(row, column);
+  }
+};
+
+/**
+ * Move the cursor relative to its current position.
+ *
+ * @param {number} row
+ * @param {number} column
+ */
+hterm.Terminal.prototype.setRelativeCursorPosition = function(row, column) {
+  var scrollTop = this.getVTScrollTop();
+  row = lib.f.clamp(row + scrollTop, scrollTop, this.getVTScrollBottom());
+  column = lib.f.clamp(column, 0, this.screenSize.width - 1);
+  this.screen_.setCursorPosition(row, column);
+};
+
+/**
+ * Move the cursor to the specified position.
+ *
+ * @param {number} row
+ * @param {number} column
+ */
+hterm.Terminal.prototype.setAbsoluteCursorPosition = function(row, column) {
+  row = lib.f.clamp(row, 0, this.screenSize.height - 1);
+  column = lib.f.clamp(column, 0, this.screenSize.width - 1);
+  this.screen_.setCursorPosition(row, column);
+};
+
+/**
+ * Set the cursor column.
+ *
+ * @param {number} column The new zero-based cursor column.
+ */
+hterm.Terminal.prototype.setCursorColumn = function(column) {
+  this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row, column);
+};
+
+/**
+ * Return the cursor column.
+ *
+ * @return {number} The zero-based cursor column.
+ */
+hterm.Terminal.prototype.getCursorColumn = function() {
+  return this.screen_.cursorPosition.column;
+};
+
+/**
+ * Set the cursor row.
+ *
+ * The cursor row is relative to the scroll region if the terminal has
+ * 'origin mode' enabled, or relative to the addressable screen otherwise.
+ *
+ * @param {number} row The new cursor row.
+ */
+hterm.Terminal.prototype.setAbsoluteCursorRow = function(row) {
+  this.setAbsoluteCursorPosition(row, this.screen_.cursorPosition.column);
+};
+
+/**
+ * Return the cursor row.
+ *
+ * @return {number} The zero-based cursor row.
+ */
+hterm.Terminal.prototype.getCursorRow = function() {
+  return this.screen_.cursorPosition.row;
+};
+
+/**
+ * Request that the ScrollPort redraw itself soon.
+ *
+ * The redraw will happen asynchronously, soon after the call stack winds down.
+ * Multiple calls will be coalesced into a single redraw.
+ */
+hterm.Terminal.prototype.scheduleRedraw_ = function() {
+  if (this.timeouts_.redraw)
+    return;
+
+  var self = this;
+  this.timeouts_.redraw = setTimeout(function() {
+      delete self.timeouts_.redraw;
+      self.scrollPort_.redraw_();
+    }, 0);
+};
+
+/**
+ * Request that the ScrollPort be scrolled to the bottom.
+ *
+ * The scroll will happen asynchronously, soon after the call stack winds down.
+ * Multiple calls will be coalesced into a single scroll.
+ *
+ * This affects the scrollbar position of the ScrollPort, and has nothing to
+ * do with the VT scroll commands.
+ */
+hterm.Terminal.prototype.scheduleScrollDown_ = function() {
+  if (this.timeouts_.scrollDown)
+    return;
+
+  var self = this;
+  this.timeouts_.scrollDown = setTimeout(function() {
+      delete self.timeouts_.scrollDown;
+      self.scrollPort_.scrollRowToBottom(self.getRowCount());
+    }, 10);
+};
+
+/**
+ * Move the cursor up a specified number of rows.
+ *
+ * @param {number} count The number of rows to move the cursor.
+ */
+hterm.Terminal.prototype.cursorUp = function(count) {
+  this.cursorDown(-(count || 1));
+};
+
+/**
+ * Move the cursor down a specified number of rows.
+ *
+ * @param {number} count The number of rows to move the cursor.
+ */
+hterm.Terminal.prototype.cursorDown = function(count) {
+  count = count || 1;
+  var minHeight = (this.options_.originMode ? this.getVTScrollTop() : 0);
+  var maxHeight = (this.options_.originMode ? this.getVTScrollBottom() :
+                   this.screenSize.height - 1);
+
+  var row = lib.f.clamp(this.screen_.cursorPosition.row + count,
+                        minHeight, maxHeight);
+  this.setAbsoluteCursorRow(row);
+};
+
+/**
+ * Move the cursor left a specified number of columns.
+ *
+ * If reverse wraparound mode is enabled and the previous row wrapped into
+ * the current row then we back up through the wraparound as well.
+ *
+ * @param {number} count The number of columns to move the cursor.
+ */
+hterm.Terminal.prototype.cursorLeft = function(count) {
+  count = count || 1;
+
+  if (count < 1)
+    return;
+
+  var currentColumn = this.screen_.cursorPosition.column;
+  if (this.options_.reverseWraparound) {
+    if (this.screen_.cursorPosition.overflow) {
+      // If this cursor is in the right margin, consume one count to get it
+      // back to the last column.  This only applies when we're in reverse
+      // wraparound mode.
+      count--;
+      this.clearCursorOverflow();
+
+      if (!count)
+        return;
+    }
+
+    var newRow = this.screen_.cursorPosition.row;
+    var newColumn = currentColumn - count;
+    if (newColumn < 0) {
+      newRow = newRow - Math.floor(count / this.screenSize.width) - 1;
+      if (newRow < 0) {
+        // xterm also wraps from row 0 to the last row.
+        newRow = this.screenSize.height + newRow % this.screenSize.height;
+      }
+      newColumn = this.screenSize.width + newColumn % this.screenSize.width;
+    }
+
+    this.setCursorPosition(Math.max(newRow, 0), newColumn);
+
+  } else {
+    var newColumn = Math.max(currentColumn - count, 0);
+    this.setCursorColumn(newColumn);
+  }
+};
+
+/**
+ * Move the cursor right a specified number of columns.
+ *
+ * @param {number} count The number of columns to move the cursor.
+ */
+hterm.Terminal.prototype.cursorRight = function(count) {
+  count = count || 1;
+
+  if (count < 1)
+    return;
+
+  var column = lib.f.clamp(this.screen_.cursorPosition.column + count,
+                           0, this.screenSize.width - 1);
+  this.setCursorColumn(column);
+};
+
+/**
+ * Reverse the foreground and background colors of the terminal.
+ *
+ * This only affects text that was drawn with no attributes.
+ *
+ * TODO(rginda): Test xterm to see if reverse is respected for text that has
+ * been drawn with attributes that happen to coincide with the default
+ * 'no-attribute' colors.  My guess is probably not.
+ *
+ * @param {boolean} state The state to set.
+ */
+hterm.Terminal.prototype.setReverseVideo = function(state) {
+  this.options_.reverseVideo = state;
+  if (state) {
+    this.scrollPort_.setForegroundColor(this.backgroundColor_);
+    this.scrollPort_.setBackgroundColor(this.foregroundColor_);
+  } else {
+    this.scrollPort_.setForegroundColor(this.foregroundColor_);
+    this.scrollPort_.setBackgroundColor(this.backgroundColor_);
+  }
+};
+
+/**
+ * Ring the terminal bell.
+ *
+ * This will not play the bell audio more than once per second.
+ */
+hterm.Terminal.prototype.ringBell = function() {
+  this.cursorNode_.style.backgroundColor =
+      this.scrollPort_.getForegroundColor();
+
+  var self = this;
+  setTimeout(function() {
+      self.restyleCursor_();
+    }, 200);
+
+  // bellSquelchTimeout_ affects both audio and notification bells.
+  if (this.bellSquelchTimeout_)
+    return;
+
+  if (this.bellAudio_.getAttribute('src')) {
+    this.bellAudio_.play();
+    this.bellSequelchTimeout_ = setTimeout(() => {
+        this.bellSquelchTimeout_ = null;
+      }, 500);
+  } else {
+    this.bellSquelchTimeout_ = null;
+  }
+
+  if (this.desktopNotificationBell_ && !this.document_.hasFocus()) {
+    var n = hterm.notify();
+    this.bellNotificationList_.push(n);
+    // TODO: Should we try to raise the window here?
+    n.onclick = function() { self.closeBellNotifications_(); };
+  }
+};
+
+/**
+ * Set the origin mode bit.
+ *
+ * If origin mode is on, certain VT cursor and scrolling commands measure their
+ * row parameter relative to the VT scroll region.  Otherwise, row 0 corresponds
+ * to the top of the addressable screen.
+ *
+ * Defaults to off.
+ *
+ * @param {boolean} state True to set origin mode, false to unset.
+ */
+hterm.Terminal.prototype.setOriginMode = function(state) {
+  this.options_.originMode = state;
+  this.setCursorPosition(0, 0);
+};
+
+/**
+ * Set the insert mode bit.
+ *
+ * If insert mode is on, existing text beyond the cursor position will be
+ * shifted right to make room for new text.  Otherwise, new text overwrites
+ * any existing text.
+ *
+ * Defaults to off.
+ *
+ * @param {boolean} state True to set insert mode, false to unset.
+ */
+hterm.Terminal.prototype.setInsertMode = function(state) {
+  this.options_.insertMode = state;
+};
+
+/**
+ * Set the auto carriage return bit.
+ *
+ * If auto carriage return is on then a formfeed character is interpreted
+ * as a newline, otherwise it's the same as a linefeed.  The difference boils
+ * down to whether or not the cursor column is reset.
+ *
+ * @param {boolean} state The state to set.
+ */
+hterm.Terminal.prototype.setAutoCarriageReturn = function(state) {
+  this.options_.autoCarriageReturn = state;
+};
+
+/**
+ * Set the wraparound mode bit.
+ *
+ * If wraparound mode is on, certain VT commands will allow the cursor to wrap
+ * to the start of the following row.  Otherwise, the cursor is clamped to the
+ * end of the screen and attempts to write past it are ignored.
+ *
+ * Defaults to on.
+ *
+ * @param {boolean} state True to set wraparound mode, false to unset.
+ */
+hterm.Terminal.prototype.setWraparound = function(state) {
+  this.options_.wraparound = state;
+};
+
+/**
+ * Set the reverse-wraparound mode bit.
+ *
+ * If wraparound mode is off, certain VT commands will allow the cursor to wrap
+ * to the end of the previous row.  Otherwise, the cursor is clamped to column
+ * 0.
+ *
+ * Defaults to off.
+ *
+ * @param {boolean} state True to set reverse-wraparound mode, false to unset.
+ */
+hterm.Terminal.prototype.setReverseWraparound = function(state) {
+  this.options_.reverseWraparound = state;
+};
+
+/**
+ * Selects between the primary and alternate screens.
+ *
+ * If alternate mode is on, the alternate screen is active.  Otherwise the
+ * primary screen is active.
+ *
+ * Swapping screens has no effect on the scrollback buffer.
+ *
+ * Each screen maintains its own cursor position.
+ *
+ * Defaults to off.
+ *
+ * @param {boolean} state True to set alternate mode, false to unset.
+ */
+hterm.Terminal.prototype.setAlternateMode = function(state) {
+  var cursor = this.saveCursor();
+  this.screen_ = state ? this.alternateScreen_ : this.primaryScreen_;
+
+  if (this.screen_.rowsArray.length &&
+      this.screen_.rowsArray[0].rowIndex != this.scrollbackRows_.length) {
+    // If the screen changed sizes while we were away, our rowIndexes may
+    // be incorrect.
+    var offset = this.scrollbackRows_.length;
+    var ary = this.screen_.rowsArray;
+    for (var i = 0; i < ary.length; i++) {
+      ary[i].rowIndex = offset + i;
+    }
+  }
+
+  this.realizeWidth_(this.screenSize.width);
+  this.realizeHeight_(this.screenSize.height);
+  this.scrollPort_.syncScrollHeight();
+  this.scrollPort_.invalidate();
+
+  this.restoreCursor(cursor);
+  this.scrollPort_.resize();
+};
+
+/**
+ * Set the cursor-blink mode bit.
+ *
+ * If cursor-blink is on, the cursor will blink when it is visible.  Otherwise
+ * a visible cursor does not blink.
+ *
+ * You should make sure to turn blinking off if you're going to dispose of a
+ * terminal, otherwise you'll leak a timeout.
+ *
+ * Defaults to on.
+ *
+ * @param {boolean} state True to set cursor-blink mode, false to unset.
+ */
+hterm.Terminal.prototype.setCursorBlink = function(state) {
+  this.options_.cursorBlink = state;
+
+  if (!state && this.timeouts_.cursorBlink) {
+    clearTimeout(this.timeouts_.cursorBlink);
+    delete this.timeouts_.cursorBlink;
+  }
+
+  if (this.options_.cursorVisible)
+    this.setCursorVisible(true);
+};
+
+/**
+ * Set the cursor-visible mode bit.
+ *
+ * If cursor-visible is on, the cursor will be visible.  Otherwise it will not.
+ *
+ * Defaults to on.
+ *
+ * @param {boolean} state True to set cursor-visible mode, false to unset.
+ */
+hterm.Terminal.prototype.setCursorVisible = function(state) {
+  this.options_.cursorVisible = state;
+
+  if (!state) {
+    if (this.timeouts_.cursorBlink) {
+      clearTimeout(this.timeouts_.cursorBlink);
+      delete this.timeouts_.cursorBlink;
+    }
+    this.cursorNode_.style.opacity = '0';
+    return;
+  }
+
+  this.syncCursorPosition_();
+
+  this.cursorNode_.style.opacity = '1';
+
+  if (this.options_.cursorBlink) {
+    if (this.timeouts_.cursorBlink)
+      return;
+
+    this.onCursorBlink_();
+  } else {
+    if (this.timeouts_.cursorBlink) {
+      clearTimeout(this.timeouts_.cursorBlink);
+      delete this.timeouts_.cursorBlink;
+    }
+  }
+};
+
+/**
+ * Pause blinking temporarily.
+ *
+ * When the cursor moves around, it can be helpful to momentarily pause the
+ * blinking.  This could be when the user is typing in things, or when they're
+ * moving around with the arrow keys.
+ */
+hterm.Terminal.prototype.pauseCursorBlink_ = function() {
+  if (!this.options_.cursorBlink) {
+    return;
+  }
+
+  this.cursorBlinkPause_ = true;
+
+  // If a timeout is already pending, reset the clock due to the new input.
+  if (this.timeouts_.cursorBlinkPause) {
+    clearTimeout(this.timeouts_.cursorBlinkPause);
+  }
+  // After 500ms, resume blinking.  That seems like a good balance between user
+  // input timings & responsiveness to resume.
+  this.timeouts_.cursorBlinkPause = setTimeout(() => {
+    delete this.timeouts_.cursorBlinkPause;
+    this.cursorBlinkPause_ = false;
+  }, 500);
+};
+
+/**
+ * Synchronizes the visible cursor and document selection with the current
+ * cursor coordinates.
+ *
+ * @return {boolean} True if the cursor is onscreen and synced.
+ */
+hterm.Terminal.prototype.syncCursorPosition_ = function() {
+  var topRowIndex = this.scrollPort_.getTopRowIndex();
+  var bottomRowIndex = this.scrollPort_.getBottomRowIndex(topRowIndex);
+  var cursorRowIndex = this.scrollbackRows_.length +
+      this.screen_.cursorPosition.row;
+
+  let forceSyncSelection = false;
+  if (this.accessibilityReader_.accessibilityEnabled) {
+    // Report the new position of the cursor for accessibility purposes.
+    const cursorColumnIndex = this.screen_.cursorPosition.column;
+    const cursorLineText =
+        this.screen_.rowsArray[this.screen_.cursorPosition.row].innerText;
+    // This will force the selection to be sync'd to the cursor position if the
+    // user has pressed a key. Generally we would only sync the cursor position
+    // when selection is collapsed so that if the user has selected something
+    // we don't clear the selection by moving the selection. However when a
+    // screen reader is used, it's intuitive for entering a key to move the
+    // selection to the cursor.
+    forceSyncSelection = this.accessibilityReader_.hasUserGesture;
+    this.accessibilityReader_.afterCursorChange(
+        cursorLineText, cursorRowIndex, cursorColumnIndex);
+  }
+
+  if (cursorRowIndex > bottomRowIndex) {
+    // Cursor is scrolled off screen, move it outside of the visible area.
+    this.setCssVar('cursor-offset-row', '-1');
+    return false;
+  }
+
+  if (this.options_.cursorVisible &&
+      this.cursorNode_.style.display == 'none') {
+    // Re-display the terminal cursor if it was hidden by the mouse cursor.
+    this.cursorNode_.style.display = '';
+  }
+
+  // Position the cursor using CSS variable math.  If we do the math in JS,
+  // the float math will end up being more precise than the CSS which will
+  // cause the cursor tracking to be off.
+  this.setCssVar(
+      'cursor-offset-row',
+      `${cursorRowIndex - topRowIndex} + ` +
+      `${this.scrollPort_.visibleRowTopMargin}px`);
+  this.setCssVar('cursor-offset-col', this.screen_.cursorPosition.column);
+
+  this.cursorNode_.setAttribute('title',
+                                '(' + this.screen_.cursorPosition.column +
+                                ', ' + this.screen_.cursorPosition.row +
+                                ')');
+
+  // Update the caret for a11y purposes.
+  var selection = this.document_.getSelection();
+  if (selection && (selection.isCollapsed || forceSyncSelection)) {
+    this.screen_.syncSelectionCaret(selection);
+  }
+  return true;
+};
+
+/**
+ * Adjusts the style of this.cursorNode_ according to the current cursor shape
+ * and character cell dimensions.
+ */
+hterm.Terminal.prototype.restyleCursor_ = function() {
+  var shape = this.cursorShape_;
+
+  if (this.cursorNode_.getAttribute('focus') == 'false') {
+    // Always show a block cursor when unfocused.
+    shape = hterm.Terminal.cursorShape.BLOCK;
+  }
+
+  var style = this.cursorNode_.style;
+
+  switch (shape) {
+    case hterm.Terminal.cursorShape.BEAM:
+      style.backgroundColor = 'transparent';
+      style.borderBottomStyle = '';
+      style.borderLeftStyle = 'solid';
+      break;
+
+    case hterm.Terminal.cursorShape.UNDERLINE:
+      style.backgroundColor = 'transparent';
+      style.borderBottomStyle = 'solid';
+      style.borderLeftStyle = '';
+      break;
+
+    default:
+      style.backgroundColor = 'var(--hterm-cursor-color)';
+      style.borderBottomStyle = '';
+      style.borderLeftStyle = '';
+      break;
+  }
+};
+
+/**
+ * Synchronizes the visible cursor with the current cursor coordinates.
+ *
+ * The sync will happen asynchronously, soon after the call stack winds down.
+ * Multiple calls will be coalesced into a single sync. This should be called
+ * prior to the cursor actually changing position.
+ */
+hterm.Terminal.prototype.scheduleSyncCursorPosition_ = function() {
+  if (this.timeouts_.syncCursor)
+    return;
+
+  if (this.accessibilityReader_.accessibilityEnabled) {
+    // Report the previous position of the cursor for accessibility purposes.
+    const cursorRowIndex = this.scrollbackRows_.length +
+        this.screen_.cursorPosition.row;
+    const cursorColumnIndex = this.screen_.cursorPosition.column;
+    const cursorLineText =
+        this.screen_.rowsArray[this.screen_.cursorPosition.row].innerText;
+    this.accessibilityReader_.beforeCursorChange(
+        cursorLineText, cursorRowIndex, cursorColumnIndex);
+  }
+
+  var self = this;
+  this.timeouts_.syncCursor = setTimeout(function() {
+      self.syncCursorPosition_();
+      delete self.timeouts_.syncCursor;
+    }, 0);
+};
+
+/**
+ * Show or hide the zoom warning.
+ *
+ * The zoom warning is a message warning the user that their browser zoom must
+ * be set to 100% in order for hterm to function properly.
+ *
+ * @param {boolean} state True to show the message, false to hide it.
+ */
+hterm.Terminal.prototype.showZoomWarning_ = function(state) {
+  if (!this.zoomWarningNode_) {
+    if (!state)
+      return;
+
+    this.zoomWarningNode_ = this.document_.createElement('div');
+    this.zoomWarningNode_.id = 'hterm:zoom-warning';
+    this.zoomWarningNode_.style.cssText = (
+        'color: black;' +
+        'background-color: #ff2222;' +
+        'font-size: large;' +
+        'border-radius: 8px;' +
+        'opacity: 0.75;' +
+        'padding: 0.2em 0.5em 0.2em 0.5em;' +
+        'top: 0.5em;' +
+        'right: 1.2em;' +
+        'position: absolute;' +
+        '-webkit-text-size-adjust: none;' +
+        '-webkit-user-select: none;' +
+        '-moz-text-size-adjust: none;' +
+        '-moz-user-select: none;');
+
+    this.zoomWarningNode_.addEventListener('click', function(e) {
+      this.parentNode.removeChild(this);
+    });
+  }
+
+  this.zoomWarningNode_.textContent = lib.i18n.replaceReferences(
+      hterm.zoomWarningMessage,
+      [Math.floor(this.scrollPort_.characterSize.zoomFactor * 100)]);
+
+  this.zoomWarningNode_.style.fontFamily = this.prefs_.get('font-family');
+
+  if (state) {
+    if (!this.zoomWarningNode_.parentNode)
+      this.div_.parentNode.appendChild(this.zoomWarningNode_);
+  } else if (this.zoomWarningNode_.parentNode) {
+    this.zoomWarningNode_.parentNode.removeChild(this.zoomWarningNode_);
+  }
+};
+
+/**
+ * Show the terminal overlay for a given amount of time.
+ *
+ * The terminal overlay appears in inverse video in a large font, centered
+ * over the terminal.  You should probably keep the overlay message brief,
+ * since it's in a large font and you probably aren't going to check the size
+ * of the terminal first.
+ *
+ * @param {string} msg The text (not HTML) message to display in the overlay.
+ * @param {number=} opt_timeout The amount of time to wait before fading out
+ *     the overlay.  Defaults to 1.5 seconds.  Pass null to have the overlay
+ *     stay up forever (or until the next overlay).
+ */
+hterm.Terminal.prototype.showOverlay = function(msg, opt_timeout) {
+  if (!this.overlayNode_) {
+    if (!this.div_)
+      return;
+
+    this.overlayNode_ = this.document_.createElement('div');
+    this.overlayNode_.style.cssText = (
+        'border-radius: 15px;' +
+        'font-size: xx-large;' +
+        'opacity: 0.75;' +
+        'padding: 0.2em 0.5em 0.2em 0.5em;' +
+        'position: absolute;' +
+        '-webkit-user-select: none;' +
+        '-webkit-transition: opacity 180ms ease-in;' +
+        '-moz-user-select: none;' +
+        '-moz-transition: opacity 180ms ease-in;');
+
+    this.overlayNode_.addEventListener('mousedown', function(e) {
+      e.preventDefault();
+      e.stopPropagation();
+    }, true);
+  }
+
+  this.overlayNode_.style.color = this.prefs_.get('background-color');
+  this.overlayNode_.style.backgroundColor = this.prefs_.get('foreground-color');
+  this.overlayNode_.style.fontFamily = this.prefs_.get('font-family');
+
+  this.overlayNode_.textContent = msg;
+  this.overlayNode_.style.opacity = '0.75';
+
+  if (!this.overlayNode_.parentNode)
+    this.div_.appendChild(this.overlayNode_);
+
+  var divSize = hterm.getClientSize(lib.notNull(this.div_));
+  var overlaySize = hterm.getClientSize(this.overlayNode_);
+
+  this.overlayNode_.style.top =
+      (divSize.height - overlaySize.height) / 2 + 'px';
+  this.overlayNode_.style.left = (divSize.width - overlaySize.width -
+      this.scrollPort_.currentScrollbarWidthPx) / 2 + 'px';
+
+  if (this.overlayTimeout_)
+    clearTimeout(this.overlayTimeout_);
+
+  this.accessibilityReader_.assertiveAnnounce(msg);
+
+  if (opt_timeout === null)
+    return;
+
+  this.overlayTimeout_ = setTimeout(() => {
+    this.overlayNode_.style.opacity = '0';
+    this.overlayTimeout_ = setTimeout(() => this.hideOverlay(), 200);
+  }, opt_timeout || 1500);
+};
+
+/**
+ * Hide the terminal overlay immediately.
+ *
+ * Useful when we show an overlay for an event with an unknown end time.
+ */
+hterm.Terminal.prototype.hideOverlay = function() {
+  if (this.overlayTimeout_)
+    clearTimeout(this.overlayTimeout_);
+  this.overlayTimeout_ = null;
+
+  if (this.overlayNode_.parentNode)
+    this.overlayNode_.parentNode.removeChild(this.overlayNode_);
+  this.overlayNode_.style.opacity = '0.75';
+};
+
+/**
+ * Paste from the system clipboard to the terminal.
+ *
+ * @return {boolean}
+ */
+hterm.Terminal.prototype.paste = function() {
+  return hterm.pasteFromClipboard(this.document_);
+};
+
+/**
+ * Copy a string to the system clipboard.
+ *
+ * Note: If there is a selected range in the terminal, it'll be cleared.
+ *
+ * @param {string} str The string to copy.
+ */
+hterm.Terminal.prototype.copyStringToClipboard = function(str) {
+  if (this.prefs_.get('enable-clipboard-notice'))
+    setTimeout(this.showOverlay.bind(this, hterm.notifyCopyMessage, 500), 200);
+
+  hterm.copySelectionToClipboard(this.document_, str);
+};
+
+/**
+ * Display an image.
+ *
+ * Either URI or buffer or blob fields must be specified.
+ *
+ * @param {{
+ *     name: (string|undefined),
+ *     size: (string|number|undefined),
+ *     preserveAspectRation: (boolean|undefined),
+ *     inline: (boolean|undefined),
+ *     width: (string|number|undefined),
+ *     height: (string|number|undefined),
+ *     align: (string|undefined),
+ *     url: (string|undefined),
+ *     buffer: (!ArrayBuffer|undefined),
+ *     blob: (!Blob|undefined),
+ *     type: (string|undefined),
+ * }} options The image to display.
+ *   name A human readable string for the image
+ *   size The size (in bytes).
+ *   preserveAspectRatio Whether to preserve aspect.
+ *   inline Whether to display the image inline.
+ *   width The width of the image.
+ *   height The height of the image.
+ *   align Direction to align the image.
+ *   uri The source URI for the image.
+ *   buffer The ArrayBuffer image data.
+ *   blob The Blob image data.
+ *   type The MIME type of the image data.
+ * @param {function()=} onLoad Callback when loading finishes.
+ * @param {function(!Event)=} onError Callback when loading fails.
+ */
+hterm.Terminal.prototype.displayImage = function(options, onLoad, onError) {
+  // Make sure we're actually given a resource to display.
+  if (options.uri === undefined && options.buffer === undefined &&
+      options.blob === undefined)
+    return;
+
+  // Set up the defaults to simplify code below.
+  if (!options.name)
+    options.name = '';
+
+  // See if the mime type is available.  If not, guess from the filename.
+  // We don't list all possible mime types because the browser can usually
+  // guess it correctly.  So list the ones that need a bit more help.
+  if (!options.type) {
+    const ary = options.name.split('.');
+    const ext = ary[ary.length - 1].trim();
+    switch (ext) {
+      case 'svg':
+      case 'svgz':
+        options.type = 'image/svg+xml';
+        break;
+    }
+  }
+
+  // Has the user approved image display yet?
+  if (this.allowImagesInline !== true) {
+    this.newLine();
+    const row = this.getRowNode(this.scrollbackRows_.length +
+                                this.getCursorRow() - 1);
+
+    if (this.allowImagesInline === false) {
+      row.textContent = hterm.msg('POPUP_INLINE_IMAGE_DISABLED', [],
+                                  'Inline Images Disabled');
+      return;
+    }
+
+    // Show a prompt.
+    let button;
+    const span = this.document_.createElement('span');
+    span.innerText = hterm.msg('POPUP_INLINE_IMAGE', [], 'Inline Images');
+    span.style.fontWeight = 'bold';
+    span.style.borderWidth = '1px';
+    span.style.borderStyle = 'dashed';
+    button = this.document_.createElement('span');
+    button.innerText = hterm.msg('BUTTON_BLOCK', [], 'block');
+    button.style.marginLeft = '1em';
+    button.style.borderWidth = '1px';
+    button.style.borderStyle = 'solid';
+    button.addEventListener('click', () => {
+      this.prefs_.set('allow-images-inline', false);
+    });
+    span.appendChild(button);
+    button = this.document_.createElement('span');
+    button.innerText = hterm.msg('BUTTON_ALLOW_SESSION', [],
+                                 'allow this session');
+    button.style.marginLeft = '1em';
+    button.style.borderWidth = '1px';
+    button.style.borderStyle = 'solid';
+    button.addEventListener('click', () => {
+      this.allowImagesInline = true;
+    });
+    span.appendChild(button);
+    button = this.document_.createElement('span');
+    button.innerText = hterm.msg('BUTTON_ALLOW_ALWAYS', [], 'always allow');
+    button.style.marginLeft = '1em';
+    button.style.borderWidth = '1px';
+    button.style.borderStyle = 'solid';
+    button.addEventListener('click', () => {
+      this.prefs_.set('allow-images-inline', true);
+    });
+    span.appendChild(button);
+
+    row.appendChild(span);
+    return;
+  }
+
+  // See if we should show this object directly, or download it.
+  if (options.inline) {
+    const io = this.io.push();
+    io.showOverlay(hterm.msg('LOADING_RESOURCE_START', [options.name],
+                             'Loading $1 ...'));
+
+    // While we're loading the image, eat all the user's input.
+    io.onVTKeystroke = io.sendString = () => {};
+
+    // Initialize this new image.
+    const img = this.document_.createElement('img');
+    if (options.uri !== undefined) {
+      img.src = options.uri;
+    } else if (options.buffer !== undefined) {
+      const blob = new Blob([options.buffer], {type: options.type});
+      img.src = URL.createObjectURL(blob);
+    } else {
+      const blob = new Blob([options.blob], {type: options.type});
+      img.src = URL.createObjectURL(blob);
+    }
+    img.title = img.alt = options.name;
+
+    // Attach the image to the page to let it load/render.  It won't stay here.
+    // This is needed so it's visible and the DOM can calculate the height.  If
+    // the image is hidden or not in the DOM, the height is always 0.
+    this.document_.body.appendChild(img);
+
+    // Wait for the image to finish loading before we try moving it to the
+    // right place in the terminal.
+    img.onload = () => {
+      // Now that we have the image dimensions, figure out how to show it.
+      img.style.objectFit = options.preserveAspectRatio ? 'scale-down' : 'fill';
+      img.style.maxWidth = `${this.document_.body.clientWidth}px`;
+      img.style.maxHeight = `${this.document_.body.clientHeight}px`;
+
+      // Parse a width/height specification.
+      const parseDim = (dim, maxDim, cssVar) => {
+        if (!dim || dim == 'auto')
+          return '';
+
+        const ary = dim.match(/^([0-9]+)(px|%)?$/);
+        if (ary) {
+          if (ary[2] == '%')
+            return Math.floor(maxDim * ary[1] / 100) + 'px';
+          else if (ary[2] == 'px')
+            return dim;
+          else
+            return `calc(${dim} * var(${cssVar}))`;
+        }
+
+        return '';
+      };
+      img.style.width =
+          parseDim(options.width, this.document_.body.clientWidth,
+                   '--hterm-charsize-width');
+      img.style.height =
+          parseDim(options.height,  this.document_.body.clientHeight,
+                   '--hterm-charsize-height');
+
+      // Figure out how many rows the image occupies, then add that many.
+      // Note: This count will be inaccurate if the font size changes on us.
+      const padRows = Math.ceil(img.clientHeight /
+                                this.scrollPort_.characterSize.height);
+      for (let i = 0; i < padRows; ++i)
+        this.newLine();
+
+      // Update the max height in case the user shrinks the character size.
+      img.style.maxHeight = `calc(${padRows} * var(--hterm-charsize-height))`;
+
+      // Move the image to the last row.  This way when we scroll up, it doesn't
+      // disappear when the first row gets clipped.  It will disappear when we
+      // scroll down and the last row is clipped ...
+      this.document_.body.removeChild(img);
+      // Create a wrapper node so we can do an absolute in a relative position.
+      // This helps with rounding errors between JS & CSS counts.
+      const div = this.document_.createElement('div');
+      div.style.position = 'relative';
+      div.style.textAlign = options.align || '';
+      img.style.position = 'absolute';
+      img.style.bottom = 'calc(0px - var(--hterm-charsize-height))';
+      div.appendChild(img);
+      const row = this.getRowNode(this.scrollbackRows_.length +
+                                  this.getCursorRow() - 1);
+      row.appendChild(div);
+
+      // Now that the image has been read, we can revoke the source.
+      if (options.uri === undefined) {
+        URL.revokeObjectURL(img.src);
+      }
+
+      io.hideOverlay();
+      io.pop();
+
+      if (onLoad)
+        onLoad();
+    };
+
+    // If we got a malformed image, give up.
+    img.onerror = (e) => {
+      this.document_.body.removeChild(img);
+      io.showOverlay(hterm.msg('LOADING_RESOURCE_FAILED', [options.name],
+                               'Loading $1 failed'));
+      io.pop();
+
+      if (onError)
+        onError(e);
+    };
+  } else {
+    // We can't use chrome.downloads.download as that requires "downloads"
+    // permissions, and that works only in extensions, not apps.
+    const a = this.document_.createElement('a');
+    if (options.uri !== undefined) {
+      a.href = options.uri;
+    } else if (options.buffer !== undefined) {
+      const blob = new Blob([options.buffer]);
+      a.href = URL.createObjectURL(blob);
+    } else {
+      a.href = URL.createObjectURL(lib.notNull(options.blob));
+    }
+    a.download = options.name;
+    this.document_.body.appendChild(a);
+    a.click();
+    a.remove();
+    if (options.uri === undefined) {
+      URL.revokeObjectURL(a.href);
+    }
+  }
+};
+
+/**
+ * Returns the selected text, or null if no text is selected.
+ *
+ * @return {string|null}
+ */
+hterm.Terminal.prototype.getSelectionText = function() {
+  var selection = this.scrollPort_.selection;
+  selection.sync();
+
+  if (selection.isCollapsed)
+    return null;
+
+  // Start offset measures from the beginning of the line.
+  var startOffset = selection.startOffset;
+  var node = selection.startNode;
+
+  // If an x-row isn't selected, |node| will be null.
+  if (!node)
+    return null;
+
+  if (node.nodeName != 'X-ROW') {
+    // If the selection doesn't start on an x-row node, then it must be
+    // somewhere inside the x-row.  Add any characters from previous siblings
+    // into the start offset.
+
+    if (node.nodeName == '#text' && node.parentNode.nodeName == 'SPAN') {
+      // If node is the text node in a styled span, move up to the span node.
+      node = node.parentNode;
+    }
+
+    while (node.previousSibling) {
+      node = node.previousSibling;
+      startOffset += hterm.TextAttributes.nodeWidth(node);
+    }
+  }
+
+  // End offset measures from the end of the line.
+  var endOffset = (hterm.TextAttributes.nodeWidth(selection.endNode) -
+                   selection.endOffset);
+  node = selection.endNode;
+
+  if (node.nodeName != 'X-ROW') {
+    // If the selection doesn't end on an x-row node, then it must be
+    // somewhere inside the x-row.  Add any characters from following siblings
+    // into the end offset.
+
+    if (node.nodeName == '#text' && node.parentNode.nodeName == 'SPAN') {
+      // If node is the text node in a styled span, move up to the span node.
+      node = node.parentNode;
+    }
+
+    while (node.nextSibling) {
+      node = node.nextSibling;
+      endOffset += hterm.TextAttributes.nodeWidth(node);
+    }
+  }
+
+  var rv = this.getRowsText(selection.startRow.rowIndex,
+                            selection.endRow.rowIndex + 1);
+  return lib.wc.substring(rv, startOffset, lib.wc.strWidth(rv) - endOffset);
+};
+
+/**
+ * Copy the current selection to the system clipboard, then clear it after a
+ * short delay.
+ */
+hterm.Terminal.prototype.copySelectionToClipboard = function() {
+  var text = this.getSelectionText();
+  if (text != null)
+    this.copyStringToClipboard(text);
+};
+
+/**
+ * Show overlay with current terminal size.
+ */
+hterm.Terminal.prototype.overlaySize = function() {
+  if (this.prefs_.get('enable-resize-status')) {
+    this.showOverlay(this.screenSize.width + 'x' + this.screenSize.height);
+  }
+};
+
+/**
+ * Invoked by hterm.Terminal.Keyboard when a VT keystroke is detected.
+ *
+ * @param {string} string The VT string representing the keystroke, in UTF-16.
+ */
+hterm.Terminal.prototype.onVTKeystroke = function(string) {
+  if (this.scrollOnKeystroke_)
+    this.scrollPort_.scrollRowToBottom(this.getRowCount());
+
+  this.pauseCursorBlink_();
+
+  this.io.onVTKeystroke(string);
+};
+
+/**
+ * Open the selected url.
+ */
+hterm.Terminal.prototype.openSelectedUrl_ = function() {
+  var str = this.getSelectionText();
+
+  // If there is no selection, try and expand wherever they clicked.
+  if (str == null) {
+    this.screen_.expandSelectionForUrl(this.document_.getSelection());
+    str = this.getSelectionText();
+
+    // If clicking in empty space, return.
+    if (str == null)
+      return;
+  }
+
+  // Make sure URL is valid before opening.
+  if (str.length > 2048 || str.search(/[\s\[\](){}<>"'\\^`]/) >= 0)
+    return;
+
+  // If the URI isn't anchored, it'll open relative to the extension.
+  // We have no way of knowing the correct schema, so assume http.
+  if (str.search('^[a-zA-Z][a-zA-Z0-9+.-]*://') < 0) {
+    // We have to whitelist a few protocols that lack authorities and thus
+    // never use the //.  Like mailto.
+    switch (str.split(':', 1)[0]) {
+      case 'mailto':
+        break;
+      default:
+        str = 'http://' + str;
+        break;
+    }
+  }
+
+  hterm.openUrl(str);
+};
+
+/**
+ * Manage the automatic mouse hiding behavior while typing.
+ *
+ * @param {?boolean=} v Whether to enable automatic hiding.
+ */
+hterm.Terminal.prototype.setAutomaticMouseHiding = function(v=null) {
+  // Since Chrome OS & macOS do this by default everywhere, we don't need to.
+  // Linux & Windows seem to leave this to specific applications to manage.
+  if (v === null)
+    v = (hterm.os != 'cros' && hterm.os != 'mac');
+
+  this.mouseHideWhileTyping_ = !!v;
+};
+
+/**
+ * Handler for monitoring user keyboard activity.
+ *
+ * This isn't for processing the keystrokes directly, but for updating any
+ * state that might toggle based on the user using the keyboard at all.
+ *
+ * @param {!KeyboardEvent} e The keyboard event that triggered us.
+ */
+hterm.Terminal.prototype.onKeyboardActivity_ = function(e) {
+  // When the user starts typing, hide the mouse cursor.
+  if (this.mouseHideWhileTyping_ && !this.mouseHideDelay_)
+    this.setCssVar('mouse-cursor-style', 'none');
+};
+
+/**
+ * Add the terminalRow and terminalColumn properties to mouse events and
+ * then forward on to onMouse().
+ *
+ * The terminalRow and terminalColumn properties contain the (row, column)
+ * coordinates for the mouse event.
+ *
+ * @param {!MouseEvent} e The mouse event to handle.
+ */
+hterm.Terminal.prototype.onMouse_ = function(e) {
+  if (e.processedByTerminalHandler_) {
+    // We register our event handlers on the document, as well as the cursor
+    // and the scroll blocker.  Mouse events that occur on the cursor or
+    // scroll blocker will also appear on the document, but we don't want to
+    // process them twice.
+    //
+    // We can't just prevent bubbling because that has other side effects, so
+    // we decorate the event object with this property instead.
+    return;
+  }
+
+  // Consume navigation events.  Button 3 is usually "browser back" and
+  // button 4 is "browser forward" which we don't want to happen.
+  if (e.button > 2) {
+    e.preventDefault();
+    // We don't return so click events can be passed to the remote below.
+  }
+
+  var reportMouseEvents = (!this.defeatMouseReports_ &&
+      this.vt.mouseReport != this.vt.MOUSE_REPORT_DISABLED);
+
+  e.processedByTerminalHandler_ = true;
+
+  // Handle auto hiding of mouse cursor while typing.
+  if (this.mouseHideWhileTyping_ && !this.mouseHideDelay_) {
+    // Make sure the mouse cursor is visible.
+    this.syncMouseStyle();
+    // This debounce isn't perfect, but should work well enough for such a
+    // simple implementation.  If the user moved the mouse, we enabled this
+    // debounce, and then moved the mouse just before the timeout, we wouldn't
+    // debounce that later movement.
+    this.mouseHideDelay_ = setTimeout(() => this.mouseHideDelay_ = null, 1000);
+  }
+
+  // One based row/column stored on the mouse event.
+  e.terminalRow = Math.floor(
+      (e.clientY - this.scrollPort_.visibleRowTopMargin) /
+      this.scrollPort_.characterSize.height) + 1;
+  e.terminalColumn = Math.floor(
+      e.clientX / this.scrollPort_.characterSize.width) + 1;
+
+  if (e.type == 'mousedown' && e.terminalColumn > this.screenSize.width) {
+    // Mousedown in the scrollbar area.
+    return;
+  }
+
+  if (this.options_.cursorVisible && !reportMouseEvents) {
+    // If the cursor is visible and we're not sending mouse events to the
+    // host app, then we want to hide the terminal cursor when the mouse
+    // cursor is over top.  This keeps the terminal cursor from interfering
+    // with local text selection.
+    if (e.terminalRow - 1 == this.screen_.cursorPosition.row &&
+        e.terminalColumn - 1 == this.screen_.cursorPosition.column) {
+      this.cursorNode_.style.display = 'none';
+    } else if (this.cursorNode_.style.display == 'none') {
+      this.cursorNode_.style.display = '';
+    }
+  }
+
+  if (e.type == 'mousedown') {
+    this.contextMenu.hide();
+
+    if (e.altKey || !reportMouseEvents) {
+      // If VT mouse reporting is disabled, or has been defeated with
+      // alt-mousedown, then the mouse will act on the local selection.
+      this.defeatMouseReports_ = true;
+      this.setSelectionEnabled(true);
+    } else {
+      // Otherwise we defer ownership of the mouse to the VT.
+      this.defeatMouseReports_ = false;
+      this.document_.getSelection().collapseToEnd();
+      this.setSelectionEnabled(false);
+      e.preventDefault();
+    }
+  }
+
+  if (!reportMouseEvents) {
+    if (e.type == 'dblclick') {
+      this.screen_.expandSelection(this.document_.getSelection());
+      if (this.copyOnSelect)
+        this.copySelectionToClipboard();
+    }
+
+    if (e.type == 'click' && !e.shiftKey && (e.ctrlKey || e.metaKey)) {
+      // Debounce this event with the dblclick event.  If you try to doubleclick
+      // a URL to open it, Chrome will fire click then dblclick, but we won't
+      // have expanded the selection text at the first click event.
+      clearTimeout(this.timeouts_.openUrl);
+      this.timeouts_.openUrl = setTimeout(this.openSelectedUrl_.bind(this),
+                                          500);
+      return;
+    }
+
+    if (e.type == 'mousedown') {
+      if (e.ctrlKey && e.button == 2 /* right button */) {
+        e.preventDefault();
+        this.contextMenu.show(e, this);
+      } else if (e.button == this.mousePasteButton ||
+          (this.mouseRightClickPaste && e.button == 2 /* right button */)) {
+        if (!this.paste())
+          console.warn('Could not paste manually due to web restrictions');
+      }
+    }
+
+    if (e.type == 'mouseup' && e.button == 0 && this.copyOnSelect &&
+        !this.document_.getSelection().isCollapsed) {
+      this.copySelectionToClipboard();
+    }
+
+    if ((e.type == 'mousemove' || e.type == 'mouseup') &&
+        this.scrollBlockerNode_.engaged) {
+      // Disengage the scroll-blocker after one of these events.
+      this.scrollBlockerNode_.engaged = false;
+      this.scrollBlockerNode_.style.top = '-99px';
+    }
+
+    // Emulate arrow key presses via scroll wheel events.
+    if (this.scrollWheelArrowKeys_ && !e.shiftKey &&
+        this.keyboard.applicationCursor && !this.isPrimaryScreen()) {
+      if (e.type == 'wheel') {
+        const delta =
+            this.scrollPort_.scrollWheelDelta(/** @type {!WheelEvent} */ (e));
+
+        // Helper to turn a wheel event delta into a series of key presses.
+        const deltaToArrows = (distance, charSize, arrowPos, arrowNeg) => {
+          if (distance == 0) {
+            return '';
+          }
+
+          // Convert the scroll distance into a number of rows/cols.
+          const cells = lib.f.smartFloorDivide(Math.abs(distance), charSize);
+          const data = '\x1bO' + (distance < 0 ? arrowNeg : arrowPos);
+          return data.repeat(cells);
+        };
+
+        // The order between up/down and left/right doesn't really matter.
+        this.io.sendString(
+            // Up/down arrow keys.
+            deltaToArrows(delta.y, this.scrollPort_.characterSize.height,
+                          'A', 'B') +
+            // Left/right arrow keys.
+            deltaToArrows(delta.x, this.scrollPort_.characterSize.width,
+                          'C', 'D')
+        );
+
+        e.preventDefault();
+      }
+    }
+  } else /* if (this.reportMouseEvents) */ {
+    if (!this.scrollBlockerNode_.engaged) {
+      if (e.type == 'mousedown') {
+        // Move the scroll-blocker into place if we want to keep the scrollport
+        // from scrolling.
+        this.scrollBlockerNode_.engaged = true;
+        this.scrollBlockerNode_.style.top = (e.clientY - 5) + 'px';
+        this.scrollBlockerNode_.style.left = (e.clientX - 5) + 'px';
+      } else if (e.type == 'mousemove') {
+        // Oh.  This means that drag-scroll was disabled AFTER the mouse down,
+        // in which case it's too late to engage the scroll-blocker.
+        this.document_.getSelection().collapseToEnd();
+        e.preventDefault();
+      }
+    }
+
+    this.onMouse(e);
+  }
+
+  if (e.type == 'mouseup' && this.document_.getSelection().isCollapsed) {
+    // Restore this on mouseup in case it was temporarily defeated with a
+    // alt-mousedown.  Only do this when the selection is empty so that
+    // we don't immediately kill the users selection.
+    this.defeatMouseReports_ = false;
+  }
+};
+
+/**
+ * Clients should override this if they care to know about mouse events.
+ *
+ * The event parameter will be a normal DOM mouse click event with additional
+ * 'terminalRow' and 'terminalColumn' properties.
+ *
+ * @param {!MouseEvent} e The mouse event to handle.
+ */
+hterm.Terminal.prototype.onMouse = function(e) { };
+
+/**
+ * React when focus changes.
+ *
+ * @param {boolean} focused True if focused, false otherwise.
+ */
+hterm.Terminal.prototype.onFocusChange_ = function(focused) {
+  this.cursorNode_.setAttribute('focus', focused);
+  this.restyleCursor_();
+
+  if (this.reportFocus)
+    this.io.sendString(focused === true ? '\x1b[I' : '\x1b[O');
+
+  if (focused === true)
+    this.closeBellNotifications_();
+};
+
+/**
+ * React when the ScrollPort is scrolled.
+ */
+hterm.Terminal.prototype.onScroll_ = function() {
+  this.scheduleSyncCursorPosition_();
+};
+
+/**
+ * React when text is pasted into the scrollPort.
+ *
+ * @param {{text: string}} e The text of the paste event to handle.
+ */
+hterm.Terminal.prototype.onPaste_ = function(e) {
+  var data = e.text.replace(/\n/mg, '\r');
+  if (this.options_.bracketedPaste) {
+    // We strip out most escape sequences as they can cause issues (like
+    // inserting an \x1b[201~ midstream).  We pass through whitespace
+    // though: 0x08:\b 0x09:\t 0x0a:\n 0x0d:\r.
+    // This matches xterm behavior.
+    const filter = (data) => data.replace(/[\x00-\x07\x0b-\x0c\x0e-\x1f]/g, '');
+    data = '\x1b[200~' + filter(data) + '\x1b[201~';
+  }
+
+  this.io.sendString(data);
+};
+
+/**
+ * React when the user tries to copy from the scrollPort.
+ *
+ * @param {!Event} e The DOM copy event.
+ */
+hterm.Terminal.prototype.onCopy_ = function(e) {
+  if (!this.useDefaultWindowCopy) {
+    e.preventDefault();
+    setTimeout(this.copySelectionToClipboard.bind(this), 0);
+  }
+};
+
+/**
+ * React when the ScrollPort is resized.
+ *
+ * Note: This function should not directly contain code that alters the internal
+ * state of the terminal.  That kind of code belongs in realizeWidth or
+ * realizeHeight, so that it can be executed synchronously in the case of a
+ * programmatic width change.
+ */
+hterm.Terminal.prototype.onResize_ = function() {
+  var columnCount = Math.floor(this.scrollPort_.getScreenWidth() /
+                               this.scrollPort_.characterSize.width) || 0;
+  var rowCount = lib.f.smartFloorDivide(this.scrollPort_.getScreenHeight(),
+                            this.scrollPort_.characterSize.height) || 0;
+
+  if (columnCount <= 0 || rowCount <= 0) {
+    // We avoid these situations since they happen sometimes when the terminal
+    // gets removed from the document or during the initial load, and we can't
+    // deal with that.
+    // This can also happen if called before the scrollPort calculates the
+    // character size, meaning we dived by 0 above and default to 0 values.
+    return;
+  }
+
+  var isNewSize = (columnCount != this.screenSize.width ||
+                   rowCount != this.screenSize.height);
+  const wasScrolledEnd = this.scrollPort_.isScrolledEnd;
+
+  // We do this even if the size didn't change, just to be sure everything is
+  // in sync.
+  this.realizeSize_(columnCount, rowCount);
+  this.showZoomWarning_(this.scrollPort_.characterSize.zoomFactor != 1);
+
+  if (isNewSize)
+    this.overlaySize();
+
+  this.restyleCursor_();
+  this.scheduleSyncCursorPosition_();
+
+  if (wasScrolledEnd) {
+    this.scrollEnd();
+  }
+};
+
+/**
+ * Service the cursor blink timeout.
+ */
+hterm.Terminal.prototype.onCursorBlink_ = function() {
+  if (!this.options_.cursorBlink) {
+    delete this.timeouts_.cursorBlink;
+    return;
+  }
+
+  if (this.cursorNode_.getAttribute('focus') == 'false' ||
+      this.cursorNode_.style.opacity == '0' ||
+      this.cursorBlinkPause_) {
+    this.cursorNode_.style.opacity = '1';
+    this.timeouts_.cursorBlink = setTimeout(this.myOnCursorBlink_,
+                                            this.cursorBlinkCycle_[0]);
+  } else {
+    this.cursorNode_.style.opacity = '0';
+    this.timeouts_.cursorBlink = setTimeout(this.myOnCursorBlink_,
+                                            this.cursorBlinkCycle_[1]);
+  }
+};
+
+/**
+ * Set the scrollbar-visible mode bit.
+ *
+ * If scrollbar-visible is on, the vertical scrollbar will be visible.
+ * Otherwise it will not.
+ *
+ * Defaults to on.
+ *
+ * @param {boolean} state True to set scrollbar-visible mode, false to unset.
+ */
+hterm.Terminal.prototype.setScrollbarVisible = function(state) {
+  this.scrollPort_.setScrollbarVisible(state);
+};
+
+/**
+ * Set the scroll wheel move multiplier.  This will affect how fast the page
+ * scrolls on wheel events.
+ *
+ * Defaults to 1.
+ *
+ * @param {number} multiplier The multiplier to set.
+ */
+hterm.Terminal.prototype.setScrollWheelMoveMultipler = function(multiplier) {
+  this.scrollPort_.setScrollWheelMoveMultipler(multiplier);
+};
+
+/**
+ * Close all web notifications created by terminal bells.
+ */
+hterm.Terminal.prototype.closeBellNotifications_ = function() {
+  this.bellNotificationList_.forEach(function(n) {
+      n.close();
+    });
+  this.bellNotificationList_.length = 0;
+};
+
+/**
+ * Syncs the cursor position when the scrollport gains focus.
+ */
+hterm.Terminal.prototype.onScrollportFocus_ = function() {
+  // If the cursor is offscreen we set selection to the last row on the screen.
+  const topRowIndex = this.scrollPort_.getTopRowIndex();
+  const bottomRowIndex = this.scrollPort_.getBottomRowIndex(topRowIndex);
+  const selection = this.document_.getSelection();
+  if (!this.syncCursorPosition_() && selection) {
+    selection.collapse(this.getRowNode(bottomRowIndex));
+  }
+};
+// SOURCE FILE: hterm/js/hterm_terminal_io.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Input/Output interface used by commands to communicate with the terminal.
+ *
+ * Commands like `nassh` and `crosh` receive an instance of this class as
+ * part of their argv object.  This allows them to write to and read from the
+ * terminal without exposing them to an entire hterm.Terminal instance.
+ *
+ * The active command must override the onVTKeystroke() and sendString() methods
+ * of this class in order to receive keystrokes and send output to the correct
+ * destination.
+ *
+ * Isolating commands from the terminal provides the following benefits:
+ * - Provides a mechanism to save and restore onVTKeystroke and sendString
+ *   handlers when invoking subcommands (see the push() and pop() methods).
+ * - The isolation makes it easier to make changes in Terminal and supporting
+ *   classes without affecting commands.
+ * - In The Future commands may run in web workers where they would only be able
+ *   to talk to a Terminal instance through an IPC mechanism.
+ *
+ * @param {!hterm.Terminal} terminal
+ * @constructor
+ */
+hterm.Terminal.IO = function(terminal) {
+  this.terminal_ = terminal;
+
+  // The IO object to restore on IO.pop().
+  this.previousIO_ = null;
+
+  // Any data this object accumulated while not active.
+  this.buffered_ = '';
+
+  // Decoder to maintain UTF-8 decode state.
+  this.textDecoder_ = new TextDecoder();
+};
+
+/**
+ * Show the terminal overlay for a given amount of time.
+ *
+ * The terminal overlay appears in inverse video in a large font, centered
+ * over the terminal.  You should probably keep the overlay message brief,
+ * since it's in a large font and you probably aren't going to check the size
+ * of the terminal first.
+ *
+ * @param {string} message The text (not HTML) message to display in the
+ *     overlay.
+ * @param {number=} opt_timeout The amount of time to wait before fading out
+ *     the overlay.  Defaults to 1.5 seconds.  Pass null to have the overlay
+ *     stay up forever (or until the next overlay).
+ */
+hterm.Terminal.IO.prototype.showOverlay = function(message, opt_timeout) {
+  this.terminal_.showOverlay(message, opt_timeout);
+};
+
+/**
+ * Hide the current overlay immediately.
+ *
+ * Useful when we show an overlay for an event with an unknown end time.
+ */
+hterm.Terminal.IO.prototype.hideOverlay = function() {
+  this.terminal_.hideOverlay();
+};
+
+/**
+ * Open an frame in the current terminal window, pointed to the specified
+ * url.
+ *
+ * Eventually we'll probably need size/position/decoration options.
+ * The user should also be able to move/resize the frame.
+ *
+ * @param {string} url The URL to load in the frame.
+ * @param {!Object=} opt_options Optional frame options.  Not implemented.
+ * @return {!hterm.Frame}
+ */
+hterm.Terminal.IO.prototype.createFrame = function(url, opt_options) {
+  return new hterm.Frame(this.terminal_, url, opt_options);
+};
+
+/**
+ * Change the preference profile for the terminal.
+ *
+ * @param {string} profileName The name of the preference profile to activate.
+ */
+hterm.Terminal.IO.prototype.setTerminalProfile = function(profileName) {
+  this.terminal_.setProfile(profileName);
+};
+
+/**
+ * Create a new hterm.Terminal.IO instance and make it active on the Terminal
+ * object associated with this instance.
+ *
+ * This is used to pass control of the terminal IO off to a subcommand.  The
+ * IO.pop() method can be used to restore control when the subcommand completes.
+ *
+ * @return {!hterm.Terminal.IO} The new foreground IO instance.
+ */
+hterm.Terminal.IO.prototype.push = function() {
+  var io = new hterm.Terminal.IO(this.terminal_);
+  io.keyboardCaptured_ = this.keyboardCaptured_;
+
+  io.columnCount = this.columnCount;
+  io.rowCount = this.rowCount;
+
+  io.previousIO_ = this.terminal_.io;
+  this.terminal_.io = io;
+
+  return io;
+};
+
+/**
+ * Restore the Terminal's previous IO object.
+ *
+ * We'll flush out any queued data.
+ */
+hterm.Terminal.IO.prototype.pop = function() {
+  this.terminal_.io = this.previousIO_;
+  this.previousIO_.flush();
+};
+
+/**
+ * Flush accumulated data.
+ *
+ * If we're not the active IO, the connected process might still be writing
+ * data to us, but we won't be displaying it.  Flush any buffered data now.
+ */
+hterm.Terminal.IO.prototype.flush = function() {
+  if (this.buffered_) {
+    this.terminal_.interpret(this.buffered_);
+    this.buffered_ = '';
+  }
+};
+
+/**
+ * Called when data needs to be sent to the current command.
+ *
+ * Clients should override this to receive notification of pending data.
+ *
+ * @param {string} string The data to send.
+ */
+hterm.Terminal.IO.prototype.sendString = function(string) {
+  // Override this.
+  console.log('Unhandled sendString: ' + string);
+};
+
+/**
+ * Called when a terminal keystroke is detected.
+ *
+ * Clients should override this to receive notification of keystrokes.
+ *
+ * @param {string} string The VT key sequence.
+ */
+hterm.Terminal.IO.prototype.onVTKeystroke = function(string) {
+  // Override this.
+  console.log('Unobserverd VT keystroke: ' + JSON.stringify(string));
+};
+
+/**
+ * Receives notification when the terminal is resized.
+ *
+ * @param {number} width The new terminal width.
+ * @param {number} height The new terminal height.
+ */
+hterm.Terminal.IO.prototype.onTerminalResize_ = function(width, height) {
+  var obj = this;
+  while (obj) {
+    obj.columnCount = width;
+    obj.rowCount = height;
+    obj = obj.previousIO_;
+  }
+
+  this.onTerminalResize(width, height);
+};
+
+/**
+ * Called when terminal size is changed.
+ *
+ * Clients should override this to receive notification of resize.
+ *
+ * @param {string|number} width The new terminal width.
+ * @param {string|number} height The new terminal height.
+ */
+hterm.Terminal.IO.prototype.onTerminalResize = function(width, height) {
+  // Override this.
+};
+
+/**
+ * Write a UTF-8 encoded byte string to the terminal.
+ *
+ * @param {string|!ArrayBuffer} string The UTF-8 encoded string to print.
+ */
+hterm.Terminal.IO.prototype.writeUTF8 = function(string) {
+  // We can't use instanceof here on string to see if it's an ArrayBuffer as it
+  // might be constructed in a different runtime context whose ArrayBuffer was
+  // not the same.  See https://crbug.com/930171#5 for more details.
+  if (typeof string == 'string') {
+    if (this.terminal_.vt.characterEncoding != 'raw') {
+      const bytes = lib.codec.stringToCodeUnitArray(string);
+      string = this.textDecoder_.decode(bytes, {stream: true});
+    }
+  } else {
+    // Handle array buffers & typed arrays by normalizing into a typed array.
+    const u8 = new Uint8Array(string);
+    if (this.terminal_.vt.characterEncoding == 'raw') {
+      string = lib.codec.codeUnitArrayToString(u8);
+    } else {
+      string = this.textDecoder_.decode(u8, {stream: true});
+    }
+  }
+
+  this.print(string);
+};
+
+/**
+ * Write a UTF-8 encoded byte string to the terminal followed by crlf.
+ *
+ * @param {string} string The UTF-8 encoded string to print.
+ */
+hterm.Terminal.IO.prototype.writelnUTF8 = function(string) {
+  this.writeUTF8(string);
+  // We need to use writeUTF8 to make sure we flush the decoder state.
+  this.writeUTF8('\r\n');
+};
+
+/**
+ * Write a UTF-16 JavaScript string to the terminal.
+ *
+ * @param {string} string The string to print.
+ */
+hterm.Terminal.IO.prototype.print =
+hterm.Terminal.IO.prototype.writeUTF16 = function(string) {
+  // If another process has the foreground IO, buffer new data sent to this IO
+  // (since it's in the background).  When we're made the foreground IO again,
+  // we'll flush everything.
+  if (this.terminal_.io != this) {
+    this.buffered_ += string;
+    return;
+  }
+
+  this.terminal_.interpret(string);
+};
+
+/**
+ * Print a UTF-16 JavaScript string to the terminal followed by a newline.
+ *
+ * @param {string} string The string to print.
+ */
+hterm.Terminal.IO.prototype.println =
+hterm.Terminal.IO.prototype.writelnUTF16 = function(string) {
+  this.print(string + '\r\n');
+};
+// SOURCE FILE: hterm/js/hterm_text_attributes.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Constructor for TextAttribute objects.
+ *
+ * These objects manage a set of text attributes such as foreground/
+ * background color, bold, faint, italic, blink, underline, and strikethrough.
+ *
+ * TextAttribute instances can be used to construct a DOM container implementing
+ * the current attributes, or to test an existing DOM container for
+ * compatibility with the current attributes.
+ *
+ * @constructor
+ * @param {!Document=} document The parent document to use when creating
+ *     new DOM containers.
+ */
+hterm.TextAttributes = function(document) {
+  this.document_ = document;
+  // These variables contain the source of the color as either:
+  // SRC_DEFAULT  (use context default)
+  // rgb(...)     (true color form)
+  // number       (representing the index from color palette to use)
+  /** @type {symbol|string|number} */
+  this.foregroundSource = this.SRC_DEFAULT;
+  /** @type {symbol|string|number} */
+  this.backgroundSource = this.SRC_DEFAULT;
+  /** @type {symbol|string|number} */
+  this.underlineSource = this.SRC_DEFAULT;
+
+  // These properties cache the value in the color table, but foregroundSource
+  // and backgroundSource contain the canonical values.
+  /** @type {symbol|string} */
+  this.foreground = this.DEFAULT_COLOR;
+  /** @type {symbol|string} */
+  this.background = this.DEFAULT_COLOR;
+  /** @type {symbol|string} */
+  this.underlineColor = this.DEFAULT_COLOR;
+
+  this.defaultForeground = 'rgb(255, 255, 255)';
+  this.defaultBackground = 'rgb(0, 0, 0)';
+
+  // Any attributes added here that do not default to falsey (e.g. undefined or
+  // null) require a bit more care.  createContainer has to always attach the
+  // attribute so matchesContainer can work correctly.
+  this.bold = false;
+  this.faint = false;
+  this.italic = false;
+  this.blink = false;
+  this.underline = false;
+  this.strikethrough = false;
+  this.inverse = false;
+  this.invisible = false;
+  this.wcNode = false;
+  this.asciiNode = true;
+  /** @type {?string} */
+  this.tileData = null;
+  /** @type {?string} */
+  this.uri = null;
+  /** @type {?string} */
+  this.uriId = null;
+
+  this.colorPalette = null;
+  this.resetColorPalette();
+};
+
+/**
+ * If false, we ignore the bold attribute.
+ *
+ * This is used for fonts that have a bold version that is a different size
+ * than the normal weight version.
+ */
+hterm.TextAttributes.prototype.enableBold = true;
+
+/**
+ * If true, use bright colors (if available) for bold text.
+ *
+ * This setting is independent of the enableBold setting.
+ */
+hterm.TextAttributes.prototype.enableBoldAsBright = true;
+
+/**
+ * A sentinel constant meaning "whatever the default color is in this context".
+ */
+hterm.TextAttributes.prototype.DEFAULT_COLOR = Symbol('DEFAULT_COLOR');
+
+/**
+ * A constant string used to specify that source color is context default.
+ */
+hterm.TextAttributes.prototype.SRC_DEFAULT = Symbol('SRC_DEFAULT');
+
+/**
+ * The document object which should own the DOM nodes created by this instance.
+ *
+ * @param {!Document} document The parent document.
+ */
+hterm.TextAttributes.prototype.setDocument = function(document) {
+  this.document_ = document;
+};
+
+/**
+ * Create a deep copy of this object.
+ *
+ * @return {!hterm.TextAttributes} A deep copy of this object.
+ */
+hterm.TextAttributes.prototype.clone = function() {
+  var rv = new hterm.TextAttributes();
+
+  for (var key in this) {
+    rv[key] = this[key];
+  }
+
+  rv.colorPalette = this.colorPalette.concat();
+  return rv;
+};
+
+/**
+ * Reset the current set of attributes.
+ *
+ * This does not affect the palette.  Use resetColorPalette() for that.
+ * It also doesn't affect the tile data, it's not meant to.
+ */
+hterm.TextAttributes.prototype.reset = function() {
+  this.foregroundSource = this.SRC_DEFAULT;
+  this.backgroundSource = this.SRC_DEFAULT;
+  this.underlineSource = this.SRC_DEFAULT;
+  this.foreground = this.DEFAULT_COLOR;
+  this.background = this.DEFAULT_COLOR;
+  this.underlineColor = this.DEFAULT_COLOR;
+  this.bold = false;
+  this.faint = false;
+  this.italic = false;
+  this.blink = false;
+  this.underline = false;
+  this.strikethrough = false;
+  this.inverse = false;
+  this.invisible = false;
+  this.wcNode = false;
+  this.asciiNode = true;
+  this.uri = null;
+  this.uriId = null;
+};
+
+/**
+ * Reset the color palette to the default state.
+ */
+hterm.TextAttributes.prototype.resetColorPalette = function() {
+  this.colorPalette = lib.colors.colorPalette.concat();
+  this.syncColors();
+};
+
+/**
+ * Reset the color.
+ *
+ * @param {number|string} index The color index in the palette to reset.
+ */
+hterm.TextAttributes.prototype.resetColor = function(index) {
+  index = parseInt(index, 10);
+  if (isNaN(index) || index >= this.colorPalette.length)
+    return;
+
+  this.colorPalette[index] = lib.colors.stockColorPalette[index];
+  this.syncColors();
+};
+
+/**
+ * Test if the current attributes describe unstyled text.
+ *
+ * @return {boolean} True if the current attributes describe unstyled text.
+ */
+hterm.TextAttributes.prototype.isDefault = function() {
+  return (this.foregroundSource == this.SRC_DEFAULT &&
+          this.backgroundSource == this.SRC_DEFAULT &&
+          !this.bold &&
+          !this.faint &&
+          !this.italic &&
+          !this.blink &&
+          !this.underline &&
+          !this.strikethrough &&
+          !this.inverse &&
+          !this.invisible &&
+          !this.wcNode &&
+          this.asciiNode &&
+          this.tileData == null &&
+          this.uri == null);
+};
+
+/**
+ * Create a DOM container (a span or a text node) with a style to match the
+ * current set of attributes.
+ *
+ * This method will create a plain text node if the text is unstyled, or
+ * an HTML span if the text is styled.  Due to lack of monospace wide character
+ * fonts on certain systems (e.g. Chrome OS), we need to put each wide character
+ * in a span of CSS class '.wc-node' which has double column width.
+ * Each vt_tiledata tile is also represented by a span with a single
+ * character, with CSS classes '.tile' and '.tile_<glyph number>'.
+ *
+ * @param {string=} opt_textContent Optional text content for the new container.
+ * @return {!Node} An HTML span or text nodes styled to match the current
+ *     attributes.
+ */
+hterm.TextAttributes.prototype.createContainer = function(
+    opt_textContent = '') {
+  if (this.isDefault()) {
+    // Only attach attributes where we need an explicit default for the
+    // matchContainer logic below.
+    const node = this.document_.createTextNode(opt_textContent);
+    node.asciiNode = true;
+    return node;
+  }
+
+  var span = this.document_.createElement('span');
+  var style = span.style;
+  var classes = [];
+
+  if (this.foreground != this.DEFAULT_COLOR)
+    style.color = this.foreground.toString();
+
+  if (this.background != this.DEFAULT_COLOR)
+    style.backgroundColor = this.background.toString();
+
+  if (this.enableBold && this.bold)
+    style.fontWeight = 'bold';
+
+  if (this.faint)
+    span.faint = true;
+
+  if (this.italic)
+    style.fontStyle = 'italic';
+
+  if (this.blink) {
+    classes.push('blink-node');
+    span.blinkNode = true;
+  }
+
+  let textDecorationLine = '';
+  span.underline = this.underline;
+  if (this.underline) {
+    textDecorationLine += ' underline';
+    style.textDecorationStyle = this.underline;
+  }
+  if (this.underlineColor != this.DEFAULT_COLOR)
+    style.textDecorationColor = this.underlineColor;
+  if (this.strikethrough) {
+    textDecorationLine += ' line-through';
+    span.strikethrough = true;
+  }
+  if (textDecorationLine)
+    style.textDecorationLine = textDecorationLine;
+
+  if (this.wcNode) {
+    classes.push('wc-node');
+    span.wcNode = true;
+  }
+  span.asciiNode = this.asciiNode;
+
+  if (this.tileData != null) {
+    classes.push('tile');
+    classes.push('tile_' + this.tileData);
+    span.tileNode = true;
+  }
+
+  if (opt_textContent)
+    span.textContent = opt_textContent;
+
+  if (this.uri) {
+    classes.push('uri-node');
+    span.uriId = this.uriId;
+    span.title = this.uri;
+    span.addEventListener('click', hterm.openUrl.bind(this, this.uri));
+  }
+
+  if (classes.length)
+    span.className = classes.join(' ');
+
+  return span;
+};
+
+/**
+ * Tests if the provided object (string, span or text node) has the same
+ * style as this TextAttributes instance.
+ *
+ * This indicates that text with these attributes could be inserted directly
+ * into the target DOM node.
+ *
+ * For the purposes of this method, a string is considered a text node.
+ *
+ * @param {string|!Node} obj The object to test.
+ * @return {boolean} True if the provided container has the same style as
+ *     this attributes instance.
+ */
+hterm.TextAttributes.prototype.matchesContainer = function(obj) {
+  if (typeof obj == 'string' || obj.nodeType == Node.TEXT_NODE)
+    return this.isDefault();
+
+  var style = obj.style;
+
+  // We don't want to put multiple characters in a wcNode or a tile.
+  // See the comments in createContainer.
+  // For attributes that default to false, we do not require that obj have them
+  // declared, so always normalize them using !! (to turn undefined into false)
+  // in the compares below.
+  return (!(this.wcNode || obj.wcNode) &&
+          this.asciiNode == obj.asciiNode &&
+          !(this.tileData != null || obj.tileNode) &&
+          this.uriId == obj.uriId &&
+          (this.foreground == this.DEFAULT_COLOR &&
+           style.color == '') &&
+          (this.background == this.DEFAULT_COLOR &&
+           style.backgroundColor == '') &&
+          (this.underlineColor == this.DEFAULT_COLOR &&
+           style.textDecorationColor == '') &&
+          (this.enableBold && this.bold) == !!style.fontWeight &&
+          this.blink == !!obj.blinkNode &&
+          this.italic == !!style.fontStyle &&
+          this.underline == obj.underline &&
+          !!this.strikethrough == !!obj.strikethrough);
+};
+
+/**
+ * Set default foreground & background colors.
+ *
+ * @param {?string} foreground The terminal foreground color for use as
+ *     inverse text background.
+ * @param {?string} background The terminal background color for use as
+ *     inverse text foreground.
+ */
+hterm.TextAttributes.prototype.setDefaults = function(foreground, background) {
+  this.defaultForeground = foreground;
+  this.defaultBackground = background;
+
+  this.syncColors();
+};
+
+/**
+ * Updates foreground and background properties based on current indices and
+ * other state.
+ */
+hterm.TextAttributes.prototype.syncColors = function() {
+  function getBrightIndex(i) {
+    if (i < 8) {
+      // If the color is from the lower half of the ANSI 16, add 8.
+      return i + 8;
+    }
+
+    // If it's not from the 16 color palette, ignore bold requests.  This
+    // matches the behavior of gnome-terminal.
+    return i;
+  }
+
+  // Expand the default color as makes sense.
+  const getDefaultColor = (color, defaultColor) => {
+    return color == this.DEFAULT_COLOR ? defaultColor : color;
+  };
+
+  // TODO(joelhockey): Remove redundant `typeof foo == 'number'` when
+  // externs/es6.js is updated.
+  // https://github.com/google/closure-compiler/pull/3472.
+
+  if (this.enableBoldAsBright && this.bold) {
+    if (typeof this.foregroundSource == 'number' &&
+        Number.isInteger(this.foregroundSource)) {
+      this.foregroundSource = getBrightIndex(this.foregroundSource);
+    }
+  }
+
+  /**
+   * @param {symbol|string|number} source
+   * @return {symbol|string}
+   */
+  const colorFromSource = (source) => {
+    if (source == this.SRC_DEFAULT) {
+      return this.DEFAULT_COLOR;
+    } else if (typeof source == 'number' && Number.isInteger(source)) {
+      return this.colorPalette[source];
+    } else {
+      return source.toString();
+    }
+  };
+
+  this.foreground = colorFromSource(this.foregroundSource);
+
+  if (this.faint) {
+    const colorToMakeFaint =
+        getDefaultColor(this.foreground, this.defaultForeground);
+    this.foreground = lib.colors.mix(colorToMakeFaint, 'rgb(0, 0, 0)', 0.3333);
+  }
+
+  this.background = colorFromSource(this.backgroundSource);
+
+  // Once we've processed the bold-as-bright and faint attributes, swap.
+  // This matches xterm/gnome-terminal.
+  if (this.inverse) {
+    const swp = getDefaultColor(this.foreground, this.defaultForeground);
+    this.foreground = getDefaultColor(this.background, this.defaultBackground);
+    this.background = swp;
+  }
+
+  // Process invisible settings last to keep it simple.
+  if (this.invisible)
+    this.foreground = this.background;
+
+  this.underlineColor = colorFromSource(this.underlineSource);
+};
+
+/**
+ * Static method used to test if the provided objects (strings, spans or
+ * text nodes) have the same style.
+ *
+ * For the purposes of this method, a string is considered a text node.
+ *
+ * @param {string|!Node} obj1 An object to test.
+ * @param {string|!Node} obj2 Another object to test.
+ * @return {boolean} True if the containers have the same style.
+ */
+hterm.TextAttributes.containersMatch = function(obj1, obj2) {
+  if (typeof obj1 == 'string')
+    return hterm.TextAttributes.containerIsDefault(obj2);
+
+  if (obj1.nodeType != obj2.nodeType)
+    return false;
+
+  if (obj1.nodeType == Node.TEXT_NODE)
+    return true;
+
+  var style1 = obj1.style;
+  var style2 = obj2.style;
+
+  return (style1.color == style2.color &&
+          style1.backgroundColor == style2.backgroundColor &&
+          style1.backgroundColor == style2.backgroundColor &&
+          style1.fontWeight == style2.fontWeight &&
+          style1.fontStyle == style2.fontStyle &&
+          style1.textDecoration == style2.textDecoration &&
+          style1.textDecorationColor == style2.textDecorationColor &&
+          style1.textDecorationStyle == style2.textDecorationStyle &&
+          style1.textDecorationLine == style2.textDecorationLine);
+};
+
+/**
+ * Static method to test if a given DOM container represents unstyled text.
+ *
+ * For the purposes of this method, a string is considered a text node.
+ *
+ * @param {string|!Node} obj An object to test.
+ * @return {boolean} True if the object is unstyled.
+ */
+hterm.TextAttributes.containerIsDefault = function(obj) {
+  return typeof obj == 'string'  || obj.nodeType == Node.TEXT_NODE;
+};
+
+/**
+ * Static method to get the column width of a node's textContent.
+ *
+ * @param {!Node} node The HTML element to get the width of textContent
+ *     from.
+ * @return {number} The column width of the node's textContent.
+ */
+hterm.TextAttributes.nodeWidth = function(node) {
+  if (!node.asciiNode) {
+    return lib.wc.strWidth(node.textContent);
+  } else {
+    return node.textContent.length;
+  }
+};
+
+/**
+ * Static method to get the substr of a node's textContent.  The start index
+ * and substr width are computed in column width.
+ *
+ * @param {!Node} node The HTML element to get the substr of textContent
+ *     from.
+ * @param {number} start The starting offset in column width.
+ * @param {number=} width The width to capture in column width.
+ * @return {string} The extracted substr of the node's textContent.
+ */
+hterm.TextAttributes.nodeSubstr = function(node, start, width) {
+  if (!node.asciiNode) {
+    return lib.wc.substr(node.textContent, start, width);
+  } else {
+    return node.textContent.substr(start, width);
+  }
+};
+
+/**
+ * Static method to get the substring based of a node's textContent.  The
+ * start index of end index are computed in column width.
+ *
+ * @param {!Element} node The HTML element to get the substr of textContent
+ *     from.
+ * @param {number} start The starting offset in column width.
+ * @param {number} end The ending offset in column width.
+ * @return {string} The extracted substring of the node's textContent.
+ */
+hterm.TextAttributes.nodeSubstring = function(node, start, end) {
+  if (!node.asciiNode) {
+    return lib.wc.substring(node.textContent, start, end);
+  } else {
+    return node.textContent.substring(start, end);
+  }
+};
+
+/**
+ * Static method to split a string into contiguous runs of single-width
+ * characters and runs of double-width characters.
+ *
+ * @param {string} str The string to split.
+ * @return {!Array<{str:string, wcNode:boolean, asciiNode:boolean,
+ *     wcStrWidth:number}>} An array of objects that contain substrings of str,
+ *     where each substring is either a contiguous runs of single-width
+ *     characters or a double-width character.  For objects that contain a
+ *     double-width character, its wcNode property is set to true.  For objects
+ *     that contain only ASCII content, its asciiNode property is set to true.
+ */
+hterm.TextAttributes.splitWidecharString = function(str) {
+  const asciiRegex = new RegExp('^[\u0020-\u007f]*$');
+
+  // Optimize for printable ASCII.  This should only take ~1ms/MB, but cuts out
+  // 40ms+/MB when true.  If we're dealing with UTF8, then it's already slow.
+  if (asciiRegex.test(str)) {
+    return [{
+      str: str,
+      wcNode: false,
+      asciiNode: true,
+      wcStrWidth: str.length,
+    }];
+  }
+
+  // Iterate over each grapheme and merge them together in runs of similar
+  // strings.  We want to keep narrow and wide characters separate, and the
+  // fewer overall segments we have, the faster we'll be as processing each
+  // segment in the terminal print code is a bit slow.
+  const segmenter = new Intl.Segmenter(undefined, {type: 'grapheme'});
+  const it = segmenter.segment(str);
+
+  const rv = [];
+  let segment = it.next();
+  while (!segment.done) {
+    const grapheme = segment.value.segment;
+    const isAscii = asciiRegex.test(grapheme);
+    const strWidth = isAscii ? 1 : lib.wc.strWidth(grapheme);
+    const isWideChar =
+        isAscii ? false : (lib.wc.charWidth(grapheme.codePointAt(0)) == 2);
+
+    // Only merge non-wide characters together.  Every wide character needs to
+    // be separate so it can get a unique container.
+    const prev = rv[rv.length - 1];
+    if (prev && !isWideChar && !prev.wcNode) {
+      prev.str += grapheme;
+      prev.wcStrWidth += strWidth;
+      prev.asciiNode = prev.asciiNode && isAscii;
+    } else {
+      rv.push({
+        str: grapheme,
+        wcNode: isWideChar,
+        asciiNode: isAscii,
+        wcStrWidth: strWidth,
+      });
+    }
+
+    segment = it.next();
+  }
+
+  return rv;
+};
+// SOURCE FILE: hterm/js/hterm_vt.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Constructor for the VT escape sequence interpreter.
+ *
+ * The interpreter operates on a terminal object capable of performing cursor
+ * move operations, painting characters, etc.
+ *
+ * This interpreter is intended to be compatible with xterm, though it
+ * ignores some of the more esoteric escape sequences.
+ *
+ * Control sequences are documented in hterm/doc/ControlSequences.md.
+ *
+ * @param {!hterm.Terminal} terminal Terminal to use with the interpreter.
+ * @constructor
+ */
+hterm.VT = function(terminal) {
+  /**
+   * The display terminal object associated with this virtual terminal.
+   */
+  this.terminal = terminal;
+
+  terminal.onMouse = this.onTerminalMouse_.bind(this);
+  this.mouseReport = this.MOUSE_REPORT_DISABLED;
+  this.mouseCoordinates = this.MOUSE_COORDINATES_X10;
+
+  // We only want to report mouse moves between cells, not between pixels.
+  this.lastMouseDragResponse_ = null;
+
+  // Parse state left over from the last parse.  You should use the parseState
+  // instance passed into your parse routine, rather than reading
+  // this.parseState_ directly.
+  this.parseState_ = new hterm.VT.ParseState(this.parseUnknown_);
+
+  // Any "leading modifiers" for the escape sequence, such as '?', ' ', or the
+  // other modifiers handled in this.parseCSI_.
+  this.leadingModifier_ = '';
+
+  // Any "trailing modifiers".  Same character set as a leading modifier,
+  // except these are found after the numeric arguments.
+  this.trailingModifier_ = '';
+
+  // Whether or not to respect the escape codes for setting terminal width.
+  this.allowColumnWidthChanges_ = false;
+
+  // The amount of time we're willing to wait for the end of an OSC sequence.
+  this.oscTimeLimit_ = 20000;
+
+  /**
+   * Whether to accept the 8-bit control characters.
+   *
+   * An 8-bit control character is one with the eighth bit set.  These
+   * didn't work on 7-bit terminals so they all have two byte equivalents.
+   * Most hosts still only use the two-byte versions.
+   *
+   * We ignore 8-bit control codes by default.  This is in order to avoid
+   * issues with "accidental" usage of codes that need to be terminated.
+   * The "accident" usually involves cat'ing binary data.
+   */
+  this.enable8BitControl = false;
+
+  /**
+   * Whether to allow the OSC 52 sequence to write to the system clipboard.
+   */
+  this.enableClipboardWrite = true;
+
+  /**
+   * Respect the host's attempt to change the cursor blink status using
+   * the DEC Private mode 12.
+   */
+  this.enableDec12 = false;
+
+  /**
+   * Respect the host's attempt to clear the scrollback buffer using CSI-J-3.
+   */
+  this.enableCsiJ3 = true;
+
+  /**
+   * The expected encoding method for data received from the host.
+   */
+  this.characterEncoding = 'utf-8';
+
+  /**
+   * If true, emit warnings when we encounter a control character or escape
+   * sequence that we don't recognize or explicitly ignore.
+   *
+   * We disable this by default as the console logging can be expensive when
+   * dumping binary files (e.g. `cat /dev/zero`) to the point where you can't
+   * recover w/out restarting.
+   */
+  this.warnUnimplemented = false;
+
+  /**
+   * The set of available character maps (used by G0...G3 below).
+   */
+  this.characterMaps = new hterm.VT.CharacterMaps();
+
+  /**
+   * The default G0...G3 character maps.
+   * We default to the US/ASCII map everywhere as that aligns with other
+   * terminals, and it makes it harder to accidentally switch to the graphics
+   * character map (Ctrl-N).  Any program that wants to use the graphics map
+   * will usually select it anyways since there's no guarantee what state any
+   * of the maps are in at any particular time.
+   */
+  this.G0 = this.G1 = this.G2 = this.G3 =
+      this.characterMaps.getMap('B');
+
+  /**
+   * The 7-bit visible character set.
+   *
+   * This is a mapping from inbound data to display glyph.  The GL set
+   * contains the 94 bytes from 0x21 to 0x7e.
+   *
+   * The default GL set is 'B', US ASCII.
+   */
+  this.GL = 'G0';
+
+  /**
+   * The 8-bit visible character set.
+   *
+   * This is a mapping from inbound data to display glyph.  The GR set
+   * contains the 94 bytes from 0xa1 to 0xfe.
+   */
+  this.GR = 'G0';
+
+  /**
+   * The current encoding of the terminal.
+   *
+   * We only support ECMA-35 and UTF-8, so go with a boolean here.
+   * The encoding can be locked too.
+   */
+  this.codingSystemUtf8_ = false;
+  this.codingSystemLocked_ = false;
+
+  // Construct a regular expression to match the known one-byte control chars.
+  // This is used in parseUnknown_ to quickly scan a string for the next
+  // control character.
+  this.cc1Pattern_ = null;
+  this.updateEncodingState_();
+};
+
+/**
+ * No mouse events.
+ */
+hterm.VT.prototype.MOUSE_REPORT_DISABLED = 0;
+
+/**
+ * DECSET mode 9.
+ *
+ * Report mouse down events only.
+ */
+hterm.VT.prototype.MOUSE_REPORT_PRESS = 1;
+
+/**
+ * DECSET mode 1000.
+ *
+ * Report mouse down/up events only.
+ */
+hterm.VT.prototype.MOUSE_REPORT_CLICK = 2;
+
+/**
+ * DECSET mode 1002.
+ *
+ * Report mouse down/up and movement while a button is down.
+ */
+hterm.VT.prototype.MOUSE_REPORT_DRAG = 3;
+
+/**
+ * DEC mode for X10 coorindates (the default).
+ */
+hterm.VT.prototype.MOUSE_COORDINATES_X10 = 0;
+
+/**
+ * DEC mode 1005 for UTF-8 coorindates.
+ */
+hterm.VT.prototype.MOUSE_COORDINATES_UTF8 = 1;
+
+/**
+ * DEC mode 1006 for SGR coorindates.
+ */
+hterm.VT.prototype.MOUSE_COORDINATES_SGR = 2;
+
+/**
+ * ParseState constructor.
+ *
+ * This object tracks the current state of the parse.  It has fields for the
+ * current buffer, position in the buffer, and the parse function.
+ *
+ * @param {function(!hterm.VT.ParseState)=} defaultFunction The default parser
+ *     function.
+ * @param {string=} opt_buf Optional string to use as the current buffer.
+ * @constructor
+ */
+hterm.VT.ParseState = function(defaultFunction, opt_buf) {
+  this.defaultFunction = defaultFunction;
+  this.buf = opt_buf || null;
+  this.pos = 0;
+  this.func = defaultFunction;
+  this.args = [];
+  // Whether any of the arguments in the args array have subarguments.
+  // e.g. All CSI sequences are integer arguments separated by semi-colons,
+  // so subarguments are further colon separated.
+  this.subargs = null;
+};
+
+/**
+ * Reset the parser function, buffer, and position.
+ *
+ * @param {string=} opt_buf Optional string to use as the current buffer.
+ */
+hterm.VT.ParseState.prototype.reset = function(opt_buf) {
+  this.resetParseFunction();
+  this.resetBuf(opt_buf || '');
+  this.resetArguments();
+};
+
+/**
+ * Reset the parser function only.
+ */
+hterm.VT.ParseState.prototype.resetParseFunction = function() {
+  this.func = this.defaultFunction;
+};
+
+/**
+ * Reset the buffer and position only.
+ *
+ * @param {string=} opt_buf Optional new value for buf, defaults to null.
+ */
+hterm.VT.ParseState.prototype.resetBuf = function(opt_buf) {
+  this.buf = (typeof opt_buf == 'string') ? opt_buf : null;
+  this.pos = 0;
+};
+
+/**
+ * Reset the arguments list only.
+ *
+ * Typically we reset arguments before parsing a sequence that uses them rather
+ * than always trying to make sure they're in a good state.  This can lead to
+ * confusion during debugging where args from a previous sequence appear to be
+ * "sticking around" in other sequences (which in reality don't use args).
+ *
+ * @param {string=} opt_arg_zero Optional initial value for args[0].
+ */
+hterm.VT.ParseState.prototype.resetArguments = function(opt_arg_zero) {
+  this.args.length = 0;
+  if (typeof opt_arg_zero != 'undefined')
+    this.args[0] = opt_arg_zero;
+};
+
+/**
+ * Parse an argument as an integer.
+ *
+ * This assumes the inputs are already in the proper format.  e.g. This won't
+ * handle non-numeric arguments.
+ *
+ * An "0" argument is treated the same as "" which means the default value will
+ * be applied.  This is what most terminal sequences expect.
+ *
+ * @param {string} argstr The argument to parse directly.
+ * @param {number=} defaultValue Default value if argstr is empty.
+ * @return {number} The parsed value.
+ */
+hterm.VT.ParseState.prototype.parseInt = function(argstr, defaultValue) {
+  if (defaultValue === undefined)
+    defaultValue = 0;
+
+  if (argstr) {
+    const ret = parseInt(argstr, 10);
+    // An argument of zero is treated as the default value.
+    return ret == 0 ? defaultValue : ret;
+  }
+  return defaultValue;
+};
+
+/**
+ * Get an argument as an integer.
+ *
+ * @param {number} argnum The argument number to retrieve.
+ * @param {number=} defaultValue Default value if the argument is empty.
+ * @return {number} The parsed value.
+ */
+hterm.VT.ParseState.prototype.iarg = function(argnum, defaultValue) {
+  return this.parseInt(this.args[argnum], defaultValue);
+};
+
+/**
+ * Check whether an argument has subarguments.
+ *
+ * @param {number} argnum The argument number to check.
+ * @return {number} Whether the argument has subarguments.
+ */
+hterm.VT.ParseState.prototype.argHasSubargs = function(argnum) {
+  return this.subargs && this.subargs[argnum];
+};
+
+/**
+ * Mark an argument as having subarguments.
+ *
+ * @param {number} argnum The argument number that has subarguments.
+ */
+hterm.VT.ParseState.prototype.argSetSubargs = function(argnum) {
+  if (this.subargs === null)
+    this.subargs = {};
+  this.subargs[argnum] = true;
+};
+
+/**
+ * Advance the parse position.
+ *
+ * @param {number} count The number of bytes to advance.
+ */
+hterm.VT.ParseState.prototype.advance = function(count) {
+  this.pos += count;
+};
+
+/**
+ * Return the remaining portion of the buffer without affecting the parse
+ * position.
+ *
+ * @return {string} The remaining portion of the buffer.
+ */
+hterm.VT.ParseState.prototype.peekRemainingBuf = function() {
+  return this.buf.substr(this.pos);
+};
+
+/**
+ * Return the next single character in the buffer without affecting the parse
+ * position.
+ *
+ * @return {string} The next character in the buffer.
+ */
+hterm.VT.ParseState.prototype.peekChar = function() {
+  return this.buf.substr(this.pos, 1);
+};
+
+/**
+ * Return the next single character in the buffer and advance the parse
+ * position one byte.
+ *
+ * @return {string} The next character in the buffer.
+ */
+hterm.VT.ParseState.prototype.consumeChar = function() {
+  return this.buf.substr(this.pos++, 1);
+};
+
+/**
+ * Return true if the buffer is empty, or the position is past the end.
+ *
+ * @return {boolean} Whether the buffer is empty, or the position is past the
+ *     end.
+ */
+hterm.VT.ParseState.prototype.isComplete = function() {
+  return this.buf == null || this.buf.length <= this.pos;
+};
+
+/**
+ * Reset the VT back to baseline state.
+ */
+hterm.VT.prototype.reset = function() {
+  this.G0 = this.G1 = this.G2 = this.G3 =
+      this.characterMaps.getMap('B');
+
+  this.GL = 'G0';
+  this.GR = 'G0';
+
+  this.mouseReport = this.MOUSE_REPORT_DISABLED;
+  this.mouseCoordinates = this.MOUSE_COORDINATES_X10;
+  this.lastMouseDragResponse_ = null;
+};
+
+/**
+ * Handle terminal mouse events.
+ *
+ * See the "Mouse Tracking" section of [xterm].
+ *
+ * @param {!MouseEvent} e
+ */
+hterm.VT.prototype.onTerminalMouse_ = function(e) {
+  // Short circuit a few events to avoid unnecessary processing.
+  if (this.mouseReport == this.MOUSE_REPORT_DISABLED)
+    return;
+  else if (this.mouseReport != this.MOUSE_REPORT_DRAG && e.type == 'mousemove')
+    return;
+
+  // Temporary storage for our response.
+  var response;
+
+  // Modifier key state.
+  var mod = 0;
+  if (this.mouseReport != this.MOUSE_REPORT_PRESS) {
+    if (e.shiftKey)
+      mod |= 4;
+    if (e.metaKey || (this.terminal.keyboard.altIsMeta && e.altKey))
+      mod |= 8;
+    if (e.ctrlKey)
+      mod |= 16;
+  }
+
+  // X & Y coordinate reporting.
+  let x;
+  let y;
+  // Normally X10 has a limit of 255, but since we only want to emit UTF-8 valid
+  // streams, we limit ourselves to 127 to avoid setting the 8th bit.  If we do
+  // re-enable this, we should re-enable the hterm_vt_tests.js too.
+  let limit = 127;
+  switch (this.mouseCoordinates) {
+    case this.MOUSE_COORDINATES_UTF8:
+      // UTF-8 mode is the same as X10 but with higher limits.
+      limit = 2047;
+    case this.MOUSE_COORDINATES_X10:
+      // X10 reports coordinates by encoding into strings.
+      x = String.fromCharCode(lib.f.clamp(e.terminalColumn + 32, 32, limit));
+      y = String.fromCharCode(lib.f.clamp(e.terminalRow + 32, 32, limit));
+      break;
+    case this.MOUSE_COORDINATES_SGR:
+      // SGR reports coordinates by transmitting the numbers directly.
+      x = e.terminalColumn;
+      y = e.terminalRow;
+      break;
+  }
+
+  let b;
+  switch (e.type) {
+    case 'wheel':
+      // Mouse wheel is treated as button 1 or 2 plus an additional 64.
+      b = (((e.deltaY * -1) > 0) ? 0 : 1) + 64;
+      b |= mod;
+      if (this.mouseCoordinates == this.MOUSE_COORDINATES_SGR) {
+        response = `\x1b[<${b};${x};${y}M`;
+      } else {
+        // X10 based modes (including UTF8) add 32 for legacy encoding reasons.
+        response = '\x1b[M' + String.fromCharCode(b + 32) + x + y;
+      }
+
+      // Keep the terminal from scrolling.
+      e.preventDefault();
+      break;
+
+    case 'mousedown':
+      // Buttons are encoded as button number.
+      b = Math.min(e.button, 2);
+      // X10 based modes (including UTF8) add 32 for legacy encoding reasons.
+      if (this.mouseCoordinates != this.MOUSE_COORDINATES_SGR)
+        b += 32;
+
+      // And mix in the modifier keys.
+      b |= mod;
+
+      if (this.mouseCoordinates == this.MOUSE_COORDINATES_SGR)
+        response = `\x1b[<${b};${x};${y}M`;
+      else
+        response = '\x1b[M' + String.fromCharCode(b) + x + y;
+      break;
+
+    case 'mouseup':
+      if (this.mouseReport != this.MOUSE_REPORT_PRESS) {
+        if (this.mouseCoordinates == this.MOUSE_COORDINATES_SGR) {
+          // SGR mode can report the released button.
+          response = `\x1b[<${e.button};${x};${y}m`;
+        } else {
+          // X10 mode has no indication of which button was released.
+          response = '\x1b[M\x23' + x + y;
+        }
+      }
+      break;
+
+    case 'mousemove':
+      if (this.mouseReport == this.MOUSE_REPORT_DRAG && e.buttons) {
+        // Standard button bits.  The XTerm protocol only reports the first
+        // button press (e.g. if left & right are pressed, right is ignored),
+        // and it only supports the first three buttons.  If none of them are
+        // pressed, then XTerm flags it as a release.  We'll do the same.
+        // X10 based modes (including UTF8) add 32 for legacy encoding reasons.
+        b = this.mouseCoordinates == this.MOUSE_COORDINATES_SGR ? 0 : 32;
+
+        // Priority here matches XTerm: left, middle, right.
+        if (e.buttons & 0x1) {
+          // Report left button.
+          b += 0;
+        } else if (e.buttons & 0x4) {
+          // Report middle button.
+          b += 1;
+        } else if (e.buttons & 0x2) {
+          // Report right button.
+          b += 2;
+        } else {
+          // Release higher buttons.
+          b += 3;
+        }
+
+        // Add 32 to indicate mouse motion.
+        b += 32;
+
+        // And mix in the modifier keys.
+        b |= mod;
+
+        if (this.mouseCoordinates == this.MOUSE_COORDINATES_SGR)
+          response = `\x1b[<${b};${x};${y}M`;
+        else
+          response = '\x1b[M' + String.fromCharCode(b) + x + y;
+
+        // If we were going to report the same cell because we moved pixels
+        // within, suppress the report.  This is what xterm does and cuts
+        // down on duplicate messages.
+        if (this.lastMouseDragResponse_ == response)
+          response = '';
+        else
+          this.lastMouseDragResponse_ = response;
+      }
+
+      break;
+
+    case 'click':
+    case 'dblclick':
+      break;
+
+    default:
+      console.error('Unknown mouse event: ' + e.type, e);
+      break;
+  }
+
+  if (response)
+    this.terminal.io.sendString(response);
+};
+
+/**
+ * Interpret a string of characters, displaying the results on the associated
+ * terminal object.
+ *
+ * The buffer will be decoded according to the 'receive-encoding' preference.
+ *
+ * @param {string} buf The buffer to interpret.
+ */
+hterm.VT.prototype.interpret = function(buf) {
+  this.parseState_.resetBuf(buf);
+
+  while (!this.parseState_.isComplete()) {
+    const func = this.parseState_.func;
+    const pos = this.parseState_.pos;
+    const buf = this.parseState_.buf;
+
+    this.parseState_.func.call(this, this.parseState_);
+
+    if (this.parseState_.func == func && this.parseState_.pos == pos &&
+        this.parseState_.buf == buf) {
+      throw 'Parser did not alter the state!';
+    }
+  }
+};
+
+/**
+ * Set the encoding of the terminal.
+ *
+ * @param {string} encoding The name of the encoding to set.
+ */
+hterm.VT.prototype.setEncoding = function(encoding) {
+  switch (encoding) {
+    default:
+      console.warn('Invalid value for "terminal-encoding": ' + encoding);
+      // Fall through.
+    case 'iso-2022':
+      this.codingSystemUtf8_ = false;
+      this.codingSystemLocked_ = false;
+      break;
+    case 'utf-8-locked':
+      this.codingSystemUtf8_ = true;
+      this.codingSystemLocked_ = true;
+      break;
+    case 'utf-8':
+      this.codingSystemUtf8_ = true;
+      this.codingSystemLocked_ = false;
+      break;
+  }
+
+  this.updateEncodingState_();
+};
+
+/**
+ * Refresh internal state when the encoding changes.
+ */
+hterm.VT.prototype.updateEncodingState_ = function() {
+  // If we're in UTF8 mode, don't suport 8-bit escape sequences as we'll never
+  // see those -- everything should be UTF8!
+  var cc1 = Object.keys(hterm.VT.CC1)
+      .filter((e) => !this.codingSystemUtf8_ || e.charCodeAt() < 0x80)
+      .map((e) => '\\x' + lib.f.zpad(e.charCodeAt().toString(16), 2))
+      .join('');
+  this.cc1Pattern_ = new RegExp(`[${cc1}]`);
+};
+
+/**
+ * The default parse function.
+ *
+ * This will scan the string for the first 1-byte control character (C0/C1
+ * characters from [CTRL]).  Any plain text coming before the code will be
+ * printed to the terminal, then the control character will be dispatched.
+ *
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.prototype.parseUnknown_ = function(parseState) {
+  var self = this;
+
+  function print(str) {
+    if (!self.codingSystemUtf8_ && self[self.GL].GL)
+      str = self[self.GL].GL(str);
+
+    self.terminal.print(str);
+  }
+
+  // Search for the next contiguous block of plain text.
+  var buf = parseState.peekRemainingBuf();
+  var nextControl = buf.search(this.cc1Pattern_);
+
+  if (nextControl == 0) {
+    // We've stumbled right into a control character.
+    this.dispatch('CC1', buf.substr(0, 1), parseState);
+    parseState.advance(1);
+    return;
+  }
+
+  if (nextControl == -1) {
+    // There are no control characters in this string.
+    print(buf);
+    parseState.reset();
+    return;
+  }
+
+  print(buf.substr(0, nextControl));
+  this.dispatch('CC1', buf.substr(nextControl, 1), parseState);
+  parseState.advance(nextControl + 1);
+};
+
+/**
+ * Parse a Control Sequence Introducer code and dispatch it.
+ *
+ * See [CSI] for some useful information about these codes.
+ *
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.prototype.parseCSI_ = function(parseState) {
+  var ch = parseState.peekChar();
+  var args = parseState.args;
+
+  const finishParsing = () => {
+    // Resetting the arguments isn't strictly necessary, but it makes debugging
+    // less confusing (otherwise args will stick around until the next sequence
+    // that needs arguments).
+    parseState.resetArguments();
+    // We need to clear subargs since we explicitly set it.
+    parseState.subargs = null;
+    parseState.resetParseFunction();
+  };
+
+  if (ch >= '@' && ch <= '~') {
+    // This is the final character.
+    this.dispatch('CSI', this.leadingModifier_ + this.trailingModifier_ + ch,
+                  parseState);
+    finishParsing();
+
+  } else if (ch == ';') {
+    // Parameter delimiter.
+    if (this.trailingModifier_) {
+      // Parameter delimiter after the trailing modifier.  That's a paddlin'.
+      finishParsing();
+
+    } else {
+      if (!args.length) {
+        // They omitted the first param, we need to supply it.
+        args.push('');
+      }
+
+      args.push('');
+    }
+
+  } else if (ch >= '0' && ch <= '9' || ch == ':') {
+    // Next byte in the current parameter.
+
+    if (this.trailingModifier_) {
+      // Numeric parameter after the trailing modifier.  That's a paddlin'.
+      finishParsing();
+    } else {
+      if (!args.length) {
+        args[0] = ch;
+      } else {
+        args[args.length - 1] += ch;
+      }
+
+      // Possible sub-parameters.
+      if (ch == ':')
+        parseState.argSetSubargs(args.length - 1);
+    }
+
+  } else if (ch >= ' ' && ch <= '?') {
+    // Modifier character.
+    if (!args.length) {
+      this.leadingModifier_ += ch;
+    } else {
+      this.trailingModifier_ += ch;
+    }
+
+  } else if (this.cc1Pattern_.test(ch)) {
+    // Control character.
+    this.dispatch('CC1', ch, parseState);
+
+  } else {
+    // Unexpected character in sequence, bail out.
+    finishParsing();
+  }
+
+  parseState.advance(1);
+};
+
+/**
+ * Skip over the string until the next String Terminator (ST, 'ESC \') or
+ * Bell (BEL, '\x07').
+ *
+ * The string is accumulated in parseState.args[0].  Make sure to reset the
+ * arguments (with parseState.resetArguments) before starting the parse.
+ *
+ * You can detect that parsing in complete by checking that the parse
+ * function has changed back to the default parse function.
+ *
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ * @return {boolean} If true, parsing is ongoing or complete.  If false, we've
+ *     exceeded the max string sequence.
+ */
+hterm.VT.prototype.parseUntilStringTerminator_ = function(parseState) {
+  var buf = parseState.peekRemainingBuf();
+  var args = parseState.args;
+  // Since we might modify parse state buffer locally, if we want to advance
+  // the parse state buffer later on, we need to know how many chars we added.
+  let bufInserted = 0;
+
+  if (!args.length) {
+    args[0] = '';
+    args[1] = new Date();
+  } else {
+    // If our saved buffer ends with an escape, it's because we were hoping
+    // it's an ST split across two buffers.  Move it from our saved buffer
+    // to the start of our current buffer for processing anew.
+    if (args[0].slice(-1) == '\x1b') {
+      args[0] = args[0].slice(0, -1);
+      buf = '\x1b' + buf;
+      bufInserted = 1;
+    }
+  }
+
+  const nextTerminator = buf.search(/[\x1b\x07]/);
+  const terminator = buf[nextTerminator];
+  let foundTerminator;
+
+  // If the next escape we see is not a start of a ST, fall through.  This will
+  // either be invalid (embedded escape), or we'll queue it up (wait for \\).
+  if (terminator == '\x1b' && buf[nextTerminator + 1] != '\\')
+    foundTerminator = false;
+  else
+    foundTerminator = (nextTerminator != -1);
+
+  if (!foundTerminator) {
+    // No terminator here, have to wait for the next string.
+
+    args[0] += buf;
+
+    var abortReason;
+
+    // Special case: If our buffering happens to split the ST (\e\\), we have to
+    // buffer the content temporarily.  So don't reject a trailing escape here,
+    // instead we let it timeout or be rejected in the next pass.
+    if (terminator == '\x1b' && nextTerminator != buf.length - 1)
+      abortReason = 'embedded escape: ' + nextTerminator;
+
+    if (new Date() - args[1] > this.oscTimeLimit_)
+      abortReason = 'timeout expired: ' + (new Date() - args[1]);
+
+    if (abortReason) {
+      if (this.warnUnimplemented)
+        console.log('parseUntilStringTerminator_: aborting: ' + abortReason,
+                    args[0]);
+      parseState.reset(args[0]);
+      return false;
+    }
+
+    parseState.advance(buf.length - bufInserted);
+    return true;
+  }
+
+  args[0] += buf.substr(0, nextTerminator);
+
+  parseState.resetParseFunction();
+  parseState.advance(nextTerminator +
+                     (terminator == '\x1b' ? 2 : 1) - bufInserted);
+
+  return true;
+};
+
+/**
+ * Dispatch to the function that handles a given CC1, ESC, or CSI or VT52 code.
+ *
+ * @param {string} type
+ * @param {string} code
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.prototype.dispatch = function(type, code, parseState) {
+  var handler = hterm.VT[type][code];
+  if (!handler) {
+    if (this.warnUnimplemented) {
+      console.warn(`Unknown ${type} code: ${JSON.stringify(code)}`);
+    }
+    return;
+  }
+
+  if (handler == hterm.VT.ignore) {
+    if (this.warnUnimplemented) {
+      console.warn(`Ignored ${type} code: ${JSON.stringify(code)}`);
+    }
+    return;
+  }
+
+  if (parseState.subargs && !handler.supportsSubargs) {
+    if (this.warnUnimplemented) {
+      console.warn(`Ignored ${type} code w/subargs: ${JSON.stringify(code)}`);
+    }
+    return;
+  }
+
+  if (type == 'CC1' && code > '\x7f' && !this.enable8BitControl) {
+    // It's kind of a hack to put this here, but...
+    //
+    // If we're dispatching a 'CC1' code, and it's got the eighth bit set,
+    // but we're not supposed to handle 8-bit codes?  Just ignore it.
+    //
+    // This prevents an errant (DCS, '\x90'), (OSC, '\x9d'), (PM, '\x9e') or
+    // (APC, '\x9f') from locking up the terminal waiting for its expected
+    // (ST, '\x9c') or (BEL, '\x07').
+    console.warn('Ignoring 8-bit control code: 0x' +
+                 code.charCodeAt(0).toString(16));
+    return;
+  }
+
+  handler.apply(this, [parseState, code]);
+};
+
+/**
+ * Set one of the ANSI defined terminal mode bits.
+ *
+ * Invoked in response to SM/RM.
+ *
+ * Unexpected and unimplemented values are silently ignored.
+ *
+ * @param {string} code
+ * @param {boolean} state
+ */
+hterm.VT.prototype.setANSIMode = function(code, state) {
+  if (code == 4) {  // Insert Mode (IRM)
+    this.terminal.setInsertMode(state);
+  } else if (code == 20) {  // Automatic Newline (LNM)
+    this.terminal.setAutoCarriageReturn(state);
+  } else if (this.warnUnimplemented) {
+    console.warn('Unimplemented ANSI Mode: ' + code);
+  }
+};
+
+/**
+ * Set or reset one of the DEC Private modes.
+ *
+ * Invoked in response to DECSET/DECRST.
+ *
+ * @param {string} code
+ * @param {boolean} state
+ */
+hterm.VT.prototype.setDECMode = function(code, state) {
+  switch (parseInt(code, 10)) {
+    case 1:  // DECCKM
+      this.terminal.keyboard.applicationCursor = state;
+      break;
+
+    case 3:  // DECCOLM
+      if (this.allowColumnWidthChanges_) {
+        this.terminal.setWidth(state ? 132 : 80);
+
+        this.terminal.clearHome();
+        this.terminal.setVTScrollRegion(null, null);
+      }
+      break;
+
+    case 5:  // DECSCNM
+      this.terminal.setReverseVideo(state);
+      break;
+
+    case 6:  // DECOM
+      this.terminal.setOriginMode(state);
+      break;
+
+    case 7:  // DECAWM
+      this.terminal.setWraparound(state);
+      break;
+
+    case 9:  // Report on mouse down events only (X10).
+      this.mouseReport = (
+          state ? this.MOUSE_REPORT_PRESS : this.MOUSE_REPORT_DISABLED);
+      this.terminal.syncMouseStyle();
+      break;
+
+    case 12:  // Start blinking cursor
+      if (this.enableDec12)
+        this.terminal.setCursorBlink(state);
+      break;
+
+    case 25:  // DECTCEM
+      this.terminal.setCursorVisible(state);
+      break;
+
+    case 30:  // Show scrollbar
+      this.terminal.setScrollbarVisible(state);
+      break;
+
+    case 40:  // Allow 80 - 132 (DECCOLM) Mode
+      this.terminal.allowColumnWidthChanges_ = state;
+      break;
+
+    case 45:  // Reverse-wraparound Mode
+      this.terminal.setReverseWraparound(state);
+      break;
+
+    case 67:  // Backarrow key sends backspace (DECBKM)
+      this.terminal.keyboard.backspaceSendsBackspace = state;
+      break;
+
+    case 1000:  // Report on mouse clicks only (X11).
+      this.mouseReport = (
+          state ? this.MOUSE_REPORT_CLICK : this.MOUSE_REPORT_DISABLED);
+      this.terminal.syncMouseStyle();
+      break;
+
+    case 1002:  // Report on mouse clicks and drags
+      this.mouseReport = (
+          state ? this.MOUSE_REPORT_DRAG : this.MOUSE_REPORT_DISABLED);
+      this.terminal.syncMouseStyle();
+      break;
+
+    case 1004:  // Report on window focus change.
+      this.terminal.reportFocus = state;
+      break;
+
+    case 1005:  // Extended coordinates in UTF-8 mode.
+      this.mouseCoordinates = (
+          state ? this.MOUSE_COORDINATES_UTF8 : this.MOUSE_COORDINATES_X10);
+      break;
+
+    case 1006:  // Extended coordinates in SGR mode.
+      this.mouseCoordinates = (
+          state ? this.MOUSE_COORDINATES_SGR : this.MOUSE_COORDINATES_X10);
+      break;
+
+    case 1007:  // Enable Alternate Scroll Mode.
+      this.terminal.scrollWheelArrowKeys_ = state;
+      break;
+
+    case 1010:  // Scroll to bottom on tty output
+      this.terminal.scrollOnOutput = state;
+      break;
+
+    case 1011:  // Scroll to bottom on key press
+      this.terminal.scrollOnKeystroke = state;
+      break;
+
+    case 1036:  // Send ESC when Meta modifies a key
+      this.terminal.keyboard.metaSendsEscape = state;
+      break;
+
+    case 1039:  // Send ESC when Alt modifies a key
+      if (state) {
+        if (!this.terminal.keyboard.previousAltSendsWhat_) {
+          this.terminal.keyboard.previousAltSendsWhat_ =
+              this.terminal.keyboard.altSendsWhat;
+          this.terminal.keyboard.altSendsWhat = 'escape';
+        }
+      } else if (this.terminal.keyboard.previousAltSendsWhat_) {
+        this.terminal.keyboard.altSendsWhat =
+            this.terminal.keyboard.previousAltSendsWhat_;
+        this.terminal.keyboard.previousAltSendsWhat_ = null;
+      }
+      break;
+
+    case 47:  // Use Alternate Screen Buffer
+    case 1047:
+      this.terminal.setAlternateMode(state);
+      break;
+
+    case 1048:  // Save cursor as in DECSC.
+      if (state)
+        this.terminal.saveCursorAndState();
+      else
+        this.terminal.restoreCursorAndState();
+      break;
+
+    case 1049:  // 1047 + 1048 + clear.
+      if (state) {
+        this.terminal.saveCursorAndState();
+        this.terminal.setAlternateMode(state);
+        this.terminal.clear();
+      } else {
+        this.terminal.setAlternateMode(state);
+        this.terminal.restoreCursorAndState();
+      }
+
+      break;
+
+    case 2004:  // Bracketed paste mode.
+      this.terminal.setBracketedPaste(state);
+      break;
+
+    default:
+      if (this.warnUnimplemented)
+        console.warn('Unimplemented DEC Private Mode: ' + code);
+      break;
+  }
+};
+
+/**
+ * Function shared by control characters and escape sequences that are
+ * ignored.
+ */
+hterm.VT.ignore = function() {};
+
+/**
+ * Collection of control characters expressed in a single byte.
+ *
+ * This includes the characters from the C0 and C1 sets (see [CTRL]) that we
+ * care about.  Two byte versions of the C1 codes are defined in the
+ * hterm.VT.ESC collection.
+ *
+ * The 'CC1' mnemonic here refers to the fact that these are one-byte Control
+ * Codes.  It's only used in this source file and not defined in any of the
+ * referenced documents.
+ */
+hterm.VT.CC1 = {};
+
+/**
+ * Collection of two-byte and three-byte sequences starting with ESC.
+ */
+hterm.VT.ESC = {};
+
+/**
+ * Collection of CSI (Control Sequence Introducer) sequences.
+ *
+ * These sequences begin with 'ESC [', and may take zero or more arguments.
+ */
+hterm.VT.CSI = {};
+
+/**
+ * Collection of OSC (Operating System Control) sequences.
+ *
+ * These sequences begin with 'ESC ]', followed by a function number and a
+ * string terminated by either ST or BEL.
+ */
+hterm.VT.OSC = {};
+
+/**
+ * Collection of VT52 sequences.
+ *
+ * When in VT52 mode, other sequences are disabled.
+ */
+hterm.VT.VT52 = {};
+
+/**
+ * Null (NUL).
+ *
+ * Silently ignored.
+ */
+hterm.VT.CC1['\x00'] = hterm.VT.ignore;
+
+/**
+ * Enquiry (ENQ).
+ *
+ * Transmit answerback message.
+ *
+ * The default answerback message in xterm is an empty string, so we just
+ * ignore this.
+ */
+hterm.VT.CC1['\x05'] = hterm.VT.ignore;
+
+/**
+ * Ring Bell (BEL).
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.CC1['\x07'] = function() {
+  this.terminal.ringBell();
+};
+
+/**
+ * Backspace (BS).
+ *
+ * Move the cursor to the left one character position, unless it is at the
+ * left margin, in which case no action occurs.
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.CC1['\x08'] = function() {
+  this.terminal.cursorLeft(1);
+};
+
+/**
+ * Horizontal Tab (HT).
+ *
+ * Move the cursor to the next tab stop, or to the right margin if no further
+ * tab stops are present on the line.
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.CC1['\x09'] = function() {
+  this.terminal.forwardTabStop();
+};
+
+/**
+ * Line Feed (LF).
+ *
+ * This code causes a line feed or a new line operation.  See Automatic
+ * Newline (LNM).
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.CC1['\x0a'] = function() {
+  this.terminal.formFeed();
+};
+
+/**
+ * Vertical Tab (VT).
+ *
+ * Interpreted as LF.
+ */
+hterm.VT.CC1['\x0b'] = hterm.VT.CC1['\x0a'];
+
+/**
+ * Form Feed (FF).
+ *
+ * Interpreted as LF.
+ */
+hterm.VT.CC1['\x0c'] = hterm.VT.CC1['\x0a'];
+
+/**
+ * Carriage Return (CR).
+ *
+ * Move cursor to the left margin on the current line.
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.CC1['\x0d'] = function() {
+  this.terminal.setCursorColumn(0);
+};
+
+/**
+ * Shift Out (SO), aka Lock Shift 0 (LS1).
+ *
+ * @this {!hterm.VT}
+ * Invoke G1 character set in GL.
+ */
+hterm.VT.CC1['\x0e'] = function() {
+  this.GL = 'G1';
+};
+
+/**
+ * Shift In (SI), aka Lock Shift 0 (LS0).
+ *
+ * Invoke G0 character set in GL.
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.CC1['\x0f'] = function() {
+  this.GL = 'G0';
+};
+
+/**
+ * Transmit On (XON).
+ *
+ * Not currently implemented.
+ *
+ * TODO(rginda): Implement?
+ */
+hterm.VT.CC1['\x11'] = hterm.VT.ignore;
+
+/**
+ * Transmit Off (XOFF).
+ *
+ * Not currently implemented.
+ *
+ * TODO(rginda): Implement?
+ */
+hterm.VT.CC1['\x13'] = hterm.VT.ignore;
+
+/**
+ * Cancel (CAN).
+ *
+ * If sent during a control sequence, the sequence is immediately terminated
+ * and not executed.
+ *
+ * It also causes the error character to be displayed.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CC1['\x18'] = function(parseState) {
+  // If we've shifted in the G1 character set, shift it back out to
+  // the default character set.
+  if (this.GL == 'G1') {
+    this.GL = 'G0';
+  }
+  parseState.resetParseFunction();
+  this.terminal.print('?');
+};
+
+/**
+ * Substitute (SUB).
+ *
+ * Interpreted as CAN.
+ */
+hterm.VT.CC1['\x1a'] = hterm.VT.CC1['\x18'];
+
+/**
+ * Escape (ESC).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CC1['\x1b'] = function(parseState) {
+  function parseESC(parseState) {
+    var ch = parseState.consumeChar();
+
+    if (ch == '\x1b')
+      return;
+
+    this.dispatch('ESC', ch, parseState);
+
+    if (parseState.func == parseESC)
+      parseState.resetParseFunction();
+  }
+
+  parseState.func = parseESC;
+};
+
+/**
+ * Delete (DEL).
+ */
+hterm.VT.CC1['\x7f'] = hterm.VT.ignore;
+
+// 8 bit control characters and their two byte equivalents, below...
+
+/**
+ * Index (IND).
+ *
+ * Like newline, only keep the X position
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.CC1['\x84'] =
+hterm.VT.ESC['D'] = function() {
+  this.terminal.lineFeed();
+};
+
+/**
+ * Next Line (NEL).
+ *
+ * Like newline, but doesn't add lines.
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.CC1['\x85'] =
+hterm.VT.ESC['E'] = function() {
+  this.terminal.setCursorColumn(0);
+  this.terminal.cursorDown(1);
+};
+
+/**
+ * Horizontal Tabulation Set (HTS).
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.CC1['\x88'] =
+hterm.VT.ESC['H'] = function() {
+  this.terminal.setTabStop(this.terminal.getCursorColumn());
+};
+
+/**
+ * Reverse Index (RI).
+ *
+ * Move up one line.
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.CC1['\x8d'] =
+hterm.VT.ESC['M'] = function() {
+  this.terminal.reverseLineFeed();
+};
+
+/**
+ * Single Shift 2 (SS2).
+ *
+ * Select of G2 Character Set for the next character only.
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CC1['\x8e'] =
+hterm.VT.ESC['N'] = hterm.VT.ignore;
+
+/**
+ * Single Shift 3 (SS3).
+ *
+ * Select of G3 Character Set for the next character only.
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CC1['\x8f'] =
+hterm.VT.ESC['O'] = hterm.VT.ignore;
+
+/**
+ * Device Control String (DCS).
+ *
+ * Indicate a DCS sequence.  See Device-Control functions in [XTERM].
+ * Not currently implemented.
+ *
+ * TODO(rginda): Consider implementing DECRQSS, the rest don't seem applicable.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CC1['\x90'] =
+hterm.VT.ESC['P'] = function(parseState) {
+  parseState.resetArguments();
+  parseState.func = this.parseUntilStringTerminator_;
+};
+
+/**
+ * Start of Guarded Area (SPA).
+ *
+ * Will not implement.
+ */
+hterm.VT.CC1['\x96'] =
+hterm.VT.ESC['V'] = hterm.VT.ignore;
+
+/**
+ * End of Guarded Area (EPA).
+ *
+ * Will not implement.
+ */
+hterm.VT.CC1['\x97'] =
+hterm.VT.ESC['W'] = hterm.VT.ignore;
+
+/**
+ * Start of String (SOS).
+ *
+ * Will not implement.
+ */
+hterm.VT.CC1['\x98'] =
+hterm.VT.ESC['X'] = hterm.VT.ignore;
+
+/**
+ * Single Character Introducer (SCI, also DECID).
+ *
+ * Return Terminal ID.  Obsolete form of 'ESC [ c' (DA).
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.CC1['\x9a'] =
+hterm.VT.ESC['Z'] = function() {
+  this.terminal.io.sendString('\x1b[?1;2c');
+};
+
+/**
+ * Control Sequence Introducer (CSI).
+ *
+ * The lead into most escape sequences.  See [CSI].
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CC1['\x9b'] =
+hterm.VT.ESC['['] = function(parseState) {
+  parseState.resetArguments();
+  this.leadingModifier_ = '';
+  this.trailingModifier_ = '';
+  parseState.func = this.parseCSI_;
+};
+
+/**
+ * String Terminator (ST).
+ *
+ * Used to terminate DCS/OSC/PM/APC commands which may take string arguments.
+ *
+ * We don't directly handle it here, as it's only used to terminate other
+ * sequences.  See the 'parseUntilStringTerminator_' method.
+ */
+hterm.VT.CC1['\x9c'] =
+hterm.VT.ESC['\\'] = hterm.VT.ignore;
+
+/**
+ * Operating System Command (OSC).
+ *
+ * Commands relating to the operating system.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CC1['\x9d'] =
+hterm.VT.ESC[']'] = function(parseState) {
+  parseState.resetArguments();
+
+  /**
+   * @param {!hterm.VT.ParseState} parseState The current parse state.
+   */
+  function parseOSC(parseState) {
+    if (!this.parseUntilStringTerminator_(parseState)) {
+      // The string sequence was too long.
+      return;
+    }
+
+    if (parseState.func == parseOSC) {
+      // We're not done parsing the string yet.
+      return;
+    }
+
+    // We're done.
+    var ary = parseState.args[0].match(/^(\d+);?(.*)$/);
+    if (ary) {
+      parseState.args[0] = ary[2];
+      this.dispatch('OSC', ary[1], parseState);
+    } else {
+      console.warn('Invalid OSC: ' + JSON.stringify(parseState.args[0]));
+    }
+
+    // Resetting the arguments isn't strictly necessary, but it makes debugging
+    // less confusing (otherwise args will stick around until the next sequence
+    // that needs arguments).
+    parseState.resetArguments();
+  }
+
+  parseState.func = parseOSC;
+};
+
+/**
+ * Privacy Message (PM).
+ *
+ * Will not implement.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CC1['\x9e'] =
+hterm.VT.ESC['^'] = function(parseState) {
+  parseState.resetArguments();
+  parseState.func = this.parseUntilStringTerminator_;
+};
+
+/**
+ * Application Program Control (APC).
+ *
+ * Will not implement.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CC1['\x9f'] =
+hterm.VT.ESC['_'] = function(parseState) {
+  parseState.resetArguments();
+  parseState.func = this.parseUntilStringTerminator_;
+};
+
+/**
+ * ESC \x20 - Unclear to me where these originated, possibly in xterm.
+ *
+ * Not currently implemented:
+ *   ESC \x20 F - Select 7 bit escape codes in responses (S7C1T).
+ *   ESC \x20 G - Select 8 bit escape codes in responses (S8C1T).
+ *                NB: We currently assume S7C1T always.
+ *
+ * Will not implement:
+ *   ESC \x20 L - Set ANSI conformance level 1.
+ *   ESC \x20 M - Set ANSI conformance level 2.
+ *   ESC \x20 N - Set ANSI conformance level 3.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.ESC['\x20'] = function(parseState) {
+  parseState.func = function(parseState) {
+    var ch = parseState.consumeChar();
+    if (this.warnUnimplemented)
+      console.warn('Unimplemented sequence: ESC 0x20 ' + ch);
+    parseState.resetParseFunction();
+  };
+};
+
+/**
+ * DEC 'ESC #' sequences.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.ESC['#'] = function(parseState) {
+  parseState.func = function(parseState) {
+    var ch = parseState.consumeChar();
+    if (ch == '8') {
+      // DEC Screen Alignment Test (DECALN).
+      this.terminal.setCursorPosition(0, 0);
+      this.terminal.fill('E');
+    }
+
+    parseState.resetParseFunction();
+  };
+};
+
+/**
+ * Designate Other Coding System (DOCS).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.ESC['%'] = function(parseState) {
+  parseState.func = function(parseState) {
+    var ch = parseState.consumeChar();
+
+    // If we've locked the encoding, then just eat the bytes and return.
+    if (this.codingSystemLocked_) {
+      if (ch == '/')
+        parseState.consumeChar();
+      parseState.resetParseFunction();
+      return;
+    }
+
+    // Process the encoding requests.
+    switch (ch) {
+      case '@':
+        // Switch to ECMA 35.
+        this.setEncoding('iso-2022');
+        break;
+
+      case 'G':
+        // Switch to UTF-8.
+        this.setEncoding('utf-8');
+        break;
+
+      case '/':
+        // One way transition to something else.
+        ch = parseState.consumeChar();
+        switch (ch) {
+          case 'G':  // UTF-8 Level 1.
+          case 'H':  // UTF-8 Level 2.
+          case 'I':  // UTF-8 Level 3.
+            // We treat all UTF-8 levels the same.
+            this.setEncoding('utf-8-locked');
+            break;
+
+          default:
+            if (this.warnUnimplemented)
+              console.warn('Unknown ESC % / argument: ' + JSON.stringify(ch));
+            break;
+        }
+        break;
+
+      default:
+        if (this.warnUnimplemented)
+          console.warn('Unknown ESC % argument: ' + JSON.stringify(ch));
+        break;
+    }
+
+    parseState.resetParseFunction();
+  };
+};
+
+/**
+ * Character Set Selection (SCS).
+ *
+ *   ESC ( Ps - Set G0 character set (VT100).
+ *   ESC ) Ps - Set G1 character set (VT220).
+ *   ESC * Ps - Set G2 character set (VT220).
+ *   ESC + Ps - Set G3 character set (VT220).
+ *   ESC - Ps - Set G1 character set (VT300).
+ *   ESC . Ps - Set G2 character set (VT300).
+ *   ESC / Ps - Set G3 character set (VT300).
+ *
+ * All other sequences are echoed to the terminal.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ * @param {string} code
+ */
+hterm.VT.ESC['('] =
+hterm.VT.ESC[')'] =
+hterm.VT.ESC['*'] =
+hterm.VT.ESC['+'] =
+hterm.VT.ESC['-'] =
+hterm.VT.ESC['.'] =
+hterm.VT.ESC['/'] = function(parseState, code) {
+  parseState.func = function(parseState) {
+    var ch = parseState.consumeChar();
+    if (ch == '\x1b') {
+      parseState.resetParseFunction();
+      parseState.func();
+      return;
+    }
+
+    var map = this.characterMaps.getMap(ch);
+    if (map !== undefined) {
+      if (code == '(') {
+        this.G0 = map;
+      } else if (code == ')' || code == '-') {
+        this.G1 = map;
+      } else if (code == '*' || code == '.') {
+        this.G2 = map;
+      } else if (code == '+' || code == '/') {
+        this.G3 = map;
+      }
+    } else if (this.warnUnimplemented) {
+      console.log('Invalid character set for "' + code + '": ' + ch);
+    }
+
+    parseState.resetParseFunction();
+  };
+};
+
+/**
+ * Back Index (DECBI).
+ *
+ * VT420 and up.  Not currently implemented.
+ */
+hterm.VT.ESC['6'] = hterm.VT.ignore;
+
+/**
+ * Save Cursor (DECSC).
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.ESC['7'] = function() {
+  this.terminal.saveCursorAndState();
+};
+
+/**
+ * Restore Cursor (DECRC).
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.ESC['8'] = function() {
+  this.terminal.restoreCursorAndState();
+};
+
+/**
+ * Forward Index (DECFI).
+ *
+ * VT210 and up.  Not currently implemented.
+ */
+hterm.VT.ESC['9'] = hterm.VT.ignore;
+
+/**
+ * Application keypad (DECKPAM).
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.ESC['='] = function() {
+  this.terminal.keyboard.applicationKeypad = true;
+};
+
+/**
+ * Normal keypad (DECKPNM).
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.ESC['>'] = function() {
+  this.terminal.keyboard.applicationKeypad = false;
+};
+
+/**
+ * Cursor to lower left corner of screen.
+ *
+ * Will not implement.
+ *
+ * This is only recognized by xterm when the hpLowerleftBugCompat resource is
+ * set.
+ */
+hterm.VT.ESC['F'] = hterm.VT.ignore;
+
+/**
+ * Full Reset (RIS).
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.ESC['c'] = function() {
+  this.terminal.reset();
+};
+
+/**
+ * Memory lock/unlock.
+ *
+ * Will not implement.
+ */
+hterm.VT.ESC['l'] =
+hterm.VT.ESC['m'] = hterm.VT.ignore;
+
+/**
+ * Lock Shift 2 (LS2)
+ *
+ * Invoke the G2 Character Set as GL.
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.ESC['n'] = function() {
+  this.GL = 'G2';
+};
+
+/**
+ * Lock Shift 3 (LS3)
+ *
+ * Invoke the G3 Character Set as GL.
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.ESC['o'] = function() {
+  this.GL = 'G3';
+};
+
+/**
+ * Lock Shift 2, Right (LS3R)
+ *
+ * Invoke the G3 Character Set as GR.
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.ESC['|'] = function() {
+  this.GR = 'G3';
+};
+
+/**
+ * Lock Shift 2, Right (LS2R)
+ *
+ * Invoke the G2 Character Set as GR.
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.ESC['}'] = function() {
+  this.GR = 'G2';
+};
+
+/**
+ * Lock Shift 1, Right (LS1R)
+ *
+ * Invoke the G1 Character Set as GR.
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.ESC['~'] = function() {
+  this.GR = 'G1';
+};
+
+/**
+ * Change icon name and window title.
+ *
+ * We only change the window title.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['0'] = function(parseState) {
+  this.terminal.setWindowTitle(parseState.args[0]);
+};
+
+/**
+ * Change window title.
+ */
+hterm.VT.OSC['2'] = hterm.VT.OSC['0'];
+
+/**
+ * Set/read color palette.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['4'] = function(parseState) {
+  // Args come in as a single 'index1;rgb1 ... ;indexN;rgbN' string.
+  // We split on the semicolon and iterate through the pairs.
+  var args = parseState.args[0].split(';');
+
+  var pairCount = Math.floor(args.length / 2);
+  var colorPalette = this.terminal.getTextAttributes().colorPalette;
+  var responseArray = [];
+
+  for (var pairNumber = 0; pairNumber < pairCount; ++pairNumber) {
+    var colorIndex = parseInt(args[pairNumber * 2], 10);
+    var colorValue = args[pairNumber * 2 + 1];
+
+    if (colorIndex >= colorPalette.length)
+      continue;
+
+    if (colorValue == '?') {
+      // '?' means we should report back the current color value.
+      colorValue = lib.colors.rgbToX11(colorPalette[colorIndex]);
+      if (colorValue)
+        responseArray.push(colorIndex + ';' + colorValue);
+
+      continue;
+    }
+
+    colorValue = lib.colors.x11ToCSS(colorValue);
+    if (colorValue)
+      colorPalette[colorIndex] = colorValue;
+  }
+
+  if (responseArray.length)
+    this.terminal.io.sendString('\x1b]4;' + responseArray.join(';') + '\x07');
+};
+
+/**
+ * Hyperlinks.
+ *
+ * The first argument is optional and colon separated:
+ *   id=<id>
+ * The second argument is the link itself.
+ *
+ * Calling with a non-blank URI starts it.  A blank URI stops it.
+ *
+ * https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['8'] = function(parseState) {
+  const args = parseState.args[0].split(';');
+  let id = null;
+  let uri = null;
+
+  if (args.length != 2 || args[1].length == 0) {
+    // Reset link.
+  } else {
+    // Pull out any colon separated parameters in the first argument.
+    const params = args[0].split(':');
+    id = '';
+    params.forEach((param) => {
+      const idx = param.indexOf('=');
+      if (idx == -1)
+        return;
+
+      const key = param.slice(0, idx);
+      const value = param.slice(idx + 1);
+      switch (key) {
+        case 'id':
+          id = value;
+          break;
+        default:
+          // Ignore unknown keys.
+          break;
+      }
+    });
+
+    // The URI is in the second argument.
+    uri = args[1];
+  }
+
+  const attrs = this.terminal.getTextAttributes();
+  attrs.uri = uri;
+  attrs.uriId = id;
+};
+
+/**
+ * iTerm2 growl notifications.
+ *
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['9'] = function(parseState) {
+  // This just dumps the entire string as the message.
+  hterm.notify({'body': parseState.args[0]});
+};
+
+/**
+ * Change VT100 text foreground color.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['10'] = function(parseState) {
+  // Args come in as a single string, but extra args will chain to the following
+  // OSC sequences.
+  var args = parseState.args[0].split(';');
+  if (!args)
+    return;
+
+  var colorX11 = lib.colors.x11ToCSS(args.shift());
+  if (colorX11)
+    this.terminal.setForegroundColor(colorX11);
+
+  if (args.length > 0) {
+    parseState.args[0] = args.join(';');
+    hterm.VT.OSC['11'].apply(this, [parseState]);
+  }
+};
+
+/**
+ * Change VT100 text background color.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['11'] = function(parseState) {
+  // Args come in as a single string, but extra args will chain to the following
+  // OSC sequences.
+  var args = parseState.args[0].split(';');
+  if (!args)
+    return;
+
+  var colorX11 = lib.colors.x11ToCSS(args.shift());
+  if (colorX11)
+    this.terminal.setBackgroundColor(colorX11);
+
+  if (args.length > 0) {
+    parseState.args[0] = args.join(';');
+    hterm.VT.OSC['12'].apply(this, [parseState]);
+  }
+};
+
+/**
+ * Change text cursor color.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['12'] = function(parseState) {
+  // Args come in as a single string, but extra args will chain to the following
+  // OSC sequences.
+  var args = parseState.args[0].split(';');
+  if (!args)
+    return;
+
+  var colorX11 = lib.colors.x11ToCSS(args.shift());
+  if (colorX11)
+    this.terminal.setCursorColor(colorX11);
+
+  /* Note: If we support OSC 13+, we'd chain it here.
+  if (args.length > 0) {
+    parseState.args[0] = args.join(';');
+    hterm.VT.OSC['13'].apply(this, [parseState]);
+  }
+  */
+};
+
+/**
+ * Set the cursor shape.
+ *
+ * Parameter is expected to be in the form "CursorShape=number", where number is
+ * one of:
+ *
+ *   0 - Block
+ *   1 - I-Beam
+ *   2 - Underline
+ *
+ * This is a bit of a de-facto standard supported by iTerm 2 and Konsole.  See
+ * also: DECSCUSR.
+ *
+ * Invalid numbers will restore the cursor to the block shape.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['50'] = function(parseState) {
+  var args = parseState.args[0].match(/CursorShape=(.)/i);
+  if (!args) {
+    console.warn('Could not parse OSC 50 args: ' + parseState.args[0]);
+    return;
+  }
+
+  switch (args[1]) {
+    case '1':  // CursorShape=1: I-Beam.
+      this.terminal.setCursorShape(hterm.Terminal.cursorShape.BEAM);
+      break;
+
+    case '2':  // CursorShape=2: Underline.
+      this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE);
+      break;
+
+    default:  // CursorShape=0: Block.
+      this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK);
+  }
+};
+
+/**
+ * Set/read system clipboard.
+ *
+ * Read is not implemented due to security considerations.  A remote app
+ * that is able to both write and read to the clipboard could essentially
+ * take over your session.
+ *
+ * The clipboard data will be decoded according to the 'receive-encoding'
+ * preference.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['52'] = function(parseState) {
+  if (!this.enableClipboardWrite)
+    return;
+
+  // Args come in as a single 'clipboard;b64-data' string.  The clipboard
+  // parameter is used to select which of the X clipboards to address.  Since
+  // we're not integrating with X, we treat them all the same.
+  var args = parseState.args[0].match(/^[cps01234567]*;(.*)/);
+  if (!args)
+    return;
+
+  let data;
+  try {
+    data = window.atob(args[1]);
+  } catch (e) {
+    // If the user sent us invalid base64 content, silently ignore it.
+    return;
+  }
+  if (this.characterEncoding == 'utf-8') {
+    const decoder = new TextDecoder();
+    const bytes = lib.codec.stringToCodeUnitArray(data);
+    data = decoder.decode(bytes);
+  }
+  if (data)
+    this.terminal.copyStringToClipboard(data);
+};
+
+/**
+ * Reset color palette.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['104'] = function(parseState) {
+  const attrs = this.terminal.getTextAttributes();
+
+  // If there are no args, we reset the entire palette.
+  if (!parseState.args[0]) {
+    attrs.resetColorPalette();
+    return;
+  }
+
+  // Args come in as a single 'index1;index2;...;indexN' string.
+  // Split on the semicolon and iterate through the colors.
+  const args = parseState.args[0].split(';');
+  args.forEach((c) => attrs.resetColor(c));
+};
+
+/**
+ * Reset foreground color.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['110'] = function(parseState) {
+  this.terminal.setForegroundColor();
+};
+
+/**
+ * Reset background color.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['111'] = function(parseState) {
+  this.terminal.setBackgroundColor();
+};
+
+/**
+ * Reset text cursor color.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['112'] = function(parseState) {
+  this.terminal.setCursorColor();
+};
+
+/**
+ * iTerm2 extended sequences.
+ *
+ * We only support image display atm.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['1337'] = function(parseState) {
+  // Args come in as a set of key value pairs followed by data.
+  // File=name=<base64>;size=123;inline=1:<base64 data>
+  let args = parseState.args[0].match(/^File=([^:]*):([\s\S]*)$/m);
+  if (!args) {
+    if (this.warnUnimplemented)
+      console.log(`iTerm2 1337: unsupported sequence: ${args[1]}`);
+    return;
+  }
+
+  const options = {
+    name: '',
+    size: 0,
+    preserveAspectRatio: true,
+    inline: false,
+    width: 'auto',
+    height: 'auto',
+    align: 'left',
+    type: '',
+    buffer: lib.codec.stringToCodeUnitArray(atob(args[2])).buffer,
+  };
+  // Walk the "key=value;" sets.
+  args[1].split(';').forEach((ele) => {
+    const kv = ele.match(/^([^=]+)=(.*)$/m);
+    if (!kv)
+      return;
+
+    // Sanitize values nicely.
+    switch (kv[1]) {
+      case 'name':
+        try {
+          options.name = window.atob(kv[2]);
+        } catch (e) {}
+        break;
+      case 'size':
+        try {
+          options.size = parseInt(kv[2], 10);
+        } catch (e) {}
+        break;
+      case 'width':
+        options.width = kv[2];
+        break;
+      case 'height':
+        options.height = kv[2];
+        break;
+      case 'preserveAspectRatio':
+        options.preserveAspectRatio = !(kv[2] == '0');
+        break;
+      case 'inline':
+        options.inline = !(kv[2] == '0');
+        break;
+      // hterm-specific keys.
+      case 'align':
+        options.align = kv[2];
+        break;
+      case 'type':
+        options.type = kv[2];
+        break;
+      default:
+        // Ignore unknown keys.  Don't want remote stuffing our JS env.
+        break;
+    }
+  });
+
+  // This is a bit of a hack.  If the buffer has data following the image, we
+  // need to delay processing of it until after we've finished with the image.
+  // Otherwise while we wait for the the image to load asynchronously, the new
+  // text data will intermingle with the image.
+  if (options.inline) {
+    const io = this.terminal.io;
+    const queued = parseState.peekRemainingBuf();
+    parseState.advance(queued.length);
+    this.terminal.displayImage(options);
+    io.print(queued);
+  } else
+    this.terminal.displayImage(options);
+};
+
+/**
+ * URxvt perl modules.
+ *
+ * This is the escape system used by rxvt-unicode and its perl modules.
+ * Obviously we don't support perl or custom modules, so we list a few common
+ * ones that we find useful.
+ *
+ * Technically there is no format here, but most modules obey:
+ * <module name>;<module args, usually ; delimited>
+ *
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.OSC['777'] = function(parseState) {
+  var ary;
+  var urxvtMod = parseState.args[0].split(';', 1)[0];
+
+  switch (urxvtMod) {
+    case 'notify':
+      // Format:
+      // notify;title;message
+      var title, message;
+      ary = parseState.args[0].match(/^[^;]+;([^;]*)(;([\s\S]*))?$/);
+      if (ary) {
+        title = ary[1];
+        message = ary[3];
+      }
+      hterm.notify({'title': title, 'body': message});
+      break;
+
+    default:
+      console.warn('Unknown urxvt module: ' + parseState.args[0]);
+      break;
+  }
+};
+
+/**
+ * Insert (blank) characters (ICH).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['@'] = function(parseState) {
+  this.terminal.insertSpace(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Up (CUU).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['A'] = function(parseState) {
+  this.terminal.cursorUp(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Down (CUD).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['B'] = function(parseState) {
+  this.terminal.cursorDown(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Forward (CUF).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['C'] = function(parseState) {
+  this.terminal.cursorRight(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Backward (CUB).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['D'] = function(parseState) {
+  this.terminal.cursorLeft(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Next Line (CNL).
+ *
+ * This is like Cursor Down, except the cursor moves to the beginning of the
+ * line as well.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['E'] = function(parseState) {
+  this.terminal.cursorDown(parseState.iarg(0, 1));
+  this.terminal.setCursorColumn(0);
+};
+
+/**
+ * Cursor Preceding Line (CPL).
+ *
+ * This is like Cursor Up, except the cursor moves to the beginning of the
+ * line as well.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['F'] = function(parseState) {
+  this.terminal.cursorUp(parseState.iarg(0, 1));
+  this.terminal.setCursorColumn(0);
+};
+
+/**
+ * Cursor Horizontal Absolute (CHA).
+ *
+ * Xterm calls this Cursor Character Absolute.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['G'] = function(parseState) {
+  this.terminal.setCursorColumn(parseState.iarg(0, 1) - 1);
+};
+
+/**
+ * Cursor Position (CUP).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['H'] = function(parseState) {
+  this.terminal.setCursorPosition(parseState.iarg(0, 1) - 1,
+                                  parseState.iarg(1, 1) - 1);
+};
+
+/**
+ * Cursor Forward Tabulation (CHT).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['I'] = function(parseState) {
+  var count = parseState.iarg(0, 1);
+  count = lib.f.clamp(count, 1, this.terminal.screenSize.width);
+  for (var i = 0; i < count; i++) {
+    this.terminal.forwardTabStop();
+  }
+};
+
+/**
+ * Erase in Display (ED, DECSED).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['J'] =
+hterm.VT.CSI['?J'] = function(parseState) {
+  var arg = parseState.args[0];
+
+  if (!arg || arg == 0) {
+    this.terminal.eraseBelow();
+  } else if (arg == 1) {
+    this.terminal.eraseAbove();
+  } else if (arg == 2) {
+    this.terminal.clear();
+  } else if (arg == 3) {
+    if (this.enableCsiJ3) {
+      this.terminal.clearScrollback();
+    }
+  }
+};
+
+/**
+ * Erase in line (EL, DECSEL).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['K'] =
+hterm.VT.CSI['?K'] = function(parseState) {
+  var arg = parseState.args[0];
+
+  if (!arg || arg == 0) {
+    this.terminal.eraseToRight();
+  } else if (arg == 1) {
+    this.terminal.eraseToLeft();
+  } else if (arg == 2) {
+    this.terminal.eraseLine();
+  }
+};
+
+/**
+ * Insert Lines (IL).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['L'] = function(parseState) {
+  this.terminal.insertLines(parseState.iarg(0, 1));
+};
+
+/**
+ * Delete Lines (DL).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['M'] = function(parseState) {
+  this.terminal.deleteLines(parseState.iarg(0, 1));
+};
+
+/**
+ * Delete Characters (DCH).
+ *
+ * This command shifts the line contents left, starting at the cursor position.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['P'] = function(parseState) {
+  this.terminal.deleteChars(parseState.iarg(0, 1));
+};
+
+/**
+ * Scroll Up (SU).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['S'] = function(parseState) {
+  this.terminal.vtScrollUp(parseState.iarg(0, 1));
+};
+
+/**
+ * Scroll Down (SD).
+ * Also 'Initiate highlight mouse tracking'.  Will not implement this part.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['T'] = function(parseState) {
+  if (parseState.args.length <= 1)
+    this.terminal.vtScrollDown(parseState.iarg(0, 1));
+};
+
+/**
+ * Reset one or more features of the title modes to the default value.
+ *
+ *   ESC [ > Ps T
+ *
+ * Normally, "reset" disables the feature. It is possible to disable the
+ * ability to reset features by compiling a different default for the title
+ * modes into xterm.
+ *
+ * Ps values:
+ *   0 - Do not set window/icon labels using hexadecimal.
+ *   1 - Do not query window/icon labels using hexadecimal.
+ *   2 - Do not set window/icon labels using UTF-8.
+ *   3 - Do not query window/icon labels using UTF-8.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['>T'] = hterm.VT.ignore;
+
+/**
+ * Erase Characters (ECH).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['X'] = function(parseState) {
+  this.terminal.eraseToRight(parseState.iarg(0, 1));
+};
+
+/**
+ * Cursor Backward Tabulation (CBT).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['Z'] = function(parseState) {
+  var count = parseState.iarg(0, 1);
+  count = lib.f.clamp(count, 1, this.terminal.screenSize.width);
+  for (var i = 0; i < count; i++) {
+    this.terminal.backwardTabStop();
+  }
+};
+
+/**
+ * Character Position Absolute (HPA).
+ *
+ * Same as Cursor Horizontal Absolute (CHA).
+ */
+hterm.VT.CSI['`'] = hterm.VT.CSI['G'];
+
+/**
+ * Character Position Relative (HPR).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['a'] = function(parseState) {
+  this.terminal.setCursorColumn(this.terminal.getCursorColumn() +
+                                parseState.iarg(0, 1));
+};
+
+/**
+ * Repeat the preceding graphic character.
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['b'] = hterm.VT.ignore;
+
+/**
+ * Send Device Attributes (Primary DA).
+ *
+ * TODO(rginda): This is hardcoded to send back 'VT100 with Advanced Video
+ * Option', but it may be more correct to send a VT220 response once
+ * we fill out the 'Not currently implemented' parts.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['c'] = function(parseState) {
+  if (!parseState.args[0] || parseState.args[0] == 0) {
+    this.terminal.io.sendString('\x1b[?1;2c');
+  }
+};
+
+/**
+ * Send Device Attributes (Secondary DA).
+ *
+ * TODO(rginda): This is hardcoded to send back 'VT100' but it may be more
+ * correct to send a VT220 response once we fill out more 'Not currently
+ * implemented' parts.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['>c'] = function(parseState) {
+  this.terminal.io.sendString('\x1b[>0;256;0c');
+};
+
+/**
+ * Line Position Absolute (VPA).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['d'] = function(parseState) {
+  this.terminal.setAbsoluteCursorRow(parseState.iarg(0, 1) - 1);
+};
+
+/**
+ * Horizontal and Vertical Position (HVP).
+ *
+ * Same as Cursor Position (CUP).
+ */
+hterm.VT.CSI['f'] = hterm.VT.CSI['H'];
+
+/**
+ * Tab Clear (TBC).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['g'] = function(parseState) {
+  if (!parseState.args[0] || parseState.args[0] == 0) {
+    // Clear tab stop at cursor.
+    this.terminal.clearTabStopAtCursor();
+  } else if (parseState.args[0] == 3) {
+    // Clear all tab stops.
+    this.terminal.clearAllTabStops();
+  }
+};
+
+/**
+ * Set Mode (SM).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['h'] = function(parseState) {
+  for (var i = 0; i < parseState.args.length; i++) {
+    this.setANSIMode(parseState.args[i], true);
+  }
+};
+
+/**
+ * DEC Private Mode Set (DECSET).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['?h'] = function(parseState) {
+  for (var i = 0; i < parseState.args.length; i++) {
+    this.setDECMode(parseState.args[i], true);
+  }
+};
+
+/**
+ * Media Copy (MC).
+ * Media Copy (MC, DEC Specific).
+ *
+ * These commands control the printer.  Will not implement.
+ */
+hterm.VT.CSI['i'] =
+hterm.VT.CSI['?i'] = hterm.VT.ignore;
+
+/**
+ * Reset Mode (RM).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['l'] = function(parseState) {
+  for (var i = 0; i < parseState.args.length; i++) {
+    this.setANSIMode(parseState.args[i], false);
+  }
+};
+
+/**
+ * DEC Private Mode Reset (DECRST).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current parse state.
+ */
+hterm.VT.CSI['?l'] = function(parseState) {
+  for (var i = 0; i < parseState.args.length; i++) {
+    this.setDECMode(parseState.args[i], false);
+  }
+};
+
+/**
+ * Parse extended SGR 38/48 sequences.
+ *
+ * This deals with the various ISO 8613-6 forms, and with legacy xterm forms
+ * that are common in the wider application world.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState The current input state.
+ * @param {number} i The argument in parseState to start processing.
+ * @param {!hterm.TextAttributes} attrs The current text attributes.
+ * @return {!Object} The skipCount member defines how many arguments to skip
+ *     (i.e. how many were processed), and the color member is the color that
+ *     was successfully processed, or undefined if not.
+ */
+hterm.VT.prototype.parseSgrExtendedColors = function(parseState, i, attrs) {
+  let ary;
+  let usedSubargs;
+
+  if (parseState.argHasSubargs(i)) {
+    // The ISO 8613-6 compliant form.
+    // e.g. 38:[color choice]:[arg1]:[arg2]:...
+    ary = parseState.args[i].split(':');
+    ary.shift();  // Remove "38".
+    usedSubargs = true;
+  } else if (parseState.argHasSubargs(i + 1)) {
+    // The xterm form which isn't ISO 8613-6 compliant.  Not many emulators
+    // support this, and others actively do not want to.  We'll ignore it so
+    // at least the rest of the stream works correctly.  e.g. 38;2:R:G:B
+    // We return 0 here so we only skip the "38" ... we can't be confident the
+    // next arg is actually supposed to be part of it vs a typo where the next
+    // arg is legit.
+    return {skipCount: 0};
+  } else {
+    // The xterm form which isn't ISO 8613-6 compliant, but many emulators
+    // support, and many applications rely on.
+    // e.g. 38;2;R;G;B
+    ary = parseState.args.slice(i + 1);
+    usedSubargs = false;
+  }
+
+  // Figure out which form to parse.
+  switch (parseInt(ary[0], 10)) {
+    default:  // Unknown.
+    case 0:  // Implementation defined.  We ignore it.
+      return {skipCount: 0};
+
+    case 1: {  // Transparent color.
+      // Require ISO 8613-6 form.
+      if (!usedSubargs)
+        return {skipCount: 0};
+
+      return {
+        color: 'rgba(0, 0, 0, 0)',
+        skipCount: 0,
+      };
+    }
+
+    case 2: {  // RGB color.
+      // Skip over the color space identifier, if it exists.
+      let start;
+      if (usedSubargs) {
+        // The ISO 8613-6 compliant form:
+        //   38:2:<color space id>:R:G:B[:...]
+        // The xterm form isn't ISO 8613-6 compliant.
+        //   38:2:R:G:B
+        // Since the ISO 8613-6 form requires at least 5 arguments,
+        // we can still support the xterm form unambiguously.
+        if (ary.length == 4)
+          start = 1;
+        else
+          start = 2;
+      } else {
+        // The legacy xterm form: 38;2;R;G;B
+        start = 1;
+      }
+
+      // We need at least 3 args for RGB.  If we don't have them, assume this
+      // sequence is corrupted, so don't eat anything more.
+      // We ignore more than 3 args on purpose since ISO 8613-6 defines some,
+      // and we don't care about them.
+      if (ary.length < start + 3)
+        return {skipCount: 0};
+
+      const r = parseState.parseInt(ary[start + 0]);
+      const g = parseState.parseInt(ary[start + 1]);
+      const b = parseState.parseInt(ary[start + 2]);
+      return {
+        color: `rgb(${r}, ${g}, ${b})`,
+        skipCount: usedSubargs ? 0 : 4,
+      };
+    }
+
+    case 3: {  // CMY color.
+      // No need to support xterm/legacy forms as xterm doesn't support CMY.
+      if (!usedSubargs)
+        return {skipCount: 0};
+
+      // We need at least 4 args for CMY.  If we don't have them, assume
+      // this sequence is corrupted.  We ignore the color space identifier,
+      // tolerance, etc...
+      if (ary.length < 4)
+        return {skipCount: 0};
+
+      // TODO: See CMYK below.
+      // const c = parseState.parseInt(ary[1]);
+      // const m = parseState.parseInt(ary[2]);
+      // const y = parseState.parseInt(ary[3]);
+      return {skipCount: 0};
+    }
+
+    case 4: {  // CMYK color.
+      // No need to support xterm/legacy forms as xterm doesn't support CMYK.
+      if (!usedSubargs)
+        return {skipCount: 0};
+
+      // We need at least 5 args for CMYK.  If we don't have them, assume
+      // this sequence is corrupted.  We ignore the color space identifier,
+      // tolerance, etc...
+      if (ary.length < 5)
+        return {skipCount: 0};
+
+      // TODO: Implement this.
+      // Might wait until CSS4 is adopted for device-cmyk():
+      // https://www.w3.org/TR/css-color-4/#cmyk-colors
+      // Or normalize it to RGB ourselves:
+      // https://www.w3.org/TR/css-color-4/#cmyk-rgb
+      // const c = parseState.parseInt(ary[1]);
+      // const m = parseState.parseInt(ary[2]);
+      // const y = parseState.parseInt(ary[3]);
+      // const k = parseState.parseInt(ary[4]);
+      return {skipCount: 0};
+    }
+
+    case 5: {  // Color palette index.
+      // If we're short on args, assume this sequence is corrupted, so don't
+      // eat anything more.
+      if (ary.length < 2)
+        return {skipCount: 0};
+
+      // Support 38:5:P (ISO 8613-6) and 38;5;P (xterm/legacy).
+      // We also ignore extra args with 38:5:P:[...], but more for laziness.
+      const ret = {
+        skipCount: usedSubargs ? 0 : 2,
+      };
+      const color = parseState.parseInt(ary[1]);
+      if (color < attrs.colorPalette.length)
+        ret.color = color;
+      return ret;
+    }
+  }
+};
+
+/**
+ * Character Attributes (SGR).
+ *
+ * Iterate through the list of arguments, applying the attribute changes based
+ * on the argument value...
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState
+ */
+hterm.VT.CSI['m'] = function(parseState) {
+  var attrs = this.terminal.getTextAttributes();
+
+  if (!parseState.args.length) {
+    attrs.reset();
+    return;
+  }
+
+  for (var i = 0; i < parseState.args.length; i++) {
+    // If this argument has subargs (i.e. it has args followed by colons),
+    // the iarg logic will implicitly truncate that off for us.
+    var arg = parseState.iarg(i, 0);
+
+    if (arg < 30) {
+      if (arg == 0) {  // Normal (default).
+        attrs.reset();
+      } else if (arg == 1) {  // Bold.
+        attrs.bold = true;
+      } else if (arg == 2) {  // Faint.
+        attrs.faint = true;
+      } else if (arg == 3) {  // Italic.
+        attrs.italic = true;
+      } else if (arg == 4) {  // Underline.
+        if (parseState.argHasSubargs(i)) {
+          const uarg = parseState.args[i].split(':')[1];
+          if (uarg == 0)
+            attrs.underline = false;
+          else if (uarg == 1)
+            attrs.underline = 'solid';
+          else if (uarg == 2)
+            attrs.underline = 'double';
+          else if (uarg == 3)
+            attrs.underline = 'wavy';
+          else if (uarg == 4)
+            attrs.underline = 'dotted';
+          else if (uarg == 5)
+            attrs.underline = 'dashed';
+        } else {
+          attrs.underline = 'solid';
+        }
+      } else if (arg == 5) {  // Blink.
+        attrs.blink = true;
+      } else if (arg == 7) {  // Inverse.
+        attrs.inverse = true;
+      } else if (arg == 8) {  // Invisible.
+        attrs.invisible = true;
+      } else if (arg == 9) {  // Crossed out.
+        attrs.strikethrough = true;
+      } else if (arg == 21) {  // Double underlined.
+        attrs.underline = 'double';
+      } else if (arg == 22) {  // Not bold & not faint.
+        attrs.bold = false;
+        attrs.faint = false;
+      } else if (arg == 23) {  // Not italic.
+        attrs.italic = false;
+      } else if (arg == 24) {  // Not underlined.
+        attrs.underline = false;
+      } else if (arg == 25) {  // Not blink.
+        attrs.blink = false;
+      } else if (arg == 27) {  // Steady.
+        attrs.inverse = false;
+      } else if (arg == 28) {  // Visible.
+        attrs.invisible = false;
+      } else if (arg == 29) {  // Not crossed out.
+        attrs.strikethrough = false;
+      }
+
+    } else if (arg < 50) {
+      // Select fore/background color from bottom half of 16 color palette
+      // or from the 256 color palette or alternative specify color in fully
+      // qualified rgb(r, g, b) form.
+      if (arg < 38) {
+        attrs.foregroundSource = arg - 30;
+
+      } else if (arg == 38) {
+        const result = this.parseSgrExtendedColors(parseState, i, attrs);
+        if (result.color !== undefined)
+          attrs.foregroundSource = result.color;
+        i += result.skipCount;
+
+      } else if (arg == 39) {
+        attrs.foregroundSource = attrs.SRC_DEFAULT;
+
+      } else if (arg < 48) {
+        attrs.backgroundSource = arg - 40;
+
+      } else if (arg == 48) {
+        const result = this.parseSgrExtendedColors(parseState, i, attrs);
+        if (result.color !== undefined)
+          attrs.backgroundSource = result.color;
+        i += result.skipCount;
+
+      } else {
+        attrs.backgroundSource = attrs.SRC_DEFAULT;
+      }
+
+    } else if (arg == 58) {  // Underline coloring.
+      const result = this.parseSgrExtendedColors(parseState, i, attrs);
+      if (result.color !== undefined)
+        attrs.underlineSource = result.color;
+      i += result.skipCount;
+
+    } else if (arg == 59) {  // Disable underline coloring.
+      attrs.underlineSource = attrs.SRC_DEFAULT;
+
+    } else if (arg >= 90 && arg <= 97) {
+      attrs.foregroundSource = arg - 90 + 8;
+
+    } else if (arg >= 100 && arg <= 107) {
+      attrs.backgroundSource = arg - 100 + 8;
+    }
+  }
+
+  attrs.setDefaults(this.terminal.getForegroundColor(),
+                    this.terminal.getBackgroundColor());
+};
+
+// SGR calls can handle subargs.
+hterm.VT.CSI['m'].supportsSubargs = true;
+
+/**
+ * Set xterm-specific keyboard modes.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['>m'] = hterm.VT.ignore;
+
+/**
+ * Device Status Report (DSR, DEC Specific).
+ *
+ * 5 - Status Report. Result (OK) is CSI 0 n
+ * 6 - Report Cursor Position (CPR) [row;column]. Result is CSI r ; c R
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState
+ */
+hterm.VT.CSI['n'] = function(parseState) {
+  if (parseState.args[0] == 5) {
+    this.terminal.io.sendString('\x1b0n');
+  } else if (parseState.args[0] == 6) {
+    var row = this.terminal.getCursorRow() + 1;
+    var col = this.terminal.getCursorColumn() + 1;
+    this.terminal.io.sendString('\x1b[' + row + ';' + col + 'R');
+  }
+};
+
+/**
+ * Disable modifiers which may be enabled via CSI['>m'].
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['>n'] = hterm.VT.ignore;
+
+/**
+ * Device Status Report (DSR, DEC Specific).
+ *
+ * 6  - Report Cursor Position (CPR) [row;column] as CSI ? r ; c R
+ * 15 - Report Printer status as CSI ? 1 0 n (ready) or
+ *      CSI ? 1 1 n (not ready).
+ * 25 - Report UDK status as CSI ? 2 0 n (unlocked) or CSI ? 2 1 n (locked).
+ * 26 - Report Keyboard status as CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).
+ *      The last two parameters apply to VT400 & up, and denote keyboard ready
+ *      and LK01 respectively.
+ * 53 - Report Locator status as CSI ? 5 3 n Locator available, if compiled-in,
+ *      or CSI ? 5 0 n No Locator, if not.
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState
+ */
+hterm.VT.CSI['?n'] = function(parseState) {
+  if (parseState.args[0] == 6) {
+    var row = this.terminal.getCursorRow() + 1;
+    var col = this.terminal.getCursorColumn() + 1;
+    this.terminal.io.sendString('\x1b[' + row + ';' + col + 'R');
+  } else if (parseState.args[0] == 15) {
+    this.terminal.io.sendString('\x1b[?11n');
+  } else if (parseState.args[0] == 25) {
+    this.terminal.io.sendString('\x1b[?21n');
+  } else if (parseState.args[0] == 26) {
+    this.terminal.io.sendString('\x1b[?12;1;0;0n');
+  } else if (parseState.args[0] == 53) {
+    this.terminal.io.sendString('\x1b[?50n');
+  }
+};
+
+/**
+ * This is used by xterm to decide whether to hide the pointer cursor as the
+ * user types.
+ *
+ * Valid values for the parameter:
+ *   0 - Never hide the pointer.
+ *   1 - Hide if the mouse tracking mode is not enabled.
+ *   2 - Always hide the pointer.
+ *
+ * If no parameter is given, xterm uses the default, which is 1.
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['>p'] = hterm.VT.ignore;
+
+/**
+ * Soft terminal reset (DECSTR).
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.CSI['!p'] = function() {
+  this.terminal.softReset();
+};
+
+/**
+ * Request ANSI Mode (DECRQM).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['$p'] = hterm.VT.ignore;
+hterm.VT.CSI['?$p'] = hterm.VT.ignore;
+
+/**
+ * Set conformance level (DECSCL).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['"p'] = hterm.VT.ignore;
+
+/**
+ * Load LEDs (DECLL).
+ *
+ * Not currently implemented.  Could be implemented as virtual LEDs overlaying
+ * the terminal if anyone cares.
+ */
+hterm.VT.CSI['q'] = hterm.VT.ignore;
+
+/**
+ * Set cursor style (DECSCUSR, VT520).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState
+ */
+hterm.VT.CSI[' q'] = function(parseState) {
+  var arg = parseState.args[0];
+
+  if (arg == 0 || arg == 1) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK);
+    this.terminal.setCursorBlink(true);
+  } else if (arg == 2) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK);
+    this.terminal.setCursorBlink(false);
+  } else if (arg == 3) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE);
+    this.terminal.setCursorBlink(true);
+  } else if (arg == 4) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE);
+    this.terminal.setCursorBlink(false);
+  } else if (arg == 5) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.BEAM);
+    this.terminal.setCursorBlink(true);
+  } else if (arg == 6) {
+    this.terminal.setCursorShape(hterm.Terminal.cursorShape.BEAM);
+    this.terminal.setCursorBlink(false);
+  } else {
+    console.warn('Unknown cursor style: ' + arg);
+  }
+};
+
+/**
+ * Select character protection attribute (DECSCA).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['"q'] = hterm.VT.ignore;
+
+/**
+ * Set Scrolling Region (DECSTBM).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState
+ */
+hterm.VT.CSI['r'] = function(parseState) {
+  var args = parseState.args;
+  var scrollTop = args[0] ? parseInt(args[0], 10) -1 : null;
+  var scrollBottom = args[1] ? parseInt(args[1], 10) - 1 : null;
+  this.terminal.setVTScrollRegion(scrollTop, scrollBottom);
+  this.terminal.setCursorPosition(0, 0);
+};
+
+/**
+ * Restore DEC Private Mode Values.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['?r'] = hterm.VT.ignore;
+
+/**
+ * Change Attributes in Rectangular Area (DECCARA)
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$r'] = hterm.VT.ignore;
+
+/**
+ * Save cursor (ANSI.SYS)
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.CSI['s'] = function() {
+  this.terminal.saveCursorAndState();
+};
+
+/**
+ * Save DEC Private Mode Values.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['?s'] = hterm.VT.ignore;
+
+/**
+ * Window manipulation (from dtterm, as well as extensions).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['t'] = hterm.VT.ignore;
+
+/**
+ * Reverse Attributes in Rectangular Area (DECRARA).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$t'] = hterm.VT.ignore;
+
+/**
+ * Set one or more features of the title modes.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['>t'] = hterm.VT.ignore;
+
+/**
+ * Set warning-bell volume (DECSWBV, VT520).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI[' t'] = hterm.VT.ignore;
+
+/**
+ * Restore cursor (ANSI.SYS).
+ *
+ * @this {!hterm.VT}
+ */
+hterm.VT.CSI['u'] = function() {
+  this.terminal.restoreCursorAndState();
+};
+
+/**
+ * Set margin-bell volume (DECSMBV, VT520).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI[' u'] = hterm.VT.ignore;
+
+/**
+ * Copy Rectangular Area (DECCRA, VT400 and up).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$v'] = hterm.VT.ignore;
+
+/**
+ * Enable Filter Rectangle (DECEFR).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['\'w'] = hterm.VT.ignore;
+
+/**
+ * Request Terminal Parameters (DECREQTPARM).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['x'] = hterm.VT.ignore;
+
+/**
+ * Select Attribute Change Extent (DECSACE).
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['*x'] = hterm.VT.ignore;
+
+/**
+ * Fill Rectangular Area (DECFRA), VT420 and up.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$x'] = hterm.VT.ignore;
+
+/**
+ * vt_tiledata (as used by NAOhack and UnNetHack)
+ * (see https://nethackwiki.com/wiki/Vt_tiledata for more info)
+ *
+ * Implemented as far as we care (start a glyph and end a glyph).
+ *
+ * @this {!hterm.VT}
+ * @param {!hterm.VT.ParseState} parseState
+ */
+hterm.VT.CSI['z'] = function(parseState) {
+  if (parseState.args.length < 1)
+    return;
+  var arg = parseState.args[0];
+  if (arg == 0) {
+    // Start a glyph (one parameter, the glyph number).
+    if (parseState.args.length < 2)
+      return;
+    this.terminal.getTextAttributes().tileData = parseState.args[1];
+  } else if (arg == 1) {
+    // End a glyph.
+    this.terminal.getTextAttributes().tileData = null;
+  }
+};
+
+/**
+ * Enable Locator Reporting (DECELR).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['\'z'] = hterm.VT.ignore;
+
+/**
+ * Erase Rectangular Area (DECERA), VT400 and up.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['$z'] = hterm.VT.ignore;
+
+/**
+ * Select Locator Events (DECSLE).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['\'{'] = hterm.VT.ignore;
+
+/**
+ * Request Locator Position (DECRQLP).
+ *
+ * Not currently implemented.
+ */
+hterm.VT.CSI['\'|'] = hterm.VT.ignore;
+
+/**
+ * Insert Columns (DECIC), VT420 and up.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['\'}'] = hterm.VT.ignore;
+
+/**
+ * Delete P s Columns (DECDC), VT420 and up.
+ *
+ * Will not implement.
+ */
+hterm.VT.CSI['\'~'] = hterm.VT.ignore;
+// SOURCE FILE: hterm/js/hterm_vt_character_map.js
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Character map object.
+ *
+ * Mapping from received to display character, used depending on the active
+ * VT character set.
+ *
+ * GR maps are not currently supported.
+ *
+ * @param {string} description A human readable description of this map.
+ * @param {?Object} glmap The GL mapping from input to output characters.
+ * @constructor
+ */
+hterm.VT.CharacterMap = function(description, glmap) {
+  /**
+   * Short description for this character set, useful for debugging.
+   */
+  this.description = description;
+
+  /**
+   * The function to call to when this map is installed in GL.
+   */
+  this.GL = null;
+
+  // Always keep an unmodified reference to the map.
+  // This allows us to sanely reset back to the original state.
+  this.glmapBase_ = glmap;
+
+  // Now sync the internal state as needed.
+  this.sync_();
+};
+
+/**
+ * Internal helper for resyncing internal state.
+ *
+ * Used when the mappings change.
+ *
+ * @param {!Object=} opt_glmap Additional mappings to overlay on top of the
+ *     base mapping.
+ */
+hterm.VT.CharacterMap.prototype.sync_ = function(opt_glmap) {
+  // If there are no maps, then reset the state back.
+  if (!this.glmapBase_ && !opt_glmap) {
+    this.GL = null;
+    delete this.glmap_;
+    delete this.glre_;
+    return;
+  }
+
+  // Set the the GL mapping.  If we're given a custom mapping, then create a
+  // new object to hold the merged map.  This way we can cleanly reset back.
+  if (opt_glmap)
+    this.glmap_ = Object.assign({}, this.glmapBase_, opt_glmap);
+  else
+    this.glmap_ = this.glmapBase_;
+
+  var glchars = Object.keys(lib.notNull(this.glmap_)).map((key) =>
+      '\\x' + lib.f.zpad(key.charCodeAt(0).toString(16), 2));
+  this.glre_ = new RegExp('[' + glchars.join('') + ']', 'g');
+
+  this.GL = (str) => str.replace(this.glre_, (ch) => this.glmap_[ch]);
+};
+
+/**
+ * Reset map back to original mappings (discarding runtime updates).
+ *
+ * Specifically, any calls to setOverrides will be discarded.
+ */
+hterm.VT.CharacterMap.prototype.reset = function() {
+  // If we haven't been given a custom mapping, then there's nothing to reset.
+  if (this.glmap_ !== this.glmapBase_)
+    this.sync_();
+};
+
+/**
+ * Merge custom changes to this map.
+ *
+ * The input map need not duplicate the existing mappings as it is merged with
+ * the existing base map (what was created with).  Subsequent calls to this
+ * will throw away previous override settings.
+ *
+ * @param {!Object} glmap The custom map to override existing mappings.
+ */
+hterm.VT.CharacterMap.prototype.setOverrides = function(glmap) {
+  this.sync_(glmap);
+};
+
+/**
+ * Return a copy of this mapping.
+ *
+ * @return {!hterm.VT.CharacterMap} A new hterm.VT.CharacterMap instance.
+ */
+hterm.VT.CharacterMap.prototype.clone = function() {
+  var map = new hterm.VT.CharacterMap(this.description, this.glmapBase_);
+  if (this.glmap_ !== this.glmapBase_)
+    map.setOverrides(this.glmap_);
+  return map;
+};
+
+/**
+ * Table of character maps.
+ *
+ * @constructor
+ */
+hterm.VT.CharacterMaps = function() {
+  this.maps_ = hterm.VT.CharacterMaps.DefaultMaps;
+
+  // Always keep an unmodified reference to the map.
+  // This allows us to sanely reset back to the original state.
+  this.mapsBase_ = this.maps_;
+};
+
+/**
+ * Look up a previously registered map.
+ *
+ * @param {string} name The name of the map to lookup.
+ * @return {!hterm.VT.CharacterMap|undefined} The map, if it's been registered
+ *     or undefined.
+ */
+hterm.VT.CharacterMaps.prototype.getMap = function(name) {
+  if (this.maps_.hasOwnProperty(name))
+    return this.maps_[name];
+  else
+    return undefined;
+};
+
+/**
+ * Register a new map.
+ *
+ * Any previously registered maps by this name will be discarded.
+ *
+ * @param {string} name The name of the map.
+ * @param {!hterm.VT.CharacterMap} map The map to register.
+ */
+hterm.VT.CharacterMaps.prototype.addMap = function(name, map) {
+  if (this.maps_ === this.mapsBase_)
+    this.maps_ = Object.assign({}, this.mapsBase_);
+  this.maps_[name] = map;
+};
+
+/**
+ * Reset the table and all its maps back to original state.
+ */
+hterm.VT.CharacterMaps.prototype.reset = function() {
+  if (this.maps_ !== hterm.VT.CharacterMaps.DefaultMaps)
+    this.maps_ = hterm.VT.CharacterMaps.DefaultMaps;
+};
+
+/**
+ * Merge custom changes to this table.
+ *
+ * @param {!Object} maps A set of hterm.VT.CharacterMap objects.
+ */
+hterm.VT.CharacterMaps.prototype.setOverrides = function(maps) {
+  if (this.maps_ === this.mapsBase_)
+    this.maps_ = Object.assign({}, this.mapsBase_);
+
+  for (var name in maps) {
+    var map = this.getMap(name);
+    if (map !== undefined) {
+      this.maps_[name] = map.clone();
+      this.maps_[name].setOverrides(maps[name]);
+    } else
+      this.addMap(name, new hterm.VT.CharacterMap('user ' + name, maps[name]));
+  }
+};
+
+/**
+ * The default set of supported character maps.
+ */
+hterm.VT.CharacterMaps.DefaultMaps = {};
+
+/**
+ * VT100 Graphic character map.
+ * http://vt100.net/docs/vt220-rm/table2-4.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['0'] = new hterm.VT.CharacterMap(
+    'graphic', {
+      '\x60':'\u25c6',  // ` -> diamond
+      '\x61':'\u2592',  // a -> grey-box
+      '\x62':'\u2409',  // b -> h/t
+      '\x63':'\u240c',  // c -> f/f
+      '\x64':'\u240d',  // d -> c/r
+      '\x65':'\u240a',  // e -> l/f
+      '\x66':'\u00b0',  // f -> degree
+      '\x67':'\u00b1',  // g -> +/-
+      '\x68':'\u2424',  // h -> n/l
+      '\x69':'\u240b',  // i -> v/t
+      '\x6a':'\u2518',  // j -> bottom-right
+      '\x6b':'\u2510',  // k -> top-right
+      '\x6c':'\u250c',  // l -> top-left
+      '\x6d':'\u2514',  // m -> bottom-left
+      '\x6e':'\u253c',  // n -> line-cross
+      '\x6f':'\u23ba',  // o -> scan1
+      '\x70':'\u23bb',  // p -> scan3
+      '\x71':'\u2500',  // q -> scan5
+      '\x72':'\u23bc',  // r -> scan7
+      '\x73':'\u23bd',  // s -> scan9
+      '\x74':'\u251c',  // t -> left-tee
+      '\x75':'\u2524',  // u -> right-tee
+      '\x76':'\u2534',  // v -> bottom-tee
+      '\x77':'\u252c',  // w -> top-tee
+      '\x78':'\u2502',  // x -> vertical-line
+      '\x79':'\u2264',  // y -> less-equal
+      '\x7a':'\u2265',  // z -> greater-equal
+      '\x7b':'\u03c0',  // { -> pi
+      '\x7c':'\u2260',  // | -> not-equal
+      '\x7d':'\u00a3',  // } -> british-pound
+      '\x7e':'\u00b7',  // ~ -> dot
+    });
+
+/**
+ * British character map.
+ * http://vt100.net/docs/vt220-rm/table2-5.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['A'] = new hterm.VT.CharacterMap(
+    'british', {
+      '\x23': '\u00a3',  // # -> british-pound
+    });
+
+/**
+ * US ASCII map, no changes.
+ */
+hterm.VT.CharacterMaps.DefaultMaps['B'] = new hterm.VT.CharacterMap(
+    'us', null);
+
+/**
+ * Dutch character map.
+ * http://vt100.net/docs/vt220-rm/table2-6.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['4'] = new hterm.VT.CharacterMap(
+    'dutch', {
+      '\x23': '\u00a3',  // # -> british-pound
+
+      '\x40': '\u00be',  // @ -> 3/4
+
+      '\x5b': '\u0132',  // [ -> 'ij' ligature (xterm goes with \u00ff?)
+      '\x5c': '\u00bd',  // \ -> 1/2
+      '\x5d': '\u007c',  // ] -> vertical bar
+
+      '\x7b': '\u00a8',  // { -> two dots
+      '\x7c': '\u0066',  // | -> f
+      '\x7d': '\u00bc',  // } -> 1/4
+      '\x7e': '\u00b4',  // ~ -> acute
+    });
+
+/**
+ * Finnish character map.
+ * http://vt100.net/docs/vt220-rm/table2-7.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['C'] =
+hterm.VT.CharacterMaps.DefaultMaps['5'] = new hterm.VT.CharacterMap(
+    'finnish', {
+      '\x5b': '\u00c4',  // [ -> 'A' umlaut
+      '\x5c': '\u00d6',  // \ -> 'O' umlaut
+      '\x5d': '\u00c5',  // ] -> 'A' ring
+      '\x5e': '\u00dc',  // ~ -> 'u' umlaut
+
+      '\x60': '\u00e9',  // ` -> 'e' acute
+
+      '\x7b': '\u00e4',  // { -> 'a' umlaut
+      '\x7c': '\u00f6',  // | -> 'o' umlaut
+      '\x7d': '\u00e5',  // } -> 'a' ring
+      '\x7e': '\u00fc',  // ~ -> 'u' umlaut
+    });
+
+/**
+ * French character map.
+ * http://vt100.net/docs/vt220-rm/table2-8.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['R'] = new hterm.VT.CharacterMap(
+    'french', {
+      '\x23': '\u00a3',  // # -> british-pound
+
+      '\x40': '\u00e0',  // @ -> 'a' grave
+
+      '\x5b': '\u00b0',  // [ -> ring
+      '\x5c': '\u00e7',  // \ -> 'c' cedilla
+      '\x5d': '\u00a7',  // ] -> section symbol (double s)
+
+      '\x7b': '\u00e9',  // { -> 'e' acute
+      '\x7c': '\u00f9',  // | -> 'u' grave
+      '\x7d': '\u00e8',  // } -> 'e' grave
+      '\x7e': '\u00a8',  // ~ -> umlaut
+    });
+
+/**
+ * French Canadian character map.
+ * http://vt100.net/docs/vt220-rm/table2-9.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['Q'] = new hterm.VT.CharacterMap(
+    'french canadian', {
+      '\x40': '\u00e0',  // @ -> 'a' grave
+
+      '\x5b': '\u00e2',  // [ -> 'a' circumflex
+      '\x5c': '\u00e7',  // \ -> 'c' cedilla
+      '\x5d': '\u00ea',  // ] -> 'e' circumflex
+      '\x5e': '\u00ee',  // ^ -> 'i' circumflex
+
+      '\x60': '\u00f4',  // ` -> 'o' circumflex
+
+      '\x7b': '\u00e9',  // { -> 'e' acute
+      '\x7c': '\u00f9',  // | -> 'u' grave
+      '\x7d': '\u00e8',  // } -> 'e' grave
+      '\x7e': '\u00fb',  // ~ -> 'u' circumflex
+    });
+
+/**
+ * German character map.
+ * http://vt100.net/docs/vt220-rm/table2-10.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['K'] = new hterm.VT.CharacterMap(
+    'german', {
+      '\x40': '\u00a7',  // @ -> section symbol (double s)
+
+      '\x5b': '\u00c4',  // [ -> 'A' umlaut
+      '\x5c': '\u00d6',  // \ -> 'O' umlaut
+      '\x5d': '\u00dc',  // ] -> 'U' umlaut
+
+      '\x7b': '\u00e4',  // { -> 'a' umlaut
+      '\x7c': '\u00f6',  // | -> 'o' umlaut
+      '\x7d': '\u00fc',  // } -> 'u' umlaut
+      '\x7e': '\u00df',  // ~ -> eszett
+    });
+
+/**
+ * Italian character map.
+ * http://vt100.net/docs/vt220-rm/table2-11.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['Y'] = new hterm.VT.CharacterMap(
+    'italian', {
+      '\x23': '\u00a3',  // # -> british-pound
+
+      '\x40': '\u00a7',  // @ -> section symbol (double s)
+
+      '\x5b': '\u00b0',  // [ -> ring
+      '\x5c': '\u00e7',  // \ -> 'c' cedilla
+      '\x5d': '\u00e9',  // ] -> 'e' acute
+
+      '\x60': '\u00f9',  // ` -> 'u' grave
+
+      '\x7b': '\u00e0',  // { -> 'a' grave
+      '\x7c': '\u00f2',  // | -> 'o' grave
+      '\x7d': '\u00e8',  // } -> 'e' grave
+      '\x7e': '\u00ec',  // ~ -> 'i' grave
+    });
+
+/**
+ * Norwegian/Danish character map.
+ * http://vt100.net/docs/vt220-rm/table2-12.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['E'] =
+hterm.VT.CharacterMaps.DefaultMaps['6'] = new hterm.VT.CharacterMap(
+    'norwegian/danish', {
+      '\x40': '\u00c4',  // @ -> 'A' umlaut
+
+      '\x5b': '\u00c6',  // [ -> 'AE' ligature
+      '\x5c': '\u00d8',  // \ -> 'O' stroke
+      '\x5d': '\u00c5',  // ] -> 'A' ring
+      '\x5e': '\u00dc',  // ^ -> 'U' umlaut
+
+      '\x60': '\u00e4',  // ` -> 'a' umlaut
+
+      '\x7b': '\u00e6',  // { -> 'ae' ligature
+      '\x7c': '\u00f8',  // | -> 'o' stroke
+      '\x7d': '\u00e5',  // } -> 'a' ring
+      '\x7e': '\u00fc',  // ~ -> 'u' umlaut
+    });
+
+/**
+ * Spanish character map.
+ * http://vt100.net/docs/vt220-rm/table2-13.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['Z'] = new hterm.VT.CharacterMap(
+    'spanish', {
+      '\x23': '\u00a3',  // # -> british-pound
+
+      '\x40': '\u00a7',  // @ -> section symbol (double s)
+
+      '\x5b': '\u00a1',  // [ -> '!' inverted
+      '\x5c': '\u00d1',  // \ -> 'N' tilde
+      '\x5d': '\u00bf',  // ] -> '?' inverted
+
+      '\x7b': '\u00b0',  // { -> ring
+      '\x7c': '\u00f1',  // | -> 'n' tilde
+      '\x7d': '\u00e7',  // } -> 'c' cedilla
+    });
+
+/**
+ * Swedish character map.
+ * http://vt100.net/docs/vt220-rm/table2-14.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['7'] =
+hterm.VT.CharacterMaps.DefaultMaps['H'] = new hterm.VT.CharacterMap(
+    'swedish', {
+      '\x40': '\u00c9',  // @ -> 'E' acute
+
+      '\x5b': '\u00c4',  // [ -> 'A' umlaut
+      '\x5c': '\u00d6',  // \ -> 'O' umlaut
+      '\x5d': '\u00c5',  // ] -> 'A' ring
+      '\x5e': '\u00dc',  // ^ -> 'U' umlaut
+
+      '\x60': '\u00e9',  // ` -> 'e' acute
+
+      '\x7b': '\u00e4',  // { -> 'a' umlaut
+      '\x7c': '\u00f6',  // | -> 'o' umlaut
+      '\x7d': '\u00e5',  // } -> 'a' ring
+      '\x7e': '\u00fc',  // ~ -> 'u' umlaut
+    });
+
+/**
+ * Swiss character map.
+ * http://vt100.net/docs/vt220-rm/table2-15.html
+ */
+hterm.VT.CharacterMaps.DefaultMaps['='] = new hterm.VT.CharacterMap(
+    'swiss', {
+      '\x23': '\u00f9',  // # -> 'u' grave
+
+      '\x40': '\u00e0',  // @ -> 'a' grave
+
+      '\x5b': '\u00e9',  // [ -> 'e' acute
+      '\x5c': '\u00e7',  // \ -> 'c' cedilla
+      '\x5d': '\u00ea',  // ] -> 'e' circumflex
+      '\x5e': '\u00ee',  // ^ -> 'i' circumflex
+      '\x5f': '\u00e8',  // _ -> 'e' grave
+
+      '\x60': '\u00f4',  // ` -> 'o' circumflex
+
+      '\x7b': '\u00e4',  // { -> 'a' umlaut
+      '\x7c': '\u00f6',  // | -> 'o' umlaut
+      '\x7d': '\u00fc',  // } -> 'u' umlaut
+      '\x7e': '\u00fb',  // ~ -> 'u' circumflex
+    });
+lib.resource.add('hterm/audio/bell', 'audio/ogg;base64',
+'T2dnUwACAAAAAAAAAADhqW5KAAAAAMFvEjYBHgF2b3JiaXMAAAAAAYC7AAAAAAAAAHcBAAAAAAC4' +
+'AU9nZ1MAAAAAAAAAAAAA4aluSgEAAAAAesI3EC3//////////////////8kDdm9yYmlzHQAAAFhp' +
+'cGguT3JnIGxpYlZvcmJpcyBJIDIwMDkwNzA5AAAAAAEFdm9yYmlzKUJDVgEACAAAADFMIMWA0JBV' +
+'AAAQAABgJCkOk2ZJKaWUoSh5mJRISSmllMUwiZiUicUYY4wxxhhjjDHGGGOMIDRkFQAABACAKAmO' +
+'o+ZJas45ZxgnjnKgOWlOOKcgB4pR4DkJwvUmY26mtKZrbs4pJQgNWQUAAAIAQEghhRRSSCGFFGKI' +
+'IYYYYoghhxxyyCGnnHIKKqigggoyyCCDTDLppJNOOumoo4466ii00EILLbTSSkwx1VZjrr0GXXxz' +
+'zjnnnHPOOeecc84JQkNWAQAgAAAEQgYZZBBCCCGFFFKIKaaYcgoyyIDQkFUAACAAgAAAAABHkRRJ' +
+'sRTLsRzN0SRP8ixREzXRM0VTVE1VVVVVdV1XdmXXdnXXdn1ZmIVbuH1ZuIVb2IVd94VhGIZhGIZh' +
+'GIZh+H3f933f930gNGQVACABAKAjOZbjKaIiGqLiOaIDhIasAgBkAAAEACAJkiIpkqNJpmZqrmmb' +
+'tmirtm3LsizLsgyEhqwCAAABAAQAAAAAAKBpmqZpmqZpmqZpmqZpmqZpmqZpmmZZlmVZlmVZlmVZ' +
+'lmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZQGjIKgBAAgBAx3Ecx3EkRVIkx3IsBwgNWQUAyAAA' +
+'CABAUizFcjRHczTHczzHczxHdETJlEzN9EwPCA1ZBQAAAgAIAAAAAABAMRzFcRzJ0SRPUi3TcjVX' +
+'cz3Xc03XdV1XVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVYHQkFUAAAQAACGdZpZq' +
+'gAgzkGEgNGQVAIAAAAAYoQhDDAgNWQUAAAQAAIih5CCa0JrzzTkOmuWgqRSb08GJVJsnuamYm3PO' +
+'OeecbM4Z45xzzinKmcWgmdCac85JDJqloJnQmnPOeRKbB62p0ppzzhnnnA7GGWGcc85p0poHqdlY' +
+'m3POWdCa5qi5FJtzzomUmye1uVSbc84555xzzjnnnHPOqV6czsE54Zxzzonam2u5CV2cc875ZJzu' +
+'zQnhnHPOOeecc84555xzzglCQ1YBAEAAAARh2BjGnYIgfY4GYhQhpiGTHnSPDpOgMcgppB6NjkZK' +
+'qYNQUhknpXSC0JBVAAAgAACEEFJIIYUUUkghhRRSSCGGGGKIIaeccgoqqKSSiirKKLPMMssss8wy' +
+'y6zDzjrrsMMQQwwxtNJKLDXVVmONteaec645SGultdZaK6WUUkoppSA0ZBUAAAIAQCBkkEEGGYUU' +
+'UkghhphyyimnoIIKCA1ZBQAAAgAIAAAA8CTPER3RER3RER3RER3RER3P8RxREiVREiXRMi1TMz1V' +
+'VFVXdm1Zl3Xbt4Vd2HXf133f141fF4ZlWZZlWZZlWZZlWZZlWZZlCUJDVgEAIAAAAEIIIYQUUkgh' +
+'hZRijDHHnINOQgmB0JBVAAAgAIAAAAAAR3EUx5EcyZEkS7IkTdIszfI0T/M00RNFUTRNUxVd0RV1' +
+'0xZlUzZd0zVl01Vl1XZl2bZlW7d9WbZ93/d93/d93/d93/d939d1IDRkFQAgAQCgIzmSIimSIjmO' +
+'40iSBISGrAIAZAAABACgKI7iOI4jSZIkWZImeZZniZqpmZ7pqaIKhIasAgAAAQAEAAAAAACgaIqn' +
+'mIqniIrniI4oiZZpiZqquaJsyq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7rukBo' +
+'yCoAQAIAQEdyJEdyJEVSJEVyJAcIDVkFAMgAAAgAwDEcQ1Ikx7IsTfM0T/M00RM90TM9VXRFFwgN' +
+'WQUAAAIACAAAAAAAwJAMS7EczdEkUVIt1VI11VItVVQ9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV' +
+'VVVVVVVVVVVV1TRN0zSB0JCVAAAZAAAjQQYZhBCKcpBCbj1YCDHmJAWhOQahxBiEpxAzDDkNInSQ' +
+'QSc9uJI5wwzz4FIoFURMg40lN44gDcKmXEnlOAhCQ1YEAFEAAIAxyDHEGHLOScmgRM4xCZ2UyDkn' +
+'pZPSSSktlhgzKSWmEmPjnKPSScmklBhLip2kEmOJrQAAgAAHAIAAC6HQkBUBQBQAAGIMUgophZRS' +
+'zinmkFLKMeUcUko5p5xTzjkIHYTKMQadgxAppRxTzinHHITMQeWcg9BBKAAAIMABACDAQig0ZEUA' +
+'ECcA4HAkz5M0SxQlSxNFzxRl1xNN15U0zTQ1UVRVyxNV1VRV2xZNVbYlTRNNTfRUVRNFVRVV05ZN' +
+'VbVtzzRl2VRV3RZV1bZl2xZ+V5Z13zNNWRZV1dZNVbV115Z9X9ZtXZg0zTQ1UVRVTRRV1VRV2zZV' +
+'17Y1UXRVUVVlWVRVWXZlWfdVV9Z9SxRV1VNN2RVVVbZV2fVtVZZ94XRVXVdl2fdVWRZ+W9eF4fZ9' +
+'4RhV1dZN19V1VZZ9YdZlYbd13yhpmmlqoqiqmiiqqqmqtm2qrq1bouiqoqrKsmeqrqzKsq+rrmzr' +
+'miiqrqiqsiyqqiyrsqz7qizrtqiquq3KsrCbrqvrtu8LwyzrunCqrq6rsuz7qizruq3rxnHrujB8' +
+'pinLpqvquqm6um7runHMtm0co6rqvirLwrDKsu/rui+0dSFRVXXdlF3jV2VZ921fd55b94WybTu/' +
+'rfvKceu60vg5z28cubZtHLNuG7+t+8bzKz9hOI6lZ5q2baqqrZuqq+uybivDrOtCUVV9XZVl3zdd' +
+'WRdu3zeOW9eNoqrquirLvrDKsjHcxm8cuzAcXds2jlvXnbKtC31jyPcJz2vbxnH7OuP2daOvDAnH' +
+'jwAAgAEHAIAAE8pAoSErAoA4AQAGIecUUxAqxSB0EFLqIKRUMQYhc05KxRyUUEpqIZTUKsYgVI5J' +
+'yJyTEkpoKZTSUgehpVBKa6GU1lJrsabUYu0gpBZKaS2U0lpqqcbUWowRYxAy56RkzkkJpbQWSmkt' +
+'c05K56CkDkJKpaQUS0otVsxJyaCj0kFIqaQSU0mptVBKa6WkFktKMbYUW24x1hxKaS2kEltJKcYU' +
+'U20txpojxiBkzknJnJMSSmktlNJa5ZiUDkJKmYOSSkqtlZJSzJyT0kFIqYOOSkkptpJKTKGU1kpK' +
+'sYVSWmwx1pxSbDWU0lpJKcaSSmwtxlpbTLV1EFoLpbQWSmmttVZraq3GUEprJaUYS0qxtRZrbjHm' +
+'GkppraQSW0mpxRZbji3GmlNrNabWam4x5hpbbT3WmnNKrdbUUo0txppjbb3VmnvvIKQWSmktlNJi' +
+'ai3G1mKtoZTWSiqxlZJabDHm2lqMOZTSYkmpxZJSjC3GmltsuaaWamwx5ppSi7Xm2nNsNfbUWqwt' +
+'xppTS7XWWnOPufVWAADAgAMAQIAJZaDQkJUAQBQAAEGIUs5JaRByzDkqCULMOSepckxCKSlVzEEI' +
+'JbXOOSkpxdY5CCWlFksqLcVWaykptRZrLQAAoMABACDABk2JxQEKDVkJAEQBACDGIMQYhAYZpRiD' +
+'0BikFGMQIqUYc05KpRRjzknJGHMOQioZY85BKCmEUEoqKYUQSkklpQIAAAocAAACbNCUWByg0JAV' +
+'AUAUAABgDGIMMYYgdFQyKhGETEonqYEQWgutddZSa6XFzFpqrbTYQAithdYySyXG1FpmrcSYWisA' +
+'AOzAAQDswEIoNGQlAJAHAEAYoxRjzjlnEGLMOegcNAgx5hyEDirGnIMOQggVY85BCCGEzDkIIYQQ' +
+'QuYchBBCCKGDEEIIpZTSQQghhFJK6SCEEEIppXQQQgihlFIKAAAqcAAACLBRZHOCkaBCQ1YCAHkA' +
+'AIAxSjkHoZRGKcYglJJSoxRjEEpJqXIMQikpxVY5B6GUlFrsIJTSWmw1dhBKaS3GWkNKrcVYa64h' +
+'pdZirDXX1FqMteaaa0otxlprzbkAANwFBwCwAxtFNicYCSo0ZCUAkAcAgCCkFGOMMYYUYoox55xD' +
+'CCnFmHPOKaYYc84555RijDnnnHOMMeecc845xphzzjnnHHPOOeecc44555xzzjnnnHPOOeecc845' +
+'55xzzgkAACpwAAAIsFFkc4KRoEJDVgIAqQAAABFWYowxxhgbCDHGGGOMMUYSYowxxhhjbDHGGGOM' +
+'McaYYowxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHG' +
+'GFtrrbXWWmuttdZaa6211lprrQBAvwoHAP8HG1ZHOCkaCyw0ZCUAEA4AABjDmHOOOQYdhIYp6KSE' +
+'DkIIoUNKOSglhFBKKSlzTkpKpaSUWkqZc1JSKiWlllLqIKTUWkottdZaByWl1lJqrbXWOgiltNRa' +
+'a6212EFIKaXWWostxlBKSq212GKMNYZSUmqtxdhirDGk0lJsLcYYY6yhlNZaazHGGGstKbXWYoy1' +
+'xlprSam11mKLNdZaCwDgbnAAgEiwcYaVpLPC0eBCQ1YCACEBAARCjDnnnHMQQgghUoox56CDEEII' +
+'IURKMeYcdBBCCCGEjDHnoIMQQgghhJAx5hx0EEIIIYQQOucchBBCCKGEUkrnHHQQQgghlFBC6SCE' +
+'EEIIoYRSSikdhBBCKKGEUkopJYQQQgmllFJKKaWEEEIIoYQSSimllBBCCKWUUkoppZQSQgghlFJK' +
+'KaWUUkIIoZRQSimllFJKCCGEUkoppZRSSgkhhFBKKaWUUkopIYQSSimllFJKKaUAAIADBwCAACPo' +
+'JKPKImw04cIDUGjISgCADAAAcdhq6ynWyCDFnISWS4SQchBiLhFSijlHsWVIGcUY1ZQxpRRTUmvo' +
+'nGKMUU+dY0oxw6yUVkookYLScqy1dswBAAAgCAAwECEzgUABFBjIAIADhAQpAKCwwNAxXAQE5BIy' +
+'CgwKx4Rz0mkDABCEyAyRiFgMEhOqgaJiOgBYXGDIB4AMjY20iwvoMsAFXdx1IIQgBCGIxQEUkICD' +
+'E2544g1PuMEJOkWlDgIAAAAA4AAAHgAAkg0gIiKaOY4Ojw+QEJERkhKTE5QAAAAAALABgA8AgCQF' +
+'iIiIZo6jw+MDJERkhKTE5AQlAAAAAAAAAAAACAgIAAAAAAAEAAAACAhPZ2dTAAQYOwAAAAAAAOGp' +
+'bkoCAAAAmc74DRgyNjM69TAzOTk74dnLubewsbagmZiNp4d0KbsExSY/I3XUTwJgkeZdn1HY4zoj' +
+'33/q9DFtv3Ui1/jmx7lCUtPt18/sYf9MkgAsAGRBd3gMGP4sU+qCPYBy9VrA3YqJosW3W2/ef1iO' +
+'/u3cg8ZG/57jU+pPmbGEJUgkfnaI39DbPqxddZphbMRmCc5rKlkUMkyx8iIoug5dJv1OYH9a59c+' +
+'3Gevqc7Z2XFdDjL/qHztRfjWEWxJ/aiGezjohu9HsCZdQBKbiH0VtU/3m85lDG2T/+xkZcYnX+E+' +
+'aqzv/xTgOoTFG+x7SNqQ4N+oAABSxuVXw77Jd5bmmTmuJakX7509HH0kGYKvARPpwfOSAPySPAc2' +
+'EkneDwB2HwAAJlQDYK5586N79GJCjx4+p6aDUd27XSvRyXLJkIC5YZ1jLv5lpOhZTz0s+DmnF1di' +
+'ptrnM6UDgIW11Xh8cHTd0/SmbgOAdxcyWwMAAGIrZ3fNSfZbzKiYrK4+tPqtnMVLOeWOG2kVvUY+' +
+'p2PJ/hkCl5aFRO4TLGYPZcIU3vYM1hohS4jHFlnyW/2T5J7kGsShXWT8N05V+3C/GPqJ1QdWisGP' +
+'xEzHqXISBPIinWDUt7IeJv/f5OtzBxpTzZZQ+CYEhHXfqG4aABQli72GJhN4oJv+hXcApAJSErAW' +
+'8G2raAX4NUcABnVt77CzZAB+LsHcVe+Q4h+QB1wh/ZrJTPxSBdI8mgTeAdTsQOoFUEng9BHcVPhx' +
+'SRRYkKWZJXOFYP6V4AEripJoEjXgA2wJRZHSExmJDm8F0A6gEXsg5a4ZsALItrMB7+fh7UKLvYWS' +
+'dtsDwFf1mzYzS1F82N1h2Oyt2e76B1QdS0SAsQigLPMOgJS9JRC7hFXA6kUsLFNKD5cA5cTRvgSq' +
+'Pc3Fl99xW3QTi/MHR8DEm6WnvaVQATwRqRKjywQ9BrrhugR2AKTsPQeQckrAOgDOhbTESyrXQ50C' +
+'kNpXdtWjW7W2/3UjeX3U95gIdalfRAoAmqUEiwp53hCdcCwlg47fcbfzlmQMAgaBkh7c+fcDgF+i' +
+'fwDXfzegLPcLYJsAAJQArTXjnh/uXGy3v1Hk3pV6/3t5ruW81f6prfbM2Q3WNVy98BwUtbCwhFhA' +
+'WuPev6Oe/4ZaFQUcgKrVs4defzh1TADA1DEh5b3VlDaECw5b+bPfkKos3tIAue3vJZOih3ga3l6O' +
+'3PSfIkrLv0PAS86PPdL7g8oc2KteNFKKzKRehOv2gJoFLBPXmaXvPBQILgJon0bbWBszrYZYYwE7' +
+'jl2j+vTdU7Vpk21LiU0QajPkywAAHqbUC0/YsYOdb4e6BOp7E0cCi04Ao/TgD8ZVAMid6h/A8IeB' +
+'Nkp6/xsAACZELEYIk+yvI6Qz1NN6lIftB/6IMWjWJNOqPTMedAmyaj6Es0QBklJpiSWWHnQ2CoYb' +
+'GWAmt+0gLQBFKCBnp2QUUQZ/1thtZDBJUpFWY82z34ocorB62oX7qB5y0oPAv/foxH25wVmgIHf2' +
+'xFOr8leZcBq1Kx3ZvCq9Bga639AxuHuPNL/71YCF4EywJpqHFAX6XF0sjVbuANnvvdLcrufYwOM/' +
+'iDa6iA468AYAAB6mNBMXcgTD8HSRqJ4vw8CjAlCEPACASlX/APwPOJKl9xQAAAPmnev2eWp33Xgy' +
+'w3Dvfz6myGk3oyP8YTKsCOvzAgALQi0o1c6Nzs2O2Pg2h4ACIJAgAGP0aNn5x0BDgVfH7u2TtyfD' +
+'cRIuYAyQhBF/lvSRAttgA6TPbWZA9gaUrZWAUEAA+Dx47Q3/r87HxUUqZmB0BmUuMlojFjHt1gDu' +
+'nnvuX8MImsjSq5WkzSzGS62OEIlOufWWezxWpv6FBgDgJVltfXFYtNAAnqU0xQoD0YLiXo5cF5QV' +
+'4CnY1tBLAkZCOABAhbk/AM+/AwSCCdlWAAAMcFjS7owb8GVDzveDiZvznbt2tF4bL5odN1YKl88T' +
+'AEABCZvufq9YCTBtMwVAQUEAwGtNltzSaHvADYC3TxLVjqiRA+OZAMhzcqEgRcAOwoCgvdTxsTHL' +
+'QEF6+oOb2+PAI8ciPQcXg7pOY+LjxQSv2fjmFuj34gGwz310/bGK6z3xgT887eomWULEaDd04wHe' +
+'tYxdjcgV2SxvSwn0VoZXJRqkRC5ASQ/muVoAUsX7AgAQMBNaVwAAlABRxT/1PmfqLqSRNDbhXb07' +
+'berpB3b94jpuWEZjBCD2OcdXFpCKEgCDfcFPMw8AAADUwT4lnUm50lmwrpMMhPQIKj6u0E8fr2vG' +
+'BngMNdIlrZsigjahljud6AFVg+tzXwUnXL3TJLpajaWKA4VAAAAMiFfqJgKAZ08XrtS3dxtQNYcp' +
+'PvYEG8ClvrQRJgBephwnNWJjtGqmp6VEPSvBe7EBiU3qgJbQAwD4Le8LAMDMhHbNAAAlgK+tFs5O' +
+'+YyJc9yCnJa3rxLPulGnxwsXV9Fsk2k4PisCAHC8FkwbGE9gJQAAoMnyksj0CdFMZLLgoz8M+Fxz' +
+'iwYBgIx+zHiCBAKAlBKNpF1sO9JpVcyEi9ar15YlHgrut5fPJnkdJ6vEwZPyAHQBIEDUrlMcBAAd' +
+'2KAS0Qq+JwRsE4AJZtMnAD6GnOYwYlOIZvtzUNdjreB7fiMkWI0CmBB6AIAKc38A9osEFlTSGECB' +
+'+cbeRDC0aRpLHqNPplcK/76Lxn2rpmqyXsYJWRi/FQAAAKBQk9MCAOibrQBQADCDsqpooPutd+05' +
+'Ce9g6iEdiYXgVmQAI4+4wskEBEiBloNQ6Ki0/KTQ0QjWfjxzi+AeuXKoMjEVfQOZzr0y941qLgM2' +
+'AExvbZOqcxZ6J6krlrj4y2j9AdgKDx6GnJsVLhbc42uq584+ouSdNBpoCiCVHrz+WzUA/DDtD8AT' +
+'gA3h0lMCAAzcFv+S+fSSNkeYWlTpb34mf2RfmqqJeMeklhHAfu7VoAEACgAApKRktL+KkQDWMwYC' +
+'UAAAAHCKsp80xhp91UjqQBw3x45cetqkjQEyu3G9B6N+R650Uq8OVig7wOm6Wun0ea4lKDPoabJs' +
+'6aLqgbhPzpv4KR4iODilw88ZpY7q1IOMcbASAOAVtmcCnobcrkG4KGS7/ZnskVWRNF9J0RUHKOnB' +
+'yy9WA8Dv6L4AAARMCQUA4GritfVM2lcZfH3Q3T/vZ47J2YHhcmBazjfdyuV25gLAzrc0cwAAAAAY' +
+'Ch6PdwAAAGyWjFW4yScjaWa2mGcofHxWxewKALglWBpLUvwwk+UOh5eNGyUOs1/EF+pZr+ud5Ozo' +
+'GwYdAABg2p52LiSgAY/ZVlOmilEgHn6G3OcwYjzI7vOj1t6xsx4S3lBY96EUQBF6AIBAmPYH4PoG' +
+'YCoJAADWe+OZJZi7/x76/yH7Lzf9M5XzRKnFPmveMsilQHwVAAAAAKB3LQD8PCIAAADga0QujBLy' +
+'wzeJ4a6Z/ERVBAUlAEDqvoM7BQBAuAguzFqILtmjH3Kd4wfKobnOhA3z85qWoRPm9hwoOHoDAAlC' +
+'bwDAA56FHAuXflHo3fe2ttG9XUDeA9YmYCBQ0oPr/1QC8IvuCwAAApbUAQCK22MmE3O78VAbHQT9' +
+'PIPNoT9zNc3l2Oe7TAVLANBufT8MAQAAAGzT4PS8AQAAoELGHb2uaCwwEv1EWhFriUkbAaAZ27/f' +
+'VZnTZXbWz3BwWpjUaMZKRj7dZ0J//gUeTdpVEwAAZOFsNxKAjQSgA+ABPoY8Jj5y2wje81jsXc/1' +
+'TOQWTDYZBmAkNDiqVwuA2NJ9AQAAEBKAt9Vrsfs/2N19MO91S9rd8EHTZHnzC5MYmfQEACy/FBcA' +
+'AADA5c4gi4z8RANs/m6FNXVo9DV46JG1BBDukqlw/Va5G7QbuGVSI+2aZaoLXJrdVj2zlC9Z5QEA' +
+'EFz/5QzgVZwAAAAA/oXcxyC6WfTu+09Ve/c766J4VTAGUFmA51+VANKi/QPoPwYgYAkA715OH4S0' +
+'s5KDHvj99MMq8TPFc3roKZnGOoT1bmIhVgc7XAMBAAAAAMAW1VbQw3gapzOpJd+Kd2fc4iSO62fJ' +
+'v9+movui1wUNPAj059N3OVxzk4gV73PmE8FIA2F5mRq37Evc76vLXfF4rD5UJJAw46hW6LZCb5sN' +
+'Ldx+kzMCAAB+hfy95+965ZCLP7B3/VlTHCvDEKtQhTm4KiCgAEAbrfbWTPssAAAAXpee1tVrozYY' +
+'n41wD1aeYtkKfswN5/SXPO0JDnhO/4laUortv/s412fybe/nONdncoCHnBVliu0CQGBWlPY/5Kwo' +
+'m2L/kruPM6Q7oz4tvDQy+bZ3HzOi+gNHA4DZEgA='
+);
+
+lib.resource.add('hterm/images/icon-96', 'image/png;base64',
+'iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAStklEQVR42u1dBXjrupL+RzIGmjIf' +
+'vAcu42NmZub3lpmZmZmZmRkuMzPDYaYyJG0Sa9b2p2z1eQtp7bzefpv/nKnkkSw7Gg1IshNsDtpo' +
+'o4022mijDWp/tlTgzbpJSqYvMoFTC9vjRD5JLb9RYaRkpk22SS28P8pacAaPdZ41KYMCI89YB6wN' +
+'3JzQJM3UIGqurfTlKQTAZtqENid5SlNdU804VmbbWQtA6HMkAAdADsBeAJ7mxwIhIhFSXJ9iRPw4' +
+'JYDEcqmGWEp1HhCI8gAtpXF7scB1ZRH9E3HObANCNy1AoGTegNDnCdE41tfQDH2t+CINQEpJ9Xp9' +
+'7oUDh3+nXK48DYAMIWQmANIkNTn6vP69e3d/zctfeu0nXNexmVn3F0gDAMxMlBoHuht0qnsEEekC' +
+'42SdGHmNxgVjgk4bPN04Yui8bhc534cQBH35RKrPN9sGdLnB1/Wuv+HW4f+6/tZvBHAaAJvmKr0A' +
+'jJGvyQMw8pLrrvqeT378Ax8UwrKeevoFgEhfjcGGO2JO+iuTt1SW5DHzyraDExyTlWwHjCQ/CAJc' +
+'ecU+XHn5xWDmVCGQFAKljsLbx8Ynvv3Bhx7/EQCzurimU04jADLsvK3r73/7W1//g1/6hU++uVqt' +
+'0X/dcBcKxRIsy9Ji34DPow2et6FzgcXFKk6fOY83vu4VEFKkDiYHB3roSz73sc+Oj08eOHzk+B9o' +
+'MyQABGk0gCIyOt9xHPvaD3/wnT/5VV/+meumpmbwD/98A0qdvVEBNhvMDCJaVXtM01GtVlEs+LBt' +
+'C1ngzW98tX/m7Llv/emf+83HarX6vbrfGECQRgBmlLP9Ix961499+zd/5XVj45P407/8FxQ7uiGl' +
+'QK1Ww1ZCvR6gXq3AsgQ8zwYzUkMIgXe+/Q1Dd9x5/6duv/P+R7QjprQaIHQd/8orLvnCJz/2/pfm' +
+'cj7+6rf+DK5XgOu6sT3dQtBawqjW6lhYXIRlSTAjE/T39eLSS/ZeEwqgE8CiYUV4vQIgTULTyFve' +
+'9Or3WJZN/3n9HTh3fgrFjhJmZmawFaGUwkJlEffc9xh83wMYqcFg7Noxinw+l9OBikirAabz7eju' +
+'6sxJKTE7W4bn5+D7PrYmtI/gAFJasCwb4IzaBMHzXE8LgBJC4I1GQRKAa4Xo6upEsZiH53nIRYLe' +
+'olDMCIIq+nq70dFRAGckgFKpAD+UgBaAgfRRkGvbliwUcoh8ABHFYSfWMnBrxOzL12PwKufzSvV5' +
+'5Tpmi5a0IASBQCgWcujs7ABn5AQic+b5rhNlAVAmTliTEwnA990wIxEEdUQYnxjHidMnAUIcBYAB' +
+'RqNDdC7BM8t0VtfTnGRd8FKdRIjJcVlCsAbPPA5UAK4rXLJjP7aNbkO9XoPrOrEQWHEm69Kua0ca' +
+'YEspvCBQ5toSp9EASCkt27ZF1PlCxBOZOPo5feY0Xpg8jHe/7V3YNjhqjDRac3mMVl1Oo40vtREt' +
+'W+2FYwdw/S03YHJ6EkODQ1hcXIQUcaeBlUIWsCwZ+QDLdZxcubKAtBpgNmzZliUa6yLMKiRGoBR2' +
+'79yN6666FlJYABgvRhAIncUSHn/iCdQrAZjjSAiKFQQRVEhZIRJASJEACICmlAKQUtqhBETjw5ij' +
+'uFqr4oWjBwHmF7/jVUHc6aRNXxAoZA3PdYXruvlldJfTaIATaQA4KU/CzNwMDp84DOYXf+hZXiij' +
+'hJz+DK0QAEd+RYTOOAcgMw0g24oskNYAIoCXxDpbnsOxM8fB5qacwKZD+3WQcS+VxQrYYXNVNGMh' +
+'I1odiIRQSHb8BmbCpgZYjmVLYi0ANmxQNKpOj50FFOB3WnDzEpOnFkGbuOXPimG5Ap0jLqZOLiKo' +
+'MyIsVhfB9lLEpFSQ+S26jh2Fo/n0YagRCUlLRhpAAIMIyWl9vBinAkbfoIPXf+0wnrlxAs/dPInK' +
+'VB1CUOsFkdhD6Nnp49oP98EvWfjvnzqGak0hVlwwFJsaoADK9vq2Y0eOOKUGJLTAjjQgFgBAy/gT' +
+'vbGIyXC0nX66jJd+YgC7X1nCo39/AccfmUVQU1F5y0d9rsvGJW/txuXv7oGqMx7+2/OoVxWIzE5S' +
+'OkfaBBGyhGPHc4G8YYjT+wDLDgUgJbQPWDGuL0/VcefvnMLRB2dw3Uf78dZv345D90zjsX++gPGj' +
+'C7peC8yNI7DjpSVcE476rlEPB++awmP/dCEaEMtqbAP1Fqzkhn0VaUAegMzABJkaIMG8epNEiE3R' +
+'0funce75Mi4NR+MV7+3B6NUFPPnvY3jupslISJkKoW9PDld/sA+7Xt6B8SMV3Pjzx3Di0TkENQaJ' +
+'5A1qM8VRljKPgpg58pcNHyCz0ADSTnhNDTBBglCZruPhvz+PY4/M4Jqwg6772AB2vqwDd/zmKYwd' +
+'WQAJpMalb+vGSz81AA6Ah/76HJ69KfI7tej6K7RPUKwaWQT1FmiAlJEJykXZZh5cE02FoaEJkpYE' +
+'wGsKwNQGAnDhQAUP/915TJ5YwPCleZSG3WwWvwgYvryAYr8Tm5wn/2Mc5cm481c9RzXWobQPyBpS' +
+'ikgDGgJAVvMARzY0AARwc7Y5Ckn3vK4TV7+/D5YncN+fnsWpJ+cgsnDICnj0n85DSOCSUBO6Rl08' +
+'8g8XcObZ+VgjSKweKRG1xgcIEQnA9QE46aMgwwlHAmBuOFFepeMRd8rI1cU4FBzYn8exh2bw6D9e' +
+'wNihCjgrR0wI21vAzb9yIrT/pfha7/y+nXj+5gk8EWrDzJlF/WxQUgMUwEtREGW/5RlpgJdaABq0' +
+'pAGicYFVFaBzxMGV7+vFvtd3YfpsFbf+6ok4KqovxqFoph+YBBAsMg7cPonTT83jsnd247J39IQR' +
+'UUcceR28cxrVcrBUX2sAa1Nar7dCAwhevCkDN7UADB9gSyEBaBVYYeT37PTw9u/aAbcg8Pi/XMAz' +
+'109gfqLhFAktgX46LbrOg395DscemAnD0X68+suGQ+3L4Y7fOhVHRA00nDBRa3wAEGuAA8DbqABI' +
+'kyEA2xFSrBHHM2xf4Ozz82HIOb5kbgSh1TDv69wLZdz0S8dxUTgRHLwkD2HRkgCIdBi6NBPmVpgg' +
+'L7krBkrnA6xIA0Qjfl4x9Bw7XInDzHo1hblJbZYoNkvP3zqFw/fPIKgqGNC7aNoEtUQDEJkg23Ec' +
+'v1qtrhkFiWYeTYzCUCEEeI15QDTSgjpnMerTmyUB1CsKrGACyvABQb1VAnAt13V8NAHRxGqotEMI' +
+'QUbJFgGtMhNuqQa4Ui9HbEgDKFknioKIhC4kbGUwFBhsOGHO/AqhCxAh5dOsBZFBMoqCGhpARJv7' +
+'ihul35oEt84E6U0ZCv1APp0T1tACsIhEpquZQhJsT2C9UAGjtqA2vDnPzOD/NUEqymcOJ94TcPJZ' +
+'zYSFHYKIjHlA+iXk/kvyeO1XDENYtK6J16kn53H375+OBbFukBkFtWoewHAdJ1qQKwAQWcyEtQaQ' +
+'4QPSmk6KZ6gXDlVAcn0x9vTpxTSjdhkBcOYmSO+KNTZlKK0GWHYoASJkZoJIABPHFnDbb5zEFxts' +
+'hqEtMkG2rfcEtAZsJAoimBpgGRqg062KVmsAmBH2V2NfWKZ1woxYAyIBwFABXma+nE30wytV4rU/' +
+'OK9xLWaGUmpJAHE+awEDUsrGnoCERsooyJYALfPaOEHNByBl7BGwKQsy8kYLUZ1kOTXyZprgUYJH' +
+'SBzrctLHDZ6huflCLt61qtWDWAMawsgOWgCe5+v+JYN4vT6AtAbIpSCIGuEcRoaG8TrXRcwzCeZ7' +
+'u2gcm4QIZn0QEudC5wGYdYxUt2PyjRSAyWsc6mvW6hW0CnpXzAdgQ6NZAdByJsgKBQAQGCp+oQFQ' +
+'8ePdhUIBxWJxXfrJYKQHNRUMMK9kuwhzc3O4eO+eeLQqpbLfFfMaAgAnhdDccrSpAZYtAUApxujI' +
+'EN725lfg3//7bvT19cOyLJhg44/ZCTo1y40yI79qmT4/5un2jTx0+XLtmAOAlUJXVx6ve83LdFkr' +
+'dsWMTZkUTpikjFyAJUxHFr6oDc918cDDT6KyMB8xzVFpmBpAGGZHiCgVZgoRphSlQkCQTvXxEhFk' +
+'lMolXnyseY28NMtlIjXaCzsHO7aPoFDIQ6nWCMDzXS2AdJvybMl4HiaSLyK89S2vxRte/wrU6vXG' +
+'IFrzOxdWTZcaMNtCgq15a9vNtWyTMjUncwEguSu2ISesO3vp3YDkE2ZSypiyQMO0JO331gTFryoJ' +
+'IXylVLrFOCtEpAHmaG5jbQ3Qb8r45XKFN2qCOCJpSUsxi/n5SlOP8rXB0WpoUgC8HgGwQYqI7AMH' +
+'j1G9zk2Ea20wgI5iPhqs8dMk6/26GrOyiqharc16nlffvn3EaWtAc/BcBw8+/Ojc+PjkKaMvuWkN' +
+'ME+YnZ17+rnnDxweHOi9iCM+gzbLOXLrG8piu46JIO5/4NHD9XpwbEPfEqjJ01R0XecDYcz8lvhF' +
+'MSEkwJIBaU76AZA+SsST5oHOmidqvsHQieYk6ya/ucysT/pPon6yLum/5tXN4uV45ocAKHEeWFdQ' +
+'YcpKKb4wNnH/xMTUjwGYArBofLHfuhfjeO+eXbu+/ms+946JyWl16NAxWmV80AZGImW+M0z/dxWU' +
+'NbvJNQzaqNK4ro13v/NN9C//doP4gz/+mxKAWWNQb2hHzL/s0n1XDfT3W3fe8wRAVmLytCE56HM3' +
+'LL/E+bRqb+niFZ9rSvD0nnHzd2Y+M3vs5Ckwc/S9QQMABgGc0cvS9fU8migi0uUDey7asfvQ4eMQ' +
+'louuzs74Am0sL4TZQhHHTpzG8FB/qdRR3DU9M/sUgJqmphfjhJaa9H1v9/Ztw/1PPn0QtWoNs7Oz' +
+'WBltATiOixMnzuCS/bvtgTBwCQXg6s5fNLdTmnkuSAKww0WrS7q6St7E5Ax6egbWWHpow3EcnDs/' +
+'EX8v6fDw4J4XDhzxASwAEOvSAF2Wu2j3jssAQqVSQ6+ULTQ/W3+pQy/dYHauEi9Sbhsd2gGgqB2x' +
+'BEDN+gCpy3rCCGjP5OQ0FHO0idGeDTexHRkoxvjEJHZsGxkE0APgnO5TYc6x1hKAIKJtu3dtGzp1' +
+'+hyKxY5oB6wpDWibIRenTp3D6OhQl5RyMAiC5w0TRCtpACW+rM8aGR7cPzTYX3ziqQPw/dzmm4gt' +
+'YOaYGZ7n4cTJs3jVK67xw++l23723AVtURLhaFIDEuGnG47+S33fo8mpWZQ6XUxPT6ONtfeD7dgR' +
+'j6NQyNHQ0MCOUAA2ANmMBpAhhGJo//eFy6lgFsjn823zsw6cnhyHUhw74kcfe8ozfMCKAkjOAYb2' +
+'7tk5cubsBTiuF3v35h1w2xwpRmgxZrBj+/AIgA4AY7pfsZYGyIi6uzv3hHOArocefQbMwNTUVFsD' +
+'mjdDIUmcDgfv6OhwH4CIjie0gJfVAF3J2bVjWzgB65TnL0ygs7NrnROwthZUqzWcPHUOV1y2txiu' +
+'JA/Pzc0/spYJEob5ye/Zs/NiZka5XEVPr4821gfP9xAN3nA9yB4c6Nt+cG5eLvPGDCdNUKNS7769' +
+'u3ZGX1NfqwfR+s//C/PDnH5TRq+kxun8fBkdxQJGhgd2Hjx01BBAwgQl7L/I5fyd4RJE3+TUdNjI' +
+'PKSc0AJg/T+JxNNnK5Uly3VuterJOpzh3hmts5DWKExy3/j6l2J4eAAjI4PbjG9UF6YQrMaBWRCu' +
+'fu4fHRn0Bvp7USzkUS4vmD9as+IP3cSHWL5eXGTUizk6v/IDubodM7+++qs+ENbsg2RxLlE/5pr1' +
+'Ew8H25aFnp6u2CFvGx0e0JHQGdMEJTWgkTo7d4xe3NfXg1KpiLe86TWg9ONtc3eKuVX3yatei5m1' +
+'AIa6pRT9QaCeb2YporBzx7Zd0chnRkgKbaSLsMLZcK6/rzecU53n5TSAEkw/HPkFy86BpJtq3LRB' +
+'IK6jq7NDhPOqPi0A0+cuuxq6EMas5bGJaVQWFWgTbrqVTdEX9f4ZvmfB9/3Il5bW2hNmnZbDB4om' +
+'Lpw/h7n5RYCa+3E0ToY4Jp9XiGSYk/WMvHmlxDEn7yN5ffN4mTzrM808G+0leJqVbG81njbfjFJH' +
+'Hr4no4lZ3fjRT06GoWxQ+eFHn7rTz/1Tv5QSrBQpZrAmfVMaQJyNOXHOPESjztJfs54uxFJWl5q1' +
+'zYuZRzD+RzAPEufoJFln2TyMv8axwUheJPGRVSMFEHe4ZckqMy8cOXLin5f7xVUyyPypwhKAHp13' +
+'IjJCVW4iHGAz30Q5mmx3I+dwyvbWE36x0ck1AFW9Gb+g06qmWkMQVuLEQEtuVldyjR/vFJqyjxNb' +
+'6+mTA6DV96HMvkx0ej2pAZZxoBL5QJ8oDKIW3jxnfA5twj1xUhPMjjd9wGpOOEgIgUzaxFG8RZ4F' +
+'Tgxos9N1atajtd+S1LytA26p8NKbQE7/0+BtpNakNtpoo4022vgf7lRPtKCE39oAAAAASUVORK5C' +
+'YII='
+);
+
+lib.resource.add('hterm/concat/date', 'text/plain',
+'Thu, 05 Dec 2019 19:56:34 +0000'
+);
+
+lib.resource.add('hterm/changelog/version', 'text/plain',
+'1.87'
+);
+
+lib.resource.add('hterm/changelog/date', 'text/plain',
+'2019-11-28'
+);
+
+lib.resource.add('hterm/git/HEAD', 'text/plain',
+'307bace043a3f3f7069c99b08c4f6a2f8c0ca6eb'
+);
+
diff --git a/htdocs/index.js b/htdocs/index.js
index ea40e4d..8c6f270 100644
--- a/htdocs/index.js
+++ b/htdocs/index.js
@@ -9,13 +9,16 @@
  */
 
 // The latest hterm release that we default to.
-const latestRelease = '1.84';
+const latestRelease = '1.87';
 // All hterm releases that may be dynamically selected.
 const allReleases = [
   '1.80',
   '1.81',
   '1.82',
   '1.83',
+  '1.84',
+  '1.85',
+  '1.86',
   latestRelease,
 ];
 // The current version loaded.
